| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597 |
- #include <linux/delay.h>
- #include <linux/sched.h>
- #include <linux/semaphore.h>
- #include <linux/module.h>
- #include <linux/wait.h>
- #include <linux/kthread.h>
- #include <linux/mutex.h>
- #include <linux/types.h>
- #include <linux/ktime.h>
- #include <linux/of.h>
- #include <linux/of_irq.h>
- #include <linux/vmalloc.h>
- #include <linux/slab.h>
- #include <linux/switch.h>
- #include "disp_drv_platform.h"
- #include "ion_drv.h"
- #include "mtk_ion.h"
- #include "m4u.h"
- #include "mt_idle.h"
- #include "mt_spm_idle.h"
- #include "mt_spm.h" /* for sodi reg addr define */
- #define mt_eint_set_hw_debounce(eint_num, ms) (void)0
- /* #include <linux/rtpm_prio.h> */
- /* #include "mach/eint.h" */
- #include <mt-plat/mt_gpio.h>
- #ifdef CONFIG_MTK_CLKMGR
- #include <mach/mt_clkmgr.h>
- #endif
- #if defined(CONFIG_MTK_LEGACY)
- /* #include <cust_eint.h> */
- /* #include <cust_gpio_usage.h> */
- #endif
- #include "mtk_sync.h"
- #include "mtkfb.h"
- #include "mtkfb_fence.h"
- #include "disp_session.h"
- #include "debug.h"
- #include "disp_drv_log.h"
- #include "disp_lcm.h"
- #include "disp_utils.h"
- #include "display_recorder.h"
- #include "fbconfig_kdebug.h"
- #include "primary_display.h"
- #include "disp_helper.h"
- #include "ddp_hal.h"
- #include "ddp_dump.h"
- #include "ddp_path.h"
- #include "ddp_drv.h"
- #include "ddp_ovl.h"
- #include "ddp_rdma.h"
- #include "ddp_manager.h"
- #include "ddp_mmp.h"
- #include "ddp_reg.h"
- #include "ddp_debug.h"
- #include "ddp_irq.h"
- #ifndef MTK_FB_CMDQ_DISABLE
- #include "cmdq_def.h"
- #include "cmdq_record.h"
- #include "cmdq_reg.h"
- #include "cmdq_core.h"
- #endif
- #include "disp_assert_layer.h"
- #include "ddp_dsi.h"
- #include "mtk_disp_mgr.h"
- #include "ddp_wdma.h"
- #include "ddp_wdma_ex.h"
- #include "mt_clk_id.h"
- #include "mmdvfs_mgr.h"
- #include "mt_smi.h"
- #include <mach/mt_freqhopping.h>
- typedef void (*fence_release_callback) (unsigned int data);
- unsigned int is_hwc_enabled = 0;
- static int is_hwc_update_frame;
- unsigned int gEnableLowPowerFeature = 0;
- /* int _trigger_display_interface(int blocking, void *callback, unsigned int userdata); */
- int primary_display_use_cmdq = CMDQ_DISABLE;
- int primary_display_use_m4u = 1;
- #if defined(MTK_OVL_DECOUPLE_SUPPORT)
- DISP_PRIMARY_PATH_MODE primary_display_mode = DECOUPLE_MODE;
- #else
- DISP_PRIMARY_PATH_MODE primary_display_mode = DIRECT_LINK_MODE;
- #endif
- static unsigned long dim_layer_mva;
- /* wdma dump thread */
- static unsigned int primary_dump_wdma;
- static struct task_struct *primary_display_wdma_out;
- static unsigned long dc_vAddr[DISP_INTERNAL_BUFFER_COUNT];
- static disp_internal_buffer_info *decouple_buffer_info[DISP_INTERNAL_BUFFER_COUNT];
- static RDMA_CONFIG_STRUCT decouple_rdma_config;
- static WDMA_CONFIG_STRUCT decouple_wdma_config;
- static disp_mem_output_config mem_config;
- static unsigned int primary_session_id = MAKE_DISP_SESSION(DISP_SESSION_PRIMARY, 0);
- unsigned int ext_session_id = MAKE_DISP_SESSION(DISP_SESSION_MEMORY, 2);
- /* primary display uses itself's abs macro */
- #ifdef abs
- #undef abs
- #define abs(a) (((a) < 0) ? -(a) : (a))
- #endif
- #define FRM_UPDATE_SEQ_CACHE_NUM (DISP_INTERNAL_BUFFER_COUNT+1)
- static disp_frm_seq_info frm_update_sequence[FRM_UPDATE_SEQ_CACHE_NUM];
- static unsigned int frm_update_cnt;
- /* DDP_SCENARIO_ENUM ddp_scenario = DDP_SCENARIO_SUB_RDMA1_DISP; */
- #ifdef DISP_SWITCH_DST_MODE
- int primary_display_def_dst_mode = 0;
- int primary_display_cur_dst_mode = 0;
- #endif
- #ifdef CONFIG_OF
- /* extern unsigned int islcmconnected; */
- #endif
- #define ALIGN_TO(x, n) \
- (((x) + ((n) - 1)) & ~((n) - 1))
- int primary_trigger_cnt = 0;
- #define PRIMARY_DISPLAY_TRIGGER_CNT (1)
- unsigned int gEnterSodiAfterEOF = 0;
- unsigned int WDMA0_FRAME_START_FLAG = 0;
- unsigned int NEW_BUF_IDX = 0;
- unsigned int ALL_LAYER_DISABLE_STEP = 0;
- unsigned long long last_primary_trigger_time = 0xffffffffffffffff;
- unsigned int isIdlePowerOff = 0;
- unsigned int isDSIOff = 0;
- unsigned int gPresentFenceIndex = 0;
- unsigned int gTriggerDispMode = 0; /* 0: normal, 1: lcd only, 2: none of lcd and lcm */
- disp_ddp_path_config last_primary_config;
- static atomic_t DvfsIsHPM = ATOMIC_INIT(1);
- #ifdef CONFIG_TRUSTONIC_TRUSTED_UI
- static struct switch_dev disp_switch_data;
- #endif
- void enqueue_buffer(display_primary_path_context *ctx, struct list_head *head,
- disp_internal_buffer_info *buf)
- {
- if (ctx && head && buf)
- list_add_tail(&buf->list, head);
- /* DISPMSG("enqueue_buffer, head=0x%08x, buf=0x%08x, mva=0x%08x\n", head, buf, buf->mva); */
- }
- void reset_buffer(display_primary_path_context *ctx, disp_internal_buffer_info *buf)
- {
- if (ctx && buf)
- list_del_init(&buf->list);
- /* DISPMSG("reset_buffer, buf=0x%08x, mva=0x%08x\n", buf, buf->mva); */
- }
- disp_internal_buffer_info *dequeue_buffer(display_primary_path_context *ctx,
- struct list_head *head)
- {
- disp_internal_buffer_info *temp = NULL;
- if (ctx && head) {
- if (!list_empty(head)) {
- temp = list_entry(head->prev, disp_internal_buffer_info, list);
- /* DISPMSG("dequeue_buffer, head=0x%08x, buf=0x%08x, mva=0x%08x\n", head, temp, temp->mva); */
- list_del_init(&temp->list);
- if (list_empty(head))
- ; /* DISPMSG("after dequeue_buffer, head:0x%08x is empty\n", head); */
- } else {
- DISPMSG("list is empty, alloc new buffer\n");
- return NULL;
- }
- }
- return temp;
- }
- disp_internal_buffer_info *find_buffer_by_mva(display_primary_path_context *ctx,
- struct list_head *head, uint32_t mva)
- {
- disp_internal_buffer_info *buf = NULL;
- disp_internal_buffer_info *temp = NULL;
- if (ctx && head && mva) {
- if (!list_empty(head)) {
- list_for_each_entry(temp, head, list) {
- /* DISPMSG("find buffer: temp=0x%08x, mva=0x%08x\n", temp, temp->mva); */
- if (mva == temp->mva) {
- buf = temp;
- break;
- }
- }
- }
- /* DISPMSG("find buffer by mva, head=0x%08x, buf=0x%08x\n", head, buf); */
- }
- return buf;
- }
- #define pgc _get_context()
- static display_primary_path_context *_get_context(void)
- {
- static int is_context_inited;
- static display_primary_path_context g_context;
- if (!is_context_inited) {
- memset((void *)&g_context, 0, sizeof(display_primary_path_context));
- is_context_inited = 1;
- }
- return &g_context;
- }
- static inline int _is_mirror_mode(DISP_MODE mode)
- {
- if (mode == DISP_SESSION_DIRECT_LINK_MIRROR_MODE || mode == DISP_SESSION_DECOUPLE_MIRROR_MODE)
- return 1;
- else
- return 0;
- }
- static inline int _is_decouple_mode(DISP_MODE mode)
- {
- if (mode == DISP_SESSION_DECOUPLE_MODE || mode == DISP_SESSION_DECOUPLE_MIRROR_MODE)
- return 1;
- else
- return 0;
- }
- struct mutex esd_mode_switch_lock;
- static void _primary_path_esd_check_lock(void)
- {
- mutex_lock(&esd_mode_switch_lock);
- }
- static void _primary_path_esd_check_unlock(void)
- {
- mutex_unlock(&esd_mode_switch_lock);
- }
- display_primary_path_context *primary_display_path_lock(const char *caller)
- {
- dprec_logger_start(DPREC_LOGGER_PRIMARY_MUTEX, 0, 0);
- disp_sw_mutex_lock(&(pgc->lock));
- pgc->mutex_locker = (char *)caller;
- return pgc;
- }
- void primary_display_path_unlock(const char *caller)
- {
- pgc->mutex_locker = NULL;
- disp_sw_mutex_unlock(&(pgc->lock));
- dprec_logger_done(DPREC_LOGGER_PRIMARY_MUTEX, 0, 0);
- }
- static void _primary_path_cmd_lock(void)
- {
- mutex_lock(&(pgc->cmd_lock));
- }
- static void _primary_path_cmd_unlock(void)
- {
- mutex_unlock(&(pgc->cmd_lock));
- }
- static void _primary_path_lock(const char *caller)
- {
- dprec_logger_start(DPREC_LOGGER_PRIMARY_MUTEX, 0, 0);
- disp_sw_mutex_lock(&(pgc->lock));
- pgc->mutex_locker = (char *)caller;
- }
- static void _primary_path_unlock(const char *caller)
- {
- pgc->mutex_locker = NULL;
- disp_sw_mutex_unlock(&(pgc->lock));
- dprec_logger_done(DPREC_LOGGER_PRIMARY_MUTEX, 0, 0);
- }
- static DECLARE_WAIT_QUEUE_HEAD(display_state_wait_queue);
- static DISP_POWER_STATE primary_get_state(void)
- {
- return pgc->state;
- }
- static DISP_POWER_STATE primary_set_state(DISP_POWER_STATE new_state)
- {
- DISP_POWER_STATE old_state = pgc->state;
- pgc->state = new_state;
- DISPMSG("%s %d to %d\n", __func__, old_state, new_state);
- wake_up(&display_state_wait_queue);
- return old_state;
- }
- /* use MAX_SCHEDULE_TIMEOUT to wait for ever
- * NOTES: primary_path_lock should NOT be held when call this func !!!!!!!!
- */
- #define __primary_display_wait_state(condition, timeout) \
- ({ \
- wait_event_timeout(display_state_wait_queue, condition, timeout);\
- })
- long primary_display_wait_state(DISP_POWER_STATE state, long timeout)
- {
- long ret;
- ret = __primary_display_wait_state(primary_get_state() == state, timeout);
- return ret;
- }
- long primary_display_wait_not_state(DISP_POWER_STATE state, long timeout)
- {
- long ret;
- ret = __primary_display_wait_state(primary_get_state() != state, timeout);
- return ret;
- }
- static void _primary_path_vsync_lock(void)
- {
- mutex_lock(&(pgc->vsync_lock));
- }
- static void _primary_path_vsync_unlock(void)
- {
- mutex_unlock(&(pgc->vsync_lock));
- }
- static void _primary_path_set_dvfsHPM(bool bForcedinHPM, unsigned int needLock)
- {
- if (needLock)
- _primary_path_lock(__func__);
- if (bForcedinHPM)
- atomic_set(&DvfsIsHPM, 1);
- else
- atomic_set(&DvfsIsHPM, 0);
- if (needLock)
- _primary_path_unlock(__func__);
- }
- #ifdef MTK_DISP_IDLE_LP
- static bool _primary_path_IsForcedHPM(unsigned int needLock)
- {
- bool bResult;
- if (needLock)
- _primary_path_lock(__func__);
- if (atomic_read(&DvfsIsHPM) == 1)
- bResult = true;
- else
- bResult = false;
- if (needLock)
- _primary_path_unlock(__func__);
- return bResult;
- }
- #endif
- static void _cmdq_flush_config_handle_mira(void *handle, int blocking);
- #ifdef MTK_DISP_IDLE_LP
- static atomic_t isDdp_Idle = ATOMIC_INIT(0);
- static atomic_t idle_detect_flag = ATOMIC_INIT(0);
- static struct mutex idle_lock;
- static struct task_struct *primary_display_idle_detect_task;
- #define DISP_DSI_REG_VFP 0x28
- static DECLARE_WAIT_QUEUE_HEAD(idle_detect_wq);
- static int _disp_primary_path_idle_clock_on(unsigned int level)
- {
- dpmgr_path_idle_on(pgc->dpmgr_handle, NULL, level);
- return 0;
- }
- static int _disp_primary_path_idle_clock_off(unsigned int level)
- {
- dpmgr_path_idle_off(pgc->dpmgr_handle, NULL, level);
- return 0;
- }
- #ifdef CONFIG_SINGLE_PANEL_OUTPUT
- static void primary_suspend_release_present_fence(void)
- {
- int fence_increment = 0;
- disp_sync_info *layer_info = NULL;
- /* if session not created, do not release present fence*/
- if (pgc->session_id == 0) {
- DISPDBG("_get_sync_info fail in present_fence_release thread\n");
- return;
- }
- layer_info = _get_sync_info(pgc->session_id, disp_sync_get_present_timeline_id());
- if (layer_info == NULL) {
- DISPERR("_get_sync_info fail in present_fence_release thread\n");
- return;
- }
- _primary_path_lock(__func__);
- fence_increment = gPresentFenceIndex-layer_info->timeline->value;
- if (fence_increment > 0) {
- timeline_inc(layer_info->timeline, fence_increment);
- MMProfileLogEx(ddp_mmp_get_events()->present_fence_release,
- MMProfileFlagPulse, gPresentFenceIndex, fence_increment);
- }
- _primary_path_unlock(__func__);
- DISPPR_FENCE("RPF/%d/%d\n", gPresentFenceIndex, gPresentFenceIndex-layer_info->timeline->value);
- }
- #endif
- static DEFINE_SPINLOCK(gLockTopClockOff);
- static int _disp_primary_path_dsi_clock_on(unsigned int level)
- {
- if (!primary_display_is_video_mode()) {
- unsigned long flags;
- #ifndef CONFIG_MTK_CLKMGR
- ddp_clk_prepare(DISP_MTCMOS_CLK);
- #endif
- spin_lock_irqsave(&gLockTopClockOff, flags);
- isDSIOff = 0;
- dpmgr_path_dsi_on(pgc->dpmgr_handle, NULL, level);
- spin_unlock_irqrestore(&gLockTopClockOff, flags);
- }
- return 0;
- }
- static int _disp_primary_path_dsi_clock_off(unsigned int level)
- {
- if (!primary_display_is_video_mode()) {
- unsigned long flags;
- spin_lock_irqsave(&gLockTopClockOff, flags);
- dpmgr_path_dsi_off(pgc->dpmgr_handle, NULL, level);
- isDSIOff = 1;
- spin_unlock_irqrestore(&gLockTopClockOff, flags);
- #ifndef CONFIG_MTK_CLKMGR
- ddp_clk_unprepare(DISP_MTCMOS_CLK);
- #endif
- }
- return 0;
- }
- int _disp_primary_path_set_vfp(int enter)
- {
- int ret = 0;
- if (primary_display_is_video_mode()) {
- LCM_PARAMS *lcm_param = disp_lcm_get_params(pgc->plcm);
- cmdqRecHandle cmdq_handle_vfp = NULL;
- ret = cmdqRecCreate(CMDQ_SCENARIO_PRIMARY_DISP, &cmdq_handle_vfp);
- if (ret != 0) {
- DISPCHECK("fail to create primary cmdq handle for set vfp\n");
- return -1;
- }
- DISPCHECK("primary set vfp, handle=%p\n", cmdq_handle_vfp);
- cmdqRecReset(cmdq_handle_vfp);
- _cmdq_insert_wait_frame_done_token_mira(cmdq_handle_vfp);
- if (enter)
- dpmgr_path_ioctl(pgc->dpmgr_handle, cmdq_handle_vfp, DDP_DSI_VFP_LP,
- (unsigned long *)&(lcm_param->dsi.vertical_vfp_lp));
- else
- dpmgr_path_ioctl(pgc->dpmgr_handle, cmdq_handle_vfp, DDP_DSI_VFP_LP,
- (unsigned long *)&(lcm_param->dsi.vertical_frontporch));
- MMProfileLogEx(ddp_mmp_get_events()->dal_clean, MMProfileFlagPulse, 0, enter);
- _cmdq_flush_config_handle_mira(cmdq_handle_vfp, 1);
- DISPCHECK("[VFP]cmdq_handle_vfp ret=%d\n", ret);
- cmdqRecDestroy(cmdq_handle_vfp);
- cmdq_handle_vfp = NULL;
- } else {
- DISPCHECK("CMD mode don't set vfp for lows\n");
- }
- return ret;
- }
- int primary_display_save_power_for_idle(int enter, unsigned int need_primary_lock)
- {
- static unsigned int isLowPowerMode;
- if (is_hwc_enabled == 0)
- return 0;
- if (need_primary_lock) /* if outer api has add primary lock, do not have to lock again */
- _primary_path_lock(__func__);
- if (primary_get_state() == DISP_SLEPT) {
- DISPMSG("suspend mode can not enable low power.\n");
- goto end;
- }
- if (enter == 1 && isLowPowerMode == 1) {
- DISPMSG("already in low power mode.\n");
- goto end;
- }
- if (enter == 0 && isLowPowerMode == 0) {
- DISPMSG("already not in low power mode.\n");
- goto end;
- }
- isLowPowerMode = enter;
- if (pgc->plcm == NULL) {
- DISPERR("lcm handle is null\n");
- goto end;
- }
- DISPMSG("low power in, enter=%d.\n", enter);
- if (disp_low_power_enlarge_blanking == 1) {
- #if 0
- if (pgc->plcm->params) {
- vfp_for_low_power = pgc->plcm->params->dsi.vertical_frontporch_for_low_power;
- vfp_original = pgc->plcm->params->dsi.vertical_frontporch;
- }
- if (enter)
- DISP_REG_SET(pgc->cmdq_handle_config, dispsys_reg[DISP_REG_DSI0] + DISP_DSI_REG_VFP,
- vfp_for_low_power);
- else
- DISP_REG_SET(pgc->cmdq_handle_config, dispsys_reg[DISP_REG_DSI0] + DISP_DSI_REG_VFP,
- vfp_original);
- #else
- if (primary_display_is_video_mode() == 1)
- _disp_primary_path_set_vfp(enter);
- #endif
- }
- if (1 == disp_low_power_disable_ddp_clock) {/* open */
- if (primary_display_is_video_mode() == 0 /* && gEnableLowPowerFeature==1 */) {
- static unsigned int disp_low_power_disable_ddp_clock_cnt;
- DISPDBG("MM clock, disp_low_power_disable_ddp_clock enter %d.\n",
- disp_low_power_disable_ddp_clock_cnt++);
- if (1 == enter) { /* only for command mode */
- if (isIdlePowerOff == 0) {
- /* extern void clk_stat_bug(void); */
- unsigned long flags;
- DISPMSG("off MM clock start.\n");
- spin_lock_irqsave(&gLockTopClockOff, flags);
- _disp_primary_path_idle_clock_off(0); /* parameter represent level */
- isIdlePowerOff = 1;
- spin_unlock_irqrestore(&gLockTopClockOff, flags);
- #ifndef CONFIG_MTK_CLKMGR
- ddp_clk_unprepare(DISP_MTCMOS_CLK);
- #endif
- /* DISPMSG("off MM clock end.\n"); */
- DISPMSG("***start dump regs! clk_stat_check\n");
- #ifdef CONFIG_MTK_CLKMGR
- clk_stat_check(SYS_DIS);
- #endif
- /*DISPMSG("---- start dump regs! clk_stat_bug.\n"); */
- /* clk_stat_bug(); */
- }
- } else {
- if (isIdlePowerOff == 1) {
- unsigned long flags;
- DISPMSG("on MM clock start.\n");
- #ifndef CONFIG_MTK_CLKMGR
- ddp_clk_prepare(DISP_MTCMOS_CLK);
- #endif
- spin_lock_irqsave(&gLockTopClockOff, flags);
- isIdlePowerOff = 0;
- _disp_primary_path_idle_clock_on(0); /* parameter represent level */
- spin_unlock_irqrestore(&gLockTopClockOff, flags);
- DISPMSG("on MM clock end.\n");
- }
- }
- }
- }
- if (disp_low_power_disable_fence_thread == 1)
- ; /* already implemented. */
- /* no need idle lock, cause primary lock will be used inside switch_mode */
- if (disp_low_power_remove_ovl == 1) {
- if (primary_display_is_video_mode() == 1) {/* only for video mode */
- /* DISPMSG("[LP] OVL pgc->session_mode=%d, enter=%d\n", pgc->session_mode, enter); */
- if (enter) {
- if (pgc->session_mode == DISP_SESSION_DIRECT_LINK_MODE) {
- DISPDBG("[LP]remove ovl.\n");
- primary_display_switch_mode_nolock(DISP_SESSION_DECOUPLE_MODE,
- pgc->session_id, 1);
- }
- /* DISPMSG("disp_low_power_remove_ovl 2\n"); */
- } else {
- if (pgc->session_mode == DISP_SESSION_DECOUPLE_MODE) {
- DISPDBG("[LP]add ovl.\n");
- primary_display_switch_mode_nolock(DISP_SESSION_DIRECT_LINK_MODE,
- pgc->session_id, 1);
- }
- /* DISPMSG("disp_low_power_remove_ovl 4\n"); */
- }
- }
- }
- if (is_mmdvfs_supported() && mmdvfs_get_mmdvfs_profile() == MMDVFS_PROFILE_D1_PLUS) {
- if (_primary_path_IsForcedHPM(0) == false) {
- DISPMSG("MMDVFS enter:%d\n", enter);
- if (enter)
- mmdvfs_set_step(MMDVFS_SCEN_DISP, MMDVFS_VOLTAGE_LOW); /* Vote to LPM mode */
- else if (primary_display_get_width() > 800)
- mmdvfs_set_step(MMDVFS_SCEN_DISP, MMDVFS_VOLTAGE_HIGH); /* Enter HPM mode */
- } else {
- DISPMSG("MMDVFS is forced into HPM\n");
- mmdvfs_set_step(MMDVFS_SCEN_DISP, MMDVFS_VOLTAGE_HIGH); /* Enter HPM mode */
- }
- }
- end:
- if (enter)
- atomic_set(&isDdp_Idle, 1);
- if (need_primary_lock)
- _primary_path_unlock(__func__);
- return 0;
- }
- #if defined(CONFIG_MTK_GMO_RAM_OPTIMIZE)
- static int release_idle_lp_dc_buffer(unsigned int need_primary_lock);
- static int allocate_idle_lp_dc_buffer(void);
- #endif
- void _disp_primary_path_exit_idle(const char *caller, unsigned int need_primary_lock)
- {
- /* _disp_primary_idle_lock(); */
- if (atomic_read(&isDdp_Idle) == 1) {
- DISPMSG("[ddp_idle_on]_disp_primary_path_exit_idle (%s) &&&\n", caller);
- primary_display_save_power_for_idle(0, need_primary_lock);
- #if defined(CONFIG_MTK_GMO_RAM_OPTIMIZE)
- if (primary_display_is_video_mode())
- release_idle_lp_dc_buffer(need_primary_lock);
- #endif
- atomic_set(&isDdp_Idle, 0);
- atomic_set(&idle_detect_flag, 1);
- wake_up(&idle_detect_wq);
- }
- /* _disp_primary_idle_unlock(); */
- }
- /* used by aal/pwm to exit idle before config register(for "screen idle top clock off" feature) */
- void disp_exit_idle_ex(const char *caller)
- {
- if (primary_display_is_video_mode() == 0) {
- disp_update_trigger_time();
- _disp_primary_path_exit_idle(caller, 0);
- }
- }
- static int _disp_primary_path_idle_detect_thread(void *data)
- {
- int ret = 0, idle_time;
- static int enter_cnt;
- static int end_cnt;
- static int stop_cnt;
- #if defined(CONFIG_MTK_GMO_RAM_OPTIMIZE)
- idle_time = 2000;
- #else
- idle_time = 500;
- #endif
- while (1) {
- msleep(idle_time); /* 0.5s trigger once */
- /* DISPMSG("[ddp_idle]_disp_primary_path_idle_detect start 1\n"); */
- if (gSkipIdleDetect || atomic_read(&isDdp_Idle) == 1 ||
- is_hwc_update_frame == 0) /* skip is already in idle mode */
- continue;
- _primary_path_lock(__func__);
- if (primary_get_state() != DISP_ALIVE) {
- MMProfileLogEx(ddp_mmp_get_events()->esd_check_t, MMProfileFlagPulse, 1, 0);
- /* DISPCHECK("[ddp_idle]primary display path is slept?? -- skip ddp_idle\n"); */
- _primary_path_unlock(__func__);
- continue;
- }
- if (pgc->session_mode != DISP_SESSION_DIRECT_LINK_MODE) {
- DISPCHECK("[ddp_idle]primary display path is decouple mode. -- skip ddp_idle\n");
- _primary_path_unlock(__func__);
- continue;
- }
- _primary_path_unlock(__func__);
- /* _disp_primary_idle_lock(); */
- _primary_path_esd_check_lock();
- if (((sched_clock() - last_primary_trigger_time) / 1000) > idle_time * 1000) {
- #if defined(CONFIG_MTK_GMO_RAM_OPTIMIZE)
- /* Dynamically allocate decouple buffer. */
- if (primary_display_is_video_mode()) {
- ret = 0;
- if (decouple_buffer_info[0] == NULL)
- ret = allocate_idle_lp_dc_buffer();
- if (ret < 0) {
- DISPCHECK("[ddp_idle]allocate dc buffer fail\n");
- _primary_path_esd_check_unlock();
- continue;
- }
- }
- #endif
- enter_cnt++;
- pr_debug("[LP] - enter: %d, flag:%d,%d\n", enter_cnt,
- atomic_read(&isDdp_Idle), atomic_read(&idle_detect_flag));
- primary_display_save_power_for_idle(1, 1);
- _primary_path_set_dvfsHPM(false, 0);
- _primary_path_esd_check_unlock();
- } else {
- /* _disp_primary_idle_unlock(); */
- _primary_path_set_dvfsHPM(false, 0);
- _primary_path_esd_check_unlock();
- continue;
- }
- /* _disp_primary_idle_unlock(); */
- ret = wait_event_interruptible(idle_detect_wq, (atomic_read(&idle_detect_flag) != 0));
- atomic_set(&idle_detect_flag, 0);
- /* printk("[ddp_idle]ret=%d\n", ret); */
- if (kthread_should_stop()) {
- stop_cnt++;
- pr_debug("[LP] stop: %d, flag:%d,%d\n", stop_cnt,
- atomic_read(&isDdp_Idle), atomic_read(&idle_detect_flag));
- break;
- }
- end_cnt++;
- pr_debug("[LP] end: %d, flag:%d,%d\n", end_cnt, atomic_read(&isDdp_Idle),
- atomic_read(&idle_detect_flag));
- if (enter_cnt != end_cnt) {
- pr_err("[LP][ASSERT]%d, %d, %d\n", enter_cnt, end_cnt, stop_cnt);
- ASSERT(0);
- }
- }
- return ret;
- }
- int primary_display_cmdq_set_reg(unsigned int addr, unsigned int val)
- {
- int ret = 0;
- cmdqRecHandle handle = NULL;
- ret = cmdqRecCreate(CMDQ_SCENARIO_PRIMARY_DISP, &handle);
- cmdqRecReset(handle);
- _cmdq_insert_wait_frame_done_token_mira(handle);
- cmdqRecWrite(handle, addr & 0x1fffffff, val, ~0);
- cmdqRecFlushAsync(handle);
- cmdqRecDestroy(handle);
- return 0;
- }
- #endif
- unsigned int dvfs_test = 0xFF;
- static atomic_t gMmsysClk = ATOMIC_INIT(0xFF);
- static void set_mmsys_clk(unsigned int clk)
- {
- if (atomic_read(&gMmsysClk) != clk)
- atomic_set(&gMmsysClk, clk);
- }
- static unsigned int get_mmsys_clk(void)
- {
- return atomic_read(&gMmsysClk);
- }
- static int _switch_mmsys_clk(int mmsys_clk_old, int mmsys_clk_new)
- {
- int ret = -1;
- cmdqRecHandle handle;
- DISPMSG("[LP]: %s\n", __func__);
- if (mmsys_clk_new == get_mmsys_clk())
- return ret;
- if (pgc->state == DISP_SLEPT) {
- DISP_REG_MASK(NULL, DISP_REG_CONFIG_C13, 0x07000000, 0x07000000); /* clear */
- DISP_REG_MASK(NULL, DISP_REG_CONFIG_C12, 0x06000000, 0x07000000); /* set syspll2_d2 */
- DISPMSG("[DISP] DVFS mode=%d, profile=%d, state=0x%x\n", mmsys_clk_new,
- mmdvfs_get_mmdvfs_profile(), pgc->state);
- switch (mmsys_clk_new) {
- case MMSYS_CLK_LOW:
- DISP_REG_MASK(NULL, DISP_REG_VENCPLL_CON1, 0x830E0000, 0xFFFFFFFF); /* update */
- break;
- case MMSYS_CLK_MEDIUM:
- /* by frequency hopping */
- goto cpu_d;
- case MMSYS_CLK_HIGH:
- if (mmdvfs_get_mmdvfs_profile() == MMDVFS_PROFILE_D2_P_PLUS) {
- DISP_REG_MASK(NULL, DISP_REG_VENCPLL_CON1, 0x82110000, 0xFFFFFFFF); /* update */
- } else if (mmdvfs_get_mmdvfs_profile() == MMDVFS_PROFILE_D2_M_PLUS) {
- DISP_REG_MASK(NULL, DISP_REG_VENCPLL_CON1, 0x820F0000, 0xFFFFFFFF); /* update */
- }
- break;
- default:
- DISPERR("[DISP] DVFS mode=%d\n", mmsys_clk_new);
- goto cpu_d;
- }
- udelay(40);
- DISP_REG_MASK(NULL, DISP_REG_CONFIG_C13, 0x07000000, 0x07000000); /* clear */
- DISP_REG_MASK(NULL, DISP_REG_CONFIG_C12, 0x01000000, 0x07000000); /* set vencpll_ck */
- cpu_d:
- /* set rdma golden setting parameters */
- set_mmsys_clk(mmsys_clk_new);
- return get_mmsys_clk();
- }
- /* 1.create and reset cmdq */
- cmdqRecCreate(CMDQ_SCENARIO_PRIMARY_DISP, &handle);
- cmdqRecReset(handle);
- /* wait eof */
- _cmdq_insert_wait_frame_done_token_mira(handle);
- cmdqRecWrite(handle, 0x10210048, 0x07000000, 0x07000000); /* clear */
- cmdqRecWrite(handle, 0x10210044, 0x06000000, 0x07000000); /* set syspll2_d2 */
- DISPMSG("[DISP] DVFS mode=%d, profile=%d, state=0x%x\n", mmsys_clk_new,
- mmdvfs_get_mmdvfs_profile(), pgc->state);
- switch (mmsys_clk_new) {
- case MMSYS_CLK_LOW:
- cmdqRecWrite(handle, 0x10209254, 0x830E0000, 0xFFFFFFFF); /* update */
- break;
- case MMSYS_CLK_MEDIUM:
- /* by frequency hopping */
- goto cmdq_d;
- case MMSYS_CLK_HIGH:
- if (mmdvfs_get_mmdvfs_profile() == MMDVFS_PROFILE_D2_P_PLUS) {
- cmdqRecWrite(handle, 0x10209254, 0x82110000, 0xFFFFFFFF); /* update */
- } else if (mmdvfs_get_mmdvfs_profile() == MMDVFS_PROFILE_D2_M_PLUS) {
- cmdqRecWrite(handle, 0x10209254, 0x820F0000, 0xFFFFFFFF); /* update */
- }
- break;
- default:
- DISPERR("[DISP] DVFS mode=%d\n", mmsys_clk_new);
- goto cmdq_d;
- }
- /* wait rdma0_sof: only used for video mode & trigger loop need wait and clear rdma0 sof */
- cmdqRecWaitNoClear(handle, CMDQ_EVENT_DISP_RDMA0_SOF);
- cmdqRecWrite(handle, 0x10210048, 0x07000000, 0x07000000); /* clear */
- cmdqRecWrite(handle, 0x10210044, 0x01000000, 0x07000000); /* set vencpll_ck */
- cmdqRecFlush(handle);
- cmdq_d:
- cmdqRecDestroy(handle);
- /* set rdma golden setting parameters */
- set_mmsys_clk(mmsys_clk_new);
- return get_mmsys_clk();
- }
- int primary_display_switch_mmsys_clk(int mmsys_clk_old, int mmsys_clk_new)
- {
- int ret = -1;
- /* need lock */
- DISPMSG("[LP] %s\n", __func__);
- primary_display_manual_lock();
- ret = _switch_mmsys_clk(mmsys_clk_old, mmsys_clk_new);
- primary_display_manual_unlock();
- return ret;
- }
- int primary_display_set_secondary_display(int add, DISP_SESSION_TYPE type)
- {
- if (add) {
- #ifdef MTK_DISP_IDLE_LP
- gSkipIdleDetect = 1;
- _disp_primary_path_exit_idle(__func__, 0);
- #endif
- } else {
- #ifdef MTK_DISP_IDLE_LP
- gSkipIdleDetect = 0;
- #endif
- }
- return 0;
- }
- static void update_frm_seq_info(unsigned int addr, unsigned int addr_offset, unsigned int seq,
- DISP_FRM_SEQ_STATE state)
- {
- int i = 0;
- if (FRM_CONFIG == state) {
- frm_update_sequence[frm_update_cnt].state = state;
- frm_update_sequence[frm_update_cnt].mva = addr;
- frm_update_sequence[frm_update_cnt].max_offset = addr_offset;
- if (seq > 0)
- frm_update_sequence[frm_update_cnt].seq = seq;
- MMProfileLogEx(ddp_mmp_get_events()->primary_seq_config, MMProfileFlagPulse, addr, seq);
- } else if (FRM_TRIGGER == state) {
- frm_update_sequence[frm_update_cnt].state = FRM_TRIGGER;
- MMProfileLogEx(ddp_mmp_get_events()->primary_seq_trigger, MMProfileFlagPulse,
- frm_update_cnt, frm_update_sequence[frm_update_cnt].seq);
- dprec_logger_frame_seq_begin(pgc->session_id, frm_update_sequence[frm_update_cnt].seq);
- frm_update_cnt++;
- frm_update_cnt %= FRM_UPDATE_SEQ_CACHE_NUM;
- } else if (FRM_START == state) {
- for (i = 0; i < FRM_UPDATE_SEQ_CACHE_NUM; i++) {
- if ((abs(addr - frm_update_sequence[i].mva) <= frm_update_sequence[i].max_offset) &&
- (frm_update_sequence[i].state == FRM_TRIGGER)) {
- MMProfileLogEx(ddp_mmp_get_events()->primary_seq_rdma_irq, MMProfileFlagPulse,
- frm_update_sequence[i].mva | seq, frm_update_sequence[i].state);
- frm_update_sequence[i].state = FRM_START;
- /* break; */
- }
- }
- } else if (FRM_END == state) {
- for (i = 0; i < FRM_UPDATE_SEQ_CACHE_NUM; i++) {
- if (FRM_START == frm_update_sequence[i].state) {
- frm_update_sequence[i].state = FRM_END;
- dprec_logger_frame_seq_end(pgc->session_id, frm_update_sequence[i].seq);
- MMProfileLogEx(ddp_mmp_get_events()->primary_seq_release, MMProfileFlagPulse,
- frm_update_sequence[i].mva, frm_update_sequence[i].seq);
- }
- }
- }
- }
- static int _config_wdma_output(WDMA_CONFIG_STRUCT *wdma_config, disp_path_handle disp_handle,
- cmdqRecHandle cmdq_handle)
- {
- disp_ddp_path_config *pconfig = dpmgr_path_get_last_config(disp_handle);
- pconfig->wdma_config = *wdma_config;
- pconfig->wdma_dirty = 1;
- dpmgr_path_config(disp_handle, pconfig, cmdq_handle);
- return 0;
- }
- static int _config_rdma_input_data(RDMA_CONFIG_STRUCT *rdma_config, disp_path_handle disp_handle,
- cmdqRecHandle cmdq_handle)
- {
- disp_ddp_path_config *pconfig = dpmgr_path_get_last_config(disp_handle);
- pconfig->rdma_config = *rdma_config;
- pconfig->rdma_dirty = 1;
- dpmgr_path_config(disp_handle, pconfig, cmdq_handle);
- return 0;
- }
- #if 0
- /**
- * Defined but not used, avoid build warning. (2015.1.30 Rynn Wu)
- */
- static unsigned int get_frm_seq_by_addr(unsigned int addr, DISP_FRM_SEQ_STATE state)
- {
- int i = 0;
- for (i = 0; i < FRM_UPDATE_SEQ_CACHE_NUM; i++) {
- if (addr == frm_update_sequence[i].mva)
- return frm_update_sequence[i].seq;
- }
- return 0;
- }
- #endif
- #if 0
- /**
- * Defined but not used, avoid build warning. (2015.1.30 Rynn Wu)
- */
- static unsigned int release_started_frm_seq(unsigned int addr, DISP_FRM_SEQ_STATE FRM_END)
- {
- int i = 0;
- for (i = 0; i < FRM_UPDATE_SEQ_CACHE_NUM; i++) {
- if (FRM_END == frm_update_sequence[i].state)
- return frm_update_sequence[i].seq;
- }
- return 0;
- }
- #endif
- #ifdef DISP_SWITCH_DST_MODE
- unsigned long long last_primary_trigger_time;
- bool is_switched_dst_mode = false;
- static struct task_struct *primary_display_switch_dst_mode_task;
- static void _primary_path_switch_dst_lock(void)
- {
- mutex_lock(&(pgc->switch_dst_lock));
- }
- static void _primary_path_switch_dst_unlock(void)
- {
- mutex_unlock(&(pgc->switch_dst_lock));
- }
- static int _disp_primary_path_switch_dst_mode_thread(void *data)
- {
- int ret = 0;
- while (1) {
- msleep(1000);
- if (((sched_clock() - last_primary_trigger_time) / 1000) > 500000) { /* 500ms not trigger disp */
- primary_display_switch_dst_mode(0); /* switch to cmd mode */
- is_switched_dst_mode = true;
- }
- if (kthread_should_stop())
- break;
- }
- return 0;
- }
- #endif
- unsigned long long idlemgr_last_kick_time = 0xffffffffffffffff;
- bool is_switched_dst_mode = false;
- /*----------------------------------------------------------------
- defined but not used because some functions are not used either.
- ----------------------------------------------------------------
- static wait_queue_head_t idlemgr_wq; // For display idle manager
- static atomic_t idlemgr_wakeup = ATOMIC_INIT(0); // For display idle manager
- ----------------------------------------------------------------*/
- struct task_struct *primary_display_idlemgr_task = NULL;
- #if 0
- /**
- * Defined but not used, avoid build warning. (2015.1.30 Rynn Wu)
- */
- static void _idlemgr_wait_for_wakeup(void)
- {
- int ret = 0;
- atomic_set(&idlemgr_wakeup, 0);
- ret = wait_event_interruptible(idlemgr_wq, atomic_read(&idlemgr_wakeup));
- if (ret < 0)
- DISPERR("display idle manager thread waked up by signal\n");
- }
- #endif
- #if 0
- /**
- * Defined but not used, avoid build warning. (2015.1.30 Rynn Wu)
- */
- static void _idlemgr_wakeup(void)
- {
- atomic_set(&idlemgr_wakeup, 1);
- wake_up_interruptible(&idlemgr_wq);
- }
- #endif
- #if 0
- /**
- * Defined but not used, avoid build warning. (2015.1.30 Rynn Wu)
- */
- static void _idlemgr_update_last_kick_time(void)
- {
- idlemgr_last_kick_time = sched_clock();
- }
- #endif
- #if 0
- void primary_display_idlemgr_enter_idle(void)
- {
- MMProfileLogEx(ddp_mmp_get_events()->idlemgr_enter_idle, MMProfileFlagPulse, 0, 0);
- if (!primary_display_is_video_mode()) {
- spm_enable_sodi(1);
- spm_sodi_mempll_pwr_mode(0);
- MMProfileLogEx(ddp_mmp_get_events()->sodi_enable, MMProfileFlagPulse, 0, 0);
- }
- }
- void primary_display_idlemgr_leave_idle(void)
- {
- MMProfileLogEx(ddp_mmp_get_events()->idlemgr_leave_idle, MMProfileFlagPulse, 0, 0);
- if (!primary_display_is_video_mode()) {
- spm_enable_sodi(0);
- MMProfileLogEx(ddp_mmp_get_events()->sodi_disable, MMProfileFlagPulse, 0, 0);
- }
- }
- static int _primary_path_idlemgr_monitor_thread(void *data)
- {
- int ret = 0;
- init_waitqueue_head(&idlemgr_wq);
- while (1) {
- msleep(100);
- if (((sched_clock() - idlemgr_last_kick_time) / 1000) > 500000) {/* 500ms not trigger disp */
- primary_display_idlemgr_enter_idle(); /* switch to cmd mode */
- _idlemgr_wait_for_wakeup();
- }
- if (kthread_should_stop())
- break;
- }
- return 0;
- }
- #else
- void primary_display_idlemgr_kick(char *source)
- {
- }
- void primary_display_idlemgr_enter_idle(void)
- {
- }
- void primary_display_idlemgr_leave_idle(void)
- {
- }
- #if 0
- /**
- * Defined but not used, avoid build warning. (2015.1.30 Rynn Wu)
- */
- static int _primary_path_idlemgr_monitor_thread(void *data)
- {
- return 0;
- }
- #endif
- #endif
- /* extern int disp_od_is_enabled(void); */
- int primary_display_get_debug_state(char *stringbuf, int buf_len)
- {
- int len = 0;
- LCM_PARAMS *lcm_param = disp_lcm_get_params(pgc->plcm);
- LCM_DRIVER *lcm_drv = pgc->plcm->drv;
- len += scnprintf(stringbuf + len, buf_len - len,
- "|--------------------------------------------------------------------------------------|\n");
- len += scnprintf(stringbuf + len, buf_len - len,
- "|********Primary Display Path General Information********\n");
- len += scnprintf(stringbuf + len, buf_len - len, "|Primary Display is %s\n",
- dpmgr_path_is_idle(pgc->dpmgr_handle) ? "idle" : "busy");
- if (mutex_trylock(&(pgc->lock))) {
- mutex_unlock(&(pgc->lock));
- len += scnprintf(stringbuf + len, buf_len - len,
- "|primary path global mutex is free\n");
- } else {
- len += scnprintf(stringbuf + len, buf_len - len,
- "|primary path global mutex is hold by [%s]\n", pgc->mutex_locker);
- }
- if (lcm_param && lcm_drv)
- len += scnprintf(stringbuf + len, buf_len - len,
- "|LCM Driver=[%s]\tResolution=%dx%d,Interface:%s\n", lcm_drv->name,
- lcm_param->width, lcm_param->height,
- (lcm_param->type == LCM_TYPE_DSI) ? "DSI" : "Other");
- /* no OD */
- /* len += scnprintf(stringbuf+len, buf_len - len, "|OD is %s\n", disp_od_is_enabled()?"enabled":"disabled"); */
- len += scnprintf(stringbuf + len, buf_len - len, "|session_mode is 0x%08x\n", pgc->session_mode);
- len += scnprintf(stringbuf + len, buf_len - len,
- "|State=%s\tlcm_fps=%d\tmax_layer=%d\tmode:%d\tvsync_drop=%d\n",
- pgc->state == DISP_ALIVE ? "Alive" : "Sleep", pgc->lcm_fps, pgc->max_layer,
- pgc->mode, pgc->vsync_drop);
- len += scnprintf(stringbuf + len, buf_len - len,
- "|cmdq_handle_config=%p\tcmdq_handle_trigger=%p\tdpmgr_handle=%p\tovl2mem_path_handle=%p\n",
- pgc->cmdq_handle_config, pgc->cmdq_handle_trigger, pgc->dpmgr_handle,
- pgc->ovl2mem_path_handle);
- len += scnprintf(stringbuf + len, buf_len - len, "|Current display driver status=%s + %s\n",
- primary_display_is_video_mode() ? "video mode" : "cmd mode",
- primary_display_cmdq_enabled() ? "CMDQ Enabled" : "CMDQ Disabled");
- return len;
- }
- static char _dump_buffer_string[512];
- static void _dump_internal_buffer_into(display_primary_path_context *ctx, char *dump_reason)
- {
- int n = 0;
- int len = 0;
- disp_internal_buffer_info *buf = NULL;
- struct list_head *head = NULL;
- int i = 0;
- len = sizeof(_dump_buffer_string);
- n += scnprintf(_dump_buffer_string + n, len - n, "dump for %s\n",
- dump_reason ? dump_reason : "unknown");
- if (ctx) {
- mutex_lock(&(pgc->dc_lock));
- head = &(pgc->dc_free_list);
- i = 0;
- n += scnprintf(_dump_buffer_string + n, len - n, "free list: ");
- if (!list_empty(head)) {
- list_for_each_entry(buf, head, list)
- n += scnprintf(_dump_buffer_string + n, len - n, "\t0x%08x", buf->mva);
- }
- n += scnprintf(_dump_buffer_string + n, len - n, "\n");
- #if 0
- head = &(pgc->dc_writing_list);
- i = 0;
- n += scnprintf(_dump_buffer_string + n, len - n, "writing list: ");
- if (!list_empty(head)) {
- list_for_each_entry(buf, head, list)
- n += scnprintf(_dump_buffer_string + n, len - n, "\t0x%08x", buf->mva);
- }
- n += scnprintf(_dump_buffer_string + n, len - n, "\n");
- #endif
- head = &(pgc->dc_reading_list);
- i = 0;
- n += scnprintf(_dump_buffer_string + n, len - n, "reading list: ");
- if (!list_empty(head)) {
- list_for_each_entry(buf, head, list)
- n += scnprintf(_dump_buffer_string + n, len - n, "\t0x%08x", buf->mva);
- }
- n += scnprintf(_dump_buffer_string + n, len - n, "\n");
- DISPMSG("%s", _dump_buffer_string);
- mutex_unlock(&(pgc->dc_lock));
- }
- }
- int32_t decouple_rdma_worker_callback(unsigned long data)
- {
- disp_internal_buffer_info *reading_buf = NULL;
- disp_internal_buffer_info *temp = NULL;
- disp_internal_buffer_info *n = NULL;
- unsigned int current_reading_addr = 0;
- mutex_lock(&(pgc->dc_lock));
- current_reading_addr = ddp_ovl_get_cur_addr(1, 0);
- DISPMSG("rdma applied, 0x%lx, 0x%08x\n", data, current_reading_addr);
- reading_buf = find_buffer_by_mva(pgc, &pgc->dc_reading_list, data);
- if (!reading_buf) {
- /* DISPERR("fatal error, we can't find related buffer info with callback data:0x%08x\n", data); */
- mutex_unlock(&(pgc->dc_lock));
- return 0;
- }
- list_for_each_entry_safe(temp, n, &(pgc->dc_reading_list), list) {
- if (temp && temp->mva != current_reading_addr) {
- DISPMSG("temp=0x%p, temp->mva=0x%08x, temp->list=0x%lx\n", temp, temp->mva,
- (unsigned long)(&temp->list));
- reset_buffer(pgc, temp);
- enqueue_buffer(pgc, &(pgc->dc_free_list), temp);
- }
- }
- mutex_unlock(&(pgc->dc_lock));
- _dump_internal_buffer_into(pgc, "interface applied");
- return 0;
- }
- #if 0
- /**
- * Defined but not used, avoid build warning. (2015.1.30 Rynn Wu)
- */
- static int _disp_primary_path_decouple_worker_thread(void *data)
- {
- int ret = 0;
- primary_disp_input_config input;
- disp_internal_buffer_info *writing_buf = NULL;
- disp_internal_buffer_info *reading_buf = NULL;
- uint32_t current_writing_mva = 0;
- disp_ddp_path_config *pconfig = NULL;
- struct sched_param param = { .sched_priority = 90 };
- sched_setscheduler(current, SCHED_RR, ¶m);
- while (1) {
- /* shuold wait FRAME_START here, but MUTEX1's sof always issued with MUTEX0's sof,
- * root cause still unkonwn. so use FRAME_COMPLETE instead
- */
- dpmgr_wait_event(pgc->ovl2mem_path_handle, DISP_PATH_EVENT_FRAME_COMPLETE);
- pconfig = dpmgr_path_get_last_config(pgc->ovl2mem_path_handle);
- current_writing_mva = pconfig->wdma_config.dstAddress;
- _dump_internal_buffer_into(pgc, "ovl2mem done");
- disp_sw_mutex_lock(&(pgc->dc_lock));
- writing_buf = find_buffer_by_mva(pgc, &pgc->dc_writing_list, current_writing_mva);
- if (!writing_buf) {
- DISPERR("fatal error, we can't find related buffer info with current_writing_mva:0x%08x\n",
- current_writing_mva);
- disp_sw_mutex_unlock(&(pgc->dc_lock));
- continue;
- } else {
- reset_buffer(pgc, writing_buf);
- enqueue_buffer(pgc, &(pgc->dc_reading_list), writing_buf);
- reading_buf = dequeue_buffer(pgc, &(pgc->dc_free_list));
- if (!reading_buf) {
- DISPERR("dc_free_list is empty!!\n");
- disp_sw_mutex_unlock(&(pgc->dc_lock));
- continue;
- } else {
- enqueue_buffer(pgc, &(pgc->dc_writing_list), reading_buf);
- }
- disp_sw_mutex_unlock(&(pgc->dc_lock));
- }
- _dump_internal_buffer_into(pgc, "trigger interface");
- pconfig->wdma_config.dstAddress = reading_buf->mva;
- pconfig->wdma_config.srcHeight = primary_display_get_height();
- pconfig->wdma_config.srcWidth = primary_display_get_width();
- pconfig->wdma_config.clipX = 0;
- pconfig->wdma_config.clipY = 0;
- pconfig->wdma_config.clipHeight = primary_display_get_height();
- pconfig->wdma_config.clipWidth = primary_display_get_width();
- pconfig->wdma_config.outputFormat = eRGB888;
- pconfig->wdma_config.useSpecifiedAlpha = 1;
- pconfig->wdma_config.alpha = 0xFF;
- pconfig->wdma_config.dstPitch = primary_display_get_width() *
- DP_COLOR_BITS_PER_PIXEL(eRGB888) / 8;
- pconfig->wdma_dirty = 1;
- ret = dpmgr_path_config(pgc->ovl2mem_path_handle, pconfig, CMDQ_DISABLE);
- memset((void *)&input, 0, sizeof(primary_disp_input_config));
- input.addr = (unsigned int) writing_buf->mva;
- input.src_x = 0;
- input.src_y = 0;
- input.src_w = primary_display_get_width();
- input.src_h = primary_display_get_height();
- input.dst_x = 0;
- input.dst_y = 0;
- input.dst_w = primary_display_get_width();
- input.dst_h = primary_display_get_height();
- input.fmt = eRGB888;
- input.alpha = 0xFF;
- input.src_pitch = primary_display_get_width() * 3;
- input.isDirty = 1;
- MMProfileLogEx(ddp_mmp_get_events()->interface_trigger, MMProfileFlagPulse,
- input.addr, pconfig->wdma_config.dstAddress);
- ret = primary_display_config_interface_input(&input);
- ret = _trigger_display_interface(FALSE, decouple_rdma_worker_callback, ddp_ovl_get_cur_addr(1, 0));
- if (kthread_should_stop())
- break;
- }
- return 0;
- }
- #endif
- static DISP_MODULE_ENUM _get_dst_module_by_lcm(disp_lcm_handle *plcm)
- {
- if (plcm == NULL) {
- DISPERR("plcm is null\n");
- return DISP_MODULE_UNKNOWN;
- }
- if (plcm->params->type == LCM_TYPE_DSI) {
- if (plcm->lcm_if_id == LCM_INTERFACE_DSI0)
- return DISP_MODULE_DSI0;
- else if (plcm->lcm_if_id == LCM_INTERFACE_DSI1)
- return DISP_MODULE_DSI1;
- else if (plcm->lcm_if_id == LCM_INTERFACE_DSI_DUAL)
- return DISP_MODULE_DSIDUAL;
- else
- return DISP_MODULE_DSI0;
- } else if (plcm->params->type == LCM_TYPE_DPI) {
- return DISP_MODULE_DPI;
- }
- DISPERR("can't find primary path dst module\n");
- return DISP_MODULE_UNKNOWN;
- }
- #define AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- /**
- * trigger operation: VDO+CMDQ CMD+CMDQ VDO+CPU CMD+CPU
- * 1.wait idle: N N Y Y
- * 2.lcm update: N Y N Y
- * 3.path start: idle->Y Y idle->Y Y
- * 4.path trigger: idle->Y Y idle->Y Y
- * 5.mutex enable: N N idle->Y Y
- * 6.set cmdq dirty: N Y N N
- * 7.flush cmdq: Y Y N N
- */
- /**
- * trigger operation: VDO+CMDQ CMD+CMDQ VDO+CPU CMD+CPU
- * 1.wait idle: N N Y Y
- */
- int _should_wait_path_idle(void)
- {
- if (primary_display_cmdq_enabled()) {
- if (primary_display_is_video_mode())
- return 0;
- else
- return 0;
- } else {
- if (primary_display_is_video_mode())
- return dpmgr_path_is_busy(pgc->dpmgr_handle);
- else
- return dpmgr_path_is_busy(pgc->dpmgr_handle);
- }
- }
- /**
- * trigger operation: VDO+CMDQ CMD+CMDQ VDO+CPU CMD+CPU
- * 2.lcm update: N Y N Y
- */
- int _should_update_lcm(void)
- {
- if (primary_display_cmdq_enabled()) {
- if (primary_display_is_video_mode())
- return 0;
- /* TODO: lcm_update can't use cmdq now */
- return 0;
- }
- if (primary_display_is_video_mode())
- return 0;
- else
- return 1;
- }
- /**
- * trigger operation: VDO+CMDQ CMD+CMDQ VDO+CPU CMD+CPU
- * 3.path start: idle->Y Y idle->Y Y
- */
- int _should_start_path(void)
- {
- if (primary_display_cmdq_enabled()) {
- if (primary_display_is_video_mode())
- return 0;
- /* return dpmgr_path_is_idle(pgc->dpmgr_handle); */
- else
- return 0;
- } else {
- if (primary_display_is_video_mode())
- return dpmgr_path_is_idle(pgc->dpmgr_handle);
- else
- return 1;
- }
- }
- /**
- * trigger operation: VDO+CMDQ CMD+CMDQ VDO+CPU CMD+CPU
- * 4.path trigger: idle->Y Y idle->Y Y
- * 5.mutex enable: N N idle->Y Y
- */
- int _should_trigger_path(void)
- {
- /* this is not a perfect design, we can't decide path trigger(ovl/rdma/dsi..) separately with mutex enable */
- /* but it's lucky because path trigger and mutex enable is the same w/o cmdq, and it's correct w/ CMDQ(Y+N). */
- if (primary_display_cmdq_enabled()) {
- if (primary_display_is_video_mode())
- return 0;
- /* return dpmgr_path_is_idle(pgc->dpmgr_handle); */
- else
- return 0;
- } else {
- if (primary_display_is_video_mode())
- return dpmgr_path_is_idle(pgc->dpmgr_handle);
- else
- return 1;
- }
- }
- /**
- * trigger operation: VDO+CMDQ CMD+CMDQ VDO+CPU CMD+CPU
- * 6.set cmdq dirty: N Y N N
- */
- int _should_set_cmdq_dirty(void)
- {
- if (primary_display_cmdq_enabled()) {
- if (primary_display_is_video_mode())
- return 0;
- else
- return 1;
- } else {
- if (primary_display_is_video_mode())
- return 0;
- else
- return 0;
- }
- }
- /**
- * trigger operation: VDO+CMDQ CMD+CMDQ VDO+CPU CMD+CPU
- * 7.flush cmdq: Y Y N N
- */
- int _should_flush_cmdq_config_handle(void)
- {
- if (primary_display_cmdq_enabled()) {
- if (primary_display_is_video_mode())
- return 1;
- else
- return 1;
- } else {
- if (primary_display_is_video_mode())
- return 0;
- else
- return 0;
- }
- }
- int _should_reset_cmdq_config_handle(void)
- {
- if (primary_display_cmdq_enabled()) {
- if (primary_display_is_video_mode())
- return 1;
- else
- return 1;
- } else {
- if (primary_display_is_video_mode())
- return 0;
- else
- return 0;
- }
- }
- /**
- * trigger operation: VDO+CMDQ CMD+CMDQ VDO+CPU CMD+CPU
- * 7.flush cmdq: Y Y N N
- */
- int _should_insert_wait_frame_done_token(void)
- {
- if (primary_display_cmdq_enabled()) {
- if (primary_display_is_video_mode())
- return 1;
- else
- return 1;
- } else {
- if (primary_display_is_video_mode())
- return 0;
- else
- return 0;
- }
- }
- int _should_trigger_interface(void)
- {
- if (pgc->mode == DECOUPLE_MODE)
- return 0;
- else
- return 1;
- }
- int _should_config_ovl_input(void)
- {
- /* should extend this when display path dynamic switch is ready */
- if (pgc->mode == SINGLE_LAYER_MODE || pgc->mode == DEBUG_RDMA1_DSI0_MODE)
- return 0;
- else
- return 1;
- }
- int _should_config_ovl_to_memory(display_primary_path_context *ctx)
- {
- if (ctx == NULL) {
- DISP_FATAL_ERR("DISP", "Context is NULL!\n");
- return 0;
- }
- if (ctx->mode == DECOUPLE_MODE)
- return 1;
- else
- return 0;
- }
- #define OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
- static unsigned long get_current_time_us(void)
- {
- struct timeval t;
- do_gettimeofday(&t);
- return (t.tv_sec & 0xFFF) * 1000000 + t.tv_usec;
- }
- static struct hrtimer cmd_mode_update_timer;
- static int is_fake_timer_inited;
- static enum hrtimer_restart _DISP_CmdModeTimer_handler(struct hrtimer *timer)
- {
- dpmgr_signal_event(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC);
- #if 0
- if ((get_current_time_us() - pgc->last_vsync_tick) > 16666) {
- dpmgr_signal_event(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC);
- pgc->last_vsync_tick = get_current_time_us();
- }
- #endif
- hrtimer_forward_now(timer, ns_to_ktime(16666666));
- return HRTIMER_RESTART;
- }
- int _init_vsync_fake_monitor(int fps)
- {
- if (is_fake_timer_inited)
- return 0;
- is_fake_timer_inited = 1;
- if (fps == 0)
- fps = 6000;
- hrtimer_init(&cmd_mode_update_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- cmd_mode_update_timer.function = _DISP_CmdModeTimer_handler;
- hrtimer_start(&cmd_mode_update_timer, ns_to_ktime(16666666), HRTIMER_MODE_REL);
- DISPMSG("fake timer, init\n");
- return 0;
- }
- #define DISP_REG_SODI_PA 0x10006b0c
- /* extern unsigned int gEnableSODIControl; */
- /* extern unsigned int gPrefetchControl; */
- void disp_set_sodi(unsigned int enable, void *cmdq_handle)
- {
- #ifndef CONFIG_FPGA_EARLY_PORTING
- #ifdef FORCE_SODI_BY_SW
- if (gEnableSODIControl == 1) {
- if (cmdq_handle != NULL) {
- if (enable == 1)
- cmdqRecWrite(cmdq_handle, DISP_REG_SODI_PA, 0, 1);
- else
- cmdqRecWrite(cmdq_handle, DISP_REG_SODI_PA, 1, 1);
- } else {
- if (enable == 1)
- DISP_REG_SET(0, SPM_PCM_SRC_REQ,
- DISP_REG_GET(SPM_PCM_SRC_REQ) & (~0x1));
- else
- DISP_REG_SET(0, SPM_PCM_SRC_REQ,
- DISP_REG_GET(SPM_PCM_SRC_REQ) | 0x1);
- }
- }
- #endif
- #endif
- }
- /* extern unsigned int gEnableSWTrigger; */
- /* extern unsigned int gEnableMutexRisingEdge; */
- /* extern unsigned int gDisableSODIForTriggerLoop; */
- static void _cmdq_build_trigger_loop(void)
- {
- #ifndef MTK_FB_CMDQ_DISABLE
- int ret = 0;
- int i = 0;
- if (pgc->cmdq_handle_trigger == NULL) {
- cmdqRecCreate(CMDQ_SCENARIO_TRIGGER_LOOP, &(pgc->cmdq_handle_trigger));
- DISPMSG("primary path trigger thread cmd handle=%p\n", pgc->cmdq_handle_trigger);
- }
- cmdqRecReset(pgc->cmdq_handle_trigger);
- if (primary_display_is_video_mode()) {
- /* wait and clear stream_done, HW will assert mutex enable automatically in frame done reset. */
- /* todo: should let dpmanager to decide wait which mutex's eof. */
- ret = cmdqRecWait(pgc->cmdq_handle_trigger, CMDQ_EVENT_DISP_RDMA0_EOF);
- ret = cmdqRecWait(pgc->cmdq_handle_trigger,
- dpmgr_path_get_mutex(pgc->dpmgr_handle) +
- CMDQ_EVENT_MUTEX0_STREAM_EOF);
- /* wait and clear rdma0_sof for vfp change */
- cmdqRecClearEventToken(pgc->cmdq_handle_trigger, CMDQ_EVENT_DISP_RDMA0_SOF);
- if (gEnableSWTrigger == 1)
- DISP_REG_SET(pgc->cmdq_handle_trigger, DISP_REG_CONFIG_MUTEX_EN(DISP_OVL_SEPARATE_MUTEX_ID), 1);
- /* for some module(like COLOR) to read hw register to GPR after frame done */
- dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_trigger,
- CMDQ_AFTER_STREAM_EOF);
- } else {
- ret = cmdqRecWaitNoClear(pgc->cmdq_handle_trigger, CMDQ_SYNC_TOKEN_CABC_EOF);
- /* DSI command mode doesn't have mutex_stream_eof, need use CMDQ token instead */
- ret = cmdqRecWait(pgc->cmdq_handle_trigger, CMDQ_SYNC_TOKEN_CONFIG_DIRTY);
- if (_need_wait_esd_eof())
- /* Wait esd config thread done. */
- ret = cmdqRecWaitNoClear(pgc->cmdq_handle_trigger, CMDQ_SYNC_TOKEN_ESD_EOF);
- /* ret = cmdqRecWait(pgc->cmdq_handle_trigger, CMDQ_EVENT_MDP_DSI0_TE_SOF); */
- /* for operations before frame transfer, such as waiting for DSI TE */
- if (islcmconnected)
- dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_trigger, CMDQ_BEFORE_STREAM_SOF);
- /* pull DSI clk lane back to HS */
- DSI_manual_enter_HS(pgc->cmdq_handle_trigger);
- /* cleat frame done token, now the config thread will not allowed to config registers. */
- /* remember that config thread's priority is higher than trigger thread,
- * so all the config queued before will be applied then STREAM_EOF token be cleared
- */
- /* this is what CMDQ did as "Merge" */
- ret = cmdqRecClearEventToken(pgc->cmdq_handle_trigger, CMDQ_SYNC_TOKEN_STREAM_EOF);
- ret = cmdqRecClearEventToken(pgc->cmdq_handle_trigger, CMDQ_SYNC_TOKEN_CONFIG_DIRTY);
- /* enable mutex, only cmd mode need this */
- /* this is what CMDQ did as "Trigger" */
- /* clear rdma EOF token before wait */
- ret = cmdqRecClearEventToken(pgc->cmdq_handle_trigger, CMDQ_EVENT_DISP_RDMA0_EOF);
- #ifdef FORCE_SODI_BY_SW
- /* TODO: use separate api for sodi control flow later */
- /* Enable EMI Force On(Equal to SODI Disable) */
- cmdqRecWrite(pgc->cmdq_handle_trigger, 0x10006b0c, 1, 1);
- #endif
- #ifndef FORCE_SODI_CG_MODE
- /* Enable SPM CG Mode(Force 30+ times to ensure write success, need find root cause and fix later) */
- cmdqRecWrite(pgc->cmdq_handle_trigger, 0x10006b04, 0x80, 0x80);
- /* Polling EMI Status to ensure EMI is enabled */
- cmdqRecPoll(pgc->cmdq_handle_trigger, 0x100063b4, 0, 0x00200000);
- #endif
- #ifdef FORCE_SODI_BY_SW
- /* Clear EMI Force on, Let SPM control EMI state now */
- cmdqRecWrite(pgc->cmdq_handle_trigger, 0x10006b0c, 0, 1);
- #endif
- dpmgr_path_trigger(pgc->dpmgr_handle, pgc->cmdq_handle_trigger, CMDQ_ENABLE);
- /* ret = cmdqRecWrite(pgc->cmdq_handle_trigger,
- (unsigned int)(DISP_REG_CONFIG_MUTEX_EN(0))&0x1fffffff, 1, ~0);
- */
- /* backup DSI state register to slot */
- if (gEnableDSIStateCheck == 1) {
- for (i = 0; i < 10; i++) {
- cmdqRecBackupRegisterToSlot(pgc->cmdq_handle_trigger, pgc->dsi_state_info, i,
- DISP_REG_DSI_STATE);
- cmdqRecBackupRegisterToSlot(pgc->cmdq_handle_trigger, pgc->rdma_state_info, i * 5 + 0,
- DISP_REG_RDMA_INT_STATUS);
- cmdqRecBackupRegisterToSlot(pgc->cmdq_handle_trigger, pgc->rdma_state_info, i * 5 + 1,
- DISP_REG_RDMA_IN_P_CNT);
- cmdqRecBackupRegisterToSlot(pgc->cmdq_handle_trigger, pgc->rdma_state_info, i * 5 + 2,
- DISP_REG_RDMA_IN_LINE_CNT);
- cmdqRecBackupRegisterToSlot(pgc->cmdq_handle_trigger, pgc->rdma_state_info, i * 5 + 3,
- DISP_REG_RDMA_OUT_P_CNT);
- cmdqRecBackupRegisterToSlot(pgc->cmdq_handle_trigger, pgc->rdma_state_info, i * 5 + 4,
- DISP_REG_RDMA_OUT_LINE_CNT);
- }
- }
- /* SODI is disabled in config thread, so mutex enable/dsi start/CPU wait
- * TE will not be blocked by SODI
- */
- /* should enable SODI here, */
- if (gDisableSODIForTriggerLoop == 1)
- disp_set_sodi(1, pgc->cmdq_handle_trigger);
- /* waiting for frame done, because we can't use mutex stream eof here,
- * so need to let dpmanager help to decide which event to wait
- */
- /* most time we wait rdmax frame done event. */
- ret = cmdqRecWait(pgc->cmdq_handle_trigger, CMDQ_EVENT_DISP_RDMA0_EOF);
- dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_trigger, CMDQ_WAIT_STREAM_EOF_EVENT);
- /* dsi is not idle rightly after rdma frame done,
- * so we need to polling about 1us for dsi returns to idle
- */
- /* do not polling dsi idle directly which will decrease CMDQ performance */
- dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_trigger, CMDQ_CHECK_IDLE_AFTER_STREAM_EOF);
- /* for some module(like COLOR) to read hw register to GPR after frame done */
- dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_trigger, CMDQ_AFTER_STREAM_EOF);
- #ifndef FORCE_SODI_CG_MODE
- /* Enable EMI Power Down Mode */
- cmdqRecWrite(pgc->cmdq_handle_trigger, 0x10006b04, 0, 0x80);
- #endif
- /* pull DSI clk lane to LP */
- DSI_sw_clk_trail_cmdq(0, pgc->cmdq_handle_trigger);
- /* polling DSI idle */
- /* ret = cmdqRecPoll(pgc->cmdq_handle_trigger, 0x1401b00c, 0, 0x80000000); */
- /* polling wdma frame done */
- /* ret = cmdqRecPoll(pgc->cmdq_handle_trigger, 0x140060A0, 1, 0x1); */
- /* now frame done, config thread is allowed to config register now */
- ret = cmdqRecSetEventToken(pgc->cmdq_handle_trigger, CMDQ_SYNC_TOKEN_STREAM_EOF);
- /* RUN forever!!!! */
- BUG_ON(ret < 0);
- }
- /* dump trigger loop instructions to check whether dpmgr_path_build_cmdq works correctly */
- DISPPRINT("primary display BUILD cmdq trigger loop finished\n");
- return;
- #endif
- }
- void disp_spm_enter_cg_mode(void)
- {
- MMProfileLogEx(ddp_mmp_get_events()->cg_mode, MMProfileFlagPulse, 0, 0);
- }
- void disp_spm_enter_power_down_mode(void)
- {
- MMProfileLogEx(ddp_mmp_get_events()->power_down_mode, MMProfileFlagPulse, 0, 0);
- }
- #if 0
- /**
- * Defined but not used, avoid build warning. (2015.1.30 Rynn Wu)
- */
- static void _cmdq_build_monitor_loop(void)
- {
- int ret = 0;
- cmdqRecHandle g_cmdq_handle_monitor;
- cmdqRecCreate(CMDQ_SCENARIO_DISP_SCREEN_CAPTURE, &(g_cmdq_handle_monitor));
- DISPMSG("primary path monitor thread cmd handle=%p\n", g_cmdq_handle_monitor);
- cmdqRecReset(g_cmdq_handle_monitor);
- /* wait and clear stream_done, HW will assert mutex enable automatically in frame done reset. */
- /* todo: should let dpmanager to decide wait which mutex's eof. */
- ret = cmdqRecWait(g_cmdq_handle_monitor, CMDQ_EVENT_DISP_RDMA0_UNDERRUN);
- cmdqRecReadToDataRegister(g_cmdq_handle_monitor, 0x10006b0c, CMDQ_DATA_REG_2D_SHARPNESS_1_DST);
- cmdqRecWriteFromDataRegister(g_cmdq_handle_monitor, CMDQ_DATA_REG_2D_SHARPNESS_1_DST, 0x1401b280);
- cmdqRecReadToDataRegister(g_cmdq_handle_monitor, 0x10006b08, CMDQ_DATA_REG_2D_SHARPNESS_1_DST);
- cmdqRecWriteFromDataRegister(g_cmdq_handle_monitor, CMDQ_DATA_REG_2D_SHARPNESS_1_DST, 0x1401b284);
- cmdqRecReadToDataRegister(g_cmdq_handle_monitor, 0x10006b04, CMDQ_DATA_REG_2D_SHARPNESS_1_DST);
- cmdqRecWriteFromDataRegister(g_cmdq_handle_monitor, CMDQ_DATA_REG_2D_SHARPNESS_1_DST, 0x1401b288);
- cmdqRecReadToDataRegister(g_cmdq_handle_monitor, 0x1401b16c, CMDQ_DATA_REG_2D_SHARPNESS_1_DST);
- cmdqRecWriteFromDataRegister(g_cmdq_handle_monitor, CMDQ_DATA_REG_2D_SHARPNESS_1_DST, 0x1401b28C);
- ret = cmdqRecStartLoop(g_cmdq_handle_monitor);
- }
- #endif
- static void _cmdq_start_trigger_loop(void)
- {
- #ifndef MTK_FB_CMDQ_DISABLE
- int ret = 0;
- cmdqRecDumpCommand(pgc->cmdq_handle_trigger);
- /* this should be called only once because trigger loop will nevet stop */
- ret = cmdqRecStartLoop(pgc->cmdq_handle_trigger);
- if (!primary_display_is_video_mode()) {
- /* Need set esd check eof synctoken to let trigger loop go. */
- if (_need_wait_esd_eof())
- cmdqCoreSetEvent(CMDQ_SYNC_TOKEN_ESD_EOF);
- /* need to set STREAM_EOF for the first time, otherwise we will stuck in dead loop */
- cmdqCoreSetEvent(CMDQ_SYNC_TOKEN_STREAM_EOF);
- cmdqCoreSetEvent(CMDQ_SYNC_TOKEN_CABC_EOF);
- dprec_event_op(DPREC_EVENT_CMDQ_SET_EVENT_ALLOW);
- } else {
- #if 0
- if (dpmgr_path_is_idle(pgc->dpmgr_handle))
- cmdqCoreSetEvent(CMDQ_EVENT_MUTEX0_STREAM_EOF);
- #endif
- }
- if (_is_decouple_mode(pgc->session_mode))
- cmdqCoreSetEvent(CMDQ_EVENT_DISP_WDMA0_EOF);
- DISPPRINT("primary display START cmdq trigger loop finished\n");
- #endif
- }
- static void _cmdq_stop_trigger_loop(void)
- {
- #ifndef MTK_FB_CMDQ_DISABLE
- int ret = 0;
- /* this should be called only once because trigger loop will nevet stop */
- ret = cmdqRecStopLoop(pgc->cmdq_handle_trigger);
- DISPCHECK("primary display STOP cmdq trigger loop finished\n");
- #endif
- }
- static void _cmdq_set_config_handle_dirty(void)
- {
- #ifndef MTK_FB_CMDQ_DISABLE
- if (!primary_display_is_video_mode()) {
- dprec_logger_start(DPREC_LOGGER_PRIMARY_CMDQ_SET_DIRTY, 0, 0);
- /* only command mode need to set dirty */
- cmdqRecSetEventToken(pgc->cmdq_handle_config, CMDQ_SYNC_TOKEN_CONFIG_DIRTY);
- dprec_event_op(DPREC_EVENT_CMDQ_SET_DIRTY);
- dprec_logger_done(DPREC_LOGGER_PRIMARY_CMDQ_SET_DIRTY, 0, 0);
- }
- #endif
- }
- static void _cmdq_set_config_handle_dirty_mira(void *handle)
- {
- #ifndef MTK_FB_CMDQ_DISABLE
- if (!primary_display_is_video_mode()) {
- dprec_logger_start(DPREC_LOGGER_PRIMARY_CMDQ_SET_DIRTY, 0, 0);
- /* only command mode need to set dirty */
- cmdqRecSetEventToken(handle, CMDQ_SYNC_TOKEN_CONFIG_DIRTY);
- dprec_event_op(DPREC_EVENT_CMDQ_SET_DIRTY);
- dprec_logger_done(DPREC_LOGGER_PRIMARY_CMDQ_SET_DIRTY, 0, 0);
- }
- #endif
- }
- static void _cmdq_reset_config_handle(void)
- {
- #ifndef MTK_FB_CMDQ_DISABLE
- cmdqRecReset(pgc->cmdq_handle_config);
- dprec_event_op(DPREC_EVENT_CMDQ_RESET);
- #endif
- }
- static void _cmdq_flush_config_handle(int blocking, void *callback, unsigned int userdata)
- {
- #ifndef MTK_FB_CMDQ_DISABLE
- dprec_logger_start(DPREC_LOGGER_PRIMARY_CMDQ_FLUSH, blocking,
- (unsigned int)(unsigned long)callback);
- if (blocking) {
- /* DISPERR("Should not use blocking cmdq flush,
- * may block primary display path for 1 frame period\n");
- */
- cmdqRecFlush(pgc->cmdq_handle_config);
- } else {
- if (callback)
- cmdqRecFlushAsyncCallback(pgc->cmdq_handle_config, callback, userdata);
- else
- cmdqRecFlushAsync(pgc->cmdq_handle_config);
- }
- dprec_event_op(DPREC_EVENT_CMDQ_FLUSH);
- dprec_logger_done(DPREC_LOGGER_PRIMARY_CMDQ_FLUSH, userdata, 0);
- #endif
- }
- static void _cmdq_flush_config_handle_mira(void *handle, int blocking)
- {
- #ifndef MTK_FB_CMDQ_DISABLE
- dprec_logger_start(DPREC_LOGGER_PRIMARY_CMDQ_FLUSH, 0, 0);
- if (blocking)
- cmdqRecFlush(handle);
- else
- cmdqRecFlushAsync(handle);
- dprec_event_op(DPREC_EVENT_CMDQ_FLUSH);
- dprec_logger_done(DPREC_LOGGER_PRIMARY_CMDQ_FLUSH, 0, 0);
- #endif
- }
- static void _cmdq_insert_wait_frame_done_token(void)
- {
- #ifndef MTK_FB_CMDQ_DISABLE
- if (primary_display_is_video_mode())
- cmdqRecWaitNoClear(pgc->cmdq_handle_config, CMDQ_EVENT_MUTEX0_STREAM_EOF);
- else
- cmdqRecWaitNoClear(pgc->cmdq_handle_config, CMDQ_SYNC_TOKEN_STREAM_EOF);
- dprec_event_op(DPREC_EVENT_CMDQ_WAIT_STREAM_EOF);
- #endif
- }
- void _cmdq_insert_wait_frame_done_token_mira(void *handle)
- {
- #ifndef MTK_FB_CMDQ_DISABLE
- if (primary_display_is_video_mode())
- cmdqRecWaitNoClear(handle, CMDQ_EVENT_MUTEX0_STREAM_EOF);
- else
- cmdqRecWaitNoClear(handle, CMDQ_SYNC_TOKEN_STREAM_EOF);
- dprec_event_op(DPREC_EVENT_CMDQ_WAIT_STREAM_EOF);
- #endif
- }
- static int primary_display_is_secure_path(DISP_SESSION_TYPE session_type)
- {
- int i;
- disp_session_input_config *session_input;
- session_input = &cached_session_input[session_type - 1];
- for (i = 0; i < session_input->config_layer_num; i++) {
- if (session_input->config[i].layer_enable &&
- (session_input->config[i].security == DISP_SECURE_BUFFER))
- return 1;
- }
- return 0;
- }
- static void directlink_path_add_memory(WDMA_CONFIG_STRUCT *p_wdma)
- {
- int ret = 0;
- int secure_path_on = primary_display_is_secure_path(DISP_SESSION_PRIMARY);
- cmdqRecHandle cmdq_handle = NULL;
- cmdqRecHandle cmdq_wait_handle = NULL;
- disp_ddp_path_config *pconfig = NULL;
- /*create config thread*/
- ret = cmdqRecCreate(CMDQ_SCENARIO_PRIMARY_DISP, &cmdq_handle);
- if (ret != 0) {
- DISPCHECK("dl_to_dc capture:Fail to create cmdq handle\n");
- ret = -1;
- goto out;
- }
- cmdqRecReset(cmdq_handle);
- /*create wait thread*/
- ret = cmdqRecCreate(CMDQ_SCENARIO_DISP_SCREEN_CAPTURE, &cmdq_wait_handle);
- if (ret != 0) {
- DISPCHECK("dl_to_dc capture:Fail to create cmdq wait handle\n");
- ret = -1;
- goto out;
- }
- cmdqRecReset(cmdq_wait_handle);
- /*configure config thread*/
- if (!secure_path_on)
- cmdqRecEnablePrefetch(cmdq_handle);
- _cmdq_insert_wait_frame_done_token_mira(cmdq_handle);
- dpmgr_path_add_memout(pgc->dpmgr_handle, ENGINE_OVL0, cmdq_handle);
- pconfig = dpmgr_path_get_last_config(pgc->dpmgr_handle);
- pconfig->wdma_config = *p_wdma;
- pconfig->wdma_dirty = 1;
- ret = dpmgr_path_config(pgc->dpmgr_handle, pconfig, cmdq_handle);
- _cmdq_set_config_handle_dirty_mira(cmdq_handle);
- dpmgr_wdma_path_force_power_on();
- if (!secure_path_on)
- cmdqRecDisablePrefetch(cmdq_handle);
- _cmdq_flush_config_handle_mira(cmdq_handle, 0);
- DISPMSG("dl_to_dc capture:Flush add memout mva(0x%lx)\n", p_wdma->dstAddress);
- /*wait wdma0 sof*/
- cmdqRecWait(cmdq_wait_handle, CMDQ_EVENT_DISP_WDMA0_SOF);
- cmdqRecFlush(cmdq_wait_handle);
- DISPMSG("dl_to_dc capture:Flush wait wdma sof\n");
- #if 0
- cmdqRecReset(cmdq_handle);
- _cmdq_insert_wait_frame_done_token_mira(cmdq_handle);
- dpmgr_path_remove_memout(pgc->dpmgr_handle, cmdq_handle);
- _cmdq_set_config_handle_dirty_mira(cmdq_handle);
- /* flush remove memory to cmdq */
- _cmdq_flush_config_handle_mira(cmdq_handle, 0);
- DISPMSG("dl_to_dc capture: Flush remove memout\n");
- dpmgr_path_memout_clock(pgc->dpmgr_handle, 0);
- #endif
- out:
- cmdqRecDestroy(cmdq_handle);
- cmdqRecDestroy(cmdq_wait_handle);
- }
- static unsigned int _get_switch_dc_buffer(void)
- {
- #ifdef CONFIG_MTK_GMO_RAM_OPTIMIZE
- return pgc->dc_buf[0];
- #else
- if (primary_display_is_secure_path(DISP_SESSION_PRIMARY))
- return pgc->session_buf[pgc->session_buf_id];
- else
- return pgc->dc_buf[pgc->dc_buf_id];
- #endif
- }
- static int _DL_switch_to_DC_fast(void)
- {
- int ret = 0;
- int secure_path_on = primary_display_is_secure_path(DISP_SESSION_PRIMARY);
- RDMA_CONFIG_STRUCT rdma_config = decouple_rdma_config;
- WDMA_CONFIG_STRUCT wdma_config = decouple_wdma_config;
- disp_ddp_path_config *data_config_dl = NULL;
- disp_ddp_path_config *data_config_dc = NULL;
- unsigned int mva;
- mva = _get_switch_dc_buffer();
- wdma_config.dstAddress = mva;
- if (secure_path_on)
- wdma_config.security = DISP_SECURE_BUFFER;
- else
- wdma_config.security = DISP_NORMAL_BUFFER;
- /* disable SODI by CPU to prevent underflow */
- #if defined(MTK_FB_SODI_SUPPORT) && !defined(CONFIG_FPGA_EARLY_PORTING)
- spm_enable_sodi(0);
- #endif
- /* 1.save a temp frame to intermediate buffer */
- directlink_path_add_memory(&wdma_config);
- /* 2.reset primary handle */
- _cmdq_reset_config_handle();
- if (!secure_path_on)
- cmdqRecEnablePrefetch(pgc->cmdq_handle_config);
- _cmdq_insert_wait_frame_done_token();
- /* 3.modify interface path handle to new scenario(rdma->dsi) */
- #ifdef CONFIG_FOR_SOURCE_PQ
- dpmgr_modify_path(pgc->dpmgr_handle, DDP_SCENARIO_PRIMARY_RDMA0_DISP, pgc->cmdq_handle_config,
- primary_display_is_video_mode() ? DDP_VIDEO_MODE : DDP_CMD_MODE);
- #else
- dpmgr_modify_path(pgc->dpmgr_handle, DDP_SCENARIO_PRIMARY_RDMA0_COLOR0_DISP, pgc->cmdq_handle_config,
- primary_display_is_video_mode() ? DDP_VIDEO_MODE : DDP_CMD_MODE);
- #endif
- /* 4.config rdma from directlink mode to memory mode */
- rdma_config.address = mva;
- rdma_config.security = DISP_NORMAL_BUFFER;
- rdma_config.pitch = primary_display_get_width() * DP_COLOR_BITS_PER_PIXEL(rdma_config.inputFormat) >> 3;
- if (secure_path_on) {
- rdma_config.address = pgc->session_buf[pgc->session_buf_id];
- rdma_config.security = DISP_SECURE_BUFFER;
- }
- data_config_dl = dpmgr_path_get_last_config(pgc->dpmgr_handle);
- data_config_dl->rdma_config = rdma_config;
- data_config_dl->rdma_dirty = 1;
- ret = dpmgr_path_config(pgc->dpmgr_handle, data_config_dl, pgc->cmdq_handle_config);
- /* 5. backup rdma address to slots */
- cmdqRecBackupUpdateSlot(pgc->cmdq_handle_config, pgc->rdma_buff_info, 0, mva);
- /* 6 .flush to cmdq */
- _cmdq_set_config_handle_dirty();
- if (!secure_path_on)
- cmdqRecDisablePrefetch(pgc->cmdq_handle_config);
- _cmdq_flush_config_handle(1, NULL, 0);
- /* ddp_mmp_rdma_layer(&rdma_config, 0, 20, 20); */
- /* 7.reset cmdq */
- _cmdq_reset_config_handle();
- _cmdq_insert_wait_frame_done_token();
- /* 9. create ovl2mem path handle */
- cmdqRecReset(pgc->cmdq_handle_ovl1to2_config);
- #ifdef CONFIG_FOR_SOURCE_PQ
- pgc->ovl2mem_path_handle = dpmgr_create_path(DDP_SCENARIO_PRIMARY_DITHER_MEMOUT,
- pgc->cmdq_handle_ovl1to2_config);
- #else
- pgc->ovl2mem_path_handle = dpmgr_create_path(DDP_SCENARIO_PRIMARY_OVL_MEMOUT,
- pgc->cmdq_handle_ovl1to2_config);
- #endif
- if (pgc->ovl2mem_path_handle) {
- DISPCHECK("dpmgr create ovl memout path SUCCESS(%p)\n", pgc->ovl2mem_path_handle);
- } else {
- DISPCHECK("dpmgr create path FAIL\n");
- return -1;
- }
- dpmgr_path_set_video_mode(pgc->ovl2mem_path_handle, 0);
- #ifndef CONFIG_MTK_CLKMGR
- ddp_clk_prepare(DISP_MTCMOS_CLK);
- #endif
- dpmgr_path_init(pgc->ovl2mem_path_handle, CMDQ_ENABLE);
- data_config_dc = dpmgr_path_get_last_config(pgc->ovl2mem_path_handle);
- data_config_dc->dst_w = rdma_config.width;
- data_config_dc->dst_h = rdma_config.height;
- data_config_dc->dst_dirty = 1;
- /* move ovl config info from dl to dc */
- memcpy(data_config_dc->ovl_config, data_config_dl->ovl_config, sizeof(data_config_dl->ovl_config));
- ret = dpmgr_path_config(pgc->ovl2mem_path_handle, data_config_dc, pgc->cmdq_handle_ovl1to2_config);
- ret = dpmgr_path_start(pgc->ovl2mem_path_handle, CMDQ_ENABLE);
- /* use blocking flush to make sure all config is done. */
- /* cmdqRecDumpCommand(pgc->cmdq_handle_ovl1to2_config); */
- cmdqRecClearEventToken(pgc->cmdq_handle_ovl1to2_config, CMDQ_EVENT_DISP_WDMA0_EOF);
- _cmdq_flush_config_handle_mira(pgc->cmdq_handle_ovl1to2_config, 1);
- cmdqRecReset(pgc->cmdq_handle_ovl1to2_config);
- /* 11..enable event for new path */
- /* dpmgr_enable_event(pgc->ovl2mem_path_handle, DISP_PATH_EVENT_FRAME_COMPLETE); */
- /* dpmgr_map_event_to_irq(pgc->ovl2mem_path_handle, DISP_PATH_EVENT_FRAME_START, DDP_IRQ_WDMA0_FRAME_COMPLETE); */
- /* dpmgr_enable_event(pgc->ovl2mem_path_handle, DISP_PATH_EVENT_FRAME_START); */
- if (primary_display_is_video_mode())
- dpmgr_map_event_to_irq(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC, DDP_IRQ_RDMA0_DONE);
- dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC);
- /* dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE); */
- dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_START);
- /* enable SODI after switch */
- #if defined(MTK_FB_SODI_SUPPORT) && !defined(CONFIG_FPGA_EARLY_PORTING)
- spm_enable_sodi(1);
- #endif
- return ret;
- }
- static int _DC_switch_to_DL_fast(void)
- {
- int ret = 0;
- int layer = 0;
- int secure_path_on = primary_display_is_secure_path(DISP_SESSION_PRIMARY);
- disp_ddp_path_config *data_config_dl = NULL;
- disp_ddp_path_config *data_config_dc = NULL;
- OVL_CONFIG_STRUCT ovl_config[OVL_LAYER_NUM];
- if(!pgc->ovl2mem_path_handle)
- return -1;
- /* 1. disable SODI */
- #if defined(MTK_FB_SODI_SUPPORT) && !defined(CONFIG_FPGA_EARLY_PORTING)
- spm_enable_sodi(0);
- #endif
- /* 2.enable ovl/wdma clock */
- /* 3.destroy ovl->mem path. */
- #if defined(OVL_TIME_SHARING)
- data_config_dc = &last_primary_config;
- #else
- data_config_dc = dpmgr_path_get_last_config(pgc->ovl2mem_path_handle);
- #endif
- /*save ovl info */;
- memcpy(ovl_config, data_config_dc->ovl_config, sizeof(ovl_config));
-
- dpmgr_path_deinit(pgc->ovl2mem_path_handle,
- (int)(unsigned long)pgc->cmdq_handle_ovl1to2_config);
- #ifndef CONFIG_MTK_CLKMGR
- ddp_clk_unprepare(DISP_MTCMOS_CLK);
- #endif
- dpmgr_destroy_path(pgc->ovl2mem_path_handle, pgc->cmdq_handle_ovl1to2_config);
- pgc->ovl2mem_path_handle = NULL;
- /*clear sof token for next dl to dc */
- cmdqRecClearEventToken(pgc->cmdq_handle_ovl1to2_config, CMDQ_EVENT_DISP_WDMA0_SOF);
- _cmdq_flush_config_handle_mira(pgc->cmdq_handle_ovl1to2_config, 1);
- cmdqRecReset(pgc->cmdq_handle_ovl1to2_config);
- /* release output buffer */
- layer = disp_sync_get_output_timeline_id();
- mtkfb_release_layer_fence(primary_session_id, layer);
- /* 4.modify interface path handle to new scenario(rdma->dsi) */
- _cmdq_reset_config_handle();
- if (!secure_path_on)
- cmdqRecEnablePrefetch(pgc->cmdq_handle_config);
- _cmdq_insert_wait_frame_done_token();
- dpmgr_modify_path(pgc->dpmgr_handle, DDP_SCENARIO_PRIMARY_DISP, pgc->cmdq_handle_config,
- primary_display_is_video_mode() ? DDP_VIDEO_MODE : DDP_CMD_MODE);
- /* 5.config rdma from memory mode to directlink mode */
- data_config_dl = dpmgr_path_get_last_config(pgc->dpmgr_handle);
- data_config_dl->rdma_config = decouple_rdma_config;
- data_config_dl->rdma_config.address = 0;
- data_config_dl->rdma_config.pitch = 0;
- data_config_dl->rdma_config.security = DISP_NORMAL_BUFFER;
- data_config_dl->rdma_dirty = 1;
- memcpy(data_config_dl->ovl_config, ovl_config, sizeof(ovl_config));
- data_config_dl->ovl_dirty = 1;
- ret = dpmgr_path_config(pgc->dpmgr_handle, data_config_dl, pgc->cmdq_handle_config);
- /* use blocking flush to make sure all config is done, then stop/start trigger loop */
- cmdqRecBackupUpdateSlot(pgc->cmdq_handle_config, pgc->rdma_buff_info, 0, 0);
- /* cmdqRecDumpCommand(pgc->cmdq_handle_config); */
- _cmdq_set_config_handle_dirty();
- if (!secure_path_on)
- cmdqRecDisablePrefetch(pgc->cmdq_handle_config);
- _cmdq_flush_config_handle(1, NULL, 0);
- /* release output buffer */
- layer = disp_sync_get_output_interface_timeline_id();
- mtkfb_release_layer_fence(primary_session_id, layer);
- _cmdq_reset_config_handle();
- _cmdq_insert_wait_frame_done_token();
- /* 9.enable event for new path */
- if (primary_display_is_video_mode())
- dpmgr_map_event_to_irq(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC, DDP_IRQ_RDMA0_DONE);
- dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC);
- dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE);
- dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_START);
- /* 1. enable SODI */
- #if defined(MTK_FB_SODI_SUPPORT) && !defined(CONFIG_FPGA_EARLY_PORTING)
- spm_enable_sodi(1);
- #endif
- return ret;
- }
- const char *session_mode_spy(unsigned int mode)
- {
- switch (mode) {
- case DISP_SESSION_DIRECT_LINK_MODE:
- return "DIRECT_LINK";
- case DISP_SESSION_DIRECT_LINK_MIRROR_MODE:
- return "DIRECT_LINK_MIRROR";
- case DISP_SESSION_DECOUPLE_MODE:
- return "DECOUPLE";
- case DISP_SESSION_DECOUPLE_MIRROR_MODE:
- return "DECOUPLE_MIRROR";
- default:
- return "UNKNOWN";
- }
- }
- static int config_display_m4u_port(void)
- {
- int ret = 0;
- M4U_PORT_STRUCT sPort;
- sPort.ePortID = M4U_PORT_DISP_OVL0;
- sPort.Virtuality = primary_display_use_m4u;
- sPort.Security = 0;
- sPort.Distance = 1;
- sPort.Direction = 0;
- ret = m4u_config_port(&sPort);
- if (ret == 0) {
- DISPCHECK("config M4U Port %s to %s SUCCESS\n",
- ddp_get_module_name(DISP_MODULE_OVL0),
- primary_display_use_m4u ? "virtual" : "physical");
- } else {
- DISPCHECK("config M4U Port %s to %s FAIL(ret=%d)\n",
- ddp_get_module_name(DISP_MODULE_OVL0),
- primary_display_use_m4u ? "virtual" : "physical", ret);
- return -1;
- }
- #ifdef OVL_CASCADE_SUPPORT
- sPort.ePortID = M4U_PORT_DISP_OVL1;
- ret = m4u_config_port(&sPort);
- if (ret) {
- DISPCHECK("config M4U Port %s to %s FAIL(ret=%d)\n",
- ddp_get_module_name(DISP_MODULE_OVL1),
- primary_display_use_m4u ? "virtual" : "physical", ret);
- return -1;
- }
- #endif
- sPort.ePortID = M4U_PORT_DISP_RDMA0;
- ret = m4u_config_port(&sPort);
- if (ret) {
- DISPCHECK("config M4U Port %s to %s FAIL(ret=%d)\n",
- ddp_get_module_name(DISP_MODULE_RDMA0),
- primary_display_use_m4u ? "virtual" : "physical", ret);
- return -1;
- }
- sPort.ePortID = M4U_PORT_DISP_WDMA0;
- ret = m4u_config_port(&sPort);
- if (ret) {
- DISPCHECK("config M4U Port %s to %s FAIL(ret=%d)\n",
- ddp_get_module_name(DISP_MODULE_WDMA0),
- primary_display_use_m4u ? "virtual" : "physical", ret);
- return -1;
- }
- return ret;
- }
- static disp_internal_buffer_info *allocat_decouple_buffer(int size)
- {
- void *buffer_va = NULL;
- unsigned int buffer_mva = 0;
- unsigned int mva_size = 0;
- struct ion_client *client = NULL;
- struct ion_handle *handle = NULL;
- disp_internal_buffer_info *buf_info = NULL;
- struct ion_mm_data mm_data;
- memset((void *)&mm_data, 0, sizeof(struct ion_mm_data));
- client = ion_client_create(g_ion_device, "disp_decouple");
- buf_info = kzalloc(sizeof(disp_internal_buffer_info), GFP_KERNEL);
- if (buf_info) {
- handle = ion_alloc(client, size, 0, ION_HEAP_MULTIMEDIA_MASK, 0);
- if (IS_ERR(handle)) {
- DISPERR("Fatal Error, ion_alloc for size %d failed\n", size);
- ion_free(client, handle);
- ion_client_destroy(client);
- kfree(buf_info);
- return NULL;
- }
- buffer_va = ion_map_kernel(client, handle);
- if (buffer_va == NULL) {
- DISPERR("ion_map_kernrl failed\n");
- ion_free(client, handle);
- ion_client_destroy(client);
- kfree(buf_info);
- return NULL;
- }
- mm_data.config_buffer_param.kernel_handle = handle;
- mm_data.mm_cmd = ION_MM_CONFIG_BUFFER;
- if (ion_kernel_ioctl(client, ION_CMD_MULTIMEDIA, (unsigned long)&mm_data) < 0) {
- DISPERR("ion_test_drv: Config buffer failed.\n");
- ion_free(client, handle);
- ion_client_destroy(client);
- kfree(buf_info);
- return NULL;
- }
- ion_phys(client, handle, (ion_phys_addr_t *) &buffer_mva, (size_t *) &mva_size);
- if (buffer_mva == 0) {
- DISPERR("Fatal Error, get mva failed\n");
- ion_free(client, handle);
- ion_client_destroy(client);
- kfree(buf_info);
- return NULL;
- }
- buf_info->handle = handle;
- buf_info->mva = buffer_mva;
- buf_info->size = mva_size;
- buf_info->va = buffer_va;
- buf_info->client = client;
- } else {
- DISPERR("Fatal error, kzalloc internal buffer info failed!!\n");
- kfree(buf_info);
- return NULL;
- }
- return buf_info;
- }
- static int init_decouple_buffers(void)
- {
- int i = 0;
- int height = primary_display_get_height();
- int width = primary_display_get_width();
- int bpp = primary_display_get_dc_bpp();
- int buffer_size = width * height * bpp / 8;
- for (i = 0; i < DISP_INTERNAL_BUFFER_COUNT; i++) {
- decouple_buffer_info[i] = allocat_decouple_buffer(buffer_size);
- if (decouple_buffer_info[i] != NULL) {
- pgc->dc_buf[i] = decouple_buffer_info[i]->mva;
- dc_vAddr[i] = (unsigned long)decouple_buffer_info[i]->va;
- }
- }
- /*initialize rdma config */
- decouple_rdma_config.height = height;
- decouple_rdma_config.width = width;
- decouple_rdma_config.idx = 0;
- decouple_rdma_config.inputFormat = eRGB888;
- decouple_rdma_config.pitch = width * DP_COLOR_BITS_PER_PIXEL(eRGB888) / 8;
- decouple_rdma_config.security = DISP_NORMAL_BUFFER;
- /*initialize wdma config */
- decouple_wdma_config.srcHeight = height;
- decouple_wdma_config.srcWidth = width;
- decouple_wdma_config.clipX = 0;
- decouple_wdma_config.clipY = 0;
- decouple_wdma_config.clipHeight = height;
- decouple_wdma_config.clipWidth = width;
- decouple_wdma_config.outputFormat = eRGB888;
- decouple_wdma_config.useSpecifiedAlpha = 1;
- decouple_wdma_config.alpha = 0xFF;
- decouple_wdma_config.dstPitch = width * DP_COLOR_BITS_PER_PIXEL(eRGB888) / 8;
- decouple_wdma_config.security = DISP_NORMAL_BUFFER;
- return 0;
- }
- #if defined(CONFIG_MTK_GMO_RAM_OPTIMIZE)
- static int allocate_idle_lp_dc_buffer(void)
- {
- int height = primary_display_get_height();
- int width = primary_display_get_width();
- int bpp = primary_display_get_dc_bpp();
- int buffer_size = width * height * bpp / 8;
- decouple_buffer_info[0] = allocat_decouple_buffer(buffer_size);
- if (decouple_buffer_info[0] != NULL) {
- pgc->dc_buf[0] = decouple_buffer_info[0]->mva;
- dc_vAddr[0] = (unsigned long)decouple_buffer_info[0]->va;
- } else {
- return -1;
- }
- /*initialize rdma config*/
- decouple_rdma_config.height = height;
- decouple_rdma_config.width = width;
- decouple_rdma_config.idx = 0;
- decouple_rdma_config.inputFormat = eRGB888;
- decouple_rdma_config.pitch = width * DP_COLOR_BITS_PER_PIXEL(eRGB888) / 8;
- decouple_rdma_config.security = DISP_NORMAL_BUFFER;
- /*initialize wdma config*/
- decouple_wdma_config.srcHeight = height;
- decouple_wdma_config.srcWidth = width;
- decouple_wdma_config.clipX = 0;
- decouple_wdma_config.clipY = 0;
- decouple_wdma_config.clipHeight = height;
- decouple_wdma_config.clipWidth = width;
- decouple_wdma_config.outputFormat = eRGB888;
- decouple_wdma_config.useSpecifiedAlpha = 1;
- decouple_wdma_config.alpha = 0xFF;
- decouple_wdma_config.dstPitch = width * DP_COLOR_BITS_PER_PIXEL(eRGB888) / 8;
- decouple_wdma_config.security = DISP_NORMAL_BUFFER;
- return 0;
- }
- static int release_idle_lp_dc_buffer(unsigned int need_primary_lock)
- {
- if (need_primary_lock)
- _primary_path_lock(__func__);
- if (decouple_buffer_info[0]) {
- ion_free(decouple_buffer_info[0]->client, decouple_buffer_info[0]->handle);
- ion_client_destroy(decouple_buffer_info[0]->client);
- kfree(decouple_buffer_info[0]);
- decouple_buffer_info[0] = NULL;
- }
- if (need_primary_lock)
- _primary_path_unlock(__func__);
- return 0;
- }
- #endif
- static int __build_path_direct_link(void)
- {
- int ret = 0;
- DISP_MODULE_ENUM dst_module = 0;
- /* DISPFUNC();*/
- DISPPRINT("%s\n", __func__);
- pgc->mode = DIRECT_LINK_MODE;
- pgc->dpmgr_handle = dpmgr_create_path(DDP_SCENARIO_PRIMARY_DISP, pgc->cmdq_handle_config);
- if (pgc->dpmgr_handle) {
- DISPPRINT("dpmgr create path SUCCESS(0x%p)\n", pgc->dpmgr_handle);
- } else {
- DISPERR("dpmgr create path FAIL\n");
- return -1;
- }
- dst_module = _get_dst_module_by_lcm(pgc->plcm);
- dpmgr_path_set_dst_module(pgc->dpmgr_handle, dst_module);
- DISPCHECK("dpmgr set dst module FINISHED(%s)\n", ddp_get_module_name(dst_module));
- #ifndef MTKFB_NO_M4U
- config_display_m4u_port();
- #if !defined(CONFIG_MTK_GMO_RAM_OPTIMIZE)
- init_decouple_buffers();
- #endif
- #endif
- dpmgr_set_lcm_utils(pgc->dpmgr_handle, pgc->plcm->drv);
- dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC);
- dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE);
- dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_START);
- /* set video mode must before path_init */
- dpmgr_path_set_video_mode(pgc->dpmgr_handle, primary_display_is_video_mode());
- #ifndef CONFIG_MTK_CLKMGR
- ddp_clk_prepare(DISP_MTCMOS_CLK);
- #endif
- #ifndef MTK_FB_CMDQ_DISABLE
- dpmgr_path_init(pgc->dpmgr_handle, CMDQ_ENABLE);
- /* cmdqRecFlush(pgc->cmdq_handle_config); */
- #else
- dpmgr_path_init(pgc->dpmgr_handle, CMDQ_DISABLE);
- #endif
- return ret;
- }
- static void copy_lklogo_to_dc_buf(void)
- {
- unsigned int line, k, src_argb8888;
- unsigned int *s;
- unsigned char *d;
- for (line = 0; line < primary_display_get_height(); line++) {
- d = (char *)(dc_vAddr[0] + line * primary_display_get_width() * DP_COLOR_BITS_PER_PIXEL(eRGB888) / 8);
- s = (int *)(pgc->framebuffer_va + line * ALIGN_TO(primary_display_get_width(),
- MTK_FB_ALIGNMENT) * primary_display_get_dc_bpp() / 8);
- for (k = 0; k < primary_display_get_width(); k++) {
- src_argb8888 = *s++;
- *d++ = ((src_argb8888 & 0xFF));
- *d++ = ((src_argb8888 & 0xFF00) >> 8);
- *d++ = ((src_argb8888 & 0xFF0000) >> 16);
- }
- }
- }
- static int _build_path_rdma_to_dsi(void)
- {
- DISP_MODULE_ENUM dst_module = 0;
- uint32_t writing_mva = 0;
- #ifdef CONFIG_FOR_SOURCE_PQ
- pgc->dpmgr_handle =
- dpmgr_create_path(DDP_SCENARIO_PRIMARY_RDMA0_DISP, pgc->cmdq_handle_config);
- #else
- pgc->dpmgr_handle =
- dpmgr_create_path(DDP_SCENARIO_PRIMARY_RDMA0_COLOR0_DISP, pgc->cmdq_handle_config);
- #endif
- if (pgc->dpmgr_handle) {
- DISPCHECK("dpmgr create interface path SUCCESS\n");
- } else {
- DISPCHECK("dpmgr create path FAIL\n");
- return -1;
- }
- /* VSYNC event will be provided to hwc for system vsync hw source
- * FRAME_DONE will be used in esd/suspend/resume for path status check
- */
- dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC);
- dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE);
- dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_START);
- dpmgr_set_lcm_utils(pgc->dpmgr_handle, pgc->plcm->drv);
- dst_module = _get_dst_module_by_lcm(pgc->plcm);
- dpmgr_path_set_dst_module(pgc->dpmgr_handle, dst_module);
- dpmgr_path_set_video_mode(pgc->dpmgr_handle, primary_display_is_video_mode());
- if (primary_display_is_video_mode())
- _cmdq_insert_wait_frame_done_token();
- #ifndef CONFIG_MTK_CLKMGR
- ddp_clk_prepare(DISP_MTCMOS_CLK);
- #endif
- dpmgr_path_init(pgc->dpmgr_handle, CMDQ_ENABLE);
- writing_mva = pgc->dc_buf[pgc->dc_buf_id];
- DISPMSG("writing_mva = 0x%08x\n", writing_mva);
- pgc->dc_buf_id++;
- pgc->dc_buf_id %= DISP_INTERNAL_BUFFER_COUNT;
- /*initialize rdma config */
- decouple_rdma_config.address = (unsigned int)writing_mva;
- decouple_rdma_config.width = primary_display_get_width();
- decouple_rdma_config.height = primary_display_get_height();
- decouple_rdma_config.idx = 0;
- decouple_rdma_config.inputFormat = eRGB888;
- decouple_rdma_config.pitch = primary_display_get_width() * DP_COLOR_BITS_PER_PIXEL(eRGB888) / 8;
- _config_rdma_input_data(&decouple_rdma_config, pgc->dpmgr_handle, pgc->cmdq_handle_config);
- cmdqRecFlush(pgc->cmdq_handle_config);
- DISPCHECK("dpmgr set dst module FINISHED(%s)\n", ddp_get_module_name(dst_module));
- return 0;
- }
- static int _build_path_ovl_to_wdma(void)
- {
- int ret = 0;
- uint32_t writing_mva = 0;
- #ifdef CONFIG_FOR_SOURCE_PQ
- pgc->ovl2mem_path_handle = dpmgr_create_path(DDP_SCENARIO_PRIMARY_DITHER_MEMOUT,
- pgc->cmdq_handle_ovl1to2_config);
- #else
- pgc->ovl2mem_path_handle = dpmgr_create_path(DDP_SCENARIO_PRIMARY_OVL_MEMOUT,
- pgc->cmdq_handle_ovl1to2_config);
- #endif
- /*
- * FRAME_START will be used in decouple-mirror mode, for post-path fence release(rdma->dsi)
- */
- dpmgr_enable_event(pgc->ovl2mem_path_handle, DISP_PATH_EVENT_FRAME_COMPLETE);
- dpmgr_enable_event(pgc->ovl2mem_path_handle, DISP_PATH_EVENT_FRAME_START);
- if (pgc->ovl2mem_path_handle) {
- DISPCHECK("dpmgr create ovl memout path SUCCESS\n");
- } else {
- DISPCHECK("dpmgr create path FAIL\n");
- return -1;
- }
- dpmgr_path_set_video_mode(pgc->ovl2mem_path_handle, 0);
- dpmgr_path_init(pgc->ovl2mem_path_handle, CMDQ_DISABLE);
- writing_mva = pgc->dc_buf[pgc->dc_buf_id];
- /*initialize wdma config */
- decouple_wdma_config.dstAddress = writing_mva;
- decouple_wdma_config.srcHeight = primary_display_get_height();
- decouple_wdma_config.srcWidth = primary_display_get_width();
- decouple_wdma_config.clipX = 0;
- decouple_wdma_config.clipY = 0;
- decouple_wdma_config.clipHeight = primary_display_get_height();
- decouple_wdma_config.clipWidth = primary_display_get_width();
- decouple_wdma_config.outputFormat = eRGB888;
- decouple_wdma_config.useSpecifiedAlpha = 1;
- decouple_wdma_config.alpha = 0xFF;
- decouple_wdma_config.dstPitch = primary_display_get_width() * DP_COLOR_BITS_PER_PIXEL(eRGB888) / 8;
- dpmgr_path_reset(pgc->ovl2mem_path_handle, CMDQ_DISABLE);
- _config_wdma_output(&decouple_wdma_config, pgc->ovl2mem_path_handle, NULL);
- ret = dpmgr_path_start(pgc->ovl2mem_path_handle, CMDQ_DISABLE);
- DISPCHECK("build rdma to dsi path finished\n");
- return ret;
- }
- /* #define CONFIG_USE_CMDQ */
- static int __build_path_decouple(void)
- {
- int ret = 0;
- /* DISPFUNC(); */
- DISPPRINT("%s\n", __func__);
- pgc->mode = DECOUPLE_MODE;
- /* 1. Allocate decouple buffers and copy the LK logo to dc buffer. */
- init_decouple_buffers();
- copy_lklogo_to_dc_buf();
- mutex_init(&(pgc->dc_lock));
- /*
- * 2. Enable m4u of RDMA0
- * The OVL engine would be used in VDO mode.
- * Before turn on all the m4u of display modules,
- * the data path need to change to rdma0->dsi.
- */
- {
- M4U_PORT_STRUCT sPort;
- sPort.ePortID = M4U_PORT_DISP_RDMA0;
- sPort.Virtuality = primary_display_use_m4u;
- sPort.Security = 0;
- sPort.Distance = 1;
- sPort.Direction = 0;
- ret = m4u_config_port(&sPort);
- if (ret == 0) {
- DISPCHECK("config M4U Port %s to %s SUCCESS\n",
- ddp_get_module_name(DISP_MODULE_OVL0),
- primary_display_use_m4u ? "virtual" : "physical");
- } else {
- DISPCHECK("config M4U Port %s to %s FAIL(ret=%d)\n",
- ddp_get_module_name(DISP_MODULE_OVL0),
- primary_display_use_m4u ? "virtual" : "physical", ret);
- return -1;
- }
- }
- /* 3. Build and switch display data path from ovl->dsi to rdma->dsi. */
- ret = _build_path_rdma_to_dsi();
- if (ret) {
- pr_debug("build path rdma to dsi fail\n");
- return ret;
- }
- /*
- * 4. Enable all display engine m4u.
- * Since the display data path has been changed to rdma->dsi,
- * all the display engine m4u can be enabled safely.
- */
- config_display_m4u_port();
- /* 5. Build/Connect ovl->wdma display data path. */
- ret = _build_path_ovl_to_wdma();
- if (ret) {
- pr_debug("build path ovl to wdma fail\n");
- return ret;
- }
- DISPCHECK("build decouple path finished\n");
- return ret;
- }
- static int __build_path_single_layer(void)
- {
- return 0; /* avoid build warning. */
- }
- static int __build_path_debug_rdma1_dsi0(void)
- {
- int ret = 0;
- #if defined(MTK_FB_RDMA1_SUPPORT)
- DISP_MODULE_ENUM dst_module = 0;
- pgc->mode = DEBUG_RDMA1_DSI0_MODE;
- pgc->dpmgr_handle = dpmgr_create_path(DDP_SCENARIO_SUB_RDMA1_DISP, pgc->cmdq_handle_config);
- if (pgc->dpmgr_handle) {
- DISPCHECK("dpmgr create path SUCCESS(0x%p)\n", pgc->dpmgr_handle);
- } else {
- DISPCHECK("dpmgr create path FAIL\n");
- return -1;
- }
- dst_module = _get_dst_module_by_lcm(pgc->plcm);
- dpmgr_path_set_dst_module(pgc->dpmgr_handle, dst_module);
- DISPCHECK("dpmgr set dst module FINISHED(%s)\n", ddp_get_module_name(dst_module));
- #ifndef MTKFB_NO_M4U
- {
- #ifdef MTK_FB_RDMA1_SUPPORT
- M4U_PORT_STRUCT sPort;
- sPort.ePortID = M4U_PORT_DISP_RDMA1;
- sPort.Virtuality = primary_display_use_m4u;
- sPort.Security = 0;
- sPort.Distance = 1;
- sPort.Direction = 0;
- ret = m4u_config_port(&sPort);
- if (ret == 0) {
- DISPCHECK("config M4U Port %s to %s SUCCESS\n",
- ddp_get_module_name(DISP_MODULE_RDMA1),
- primary_display_use_m4u ? "virtual" : "physical");
- } else {
- DISPCHECK("config M4U Port %s to %s FAIL(ret=%d)\n",
- ddp_get_module_name(DISP_MODULE_RDMA1),
- primary_display_use_m4u ? "virtual" : "physical", ret);
- return -1;
- }
- #endif
- }
- #endif
- dpmgr_set_lcm_utils(pgc->dpmgr_handle, pgc->plcm->drv);
- dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC);
- dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE);
- #endif
- return ret;
- }
- int disp_fmt_to_hw_fmt(DISP_FORMAT src_fmt, unsigned int *hw_fmt,
- unsigned int *Bpp, unsigned int *bpp)
- {
- switch (src_fmt) {
- case DISP_FORMAT_YUV422:
- *hw_fmt = eYUY2;
- *Bpp = 2;
- *bpp = 16;
- break;
- case DISP_FORMAT_RGB565:
- *hw_fmt = eRGB565;
- *Bpp = 2;
- *bpp = 16;
- break;
- case DISP_FORMAT_RGB888:
- *hw_fmt = eRGB888;
- *Bpp = 3;
- *bpp = 24;
- break;
- case DISP_FORMAT_BGR888:
- *hw_fmt = eBGR888;
- *Bpp = 3;
- *bpp = 24;
- break;
- case DISP_FORMAT_ARGB8888:
- *hw_fmt = eARGB8888;
- *Bpp = 4;
- *bpp = 32;
- break;
- case DISP_FORMAT_ABGR8888:
- *hw_fmt = eABGR8888;
- *Bpp = 4;
- *bpp = 32;
- break;
- case DISP_FORMAT_RGBA8888:
- *hw_fmt = eRGBA8888;
- *Bpp = 4;
- *bpp = 32;
- break;
- case DISP_FORMAT_BGRA8888:
- /* *hw_fmt = eABGR8888; */
- *hw_fmt = eBGRA8888;
- *Bpp = 4;
- *bpp = 32;
- break;
- case DISP_FORMAT_XRGB8888:
- *hw_fmt = eARGB8888;
- *Bpp = 4;
- *bpp = 32;
- break;
- case DISP_FORMAT_XBGR8888:
- *hw_fmt = eABGR8888;
- *Bpp = 4;
- *bpp = 32;
- break;
- case DISP_FORMAT_RGBX8888:
- *hw_fmt = eRGBA8888;
- *Bpp = 4;
- *bpp = 32;
- break;
- case DISP_FORMAT_BGRX8888:
- *hw_fmt = eBGRA8888;
- *Bpp = 4;
- *bpp = 32;
- break;
- case DISP_FORMAT_UYVY:
- *hw_fmt = eUYVY;
- *Bpp = 2;
- *bpp = 16;
- break;
- case DISP_FORMAT_YV12:
- *hw_fmt = eYV12;
- *Bpp = 1;
- *bpp = 8;
- break;
- default:
- DISPERR("Invalid color format: 0x%x\n", src_fmt);
- return -1;
- }
- return 0;
- }
- static int _convert_disp_input_to_ovl(OVL_CONFIG_STRUCT *dst, disp_input_config *src)
- {
- int ret;
- unsigned int Bpp = 0;
- unsigned int bpp = 0;
- if (!src || !dst) {
- DISP_FATAL_ERR("display", "%s src(0x%p) or dst(0x%p) is null\n",
- __func__, src, dst);
- return -1;
- }
- dst->layer = src->layer_id;
- dst->isDirty = 1;
- dst->buff_idx = src->next_buff_idx;
- dst->layer_en = src->layer_enable;
- /* if layer is disable, we just needs config above params. */
- if (!src->layer_enable)
- return 0;
- ret = disp_fmt_to_hw_fmt(src->src_fmt, (unsigned int *)(&(dst->fmt)), (unsigned int *)(&Bpp),
- (unsigned int *)(&bpp));
- dst->addr = (unsigned long)src->src_phy_addr;
- dst->vaddr = (unsigned long)src->src_base_addr;
- dst->src_x = src->src_offset_x;
- dst->src_y = src->src_offset_y;
- dst->src_w = src->src_width;
- dst->src_h = src->src_height;
- dst->src_pitch = src->src_pitch * Bpp;
- dst->dst_x = src->tgt_offset_x;
- dst->dst_y = src->tgt_offset_y;
- /* dst W/H should <= src W/H */
- if (src->buffer_source != DISP_BUFFER_ALPHA) { /* dim layer do not care for src_width */
- dst->dst_w = min(src->src_width, src->tgt_width);
- dst->dst_h = min(src->src_height, src->tgt_height);
- } else {
- dst->dst_w = src->tgt_width;
- dst->dst_h = src->tgt_height;
- }
- dst->keyEn = src->src_use_color_key;
- dst->key = src->src_color_key;
- dst->aen = src->alpha_enable;
- dst->alpha = src->alpha;
- dst->sur_aen = src->sur_aen;
- dst->src_alpha = src->src_alpha;
- dst->dst_alpha = src->dst_alpha;
- #ifdef DISP_DISABLE_X_CHANNEL_ALPHA
- if (DISP_FORMAT_ARGB8888 == src->src_fmt || DISP_FORMAT_ABGR8888 == src->src_fmt ||
- DISP_FORMAT_RGBA8888 == src->src_fmt || DISP_FORMAT_BGRA8888 == src->src_fmt ||
- src->buffer_source == DISP_BUFFER_ALPHA) {
- ;/* nothing */
- } else {
- dst->aen = FALSE;
- dst->sur_aen = FALSE;
- }
- #endif
- dst->identity = src->identity;
- dst->connected_type = src->connected_type;
- dst->security = src->security;
- dst->yuv_range = src->yuv_range;
- if (src->buffer_source == DISP_BUFFER_ALPHA) {
- dst->source = OVL_LAYER_SOURCE_RESERVED; /* dim layer, constant alpha */
- } else if (src->buffer_source == DISP_BUFFER_ION || src->buffer_source == DISP_BUFFER_MVA) {
- dst->source = OVL_LAYER_SOURCE_MEM; /* from memory */
- } else {
- DISPERR("unknown source = %d", src->buffer_source);
- dst->source = OVL_LAYER_SOURCE_MEM;
- }
- return ret;
- }
- static int _convert_disp_input_to_rdma(RDMA_CONFIG_STRUCT *dst, disp_input_config *src)
- {
- int ret;
- unsigned int Bpp = 0;
- unsigned int bpp = 0;
- if (!src || !dst) {
- DISP_FATAL_ERR("display", "%s src(0x%p) or dst(0x%p) is null\n",
- __func__, src, dst);
- return -1;
- }
- ret = disp_fmt_to_hw_fmt(src->src_fmt, &(dst->inputFormat), &Bpp, &bpp);
- dst->address = (unsigned long)src->src_phy_addr;
- dst->width = src->src_width;
- dst->height = src->src_height;
- dst->pitch = src->src_pitch * Bpp;
- return ret;
- }
- /* Video mode SODI CMDQ flow */
- /* extern unsigned int gDumpConfigCMD; */
- /* extern unsigned int gEnableOVLStatusCheck; */
- #define DISP_REG_CMDQ_TOKEN_ID 0x10212060
- #define DISP_REG_CMDQ_TOKEN_VALUE 0x10212064
- #define DISP_MUTEX0_STREAM_EOF_ID 55
- int _trigger_display_interface(int blocking, void *callback, unsigned int userdata)
- {
- static unsigned int cnt;
- /* 4. enable SODI after config */
- if (primary_display_is_video_mode() == 1)
- disp_set_sodi(1, pgc->cmdq_handle_config);
- #ifdef DISP_ENABLE_SODI_FOR_VIDEO_MODE
- if (gPrefetchControl == 1 && cnt >= 20)
- cmdqRecDisablePrefetch(pgc->cmdq_handle_config);
- #endif
- if (_should_wait_path_idle())
- dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE, HZ * 1);
- if (_should_update_lcm())
- disp_lcm_update(pgc->plcm, 0, 0, pgc->plcm->params->width,
- pgc->plcm->params->height, 0);
- if (_should_start_path())
- dpmgr_path_start(pgc->dpmgr_handle, primary_display_cmdq_enabled());
- if (_should_trigger_path())
- /* trigger_loop_handle is used only for build trigger loop,
- * which should always be NULL for config thread
- */
- dpmgr_path_trigger(pgc->dpmgr_handle, NULL, primary_display_cmdq_enabled());
- #ifndef MTK_FB_CMDQ_DISABLE
- if (_should_set_cmdq_dirty()) {
- _cmdq_set_config_handle_dirty();
- /* disable SODI after set dirty */
- if (primary_display_is_video_mode() == 0 && gDisableSODIForTriggerLoop == 1)
- disp_set_sodi(0, pgc->cmdq_handle_config);
- }
- /* 1. disable SODI by CPU before flush CMDQ by CPU */
- if (primary_display_is_video_mode() == 1)
- disp_set_sodi(0, 0);
- if (gDumpConfigCMD == 1) {
- DISPMSG("primary_display_config, dump before flush:\n");
- cmdqRecDumpCommand(pgc->cmdq_handle_config);
- }
- /* insert update ovl status slot command */
- if (primary_display_is_video_mode() == 1) {
- cmdqRecBackupRegisterToSlot(pgc->cmdq_handle_config, pgc->ovl_status_info,
- 0, DISP_REG_OVL0_STATE_PA);
- cmdqRecBackupRegisterToSlot(pgc->cmdq_handle_config, pgc->ovl_status_info,
- 1, DISP_REG_OVL0_STATUS_PA);
- }
- if (_should_flush_cmdq_config_handle())
- _cmdq_flush_config_handle(blocking, callback, userdata);
- if (_should_reset_cmdq_config_handle()) {
- _cmdq_reset_config_handle();
- #ifdef DISP_ENABLE_SODI_FOR_VIDEO_MODE
- /* do not have to enable/disable prefetch at power on stage. */
- if (gPrefetchControl == 1 && cnt >= 20)
- cmdqRecEnablePrefetch(pgc->cmdq_handle_config);
- #endif
- }
- /* TODO: _is_decouple_mode() shuold be protected by mutex!!!!!!!!when dynamic switch decouple/directlink */
- if (_should_insert_wait_frame_done_token() && (!_is_decouple_mode(pgc->session_mode))) {
- /* 2. enable SODI by CMDQ before wait */
- if (primary_display_is_video_mode() == 1)
- disp_set_sodi(1, pgc->cmdq_handle_config);
- if (primary_display_is_video_mode() == 1)
- cmdqRecWaitNoClear(pgc->cmdq_handle_config, CMDQ_EVENT_DISP_RDMA0_EOF);
- else
- _cmdq_insert_wait_frame_done_token();
- /* 3. disable AODI by CMDQ before config */
- if (primary_display_is_video_mode() == 1)
- disp_set_sodi(0, pgc->cmdq_handle_config);
- }
- if (cnt < 20)
- cnt++;
- else
- gEnableLowPowerFeature = 1;
- #endif
- return 0;
- }
- int _trigger_ovl_to_memory(disp_path_handle disp_handle, cmdqRecHandle cmdq_handle,
- fence_release_callback callback, unsigned int data, int blocking)
- {
- unsigned int rdma_pitch_sec;
- dpmgr_wdma_path_force_power_on();
- dpmgr_path_trigger(disp_handle, cmdq_handle, CMDQ_ENABLE);
- cmdqRecWaitNoClear(cmdq_handle, CMDQ_EVENT_DISP_WDMA0_EOF);
- cmdqRecBackupUpdateSlot(cmdq_handle, pgc->rdma_buff_info, 0, mem_config.addr);
- /* rdma pitch only use bit[15..0], we use bit[31:30] to store secure information */
- rdma_pitch_sec = mem_config.pitch | (mem_config.security << 30);
- cmdqRecBackupUpdateSlot(cmdq_handle, pgc->rdma_buff_info, 1, rdma_pitch_sec);
- cmdqRecBackupUpdateSlot(cmdq_handle, pgc->rdma_buff_info, 2, mem_config.fmt);
- if (blocking)
- cmdqRecFlush(cmdq_handle);
- else
- cmdqRecFlushAsyncCallback(cmdq_handle, (CmdqAsyncFlushCB) callback, data);
- cmdqRecReset(cmdq_handle);
- cmdqRecWait(cmdq_handle, CMDQ_EVENT_DISP_WDMA0_EOF);
- MMProfileLogEx(ddp_mmp_get_events()->ovl_trigger, MMProfileFlagPulse, 0, data);
- return 0;
- }
- int _trigger_ovl_to_memory_mirror(disp_path_handle disp_handle, cmdqRecHandle cmdq_handle,
- fence_release_callback callback, unsigned int data)
- {
- int layer = 0;
- unsigned int rdma_pitch_sec;
- dpmgr_wdma_path_force_power_on();
- dpmgr_path_trigger(disp_handle, cmdq_handle, CMDQ_ENABLE);
- cmdqRecWaitNoClear(cmdq_handle, CMDQ_EVENT_DISP_WDMA0_EOF);
- layer = disp_sync_get_output_timeline_id();
- cmdqRecBackupUpdateSlot(cmdq_handle, pgc->cur_config_fence, layer, mem_config.buff_idx);
- layer = disp_sync_get_output_interface_timeline_id();
- cmdqRecBackupUpdateSlot(cmdq_handle, pgc->cur_config_fence, layer, mem_config.interface_idx);
- cmdqRecBackupUpdateSlot(cmdq_handle, pgc->rdma_buff_info, 0, (unsigned int)mem_config.addr);
- /*rdma pitch only use bit[15..0], we use bit[31:30] to store secure information */
- rdma_pitch_sec = mem_config.pitch | (mem_config.security << 30);
- cmdqRecBackupUpdateSlot(cmdq_handle, pgc->rdma_buff_info, 1, rdma_pitch_sec);
- cmdqRecBackupUpdateSlot(cmdq_handle, pgc->rdma_buff_info, 2, mem_config.fmt);
- cmdqRecFlushAsyncCallback(cmdq_handle, (CmdqAsyncFlushCB) callback, data);
- cmdqRecReset(cmdq_handle);
- cmdqRecWait(cmdq_handle, CMDQ_EVENT_DISP_WDMA0_EOF);
- MMProfileLogEx(ddp_mmp_get_events()->ovl_trigger, MMProfileFlagPulse, 0, data);
- return 0;
- }
- #define EEEEEEEEEEEEEEE
- /******************************************************************************/
- /* ESD CHECK / RECOVERY ---- BEGIN */
- /******************************************************************************/
- #ifdef MTK_FB_ESD_ENABLE
- static struct task_struct *primary_display_esd_check_task;
- #define IS_ESD_ENABLE true
- #else
- #define IS_ESD_ENABLE false
- #endif
- #ifdef MTK_FB_PULLCLK_ENABLE
- static struct task_struct *primary_display_pullclk_task;
- #endif
- static wait_queue_head_t esd_check_task_wq; /* For Esd Check Task */
- static atomic_t esd_check_task_wakeup = ATOMIC_INIT(0); /* For Esd Check Task */
- static wait_queue_head_t esd_ext_te_wq; /* For Vdo Mode EXT TE Check */
- static atomic_t esd_ext_te_event = ATOMIC_INIT(0); /* For Vdo Mode EXT TE Check */
- static atomic_t esd_check_bycmdq = ATOMIC_INIT(0);
- static inline bool _is_enable_esd_check(void)
- {
- return IS_ESD_ENABLE;
- }
- struct task_struct *primary_display_frame_update_task = NULL;
- wait_queue_head_t primary_display_frame_update_wq;
- atomic_t primary_display_frame_update_event = ATOMIC_INIT(0);
- struct task_struct *decouple_fence_release_task = NULL;
- wait_queue_head_t decouple_fence_release_wq;
- atomic_t decouple_fence_release_event = ATOMIC_INIT(0);
- static int eint_flag; /* For DCT Setting */
- unsigned int _need_do_esd_check(void)
- {
- int ret = 0;
- #ifdef CONFIG_OF
- if ((pgc->plcm->params->dsi.esd_check_enable == 1) && (islcmconnected == 1))
- ret = 1;
- #else
- if (pgc->plcm->params->dsi.esd_check_enable == 1)
- ret = 1;
- #endif
- return ret;
- }
- unsigned int _need_register_eint(void)
- {
- int ret = 1;
- /* 1.need do esd check */
- /* 2.dsi vdo mode */
- /* 3.customization_esd_check_enable = 0 */
- if (_need_do_esd_check() == 0)
- ret = 0;
- else if (primary_display_is_video_mode() == 0)
- ret = 0;
- else if (pgc->plcm->params->dsi.customization_esd_check_enable == 1)
- ret = 0;
- return ret;
- }
- unsigned int _need_wait_esd_eof(void)
- {
- int ret = 1;
- /* 1.need do esd check */
- /* 2.customization_esd_check_enable = 1 */
- /* 3.dsi cmd mode */
- if (_need_do_esd_check() == 0)
- ret = 0;
- else if (pgc->plcm->params->dsi.customization_esd_check_enable == 0)
- ret = 0;
- else if (primary_display_is_video_mode())
- ret = 0;
- return ret;
- }
- /* For Cmd Mode Read LCM Check */
- /* Config cmdq_handle_config_esd */
- int _esd_check_config_handle_cmd(void)
- {
- int ret = 0; /* 0:success */
- /* 1.reset */
- cmdqRecReset(pgc->cmdq_handle_config_esd);
- /* 2.write first instruction */
- /* cmd mode: wait CMDQ_SYNC_TOKEN_STREAM_EOF(wait trigger thread done) */
- cmdqRecWaitNoClear(pgc->cmdq_handle_config_esd, CMDQ_SYNC_TOKEN_STREAM_EOF);
- /* 3.clear CMDQ_SYNC_TOKEN_ESD_EOF(trigger thread need wait this sync token) */
- cmdqRecClearEventToken(pgc->cmdq_handle_config_esd, CMDQ_SYNC_TOKEN_ESD_EOF);
- /* 4.write instruction(read from lcm) */
- dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_config_esd, CMDQ_ESD_CHECK_READ);
- /* 5.set CMDQ_SYNC_TOKE_ESD_EOF(trigger thread can work now) */
- cmdqRecSetEventToken(pgc->cmdq_handle_config_esd, CMDQ_SYNC_TOKEN_ESD_EOF);
- /* 6.flush instruction */
- dprec_logger_start(DPREC_LOGGER_ESD_CMDQ, 0, 0);
- ret = cmdqRecFlush(pgc->cmdq_handle_config_esd);
- dprec_logger_done(DPREC_LOGGER_ESD_CMDQ, 0, 0);
- DISPCHECK("[ESD]_esd_check_config_handle_cmd ret=%d\n", ret);
- if (ret)
- ret = 1;
- return ret;
- }
- void primary_display_esd_cust_bycmdq(int enable)
- {
- atomic_set(&esd_check_bycmdq, enable);
- }
- int primary_display_esd_cust_get(void)
- {
- return atomic_read(&esd_check_bycmdq);
- }
- /* For Vdo Mode Read LCM Check */
- /* Config cmdq_handle_config_esd */
- /* extern unsigned int gESDEnableSODI; */
- /* extern unsigned int gDumpESDCMD; */
- int _esd_check_config_handle_vdo(void)
- {
- int ret = 0; /* 0:success , 1:fail */
- primary_display_esd_cust_bycmdq(1);
- _primary_path_lock(__func__);
- #if defined(MTK_FB_SODI_SUPPORT) && !defined(CONFIG_FPGA_EARLY_PORTING)
- spm_enable_sodi(0);
- #endif
- /* 1.reset */
- cmdqRecReset(pgc->cmdq_handle_config_esd);
- /* wait stream eof first */
- cmdqRecWait(pgc->cmdq_handle_config_esd, CMDQ_EVENT_DISP_RDMA0_EOF);
- cmdqRecWait(pgc->cmdq_handle_config_esd, CMDQ_EVENT_MUTEX0_STREAM_EOF);
- #ifdef DISP_DUMP_EVENT_STATUS
- DISP_REG_SET_PA(pgc->cmdq_handle_config_esd, DISP_REG_CMDQ_TOKEN_ID, DISP_MUTEX0_STREAM_EOF_ID);
- cmdqRecBackupRegisterToSlot(pgc->cmdq_handle_config_esd, pgc->event_status, 1, DISP_REG_CMDQ_TOKEN_VALUE);
- #endif
- /* stop dsi vdo mode */
- dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_config_esd, CMDQ_STOP_VDO_MODE);
- /* write instruction(read from lcm) */
- dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_config_esd, CMDQ_ESD_CHECK_READ);
- /* pull DSI clock lane */
- DSI_sw_clk_trail_cmdq(0, pgc->cmdq_handle_config_esd);
- DSI_manual_enter_HS(pgc->cmdq_handle_config_esd);
- /* start dsi vdo mode */
- dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_config_esd, CMDQ_START_VDO_MODE);
- /* trigger path */
- cmdqRecClearEventToken(pgc->cmdq_handle_config_esd, CMDQ_EVENT_MUTEX0_STREAM_EOF);
- if (gEnableSWTrigger == 1)
- DISP_REG_SET(pgc->cmdq_handle_config_esd, DISP_REG_CONFIG_MUTEX_EN(DISP_OVL_SEPARATE_MUTEX_ID), 1);
- dpmgr_path_trigger(pgc->dpmgr_handle, pgc->cmdq_handle_config_esd, CMDQ_ENABLE);
- /* flush instruction */
- dprec_logger_start(DPREC_LOGGER_ESD_CMDQ, 0, 0);
- if (gDumpESDCMD == 1) {
- DISPMSG("esd dump before flush:\n");
- cmdqRecDumpCommand(pgc->cmdq_handle_config_esd);
- }
- ret = cmdqRecFlush(pgc->cmdq_handle_config_esd);
- #if defined(MTK_FB_SODI_SUPPORT) && !defined(CONFIG_FPGA_EARLY_PORTING)
- spm_enable_sodi(1);
- #endif
- _primary_path_unlock(__func__);
- #ifdef DISP_DUMP_EVENT_STATUS
- {
- unsigned int i = 0;
- unsigned int event_status[6];
- DISPMSG("dump esd status: ");
- for (i = 0; i < 6; i++)
- cmdqBackupReadSlot(pgc->event_status, i, &event_status[i]);
- DISPMSG("%d, %d, %d, %d, %d, %d\n",
- event_status[0], event_status[1], event_status[2],
- event_status[3], event_status[4], event_status[5]);
- }
- #endif
- dprec_logger_done(DPREC_LOGGER_ESD_CMDQ, 0, 0);
- DISPCHECK("[ESD]_esd_check_config_handle_vdo ret=%d\n", ret);
- if (ret)
- ret = 1;
- primary_display_esd_cust_bycmdq(0);
- return ret;
- }
- /* For Vdo Mode EXT TE Check */
- static irqreturn_t _esd_check_ext_te_irq_handler(int irq, void *data)
- {
- MMProfileLogEx(ddp_mmp_get_events()->esd_vdo_eint, MMProfileFlagPulse, 0, 0);
- atomic_set(&esd_ext_te_event, 1);
- wake_up_interruptible(&esd_ext_te_wq);
- return IRQ_HANDLED;
- }
- int primary_display_switch_esd_mode(int mode)
- {
- int ret = 0;
- #ifdef GPIO_DSI_TE_PIN
- int gpio_mode = 0;
- #endif
- DISPFUNC();
- if (pgc->plcm->params->dsi.customization_esd_check_enable != 0)
- return -1; /* avoid build warning. */
- DISPMSG("switch esd mode to %d\n", mode);
- #ifdef GPIO_DSI_TE_PIN
- #ifndef CONFIG_FPGA_EARLY_PORTING
- gpio_mode = mt_get_gpio_mode(GPIO_DSI_TE_PIN);
- /* DISPMSG("[ESD]gpio_mode=%d\n", gpio_mode); */
- #endif
- #endif
- if (mode == 1) {
- #ifdef GPIO_DSI_TE_PIN
- /*switch to vdo mode */
- if (gpio_mode == GPIO_DSI_TE_PIN_M_DSI_TE) {
- #endif
- /* if(_need_register_eint()) */
- {
- /* DISPMSG("[ESD]switch video mode\n"); */
- struct device_node *node = NULL;
- int irq;
- u32 ints[2] = { 0, 0 };
- #ifdef GPIO_DSI_TE_PIN
- #ifndef CONFIG_FPGA_EARLY_PORTING
- /* 1.set GPIO107 eint mode */
- mt_set_gpio_mode(GPIO_DSI_TE_PIN, GPIO_DSI_TE_PIN_M_GPIO);
- #endif
- #endif
- /* 2.register eint */
- node = of_find_compatible_node(NULL, NULL, "mediatek, DSI_TE_1-eint");
- if (node) {
- /* DISPMSG("node 0x%x\n", node); */
- of_property_read_u32_array(node, "debounce", ints, ARRAY_SIZE(ints));
- /* mt_gpio_set_debounce(ints[0], ints[1]); */
- mt_eint_set_hw_debounce(ints[0], ints[1]);
- irq = irq_of_parse_and_map(node, 0);
- if (request_irq(irq, _esd_check_ext_te_irq_handler, IRQF_TRIGGER_RISING,
- "DSI_TE_1-eint", NULL))
- DISPERR("[ESD]EINT IRQ LINE NOT AVAILABLE!!\n");
- } else {
- DISPERR("[ESD][%s] can't find DSI_TE_1 eint compatible node\n", __func__);
- }
- }
- #ifdef GPIO_DSI_TE_PIN
- }
- #endif
- } else if (mode == 0) {
- #ifdef GPIO_DSI_TE_PIN
- /* switch to cmd mode */
- if (gpio_mode == GPIO_DSI_TE_PIN_M_GPIO) {
- #endif
- struct device_node *node = NULL;
- int irq;
- /* DISPMSG("[ESD]switch cmd mode\n"); */
- /* unregister eint */
- node = of_find_compatible_node(NULL, NULL, "mediatek, DSI_TE_1-eint");
- /* DISPMSG("node 0x%x\n", node); */
- if (node) {
- irq = irq_of_parse_and_map(node, 0);
- free_irq(irq, NULL);
- } else {
- DISPERR("[ESD][%s] can't find DSI_TE_1 eint compatible node\n",
- __func__);
- }
- #ifdef GPIO_DSI_TE_PIN
- #ifndef CONFIG_FPGA_EARLY_PORTING
- /* set GPIO107 DSI TE mode */
- mt_set_gpio_mode(GPIO_DSI_TE_PIN, GPIO_DSI_TE_PIN_M_DSI_TE);
- #endif
- #endif
- #ifdef GPIO_DSI_TE_PIN
- }
- #endif
- }
- /* DISPMSG("primary_display_switch_esd_mode end\n"); */
- return ret;
- }
- /* ESD CHECK FUNCTION */
- /* return 1: esd check fail */
- /* return 0: esd check pass */
- int primary_display_esd_check(void)
- {
- int ret = 0;
- _primary_path_esd_check_lock();
- dprec_logger_start(DPREC_LOGGER_ESD_CHECK, 0, 0);
- MMProfileLogEx(ddp_mmp_get_events()->esd_check_t, MMProfileFlagStart, 0, 0);
- DISPCHECK("[ESD]ESD check begin\n");
- _primary_path_lock(__func__);
- if (pgc->state == DISP_SLEPT) {
- MMProfileLogEx(ddp_mmp_get_events()->esd_check_t, MMProfileFlagPulse, 1, 0);
- DISPCHECK("[ESD]primary display path is slept?? -- skip esd check\n");
- _primary_path_unlock(__func__);
- /* goto done; */
- DISPCHECK("[ESD]ESD check end\n");
- MMProfileLogEx(ddp_mmp_get_events()->esd_check_t, MMProfileFlagEnd, 0, ret);
- dprec_logger_done(DPREC_LOGGER_ESD_CHECK, 0, 0);
- _primary_path_esd_check_unlock();
- return ret;
- }
- _primary_path_unlock(__func__);
- #ifdef MTK_DISP_IDLE_LP
- _disp_primary_path_dsi_clock_on(0);
- #endif
- /* / Esd Check : EXT TE */
- if (pgc->plcm->params->dsi.customization_esd_check_enable == 0) {
- MMProfileLogEx(ddp_mmp_get_events()->esd_extte, MMProfileFlagStart, 0, 0);
- if (primary_display_is_video_mode()) {
- primary_display_switch_esd_mode(1);
- /* use cmdq to pull DSI clk lane*/
- if (primary_display_cmdq_enabled() ) {
- _primary_path_lock(__func__);
- /* 0.create esd check cmdq */
- cmdqRecCreate(CMDQ_SCENARIO_DISP_ESD_CHECK, &(pgc->cmdq_handle_config_esd));
- _primary_path_unlock(__func__);
- primary_display_esd_cust_bycmdq(1);
- /* 1.reset*/
- cmdqRecReset(pgc->cmdq_handle_config_esd);
- /* wait stream eof first */
- ret = cmdqRecWait(pgc->cmdq_handle_config_esd, CMDQ_EVENT_DISP_RDMA0_EOF);
- cmdqRecWait(pgc->cmdq_handle_config_esd, CMDQ_EVENT_MUTEX0_STREAM_EOF);
- _primary_path_lock(__func__);
- /* 2.stop dsi vdo mode */
- dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_config_esd, CMDQ_STOP_VDO_MODE);
- /* 3.pull DSI clock lane */
- DSI_sw_clk_trail_cmdq(0, pgc->cmdq_handle_config_esd);
- DSI_manual_enter_HS(pgc->cmdq_handle_config_esd);
- /* 4.start dsi vdo mode */
- dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_config_esd, CMDQ_START_VDO_MODE);
- /* 5. trigger path */
- cmdqRecClearEventToken(pgc->cmdq_handle_config_esd ,CMDQ_EVENT_MUTEX0_STREAM_EOF);
- if (gEnableSWTrigger==1)
- DISP_REG_SET(pgc->cmdq_handle_config_esd,
- DISP_REG_CONFIG_MUTEX_EN(DISP_OVL_SEPARATE_MUTEX_ID), 1);
- dpmgr_path_trigger(pgc->dpmgr_handle, pgc->cmdq_handle_config_esd, CMDQ_ENABLE);
- _primary_path_unlock(__func__);
- cmdqRecFlush(pgc->cmdq_handle_config_esd);
- primary_display_esd_cust_bycmdq(0);
- cmdqRecDestroy(pgc->cmdq_handle_config_esd);
- pgc->cmdq_handle_config_esd = NULL;
- }
- if (_need_register_eint()) {
- MMProfileLogEx(ddp_mmp_get_events()->esd_extte, MMProfileFlagPulse, 1, 1);
- if (wait_event_interruptible_timeout
- (esd_ext_te_wq, atomic_read(&esd_ext_te_event), HZ / 2) > 0) {
- ret = 0; /* esd check pass */
- } else {
- ret = 1; /* esd check fail */
- DISPCHECK("esd check fail release fence fake\n");
- primary_display_release_fence_fake();
- }
- atomic_set(&esd_ext_te_event, 0);
- }
- primary_display_switch_esd_mode(0);
- } else {
- MMProfileLogEx(ddp_mmp_get_events()->esd_extte, MMProfileFlagPulse, 0, 1);
- if (dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC, HZ / 2) > 0) {
- ret = 0; /* esd check pass */
- } else {
- ret = 1; /* esd check fail */
- DISPCHECK("esd check fail release fence fake\n");
- primary_display_release_fence_fake();
- }
- }
- MMProfileLogEx(ddp_mmp_get_events()->esd_extte, MMProfileFlagEnd, 0, ret);
- goto done;
- }
- /* / Esd Check : Read from lcm */
- MMProfileLogEx(ddp_mmp_get_events()->esd_rdlcm, MMProfileFlagStart, 0, primary_display_cmdq_enabled());
- if (primary_display_cmdq_enabled()) {
- _primary_path_lock(__func__);
- MMProfileLogEx(ddp_mmp_get_events()->esd_rdlcm, MMProfileFlagPulse, 0, 1);
- /* 0.create esd check cmdq */
- cmdqRecCreate(CMDQ_SCENARIO_DISP_ESD_CHECK, &(pgc->cmdq_handle_config_esd));
- dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_config_esd, CMDQ_ESD_ALLC_SLOT);
- MMProfileLogEx(ddp_mmp_get_events()->esd_rdlcm, MMProfileFlagPulse, 0, 2);
- DISPCHECK("[ESD]ESD config thread=%p\n", pgc->cmdq_handle_config_esd);
- _primary_path_unlock(__func__);
- /* 1.use cmdq to read from lcm */
- if (primary_display_is_video_mode())
- ret = _esd_check_config_handle_vdo();
- else
- ret = _esd_check_config_handle_cmd();
- MMProfileLogEx(ddp_mmp_get_events()->esd_rdlcm, MMProfileFlagPulse, primary_display_is_video_mode(), 3);
- if (ret == 1) {/* cmdq fail */
- /* Need set esd check eof synctoken to let trigger loop go. */
- if (_need_wait_esd_eof())
- cmdqCoreSetEvent(CMDQ_SYNC_TOKEN_ESD_EOF);
- /* do dsi reset */
- dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_config_esd, CMDQ_DSI_RESET);
- DISPCHECK("esd check fail release fence fake\n");
- primary_display_release_fence_fake();
- goto destroy_cmdq;
- }
- DISPCHECK("[ESD]ESD config thread done~\n");
- /* 2.check data(*cpu check now) */
- ret = dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_config_esd, CMDQ_ESD_CHECK_CMP);
- MMProfileLogEx(ddp_mmp_get_events()->esd_rdlcm, MMProfileFlagPulse, 0, 4);
- if (ret) {
- ret = 1; /* esd check fail */
- DISPCHECK("esd check fail release fence fake\n");
- primary_display_release_fence_fake();
- }
- destroy_cmdq:
- dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_config_esd,
- CMDQ_ESD_FREE_SLOT);
- /* 3.destroy esd config thread */
- cmdqRecDestroy(pgc->cmdq_handle_config_esd);
- pgc->cmdq_handle_config_esd = NULL;
- } else { /* by cpu */
- /* 0: lock path */
- /* 1: stop path */
- /* 2: do esd check (!!!) */
- /* 3: start path */
- /* 4: unlock path */
- MMProfileLogEx(ddp_mmp_get_events()->esd_rdlcm, MMProfileFlagPulse, 0, 1);
- _primary_path_lock(__func__);
- /* 1: stop path */
- DISPCHECK("[ESD]display cmdq trigger loop stop[begin]\n");
- _cmdq_stop_trigger_loop();
- DISPCHECK("[ESD]display cmdq trigger loop stop[end]\n");
- if (dpmgr_path_is_busy(pgc->dpmgr_handle)) {
- DISPCHECK("[ESD]primary display path is busy\n");
- ret = dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE, HZ * 1);
- DISPCHECK("[ESD]wait frame done ret:%d\n", ret);
- }
- DISPCHECK("[ESD]stop dpmgr path[begin]\n");
- dpmgr_path_stop(pgc->dpmgr_handle, CMDQ_DISABLE);
- DISPCHECK("[ESD]stop dpmgr path[end]\n");
- if (dpmgr_path_is_busy(pgc->dpmgr_handle)) {
- DISPCHECK("[ESD]primary display path is busy after stop\n");
- dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE, HZ * 1);
- DISPCHECK("[ESD]wait frame done ret:%d\n", ret);
- }
- DISPCHECK("[ESD]reset display path[begin]\n");
- dpmgr_path_reset(pgc->dpmgr_handle, CMDQ_DISABLE);
- DISPCHECK("[ESD]reset display path[end]\n");
- /* 2: do esd check (!!!) */
- MMProfileLogEx(ddp_mmp_get_events()->esd_rdlcm, MMProfileFlagPulse, 0, 2);
- if (primary_display_is_video_mode())
- /* ret = 0; */
- ret = disp_lcm_esd_check(pgc->plcm);
- else
- ret = disp_lcm_esd_check(pgc->plcm);
- /* 3: start path */
- MMProfileLogEx(ddp_mmp_get_events()->esd_rdlcm, MMProfileFlagPulse, primary_display_is_video_mode(), 3);
- DISPCHECK("[ESD]start dpmgr path[begin]\n");
- dpmgr_path_start(pgc->dpmgr_handle, CMDQ_DISABLE);
- DISPCHECK("[ESD]start dpmgr path[end]\n");
- DISPCHECK("[ESD]start cmdq trigger loop[begin]\n");
- _cmdq_start_trigger_loop();
- DISPCHECK("[ESD]start cmdq trigger loop[end]\n");
- _primary_path_unlock(__func__);
- }
- MMProfileLogEx(ddp_mmp_get_events()->esd_rdlcm, MMProfileFlagEnd, 0, ret);
- done:
- #ifdef MTK_DISP_IDLE_LP
- _disp_primary_path_dsi_clock_off(0);
- #endif
- DISPCHECK("[ESD]ESD check end\n");
- MMProfileLogEx(ddp_mmp_get_events()->esd_check_t, MMProfileFlagEnd, 0, ret);
- dprec_logger_done(DPREC_LOGGER_ESD_CHECK, 0, 0);
- _primary_path_esd_check_unlock();
- return ret;
- }
- #ifdef MTK_FB_ESD_ENABLE
- static int primary_display_esd_check_worker_kthread(void *data)
- {
- int ret = 0;
- int i = 0;
- int esd_try_cnt = 5; /* 20; */
- int count = 0;
- struct sched_param param = {.sched_priority = 87 }; /* RTPM_PRIO_FB_THREAD */
- sched_setscheduler(current, SCHED_RR, ¶m);
- dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE);
- dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_START);
- while (1) {
- if (count == 0) {
- count++;
- msleep(3000);
- }
- msleep(2000); /* esd check every 2s */
- ret = wait_event_interruptible(esd_check_task_wq, atomic_read(&esd_check_task_wakeup));
- if (ret < 0) {
- DISPCHECK("[ESD]esd check thread waked up accidently\n");
- continue;
- }
- #ifdef DISP_SWITCH_DST_MODE
- _primary_path_switch_dst_lock();
- #endif
- _primary_path_cmd_lock();
- ret = primary_display_esd_check();
- if (ret == 1) {
- DISPCHECK("[ESD]esd check fail, will do esd recovery %d\n", ret);
- i = esd_try_cnt;
- while (i--) {
- DISPCHECK("[ESD]esd recovery try:%d\n", i);
- primary_display_esd_recovery();
- ret = primary_display_esd_check();
- if (ret == 0) {
- DISPCHECK("[ESD]esd recovery success\n");
- break;
- }
- DISPCHECK("[ESD]after esd recovery, esd check still fail\n");
- if (i == 0) {
- DISPCHECK("[ESD]after esd recovery %d times, esd check still fail,\n",
- esd_try_cnt);
- DISPCHECK("disable esd check\n");
- primary_display_esd_check_enable(0);
- primary_display_esd_recovery();
- }
- }
- }
- _primary_path_cmd_unlock();
- #ifdef DISP_SWITCH_DST_MODE
- _primary_path_switch_dst_unlock();
- #endif
- if (kthread_should_stop())
- break;
- }
- return 0;
- }
- #endif /* MTK_FB_ESD_ENABLE */
- /* ESD RECOVERY */
- int primary_display_esd_recovery(void)
- {
- DISP_STATUS ret = DISP_STATUS_OK;
- LCM_PARAMS *lcm_param = NULL;
- DISPFUNC();
- dprec_logger_start(DPREC_LOGGER_ESD_RECOVERY, 0, 0);
- MMProfileLogEx(ddp_mmp_get_events()->esd_recovery_t, MMProfileFlagStart, 0, 0);
- DISPCHECK("[ESD]ESD recovery begin\n");
- _primary_path_lock(__func__);
- MMProfileLogEx(ddp_mmp_get_events()->esd_recovery_t, MMProfileFlagPulse,
- primary_display_is_video_mode(), 1);
- lcm_param = disp_lcm_get_params(pgc->plcm);
- if (pgc->state == DISP_SLEPT) {
- DISPCHECK("[ESD]esd recovery but primary display path is slept??\n");
- goto done;
- }
- MMProfileLogEx(ddp_mmp_get_events()->esd_recovery_t, MMProfileFlagPulse, 0, 2);
- if (dpmgr_path_is_busy(pgc->dpmgr_handle)) {
- DISPCHECK("[ESD]primary display path is busy\n");
- ret = dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE, HZ * 1);
- DISPCHECK("[ESD]wait frame done ret:%d\n", ret);
- }
- MMProfileLogEx(ddp_mmp_get_events()->esd_recovery_t, MMProfileFlagPulse, 0, 3);
- DISPCHECK("[ESD]stop dpmgr path[begin]\n");
- dpmgr_path_stop(pgc->dpmgr_handle, CMDQ_DISABLE);
- DISPCHECK("[ESD]stop dpmgr path[end]\n");
- MMProfileLogEx(ddp_mmp_get_events()->esd_recovery_t, MMProfileFlagPulse, 0, 4);
- if (dpmgr_path_is_busy(pgc->dpmgr_handle)) {
- DISPCHECK("[ESD]primary display path is busy after stop\n");
- dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE, HZ * 1);
- DISPCHECK("[ESD]wait frame done ret:%d\n", ret);
- }
- MMProfileLogEx(ddp_mmp_get_events()->esd_recovery_t, MMProfileFlagPulse, 0, 5);
- DISPCHECK("[ESD]display cmdq trigger loop stop[begin]\n");
- _cmdq_stop_trigger_loop();
- DISPCHECK("[ESD]display cmdq trigger loop stop[end]\n");
- MMProfileLogEx(ddp_mmp_get_events()->esd_recovery_t, MMProfileFlagPulse, 0, 6);
- DISPCHECK("[ESD]reset display path[begin]\n");
- dpmgr_path_reset(pgc->dpmgr_handle, CMDQ_DISABLE);
- DISPCHECK("[ESD]reset display path[end]\n");
- DISPCHECK("[POWER]lcm suspend[begin]\n");
- disp_lcm_suspend(pgc->plcm);
- DISPCHECK("[POWER]lcm suspend[end]\n");
- MMProfileLogEx(ddp_mmp_get_events()->esd_recovery_t, MMProfileFlagPulse, 0, 7);
- DISPCHECK("[ESD]dsi power reset[begin]\n");
- dpmgr_path_dsi_power_off(pgc->dpmgr_handle, CMDQ_DISABLE);
- dpmgr_path_dsi_power_on(pgc->dpmgr_handle, CMDQ_DISABLE);
- if (!primary_display_is_video_mode())
- dpmgr_path_ioctl(pgc->dpmgr_handle, NULL, DDP_DSI_ENABLE_TE, NULL);
- DISPCHECK("[ESD]dsi power reset[end]\n");
- MMProfileLogEx(ddp_mmp_get_events()->esd_recovery_t, MMProfileFlagPulse, 0, 8);
- DISPCHECK("[ESD]lcm force init[begin]\n");
- disp_lcm_init(pgc->plcm, 1);
- DISPCHECK("[ESD]lcm force init[end]\n");
- MMProfileLogEx(ddp_mmp_get_events()->esd_recovery_t, MMProfileFlagPulse, 0, 9);
- DISPCHECK("[ESD]start dpmgr path[begin]\n");
- dpmgr_path_start(pgc->dpmgr_handle, CMDQ_DISABLE);
- DISPCHECK("[ESD]start dpmgr path[end]\n");
- if (dpmgr_path_is_busy(pgc->dpmgr_handle)) {
- DISPERR("[ESD]Fatal error, we didn't trigger display path but it's already busy\n");
- ret = -1;
- /* goto done; */
- }
- MMProfileLogEx(ddp_mmp_get_events()->esd_recovery_t, MMProfileFlagPulse, 0, 10);
- if (primary_display_is_video_mode()) {
- /* for video mode, we need to force trigger here */
- /* for cmd mode, just set DPREC_EVENT_CMDQ_SET_EVENT_ALLOW when trigger loop start */
- dpmgr_path_trigger(pgc->dpmgr_handle, NULL, CMDQ_DISABLE);
- }
- MMProfileLogEx(ddp_mmp_get_events()->esd_recovery_t, MMProfileFlagPulse, 0, 11);
- DISPCHECK("[ESD]start cmdq trigger loop[begin]\n");
- _cmdq_start_trigger_loop();
- DISPCHECK("[ESD]start cmdq trigger loop[end]\n");
- MMProfileLogEx(ddp_mmp_get_events()->esd_recovery_t, MMProfileFlagPulse, 0, 12);
- done:
- _primary_path_unlock(__func__);
- DISPCHECK("[ESD]ESD recovery end\n");
- MMProfileLogEx(ddp_mmp_get_events()->esd_recovery_t, MMProfileFlagEnd, 0, 0);
- dprec_logger_done(DPREC_LOGGER_ESD_RECOVERY, 0, 0);
- return ret;
- }
- void primary_display_esd_check_enable(int enable)
- {
- /* check if enable ESD check mechanism first */
- if (_is_enable_esd_check() != true) {
- DISPCHECK("[ESD]Checking if ESD enable but ESD check mechanism is not enabled.\n");
- return;
- }
- if (_need_do_esd_check()) {
- if (_need_register_eint() && eint_flag != 2) {
- DISPCHECK("[ESD]Please check DCT setting about GPIO107/EINT107\n");
- return;
- }
- if (enable) {
- DISPPRINT("[ESD]esd check thread wakeup\n");
- atomic_set(&esd_check_task_wakeup, 1);
- wake_up_interruptible(&esd_check_task_wq);
- } else {
- DISPCHECK("[ESD]esd check thread stop\n");
- atomic_set(&esd_check_task_wakeup, 0);
- }
- }
- }
- /******************************************************************************/
- /* ESD CHECK / RECOVERY ---- End */
- /******************************************************************************/
- #define EEEEEEEEEEEEEEEEEEEEEEEEEE
- #ifdef MTK_FB_PULLCLK_ENABLE
- static int primary_display_vdo_pullclk_worker_kthread(void *data)
- {
- int ret = 0;
- int count = 0;
- struct sched_param param = {.sched_priority = 87 }; /* RTPM_PRIO_FB_THREAD */
- sched_setscheduler(current, SCHED_RR, ¶m);
- while (1) {
- if (count == 0) {
- count++;
- msleep(3000);
- }
- msleep(2000);
- #ifdef DISP_SWITCH_DST_MODE
- _primary_path_switch_dst_lock();
- #endif
- _primary_path_cmd_lock();
- _primary_path_esd_check_lock();
- _primary_path_lock(__func__);
- if (pgc->state == DISP_SLEPT) {
- _primary_path_unlock(__func__);
- _primary_path_esd_check_unlock();
- continue;
- }
- _primary_path_unlock(__func__);
- #ifdef MTK_DISP_IDLE_LP
- _disp_primary_path_dsi_clock_on(0);
- #endif
- _primary_path_lock(__func__);
- cmdqRecCreate(CMDQ_SCENARIO_DISP_ESD_CHECK, &(pgc->cmdq_handle_config_esd));
- dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_config_esd, CMDQ_ESD_ALLC_SLOT);
- _primary_path_unlock(__func__);
- #ifdef DISP_DUMP_EVENT_STATUS
- DISP_REG_SET_PA(pgc->cmdq_handle_config_esd, DISP_REG_CMDQ_TOKEN_ID, DISP_MUTEX0_STREAM_EOF_ID);
- cmdqRecBackupRegisterToSlot(pgc->cmdq_handle_config_esd, pgc->event_status, 1
- , DISP_REG_CMDQ_TOKEN_VALUE);
- #endif
- primary_display_esd_cust_bycmdq(1);
- _primary_path_lock(__func__);
- #if defined(MTK_FB_SODI_SUPPORT) && !defined(CONFIG_FPGA_EARLY_PORTING)
- spm_enable_sodi(0);
- #endif
- /* reset*/
- cmdqRecReset(pgc->cmdq_handle_config_esd);
- /* wait stream eof first*/
- cmdqRecWait(pgc->cmdq_handle_config_esd, CMDQ_EVENT_DISP_RDMA0_EOF);
- cmdqRecWait(pgc->cmdq_handle_config_esd, CMDQ_EVENT_MUTEX0_STREAM_EOF);
- /*stop dsi vdo mode*/
- dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_config_esd, CMDQ_STOP_VDO_MODE);
- /* pull DSI clock lane */
- DSI_sw_clk_trail_cmdq(0, pgc->cmdq_handle_config_esd);
- DSI_manual_enter_HS(pgc->cmdq_handle_config_esd);
- /* start dsi vdo mode*/
- dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_config_esd, CMDQ_START_VDO_MODE);
- /* trigger path*/
- cmdqRecClearEventToken(pgc->cmdq_handle_config_esd, CMDQ_EVENT_MUTEX0_STREAM_EOF);
- if (gEnableSWTrigger == 1)
- DISP_REG_SET(pgc->cmdq_handle_config_esd
- , DISP_REG_CONFIG_MUTEX_EN(DISP_OVL_SEPARATE_MUTEX_ID), 1);
- dpmgr_path_trigger(pgc->dpmgr_handle, pgc->cmdq_handle_config_esd, CMDQ_ENABLE);
- if (gDumpESDCMD == 1) {
- DISPMSG("esd dump before flush:\n");
- cmdqRecDumpCommand(pgc->cmdq_handle_config_esd);
- }
- ret = cmdqRecFlush(pgc->cmdq_handle_config_esd);
- #if defined(MTK_FB_SODI_SUPPORT) && !defined(CONFIG_FPGA_EARLY_PORTING)
- spm_enable_sodi(1);
- #endif
- _primary_path_unlock(__func__);
- primary_display_esd_cust_bycmdq(0);
- _primary_path_lock(__func__);
- dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_config_esd, CMDQ_ESD_FREE_SLOT);
- cmdqRecDestroy(pgc->cmdq_handle_config_esd);
- pgc->cmdq_handle_config_esd = NULL;
- _primary_path_unlock(__func__);
- #ifdef MTK_DISP_IDLE_LP
- _disp_primary_path_dsi_clock_off(0);
- #endif
- _primary_path_esd_check_unlock();
- _primary_path_cmd_unlock();
- #ifdef DISP_SWITCH_DST_MODE
- _primary_path_switch_dst_unlock();
- #endif
- if (kthread_should_stop())
- break;
- }
- return 0;
- }
- #endif
- static struct task_struct *primary_path_aal_task;
- void disp_update_trigger_time(void)
- {
- last_primary_trigger_time = sched_clock();
- }
- /* extern unsigned int gResetOVLInAALTrigger; */
- static int _disp_primary_path_check_trigger(void *data)
- {
- cmdqRecHandle handle = NULL;
- #ifndef MTK_FB_CMDQ_DISABLE
- int ret = 0;
- ret = cmdqRecCreate(CMDQ_SCENARIO_PRIMARY_DISP, &handle);
- #endif
- dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_TRIGGER);
- while (1) {
- dpmgr_wait_event(pgc->dpmgr_handle, DISP_PATH_EVENT_TRIGGER);
- MMProfileLogEx(ddp_mmp_get_events()->primary_display_aalod_trigger,
- MMProfileFlagPulse, 0, 0);
- _primary_path_lock(__func__);
- if (primary_get_state() == DISP_ALIVE) {
- #ifdef MTK_DISP_IDLE_LP
- last_primary_trigger_time = sched_clock();
- _disp_primary_path_exit_idle(__func__, 0);
- #endif
- cmdqRecReset(handle);
- #ifndef MTK_FB_CMDQ_DISABLE
- if (primary_display_is_video_mode())
- cmdqRecWaitNoClear(handle, CMDQ_EVENT_DISP_RDMA0_EOF);
- else
- cmdqRecWaitNoClear(handle, CMDQ_SYNC_TOKEN_STREAM_EOF);
- #endif
- if (gResetOVLInAALTrigger == 1) {
- ovl_reset_by_cmdq(handle, DISP_MODULE_OVL0);
- if (ovl_get_status() != DDP_OVL1_STATUS_SUB)
- ovl_reset_by_cmdq(handle, DISP_MODULE_OVL1);
- }
- _cmdq_set_config_handle_dirty_mira(handle);
- /* disable SODI after set dirty */
- if (primary_display_is_video_mode() == 0 && gDisableSODIForTriggerLoop == 1)
- disp_set_sodi(0, handle);
- _cmdq_flush_config_handle_mira(handle, 0);
- }
- _primary_path_unlock(__func__);
- if (kthread_should_stop())
- break;
- }
- cmdqRecDestroy(handle);
- return 0;
- }
- #define OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
- /* need remove */
- unsigned int cmdqDdpClockOn(uint64_t engineFlag)
- {
- /* DISP_LOG_I("cmdqDdpClockOff\n"); */
- return 0;
- }
- unsigned int cmdqDdpClockOff(uint64_t engineFlag)
- {
- /* DISP_LOG_I("cmdqDdpClockOff\n"); */
- return 0;
- }
- unsigned int cmdqDdpDumpInfo(uint64_t engineFlag, char *pOutBuf, unsigned int bufSize)
- {
- DISPERR("cmdq timeout:%llu\n", engineFlag);
- primary_display_diagnose();
- /* DISP_LOG_I("cmdqDdpDumpInfo\n"); */
- if (primary_display_is_decouple_mode()) {
- ddp_dump_analysis(DISP_MODULE_OVL0);
- #if defined(OVL_CASCADE_SUPPORT)
- ddp_dump_analysis(DISP_MODULE_OVL1);
- #endif
- }
- ddp_dump_analysis(DISP_MODULE_WDMA0);
- /* try to set event by CPU to avoid blocking auto test such as Monkey/MTBF */
- cmdqCoreSetEvent(CMDQ_SYNC_TOKEN_STREAM_EOF);
- cmdqCoreSetEvent(CMDQ_EVENT_DISP_RDMA0_EOF);
- return 0;
- }
- unsigned int cmdqDdpResetEng(uint64_t engineFlag)
- {
- /* DISP_LOG_I("cmdqDdpResetEng\n"); */
- return 0;
- }
- /* TODO: these 2 functions should be splited into another file */
- unsigned int display_path_idle_cnt = 0;
- #if defined(MTK_FB_SODI_SUPPORT)
- static void _RDMA0_INTERNAL_IRQ_Handler(DISP_MODULE_ENUM module, unsigned int param)
- {
- if (!_is_decouple_mode(pgc->session_mode) && param & 0x2) {
- /* RDMA Start */
- display_path_idle_cnt++;
- #if !defined(CONFIG_FPGA_EARLY_PORTING) && !defined(FORCE_SODI_CG_MODE)
- spm_sodi_mempll_pwr_mode(1);
- #endif
- MMProfileLogEx(ddp_mmp_get_events()->sodi_disable, MMProfileFlagPulse, 0, 0);
- }
- if (param & 0x4) {
- /* RDMA Done */
- display_path_idle_cnt--;
- if (display_path_idle_cnt == 0) {
- #if !defined(CONFIG_FPGA_EARLY_PORTING) && !defined(FORCE_SODI_CG_MODE)
- spm_sodi_mempll_pwr_mode(0);
- #endif
- MMProfileLogEx(ddp_mmp_get_events()->sodi_enable, MMProfileFlagPulse, 0, 0);
- }
- }
- }
- static void _WDMA0_INTERNAL_IRQ_Handler(DISP_MODULE_ENUM module, unsigned int param)
- {
- if (param & 0x1) {
- /* WDMA Done */
- dpmgr_wdma_path_force_power_off();
- if (!primary_display_is_video_mode()) {
- display_path_idle_cnt--;
- if (display_path_idle_cnt == 0) {
- #if !defined(CONFIG_FPGA_EARLY_PORTING) && !defined(FORCE_SODI_CG_MODE)
- spm_sodi_mempll_pwr_mode(0);
- #endif
- }
- }
- }
- }
- static void _MUTEX_INTERNAL_IRQ_Handler(DISP_MODULE_ENUM module, unsigned int param)
- {
- if (param & 0x1) { /* RDMA-->DSI SOF */
- display_path_idle_cnt++;
- #if !defined(CONFIG_FPGA_EARLY_PORTING) && !defined(FORCE_SODI_CG_MODE)
- spm_sodi_mempll_pwr_mode(1);
- #endif
- }
- if (param & 0x2) { /* OVL->WDMA SOF */
- display_path_idle_cnt++;
- #if !defined(CONFIG_FPGA_EARLY_PORTING) && !defined(FORCE_SODI_CG_MODE)
- spm_sodi_mempll_pwr_mode(1);
- #endif
- }
- }
- #endif
- void primary_display_sodi_rule_init(void)
- {
- #if defined(MTK_FB_SODI_DEFEATURE)
- if ((primary_display_get_width() > 800) && (primary_display_is_video_mode() == 1)) {
- #ifndef CONFIG_FPGA_EARLY_PORTING
- defeature_soidle_by_display();
- #endif
- DISPMSG("SODI defeatured!\n");
- return;
- }
- #endif
- #if defined(MTK_FB_SODI_SUPPORT)
- /* if ((primary_display_mode == DECOUPLE_MODE) && primary_display_is_video_mode()) */
- if (gEnableSODIControl == 0 && primary_display_is_video_mode() == 1) {
- #ifndef CONFIG_FPGA_EARLY_PORTING
- spm_enable_sodi(0);
- #endif
- DISPMSG("SODI disabled!\n");
- return;
- }
- #ifndef CONFIG_FPGA_EARLY_PORTING
- spm_enable_sodi(1);
- #endif
- if (primary_display_is_video_mode()) {
- /* if switch to video mode, should de-register callback */
- disp_unregister_module_irq_callback(DISP_MODULE_RDMA0, _RDMA0_INTERNAL_IRQ_Handler);
- #ifdef WDMA_PATH_CLOCK_DYNAMIC_SWITCH
- disp_register_module_irq_callback(DISP_MODULE_WDMA0, _WDMA0_INTERNAL_IRQ_Handler);
- #endif
- /* spm_sodi_mempll_pwr_mode(0); */
- } else {
- disp_register_module_irq_callback(DISP_MODULE_RDMA0, _RDMA0_INTERNAL_IRQ_Handler);
- #ifdef WDMA_PATH_CLOCK_DYNAMIC_SWITCH
- disp_register_module_irq_callback(DISP_MODULE_WDMA0, _WDMA0_INTERNAL_IRQ_Handler);
- #endif
- if (_is_decouple_mode(pgc->session_mode)) {
- disp_register_module_irq_callback(DISP_MODULE_MUTEX, _MUTEX_INTERNAL_IRQ_Handler);
- disp_register_module_irq_callback(DISP_MODULE_WDMA0, _WDMA0_INTERNAL_IRQ_Handler);
- }
- }
- #endif
- }
- /* extern int dfo_query(const char *s, unsigned long *v); */
- int primary_display_change_lcm_resolution(unsigned int width, unsigned int height)
- {
- if (pgc->plcm) {
- DISPMSG("LCM Resolution will be changed, original: %dx%d, now: %dx%d\n",
- pgc->plcm->params->width, pgc->plcm->params->height, width, height);
- /* align with 4 is the minimal check, to ensure we can boot up into kernel,
- * and could modify dfo setting again using meta tool
- */
- /* otherwise we will have a panic in lk(root cause unknown). */
- if (width > pgc->plcm->params->width || height > pgc->plcm->params->height ||
- width == 0 || height == 0 || width % 4 || height % 2) {
- DISPERR("Invalid resolution: %dx%d\n", width, height);
- return -1;
- }
- if (primary_display_is_video_mode()) {
- DISPERR("Warning!!!Video Mode can't support multiple resolution!\n");
- return -1;
- }
- pgc->plcm->params->width = width;
- pgc->plcm->params->height = height;
- return 0;
- } else {
- return -1;
- }
- }
- static void primary_display_frame_update_irq_callback(DISP_MODULE_ENUM module, unsigned int param)
- {
- /* if (pgc->session_mode == DISP_SESSION_DIRECT_LINK_MIRROR_MODE) */
- /* return; */
- if (module == DISP_MODULE_RDMA0) {
- if (param & 0x20) { /* rdma0 frame start */
- if (pgc->session_id > 0)
- update_frm_seq_info(ddp_ovl_get_cur_addr(1, 0), 0, 1, FRM_START);
- }
- if (param & 0x4) { /* rdma0 frame done */
- atomic_set(&primary_display_frame_update_event, 1);
- wake_up_interruptible(&primary_display_frame_update_wq);
- }
- }
- if ((module == DISP_MODULE_OVL0) && (_is_decouple_mode(pgc->session_mode) == 0)) {
- if (param & 0x2) { /* ov0 frame done */
- atomic_set(&primary_display_frame_update_event, 1);
- wake_up_interruptible(&primary_display_frame_update_wq);
- }
- }
- #if defined(CONFIG_TRUSTONIC_TEE_SUPPORT) && defined(CONFIG_MTK_SEC_VIDEO_PATH_SUPPORT)
- /* In TEE, we have to protect WDMA registers, so we can't enable WDMA interrupt */
- /* here we use ovl frame done interrupt instead */
- if ((module == DISP_MODULE_OVL0) && (_is_decouple_mode(pgc->session_mode) == 1)) {
- if (param & 0x2) {/* OVL0 frame done */
- atomic_set(&decouple_fence_release_event, 1);
- wake_up_interruptible(&decouple_fence_release_wq);
- }
- }
- #else
- if ((module == DISP_MODULE_WDMA0) && (_is_decouple_mode(pgc->session_mode) == 1)) {
- if (param & 0x1) {/* wdma0 frame done */
- atomic_set(&decouple_fence_release_event, 1);
- wake_up_interruptible(&decouple_fence_release_wq);
- }
- }
- #endif
- }
- static int primary_display_frame_update_kthread(void *data)
- {
- struct sched_param param = {.sched_priority = 94 }; /* RTPM_PRIO_SCRN_UPDATE */
- sched_setscheduler(current, SCHED_RR, ¶m);
- for (;;) {
- wait_event_interruptible(primary_display_frame_update_wq,
- atomic_read(&primary_display_frame_update_event));
- atomic_set(&primary_display_frame_update_event, 0);
- if (pgc->session_id > 0)
- update_frm_seq_info(0, 0, 0, FRM_END);
- if (kthread_should_stop())
- break;
- }
- return 0;
- }
- /* defined but not used */
- /* static struct task_struct *if_fence_release_worker_task = NULL; */
- #if 0
- /**
- * Defined but not used, avoid build warning. (2015.1.30 Rynn Wu)
- */
- static int _if_fence_release_worker_thread(void *data)
- {
- unsigned int session_id = MAKE_DISP_SESSION(DISP_SESSION_PRIMARY, 0);
- struct sched_param param = { .sched_priority = RTPM_PRIO_SCRN_UPDATE };
- sched_setscheduler(current, SCHED_RR, ¶m);
- dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_START);
- while (1) {
- dpmgr_wait_event(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_START);
- if (_is_mirror_mode(pgc->session_mode)) {
- int fence_idx, subtractor, layer;
- layer = disp_sync_get_output_interface_timeline_id();
- cmdqBackupReadSlot(pgc->cur_config_fence, layer, &fence_idx);
- cmdqBackupReadSlot(pgc->subtractor_when_free, layer, &subtractor);
- mtkfb_release_fence(session_id, layer, fence_idx-1);
- }
- if (kthread_should_stop())
- break;
- }
- return 0;
- }
- #endif
- /* defined but not used. */
- /* static struct task_struct *ovl2mem_fence_release_worker_task = NULL; */
- #if 0
- /**
- * Defined but not used, avoid build warning. (2015.1.30 Rynn Wu)
- */
- static int _ovl2mem_fence_release_worker_thread(void *data)
- {
- unsigned int session_id = MAKE_DISP_SESSION(DISP_SESSION_PRIMARY, 0);
- struct sched_param param = { .sched_priority = RTPM_PRIO_SCRN_UPDATE };
- sched_setscheduler(current, SCHED_RR, ¶m);
- dpmgr_enable_event(pgc->ovl2mem_path_handle, DISP_PATH_EVENT_FRAME_COMPLETE);
- while (1) {
- /* it's not good to use FRAME_COMPLETE here, because when CPU read wdma addr,
- * maybe it's already changed by next request,
- * but luckly currently we will wait rdma frame done after wdma done(in CMDQ), so it's safe now
- */
- dpmgr_wait_event(pgc->ovl2mem_path_handle, DISP_PATH_EVENT_FRAME_COMPLETE);
- if (_is_mirror_mode(pgc->session_mode)) {
- int fence_idx, subtractor, layer;
- layer = disp_sync_get_output_timeline_id();
- cmdqBackupReadSlot(pgc->cur_config_fence, layer, &fence_idx);
- cmdqBackupReadSlot(pgc->subtractor_when_free, layer, &subtractor);
- mtkfb_release_fence(session_id, layer, fence_idx);
- }
- if (kthread_should_stop())
- break;
- }
- return 0;
- }
- #endif
- /* defined but not used. */
- /* static struct task_struct *fence_release_worker_task = NULL; */
- /* extern unsigned int ddp_ovl_get_cur_addr(bool rdma_mode, int layerid); */
- static void _wdma_fence_release_callback(uint32_t userdata)
- {
- int fence_idx, layer;
- layer = disp_sync_get_output_timeline_id();
- cmdqBackupReadSlot(pgc->cur_config_fence, layer, &fence_idx);
- mtkfb_release_fence(primary_session_id, layer, fence_idx);
- MMProfileLogEx(ddp_mmp_get_events()->primary_wdma_fence_release, MMProfileFlagPulse, layer,
- fence_idx);
- }
- static int _Interface_fence_release_callback(uint32_t userdata)
- {
- int layer = disp_sync_get_output_interface_timeline_id();
- if (userdata > 0) {
- mtkfb_release_fence(primary_session_id, layer, userdata);
- MMProfileLogEx(ddp_mmp_get_events()->primary_wdma_fence_release, MMProfileFlagPulse,
- layer, userdata);
- }
- return 0;
- }
- static int _ovl_ext_fence_release_callback(uint32_t userdata)
- {
- int i = 0;
- int ret = 0;
- int fence_idx, layer;
- MMProfileLogEx(ddp_mmp_get_events()->session_release, MMProfileFlagStart, 1, userdata);
- #ifndef MTK_FB_CMDQ_DISABLE
- for (i = 0; i < PRIMARY_DISPLAY_SESSION_LAYER_COUNT; i++) {
- int fence_idx = 0;
- int subtractor = 0;
- if (i == primary_display_get_option("ASSERT_LAYER") && is_DAL_Enabled()) {
- mtkfb_release_layer_fence(ext_session_id, i);
- } else {
- cmdqBackupReadSlot(pgc->cur_mem_config_fence, i, &fence_idx);
- cmdqBackupReadSlot(pgc->mem_subtractor_when_free, i, &subtractor);
- mtkfb_release_fence(ext_session_id, i, fence_idx);
- }
- MMProfileLogEx(ddp_mmp_get_events()->primary_ovl_fence_release, MMProfileFlagPulse, i, fence_idx);
- }
- #endif
- if (userdata == DISP_SESSION_MEMORY) {
- #ifndef MTK_FB_CMDQ_DISABLE
- layer = disp_sync_get_output_timeline_id();
- cmdqBackupReadSlot(pgc->cur_mem_config_fence, layer, &fence_idx);
- mtkfb_release_fence(ext_session_id, layer, fence_idx);
- #endif
- }
- return ret;
- }
- static int _ovl_fence_release_callback(uint32_t userdata)
- {
- int i = 0;
- unsigned int addr = 0;
- int ret = 0;
- unsigned int dsi_state[10];
- unsigned int rdma_state[50];
- MMProfileLogEx(ddp_mmp_get_events()->session_release, MMProfileFlagStart, 1, userdata);
- /* releaes OVL1 when primary setting */
- if (ovl_get_status() == DDP_OVL1_STATUS_PRIMARY_RELEASED)
- dpmgr_set_ovl1_status(DDP_OVL1_STATUS_SUB);
- else if (ovl_get_status() == DDP_OVL1_STATUS_PRIMARY_DISABLE)
- dpmgr_set_ovl1_status(DDP_OVL1_STATUS_IDLE);
- #ifndef MTK_FB_CMDQ_DISABLE
- for (i = 0; i < PRIMARY_DISPLAY_SESSION_LAYER_COUNT; i++) {
- int fence_idx = 0;
- int subtractor = 0;
- if (i == primary_display_get_option("ASSERT_LAYER") && is_DAL_Enabled()) {
- mtkfb_release_layer_fence(primary_session_id, i);
- } else {
- cmdqBackupReadSlot(pgc->cur_config_fence, i, &fence_idx);
- cmdqBackupReadSlot(pgc->subtractor_when_free, i, &subtractor);
- mtkfb_release_fence(primary_session_id, i, fence_idx - subtractor);
- }
- MMProfileLogEx(ddp_mmp_get_events()->primary_ovl_fence_release, MMProfileFlagPulse,
- i, fence_idx - subtractor);
- }
- if (primary_display_is_video_mode() == 1) {
- unsigned int ovl_status[2];
- cmdqBackupReadSlot(pgc->ovl_status_info, 0, &ovl_status[0]);
- cmdqBackupReadSlot(pgc->ovl_status_info, 1, &ovl_status[1]);
- DISPDBG("ovl fsm state:0x%x\n", ovl_status[0]);
- if ((ovl_status[1] & 0x1) != OVL_STATUS_IDLE) {
- DISPERR("disp ovl status error, 0x%x, 0x%x\n", ovl_status[0],
- ovl_status[1]);
- /* dump cmdq cmd here */
- }
- }
- #endif
- /* backup DSI state register to slot */
- if (gEnableDSIStateCheck == 1) {
- for (i = 0; i < 10; i++) {
- cmdqBackupReadSlot(pgc->dsi_state_info, i, &dsi_state[i]);
- if ((dsi_state[i] & 0x2) == 0x2) {
- DISPERR("disp DSI_STATE error, %d, 0x%x\n", i, dsi_state[i]);
- cmdqBackupReadSlot(pgc->rdma_state_info, i * 5 + 0,
- &rdma_state[i * 5 + 0]);
- cmdqBackupReadSlot(pgc->rdma_state_info, i * 5 + 1,
- &rdma_state[i * 5 + 1]);
- cmdqBackupReadSlot(pgc->rdma_state_info, i * 5 + 2,
- &rdma_state[i * 5 + 2]);
- cmdqBackupReadSlot(pgc->rdma_state_info, i * 5 + 3,
- &rdma_state[i * 5 + 3]);
- cmdqBackupReadSlot(pgc->rdma_state_info, i * 5 + 4,
- &rdma_state[i * 5 + 4]);
- DISPERR("disp RDMA_STATE:%d, irq=0x%x, in/out=(%d,%d,%d,%d)\n",
- i, rdma_state[i * 5 + 0], rdma_state[i * 5 + 1],
- rdma_state[i * 5 + 2], rdma_state[i * 5 + 3], rdma_state[i * 5 + 4]);
- } else {
- DISPERR("disp DSI_STATE pass, %d, 0x%x\n", i, dsi_state[i]);
- }
- }
- }
- addr = ddp_ovl_get_cur_addr(!_should_config_ovl_input(), 0);
- if ((_is_decouple_mode(pgc->session_mode) == 0))
- update_frm_seq_info(addr, 0, 2, FRM_START);
- #ifndef MTK_FB_CMDQ_DISABLE
- if (userdata == 5) {
- int fence_idx, subtractor, layer;
- layer = disp_sync_get_output_timeline_id();
- cmdqBackupReadSlot(pgc->cur_config_fence, layer, &fence_idx);
- cmdqBackupReadSlot(pgc->subtractor_when_free, layer, &subtractor);
- mtkfb_release_fence(primary_session_id, layer, fence_idx);
- }
- /* async callback, need to check if it is still decouple */
- if (_is_decouple_mode(pgc->session_mode) && !_is_mirror_mode(pgc->session_mode)
- && (userdata == DISP_SESSION_DECOUPLE_MODE || userdata == 5)) {
- static cmdqRecHandle cmdq_handle;
- unsigned int rdma_pitch_sec, rdma_fmt;
- if (primary_get_state() != DISP_ALIVE)
- return 0;
- if (cmdq_handle == NULL)
- ret = cmdqRecCreate(CMDQ_SCENARIO_PRIMARY_DISP, &cmdq_handle);
- if (ret == 0) {
- cmdqBackupReadSlot(pgc->rdma_buff_info, 1, &(rdma_pitch_sec));
- rdma_pitch_sec = rdma_pitch_sec >> 30;
- if (rdma_pitch_sec == DISP_NORMAL_BUFFER)
- _primary_path_lock(__func__);
- cmdqRecReset(cmdq_handle);
- _cmdq_insert_wait_frame_done_token_mira(cmdq_handle);
- cmdqBackupReadSlot(pgc->rdma_buff_info, 0, &addr);
- decouple_rdma_config.address = addr;
- /*rdma pitch only use bit[15..0], we use bit[31:30] to store secure information */
- decouple_rdma_config.security = rdma_pitch_sec;
- _config_rdma_input_data(&decouple_rdma_config, pgc->dpmgr_handle,
- cmdq_handle);
- _cmdq_set_config_handle_dirty_mira(cmdq_handle);
- cmdqRecFlushAsyncCallback(cmdq_handle, NULL, 0);
- cmdqBackupReadSlot(pgc->rdma_buff_info, 2, &(rdma_fmt));
- decouple_rdma_config.inputFormat = rdma_fmt;
- if (rdma_pitch_sec == DISP_NORMAL_BUFFER)
- _primary_path_unlock(__func__);
- MMProfileLogEx(ddp_mmp_get_events()->primary_rdma_config,
- MMProfileFlagPulse, 0, decouple_rdma_config.address);
- /* cmdqRecDestroy(cmdq_handle); */
- } else {
- /* ret = -1; */
- DISPERR("fail to create cmdq\n");
- }
- }
- #endif
- return ret;
- }
- static int decouple_fence_release_kthread(void *data)
- {
- int interface_fence = 0;
- int layer = 0;
- int ret = 0;
- struct sched_param param = {.sched_priority = 94 }; /* RTPM_PRIO_SCRN_UPDATE */
- sched_setscheduler(current, SCHED_RR, ¶m);
- for (;;) {
- wait_event_interruptible(decouple_fence_release_wq,
- atomic_read(&decouple_fence_release_event));
- atomic_set(&decouple_fence_release_event, 0);
- /* async callback, need to check if it is still decouple */
- _primary_path_lock(__func__);
- if (pgc->session_mode == DISP_SESSION_DECOUPLE_MIRROR_MODE
- && pgc->state != DISP_SLEPT) {
- static cmdqRecHandle cmdq_handle;
- unsigned int rdma_pitch_sec, rdma_fmt;
- if (cmdq_handle == NULL)
- ret = cmdqRecCreate(CMDQ_SCENARIO_PRIMARY_DISP, &cmdq_handle);
- if (ret == 0) {
- RDMA_CONFIG_STRUCT tmpConfig = decouple_rdma_config;
- cmdqRecReset(cmdq_handle);
- _cmdq_insert_wait_frame_done_token_mira(cmdq_handle);
- cmdqBackupReadSlot(pgc->rdma_buff_info, 0,
- (uint32_t *)&(tmpConfig.address));
- /*rdma pitch only use bit[15..0], we use bit[31:30] to store secure information */
- cmdqBackupReadSlot(pgc->rdma_buff_info, 1, &(rdma_pitch_sec));
- tmpConfig.pitch = rdma_pitch_sec & ~(3 << 30);
- tmpConfig.security = rdma_pitch_sec >> 30;
- cmdqBackupReadSlot(pgc->rdma_buff_info, 2, &(rdma_fmt));
- tmpConfig.inputFormat = rdma_fmt;
- _config_rdma_input_data(&tmpConfig, pgc->dpmgr_handle, cmdq_handle);
- layer = disp_sync_get_output_timeline_id();
- cmdqBackupReadSlot(pgc->cur_config_fence, layer, &interface_fence);
- _cmdq_set_config_handle_dirty_mira(cmdq_handle);
- cmdqRecFlushAsyncCallback(cmdq_handle,
- (CmdqAsyncFlushCB)_Interface_fence_release_callback,
- interface_fence > 1 ? interface_fence - 1 : 0);
- MMProfileLogEx(ddp_mmp_get_events()->primary_rdma_config,
- MMProfileFlagPulse, interface_fence,
- decouple_rdma_config.address);
- /* dump rdma input if enabled */
- dprec_mmp_dump_rdma_layer(&tmpConfig, 0);
- /* cmdqRecDestroy(cmdq_handle); */
- } else {
- DISPERR("fail to create cmdq\n");
- }
- }
- _primary_path_unlock(__func__);
- if (kthread_should_stop())
- break;
- }
- return 0;
- }
- static int _olv_wdma_fence_release_callback(uint32_t userdata)
- {
- _ovl_fence_release_callback(userdata);
- _wdma_fence_release_callback(userdata);
- return 0;
- }
- #if 0
- /**
- * Defined but not used, avoid build warning. (2015.1.30 Rynn Wu)
- */
- static int _fence_release_worker_thread(void *data)
- {
- int i = 0;
- unsigned int addr = 0;
- unsigned int session_id = MAKE_DISP_SESSION(DISP_SESSION_PRIMARY, 0);
- struct sched_param param = { .sched_priority = RTPM_PRIO_SCRN_UPDATE };
- sched_setscheduler(current, SCHED_RR, ¶m);
- if (!_is_decouple_mode(pgc->session_mode))
- dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_START);
- else
- dpmgr_enable_event(pgc->ovl2mem_path_handle, DISP_PATH_EVENT_FRAME_START);
- while (1) {
- if (!_is_decouple_mode(pgc->session_mode))
- dpmgr_wait_event(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_START);
- else
- dpmgr_wait_event(pgc->ovl2mem_path_handle, DISP_PATH_EVENT_FRAME_START);
- if (is_hwc_enabled == 0)
- continue;
- /* releaes OVL1 when primary setting */
- if (ovl_get_status() == DDP_OVL1_STATUS_PRIMARY_RELEASED) {
- ovl_set_status(DDP_OVL1_STATUS_SUB);
- wake_up_interruptible(&ovl1_wait_queue);
- } else if (ovl_get_status() == DDP_OVL1_STATUS_PRIMARY_DISABLE) {
- ovl_set_status(DDP_OVL1_STATUS_IDLE);
- wake_up_interruptible(&ovl1_wait_queue);
- }
- for (i = 0; i < PRIMARY_DISPLAY_SESSION_LAYER_COUNT; i++) {
- int fence_idx, subtractor;
- if (i == primary_display_get_option("ASSERT_LAYER") && is_DAL_Enabled()) {
- mtkfb_release_layer_fence(session_id, i);
- } else {
- cmdqBackupReadSlot(pgc->cur_config_fence, i, &fence_idx);
- cmdqBackupReadSlot(pgc->subtractor_when_free, i, &subtractor);
- mtkfb_release_fence(session_id, i, fence_idx-subtractor);
- }
- }
- addr = ddp_ovl_get_cur_addr(!_should_config_ovl_input(), 0);
- if ((_is_decouple_mode(pgc->session_mode) == 0))
- update_frm_seq_info(addr, 0, 2, FRM_START);
- MMProfileLogEx(ddp_mmp_get_events()->session_release, MMProfileFlagEnd, 0, 0);
- if (kthread_should_stop())
- break;
- }
- return 0;
- }
- #endif
- static struct task_struct *present_fence_release_worker_task;
- static int _present_fence_release_worker_thread(void *data)
- {
- int ret = 0;
- disp_sync_info *layer_info = NULL;
- struct sched_param param = {.sched_priority = 87 }; /* RTPM_PRIO_FB_THREAD */
- sched_setscheduler(current, SCHED_RR, ¶m);
- dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC);
- while (1) {
- ret = dpmgr_wait_event(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC);
- /* release present fence in vsync callback */
- {
- /* extern disp_sync_info *_get_sync_info(unsigned int session_id,
- unsigned int timeline_id);
- */
- int fence_increment = 0;
- /* if session not created, do not release present fence */
- if (pgc->session_id == 0) {
- MMProfileLogEx(ddp_mmp_get_events()->present_fence_release,
- MMProfileFlagPulse, -1, 0x4a4a4a4a);
- /* DISPDBG("_get_sync_info fail in present_fence_release thread\n"); */
- continue;
- }
- layer_info = _get_sync_info(pgc->session_id, disp_sync_get_present_timeline_id());
- if (layer_info == NULL) {
- MMProfileLogEx(ddp_mmp_get_events()->present_fence_release,
- MMProfileFlagPulse, -1, 0x5a5a5a5a);
- /* DISPERR("_get_sync_info fail in present_fence_release thread\n"); */
- continue;
- }
- _primary_path_lock(__func__);
- fence_increment = gPresentFenceIndex - layer_info->timeline->value;
- if (fence_increment > 0) {
- timeline_inc(layer_info->timeline, fence_increment);
- MMProfileLogEx(ddp_mmp_get_events()->present_fence_release,
- MMProfileFlagPulse, gPresentFenceIndex,
- fence_increment);
- }
- _primary_path_unlock(__func__);
- /* DISPPR_FENCE("RPF/%d/%d\n",
- gPresentFenceIndex, gPresentFenceIndex-layer_info->timeline->value);
- */
- }
- }
- return 0;
- }
- int primary_display_capture_framebuffer_wdma(void *data)
- {
- int ret = 0;
- cmdqRecHandle cmdq_handle = NULL;
- disp_ddp_path_config *pconfig = NULL;
- m4u_client_t *m4uClient = NULL;
- unsigned int w_xres = primary_display_get_width();
- unsigned int h_yres = primary_display_get_height();
- unsigned int pixel_byte = primary_display_get_dc_bpp() / 8; /* bpp is either 32 or 16, can not be other value */
- int buffer_size = h_yres * w_xres * pixel_byte;
- int buf_idx = 0;
- unsigned int mva[2] = { 0, 0 };
- void *va[2] = { NULL, NULL };
- unsigned int format = eRGBA8888;
- struct sched_param param = {.sched_priority = 87 }; /* RTPM_PRIO_FB_THREAD */
- sched_setscheduler(current, SCHED_RR, ¶m);
- va[0] = vmalloc(buffer_size);
- if (va[0] == NULL) {
- DISPCHECK("wdma dump:Fail to alloc vmalloc 0\n");
- ret = -1;
- goto out;
- }
- va[1] = vmalloc(buffer_size);
- if (va[1] == NULL) {
- DISPCHECK("wdma dump:Fail to alloc vmalloc 1\n");
- ret = -1;
- goto out;
- }
- m4uClient = m4u_create_client();
- if (m4uClient == NULL) {
- DISPCHECK("wdma dump:Fail to alloc m4uClient=0x%p\n", m4uClient);
- ret = -1;
- goto out;
- }
- ret = m4u_alloc_mva(m4uClient, M4U_PORT_DISP_WDMA0, (unsigned long)va[0], NULL, buffer_size,
- M4U_PROT_READ | M4U_PROT_WRITE, 0, (unsigned int *)&mva[0]);
- if (ret != 0) {
- DISPCHECK("wdma dump::Fail to allocate mva 0\n");
- ret = -1;
- goto out;
- }
- ret = m4u_alloc_mva(m4uClient, M4U_PORT_DISP_WDMA0, (unsigned long)va[1], NULL, buffer_size,
- M4U_PROT_READ | M4U_PROT_WRITE, 0, (unsigned int *)&mva[1]);
- if (ret != 0) {
- DISPCHECK("wdma dump::Fail to allocate mva 1\n");
- ret = -1;
- goto out;
- }
- if (primary_display_cmdq_enabled()) {
- /*create config thread */
- ret = cmdqRecCreate(CMDQ_SCENARIO_PRIMARY_DISP, &cmdq_handle);
- if (ret != 0) {
- DISPCHECK("wdma dump:Fail to create primary cmdq handle for capture\n");
- ret = -1;
- goto out;
- }
- dpmgr_path_memout_clock(pgc->dpmgr_handle, 1);
- dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_START);
- cmdqRecReset(cmdq_handle);
- _cmdq_insert_wait_frame_done_token_mira(cmdq_handle);
- _primary_path_lock(__func__);
- dpmgr_path_add_memout(pgc->dpmgr_handle, ENGINE_OVL0, cmdq_handle);
- _primary_path_unlock(__func__);
- while (primary_dump_wdma) {
- ret = m4u_cache_sync(m4uClient, M4U_PORT_DISP_WDMA0, (unsigned long)va[buf_idx],
- buffer_size, mva[buf_idx], M4U_CACHE_FLUSH_BY_RANGE);
- _primary_path_lock(__func__);
- pconfig = dpmgr_path_get_last_config(pgc->dpmgr_handle);
- pconfig->wdma_dirty = 1;
- pconfig->wdma_config.dstAddress = mva[buf_idx];
- pconfig->wdma_config.srcHeight = h_yres;
- pconfig->wdma_config.srcWidth = w_xres;
- pconfig->wdma_config.clipX = 0;
- pconfig->wdma_config.clipY = 0;
- pconfig->wdma_config.clipHeight = h_yres;
- pconfig->wdma_config.clipWidth = w_xres;
- pconfig->wdma_config.outputFormat = format;
- pconfig->wdma_config.useSpecifiedAlpha = 1;
- pconfig->wdma_config.alpha = 0xFF;
- pconfig->wdma_config.dstPitch = w_xres * DP_COLOR_BITS_PER_PIXEL(format) / 8;
- ret = dpmgr_path_config(pgc->dpmgr_handle, pconfig, cmdq_handle);
- pconfig->wdma_dirty = 0;
- _primary_path_unlock(__func__);
- _cmdq_set_config_handle_dirty_mira(cmdq_handle);
- _cmdq_flush_config_handle_mira(cmdq_handle, 0);
- ret = dpmgr_wait_event(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_START);
- /* pconfig->wdma_config.dstAddress = va[buf_idx++]; */
- /* DISPCHECK("capture wdma\n"); */
- dprec_mmp_dump_wdma_layer(&pconfig->wdma_config, 0);
- buf_idx = buf_idx % 2;
- cmdqRecReset(cmdq_handle);
- _cmdq_insert_wait_frame_done_token_mira(cmdq_handle);
- }
- _primary_path_lock(__func__);
- dpmgr_path_remove_memout(pgc->dpmgr_handle, cmdq_handle);
- _primary_path_unlock(__func__);
- _cmdq_set_config_handle_dirty_mira(cmdq_handle);
- /* flush remove memory to cmdq */
- _cmdq_flush_config_handle_mira(cmdq_handle, 1);
- DISPMSG("wdma dump: Flush remove memout\n");
- dpmgr_path_memout_clock(pgc->dpmgr_handle, 0);
- }
- out:
- cmdqRecDestroy(cmdq_handle);
- if (mva[0] > 0)
- m4u_dealloc_mva(m4uClient, M4U_PORT_DISP_WDMA0, mva[0]);
- if (mva[1] > 0)
- m4u_dealloc_mva(m4uClient, M4U_PORT_DISP_WDMA0, mva[1]);
- if (va[0] != NULL)
- vfree(va[0]);
- if (va[1] != NULL)
- vfree(va[1]);
- if (m4uClient != 0)
- m4u_destroy_client(m4uClient);
- DISPMSG("wdma dump:end\n");
- return ret;
- }
- int primary_display_switch_wdma_dump(int on)
- {
- if (on && (!primary_dump_wdma)) {
- primary_dump_wdma = 1;
- primary_display_wdma_out = kthread_create(primary_display_capture_framebuffer_wdma, NULL,
- "display_wdma_out");
- wake_up_process(primary_display_wdma_out);
- } else {
- primary_dump_wdma = 0;
- }
- return 0;
- }
- #define xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- int primary_display_set_frame_buffer_address(unsigned long va, unsigned long mva)
- {
- /* DISPMSG("framebuffer va %lu, mva %lu\n", va, mva); */
- pgc->framebuffer_va = va;
- pgc->framebuffer_mva = mva;
- /*
- int frame_buffer_size = ALIGN_TO(DISP_GetScreenWidth(), MTK_FB_ALIGNMENT) *
- ALIGN_TO(DISP_GetScreenHeight(), MTK_FB_ALIGNMENT) * 4;
- unsigned long dim_layer_va = va + 2*frame_buffer_size;
- dim_layer_mva = mva + 2*frame_buffer_size;
- memset_io(dim_layer_va, 0, frame_buffer_size);
- */
- return 0;
- }
- unsigned long primary_display_get_frame_buffer_mva_address(void)
- {
- return pgc->framebuffer_mva;
- }
- unsigned long primary_display_get_frame_buffer_va_address(void)
- {
- return pgc->framebuffer_va;
- }
- int primary_display_get_session_mode(void)
- {
- return pgc->session_mode;
- }
- int is_dim_layer(unsigned int long mva)
- {
- if (mva == dim_layer_mva)
- return 1;
- return 0;
- }
- void *primary_get_dpmgr_handle(void)
- {
- return pgc->dpmgr_handle;
- }
- unsigned long get_dim_layer_mva_addr(void)
- {
- if (dim_layer_mva == 0) {
- int frame_buffer_size = ALIGN_TO(DISP_GetScreenWidth(),
- MTK_FB_ALIGNMENT) * DISP_GetScreenHeight() * 4;
- dim_layer_mva = pgc->framebuffer_mva + 2 * frame_buffer_size;
- DISPMSG("init dim layer mva %lu, size %d", dim_layer_mva, frame_buffer_size);
- }
- return dim_layer_mva;
- }
- #ifndef MTK_FB_CMDQ_DISABLE
- static int init_cmdq_slots(cmdqBackupSlotHandle *pSlot, int count, int init_val)
- {
- int i;
- cmdqBackupAllocateSlot(pSlot, count);
- for (i = 0; i < count; i++)
- cmdqBackupWriteSlot(*pSlot, i, init_val);
- return 0;
- }
- #endif
- int primary_display_init(char *lcm_name, unsigned int lcm_fps)
- {
- DISP_STATUS ret = DISP_STATUS_OK;
- #ifndef MTK_FB_DFO_DISABLE
- unsigned int lcm_fake_width = 0;
- unsigned int lcm_fake_height = 0;
- #endif
- LCM_PARAMS *lcm_param = NULL;
- disp_ddp_path_config *data_config = NULL;
- DISPPRINT("primary_display_init begin\n");
- dprec_init();
- dpmgr_init();
- #ifndef MTK_FB_CMDQ_DISABLE
- init_cmdq_slots(&(pgc->cur_config_fence), DISP_SESSION_TIMELINE_COUNT, 0);
- init_cmdq_slots(&(pgc->subtractor_when_free), DISP_SESSION_TIMELINE_COUNT, 0);
- init_cmdq_slots(&(pgc->cur_mem_config_fence), DISP_SESSION_TIMELINE_COUNT, 0);
- init_cmdq_slots(&(pgc->mem_subtractor_when_free), DISP_SESSION_TIMELINE_COUNT, 0);
- init_cmdq_slots(&(pgc->rdma_buff_info), 3, 0);
- init_cmdq_slots(&(pgc->ovl_status_info), 2, 0);
- init_cmdq_slots(&(pgc->dsi_state_info), 10, 0);
- init_cmdq_slots(&(pgc->rdma_state_info), 50, 0);
- #endif
- #ifdef DISP_DUMP_EVENT_STATUS
- init_cmdq_slots(&(pgc->event_status), 6, 0);
- #endif
- mutex_init(&(pgc->capture_lock));
- mutex_init(&(pgc->lock));
- mutex_init(&(pgc->cmd_lock));
- mutex_init(&(pgc->vsync_lock));
- mutex_init(&esd_mode_switch_lock);
- #ifdef MTK_DISP_IDLE_LP
- mutex_init(&idle_lock);
- #endif
- #ifdef DISP_SWITCH_DST_MODE
- mutex_init(&(pgc->switch_dst_lock));
- #endif
- _primary_path_lock(__func__);
- pgc->plcm = disp_lcm_probe(lcm_name, LCM_INTERFACE_NOTDEFINED);
- if (pgc->plcm == NULL) {
- DISPERR("disp_lcm_probe returns null\n");
- ret = DISP_STATUS_ERROR;
- goto done;
- }
- #ifndef MTK_FB_DFO_DISABLE
- if ((0 == dfo_query("LCM_FAKE_WIDTH", &lcm_fake_width))
- && (0 == dfo_query("LCM_FAKE_HEIGHT", &lcm_fake_height))) {
- pr_debug("[DFO] LCM_FAKE_WIDTH=%d, LCM_FAKE_HEIGHT=%d\n", lcm_fake_width,
- lcm_fake_height);
- if (lcm_fake_width && lcm_fake_height) {
- if (DISP_STATUS_OK != primary_display_change_lcm_resolution(lcm_fake_width, lcm_fake_height))
- DISPMSG("[DISP\DFO]WARNING!!! Change LCM Resolution FAILED!!!\n");
- }
- }
- #endif
- lcm_param = disp_lcm_get_params(pgc->plcm);
- if (lcm_param == NULL) {
- DISPERR("get lcm params FAILED\n");
- ret = DISP_STATUS_ERROR;
- goto done;
- }
- #ifndef MTK_FB_CMDQ_DISABLE
- ret = cmdqCoreRegisterCB(CMDQ_GROUP_DISP, (CmdqClockOnCB)cmdqDdpClockOn, (CmdqDumpInfoCB)cmdqDdpDumpInfo,
- (CmdqResetEngCB)cmdqDdpResetEng, (CmdqClockOffCB)cmdqDdpClockOff);
- if (ret) {
- DISPERR("cmdqCoreRegisterCB failed, ret=%d\n", ret);
- ret = DISP_STATUS_ERROR;
- goto done;
- }
- ret = cmdqRecCreate(CMDQ_SCENARIO_PRIMARY_DISP, &(pgc->cmdq_handle_config));
- if (ret) {
- DISPCHECK("cmdqRecCreate FAIL, ret=%d\n", ret);
- ret = DISP_STATUS_ERROR;
- goto done;
- } else {
- DISPCHECK("cmdqRecCreate SUCCESS, g_cmdq_handle=0x%p\n", pgc->cmdq_handle_config);
- }
- /*create ovl2mem path cmdq handle */
- ret = cmdqRecCreate(CMDQ_SCENARIO_DISP_COLOR, &(pgc->cmdq_handle_ovl1to2_config));
- if (ret != 0) {
- DISPERR("cmdqRecCreate FAIL, ret=%d\n", ret);
- return -1;
- }
- primary_display_use_cmdq = CMDQ_ENABLE;
- #else
- primary_display_use_cmdq = CMDQ_DISABLE;
- #endif
- /* debug for bus hang issue (need to remove) */
- ddp_dump_analysis(DISP_MODULE_CONFIG);
- if (primary_display_mode == DIRECT_LINK_MODE) {
- __build_path_direct_link();
- pgc->session_mode = DISP_SESSION_DIRECT_LINK_MODE;
- DISPCHECK("primary display is DIRECT LINK MODE\n");
- } else if (primary_display_mode == DECOUPLE_MODE) {
- __build_path_decouple();
- pgc->session_mode = DISP_SESSION_DECOUPLE_MODE;
- DISPCHECK("primary display is DECOUPLE MODE\n");
- } else if (primary_display_mode == SINGLE_LAYER_MODE) {
- __build_path_single_layer();
- DISPCHECK("primary display is SINGLE LAYER MODE\n");
- } else if (primary_display_mode == DEBUG_RDMA1_DSI0_MODE) {
- __build_path_debug_rdma1_dsi0();
- DISPCHECK("primary display is DEBUG RDMA1 DSI0 MODE\n");
- } else {
- DISPCHECK("primary display mode is WRONG\n");
- }
- #ifndef MTK_FB_CMDQ_DISABLE
- primary_display_use_cmdq = CMDQ_ENABLE;
- #else
- primary_display_use_cmdq = CMDQ_DISABLE;
- #endif
- /* dpmgr_path_init(pgc->dpmgr_handle, CMDQ_DISABLE); */
- dpmgr_path_set_video_mode(pgc->dpmgr_handle, primary_display_is_video_mode());
- /* dpmgr_path_init(pgc->dpmgr_handle, CMDQ_DISABLE); */
- /* use fake timer to generate vsync signal for cmd mode w/o LCM(originally using LCM TE Signal as VSYNC) */
- /* so we don't need to modify display driver's behavior. */
- if (disp_helper_get_option
- (DISP_HELPER_OPTION_NO_LCM_FOR_LOW_POWER_MEASUREMENT)) {
- /* only for low power measurement */
- DISPCHECK("WARNING!!!!!! FORCE NO LCM MODE!!!\n");
- islcmconnected = 0;
- /* no need to change video mode vsync behavior */
- if (!primary_display_is_video_mode()) {
- _init_vsync_fake_monitor(lcm_fps);
- dpmgr_map_event_to_irq(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC,
- DDP_IRQ_UNKNOWN);
- }
- }
- #ifdef CONFIG_FPGA_EARLY_PORTING
- dpmgr_path_reset(pgc->dpmgr_handle, CMDQ_DISABLE);
- #endif
- if (primary_display_use_cmdq == CMDQ_ENABLE) {
- _cmdq_build_trigger_loop();
- _cmdq_start_trigger_loop();
- _cmdq_reset_config_handle();
- _cmdq_insert_wait_frame_done_token();
- }
- data_config = dpmgr_path_get_last_config(pgc->dpmgr_handle);
- #ifdef OVL_CASCADE_SUPPORT
- if (ovl_get_status() == DDP_OVL1_STATUS_IDLE || ovl_get_status() == DDP_OVL1_STATUS_PRIMARY) {
- if (primary_display_mode == DECOUPLE_MODE)
- dpmgr_path_enable_cascade(pgc->ovl2mem_path_handle,
- pgc->cmdq_handle_config);
- else
- dpmgr_path_enable_cascade(pgc->dpmgr_handle, pgc->cmdq_handle_config);
- }
- #endif
- memcpy(&(data_config->dispif_config), lcm_param, sizeof(LCM_PARAMS));
- data_config->dst_w = lcm_param->width;
- data_config->dst_h = lcm_param->height;
- if (lcm_param->type == LCM_TYPE_DSI) {
- if (lcm_param->dsi.data_format.format == LCM_DSI_FORMAT_RGB888)
- data_config->lcm_bpp = 24;
- else if (lcm_param->dsi.data_format.format == LCM_DSI_FORMAT_RGB565)
- data_config->lcm_bpp = 16;
- else if (lcm_param->dsi.data_format.format == LCM_DSI_FORMAT_RGB666)
- data_config->lcm_bpp = 18;
- } else if (lcm_param->type == LCM_TYPE_DPI) {
- if (lcm_param->dpi.format == LCM_DPI_FORMAT_RGB888)
- data_config->lcm_bpp = 24;
- else if (lcm_param->dpi.format == LCM_DPI_FORMAT_RGB565)
- data_config->lcm_bpp = 16;
- if (lcm_param->dpi.format == LCM_DPI_FORMAT_RGB666)
- data_config->lcm_bpp = 18;
- }
- data_config->fps = lcm_fps;
- data_config->dst_dirty = 1;
- #ifdef CONFIG_FPGA_EARLY_PORTING
- data_config->ovl_dirty = 1;
- #endif
- rdma_set_target_line(DISP_MODULE_RDMA0, primary_display_get_height() * 1 / 2,
- pgc->cmdq_handle_config);
- rdma_set_target_line(DISP_MODULE_RDMA0, primary_display_get_height() * 1 / 2, NULL);
- if (primary_display_use_cmdq == CMDQ_ENABLE) {
- ret = dpmgr_path_config(pgc->dpmgr_handle, data_config, pgc->cmdq_handle_config);
- /* should we set dirty here???????? */
- _cmdq_flush_config_handle(0, NULL, 0);
- _cmdq_reset_config_handle();
- _cmdq_insert_wait_frame_done_token();
- } else {
- ret = dpmgr_path_config(pgc->dpmgr_handle, data_config, NULL);
- }
- {
- #ifdef MTK_NO_DISP_IN_LK
- ret = disp_lcm_init(pgc->plcm, 1);
- #else
- ret = disp_lcm_init(pgc->plcm, 0);
- #endif
- }
- #ifndef MTK_NO_DISP_IN_LK
- if (_is_decouple_mode(pgc->session_mode))
- #endif
- /* this should remove? for video mode when LK has start path */
- dpmgr_path_start(pgc->dpmgr_handle, CMDQ_DISABLE);
- #ifdef MTK_FB_PULLCLK_ENABLE
- primary_display_pullclk_task = kthread_create(primary_display_vdo_pullclk_worker_kthread,
- NULL, "display_vdo_pullclk");
- wake_up_process(primary_display_pullclk_task);
- #endif
- #ifdef MTK_FB_ESD_ENABLE
- primary_display_esd_check_task = kthread_create(primary_display_esd_check_worker_kthread,
- NULL, "display_esd_check");
- init_waitqueue_head(&esd_ext_te_wq);
- init_waitqueue_head(&esd_check_task_wq);
- if (_need_do_esd_check())
- wake_up_process(primary_display_esd_check_task);
- #if 0
- if (_need_do_esd_check())
- primary_display_esd_check_enable(1);
- #endif
- if (_need_register_eint()) {
- struct device_node *node = NULL;
- int irq;
- u32 ints[2] = { 0, 0 };
- #ifdef GPIO_DSI_TE_PIN
- #ifndef CONFIG_FPGA_EARLY_PORTING
- /* 1.set GPIO107 eint mode */
- mt_set_gpio_mode(GPIO_DSI_TE_PIN, GPIO_DSI_TE_PIN_M_GPIO);
- #endif
- eint_flag++;
- #endif
- #ifndef CONFIG_MTK_LEGACY
- eint_flag++;
- #endif
- /* 2.register eint */
- node = of_find_compatible_node(NULL, NULL, "mediatek, DSI_TE_1-eint");
- if (node) {
- of_property_read_u32_array(node, "debounce", ints, ARRAY_SIZE(ints));
- /* FIXME: find definatition of mt_gpio_set_debounce */
- /* mt_gpio_set_debounce(ints[0], ints[1]); */
- mt_eint_set_hw_debounce(ints[0], ints[1]);
- irq = irq_of_parse_and_map(node, 0);
- if (request_irq(irq, _esd_check_ext_te_irq_handler, IRQF_TRIGGER_RISING, "DSI_TE_1-eint", NULL))
- DISPCHECK("[ESD]EINT IRQ LINE NOT AVAILABLE!!\n");
- else
- eint_flag++;
- } else {
- DISPCHECK("[ESD][%s] can't find DSI_TE_1 eint compatible node\n", __func__);
- }
- }
- if (_need_do_esd_check())
- primary_display_esd_check_enable(1);
- #endif
- #ifdef DISP_SWITCH_DST_MODE
- primary_display_switch_dst_mode_task = kthread_create(_disp_primary_path_switch_dst_mode_thread, NULL,
- "display_switch_dst_mode");
- wake_up_process(primary_display_switch_dst_mode_task);
- #endif
- primary_path_aal_task = kthread_create(_disp_primary_path_check_trigger, NULL, "display_check_aal");
- wake_up_process(primary_path_aal_task);
- #if 0 /* Zaikuo: disable it when HWC not enable to reduce error log */
- fence_release_worker_task =
- kthread_create(_fence_release_worker_thread, NULL, "fence_worker");
- wake_up_process(fence_release_worker_task);
- if (_is_decouple_mode(pgc->session_mode)) {
- if_fence_release_worker_task =
- kthread_create(_if_fence_release_worker_thread, NULL, "if_fence_worker");
- wake_up_process(if_fence_release_worker_task);
- ovl2mem_fence_release_worker_task =
- kthread_create(_ovl2mem_fence_release_worker_thread, NULL,
- "ovl2mem_fence_worker");
- wake_up_process(ovl2mem_fence_release_worker_task);
- }
- #endif
- present_fence_release_worker_task = kthread_create(_present_fence_release_worker_thread, NULL,
- "present_fence_worker");
- wake_up_process(present_fence_release_worker_task);
- if (primary_display_frame_update_task == NULL) {
- init_waitqueue_head(&primary_display_frame_update_wq);
- disp_register_module_irq_callback(DISP_MODULE_RDMA0, primary_display_frame_update_irq_callback);
- disp_register_module_irq_callback(DISP_MODULE_OVL0, primary_display_frame_update_irq_callback);
- disp_register_module_irq_callback(DISP_MODULE_WDMA0, primary_display_frame_update_irq_callback);
- primary_display_frame_update_task = kthread_create(primary_display_frame_update_kthread, NULL,
- "frame_update_worker");
- wake_up_process(primary_display_frame_update_task);
- init_waitqueue_head(&decouple_fence_release_wq);
- decouple_fence_release_task = kthread_create(decouple_fence_release_kthread, NULL,
- "decouple_fence_release_worker");
- wake_up_process(decouple_fence_release_task);
- }
- /* primary_display_use_cmdq = CMDQ_ENABLE; */
- /* this will be set to always enable cmdq later */
- if (primary_display_is_video_mode()) {
- #ifdef DISP_SWITCH_DST_MODE
- primary_display_cur_dst_mode = 1; /* video mode */
- primary_display_def_dst_mode = 1; /* default mode is video mode */
- #endif
- dpmgr_map_event_to_irq(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC, DDP_IRQ_RDMA0_DONE);
- } else {
- }
- #ifndef MTKFB_NO_M4U
- {
- M4U_PORT_STRUCT sPort;
- sPort.ePortID = M4U_PORT_DISP_WDMA0;
- sPort.Virtuality = primary_display_use_m4u;
- sPort.Security = 0;
- sPort.Distance = 1;
- sPort.Direction = 0;
- ret = m4u_config_port(&sPort);
- if (ret != 0) {
- DISPCHECK("config M4U Port %s to %s FAIL(ret=%d)\n",
- ddp_get_module_name(DISP_MODULE_WDMA0),
- primary_display_use_m4u ? "virtual" : "physical", ret);
- return -1;
- }
- }
- #endif
- pgc->lcm_fps = lcm_fps;
- if (lcm_fps > 6000) /* FIXME: if fps bigger than 60, support 8 layer? */
- pgc->max_layer = OVL_LAYER_NUM;
- else
- pgc->max_layer = OVL_LAYER_NUM;
- pgc->state = DISP_ALIVE;
- #ifdef CONFIG_TRUSTONIC_TRUSTED_UI
- disp_switch_data.name = "disp";
- disp_switch_data.index = 0;
- disp_switch_data.state = DISP_ALIVE;
- ret = switch_dev_register(&disp_switch_data);
- #endif
- primary_display_sodi_rule_init();
- #ifdef MTK_DISP_IDLE_LP
- init_waitqueue_head(&idle_detect_wq);
- primary_display_idle_detect_task = kthread_create(_disp_primary_path_idle_detect_thread, NULL,
- "display_idle_detect");
- wake_up_process(primary_display_idle_detect_task);
- #endif
- pgc->dc_type = DISP_OUTPUT_DECOUPLE;
- if ((mmdvfs_get_mmdvfs_profile() == MMDVFS_PROFILE_D2_P_PLUS) ||
- (mmdvfs_get_mmdvfs_profile() == MMDVFS_PROFILE_D2_M_PLUS))
- register_mmclk_switch_cb(primary_display_switch_mmsys_clk, _switch_mmsys_clk);
- done:
- /* disable OVL TF in video mode, cause cmdq/sodi log is not ready, avoid too much TF issue */
- {
- /* extern unsigned int gDisableOVLTF; */
- if (gDisableOVLTF == 1 && primary_display_is_video_mode() == 1) {
- /* extern void disp_m4u_tf_disable(void); */
- disp_m4u_tf_disable();
- }
- }
- #ifndef WDMA_PATH_CLOCK_DYNAMIC_SWITCH
- #ifndef CONFIG_FPGA_EARLY_PORTING
- enable_soidle_by_bit(MT_CG_DISP0_DISP_WDMA0);
- #endif
- #endif
- _primary_path_unlock(__func__);
- /* DISPCHECK("primary_display_init end\n"); */
- return ret;
- }
- int primary_display_deinit(void)
- {
-
- _primary_path_lock(__func__);
- _cmdq_stop_trigger_loop();
- if(!pgc->dpmgr_handle){
- _primary_path_unlock(__func__);
- return 0;
- }else
- dpmgr_path_deinit(pgc->dpmgr_handle, CMDQ_DISABLE);
-
- #ifndef CONFIG_MTK_CLKMGR
- ddp_clk_unprepare(DISP_MTCMOS_CLK);
- #endif
- _primary_path_unlock(__func__);
- return 0;
- }
- /* register rdma done event */
- int primary_display_wait_for_idle(void)
- {
- DISP_STATUS ret = DISP_STATUS_OK;
- DISPFUNC();
- _primary_path_lock(__func__);
- /* Nothing to do ??? */
- _primary_path_unlock(__func__);
- return ret;
- }
- int primary_display_wait_for_dump(void)
- {
- return 0; /* avoid build warning. */
- }
- int primary_display_release_fence_fake(void)
- {
- unsigned int layer_en = 0;
- unsigned int addr = 0;
- unsigned int fence_idx = -1;
- unsigned int session_id = MAKE_DISP_SESSION(DISP_SESSION_PRIMARY, 0);
- int i = 0;
- DISPFUNC();
- for (i = 0; i < PRIMARY_DISPLAY_SESSION_LAYER_COUNT; i++) {
- if (i == primary_display_get_option("ASSERT_LAYER") && is_DAL_Enabled()) {
- mtkfb_release_layer_fence(session_id, 3);
- } else {
- disp_sync_get_cached_layer_info(session_id, i, &layer_en,
- (unsigned long *)&addr, &fence_idx);
- if (fence_idx < 0) {
- if (fence_idx == -1) {
- DISPPR_ERROR("find fence idx for layer %d,addr 0x%08x fail,\n", i, 0);
- DISPPR_ERROR("unregistered addr%d\n", fence_idx);
- } else if (fence_idx == -2) {
- ;
- } else {
- DISPPR_ERROR("find fence idx for layer %d,addr 0x%08x fail,reason unknown%d\n",
- i, 0, fence_idx);
- }
- } else {
- if (layer_en)
- mtkfb_release_fence(session_id, i, fence_idx - 1);
- else
- mtkfb_release_fence(session_id, i, fence_idx);
- }
- }
- }
- return 0; /* avoid build warning */
- }
- int primary_display_wait_for_vsync(void *config)
- {
- disp_session_vsync_config *c = (disp_session_vsync_config *) config;
- int ret = 0;
- /* kick idle manager here to ensure sodi is disabled when screen update begin(not 100% ensure) */
- primary_display_idlemgr_kick((char *)__func__);
- _primary_path_vsync_lock();
- if (pgc->state == DISP_SLEPT) {
- DISPCHECK("VSYNC DISP_SLEPT Return\n");
- _primary_path_vsync_unlock();
- return 0;
- }
- #ifdef MTK_DISP_IDLE_LP
- _disp_primary_path_dsi_clock_on(0);
- #endif
- if (!islcmconnected) {
- DISPCHECK("lcm not connect, use fake vsync\n");
- /* msleep(16); */
- usleep_range(16000, 17000);
- goto done;
- }
- ret = dpmgr_wait_event(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC);
- if (pgc->vsync_drop)
- ret = dpmgr_wait_event(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC);
- if (ret != 0)
- DISPCHECK("vsync signaled by unknown signal ret=%d\n", ret);
- c->vsync_ts = get_current_time_us();
- c->vsync_cnt++;
- done:
- #ifdef MTK_DISP_IDLE_LP
- _disp_primary_path_dsi_clock_off(0);
- #endif
- _primary_path_vsync_unlock();
- return 0;
- }
- unsigned int primary_display_get_ticket(void)
- {
- return dprec_get_vsync_count();
- }
- #ifdef CONFIG_SINGLE_PANEL_OUTPUT
- int primary_suspend_release_ovl_fence(disp_session_input_config *session_input)
- {
- unsigned int session = (unsigned int)((DISP_SESSION_PRIMARY)<<16 | (0));
- unsigned int i = 0;
- unsigned int layer = 0;
- for (i = 0; i < session_input->config_layer_num; i++) {
- unsigned int cur_fence;
- disp_input_config *input_cfg = &session_input->config[i];
- layer = input_cfg->layer_id;
- cur_fence = input_cfg->next_buff_idx;
- if (cur_fence != -1)
- mtkfb_release_fence(session, i, cur_fence);
- }
- return 0;
- }
- int primary_suspend_clr_ovl_config(void)
- {
- disp_ddp_path_config *data_config = NULL;
- disp_path_handle handle = NULL;
- OVL_CONFIG_STRUCT ovl_config[OVL_LAYER_NUM];
- int i = 0;
- DISPFUNC();
- if (0 == g_suspend_flag)
- return -1;
- if (_is_decouple_mode(pgc->session_mode) == 0)
- handle = pgc->dpmgr_handle;
- else
- handle = pgc->ovl2mem_path_handle;
- data_config = dpmgr_path_get_last_config(handle);
- memset((void *)&(data_config->ovl_config), 0, sizeof(ovl_config));
- last_primary_config = *data_config;
- for (i = 0; i < OVL_LAYER_NUM; i++)
- ovl_layer_switch(DISP_MODULE_OVL0, i, 0, NULL);
- DISP_REG_SET(NULL, DISP_REG_OVL_SRC_CON, 0x0);
- return 0;
- }
- #endif
- int primary_suspend_release_fence(void)
- {
- unsigned int session = (unsigned int)((DISP_SESSION_PRIMARY) << 16 | (0));
- unsigned int i = 0;
- for (i = 0; i < HW_OVERLAY_COUNT; i++) {
- DISPMSG("mtkfb_release_layer_fence session=0x%x,layerid=%d\n", session, i);
- mtkfb_release_layer_fence(session, i);
- }
- return 0;
- }
- static void primary_display_suspend_wait_tui(void)
- {
- while (primary_get_state() == DISP_BLANK) {
- _primary_path_vsync_unlock();
- _primary_path_unlock(__func__);
- _primary_path_esd_check_unlock();
- disp_sw_mutex_unlock(&(pgc->capture_lock));
- #ifdef CONFIG_TRUSTONIC_TRUSTED_UI
- switch_set_state(&disp_switch_data, DISP_SLEPT);
- #endif
- primary_display_wait_state(DISP_ALIVE, MAX_SCHEDULE_TIMEOUT);
- disp_sw_mutex_lock(&(pgc->capture_lock));
- _primary_path_esd_check_lock();
- _primary_path_lock(__func__);
- _primary_path_vsync_lock();
- DISPCHECK("primary_display_suspend wait tui done stat=%d\n", primary_get_state());
- }
- }
- int primary_display_suspend(void)
- {
- DISP_STATUS ret = DISP_STATUS_OK;
- DISPCHECK("primary_display_suspend begin\n");
- MMProfileLogEx(ddp_mmp_get_events()->primary_suspend, MMProfileFlagStart, 0, 0);
- #ifdef DISP_SWITCH_DST_MODE
- primary_display_switch_dst_mode(primary_display_def_dst_mode);
- #endif
- disp_sw_mutex_lock(&(pgc->capture_lock));
- _primary_path_esd_check_lock();
- _primary_path_lock(__func__);
- _primary_path_vsync_lock();
- DISPCHECK("wait tui finish[begin]\n");
- primary_display_suspend_wait_tui();
- DISPCHECK("wait tui finish[end]\n");
- if (pgc->state == DISP_SLEPT) {
- DISPCHECK("primary display path is already sleep, skip\n");
- goto done;
- }
- #ifdef MTK_DISP_IDLE_LP
- _disp_primary_path_exit_idle(__func__, 0);
- #endif
- MMProfileLogEx(ddp_mmp_get_events()->primary_suspend, MMProfileFlagPulse, 0, 1);
- /* msleep(16); */ /* wait last frame done */
- usleep_range(16000, 17000);
- if (dpmgr_path_is_busy(pgc->dpmgr_handle)) {
- int event_ret = 0;
- MMProfileLogEx(ddp_mmp_get_events()->primary_suspend, MMProfileFlagPulse, 1, 2);
- event_ret = dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE, HZ * 1);
- MMProfileLogEx(ddp_mmp_get_events()->primary_suspend, MMProfileFlagPulse, 2, 2);
- DISPCHECK("[POWER]primary display path is busy now, wait frame done, event_ret=%d\n", event_ret);
- if (event_ret <= 0) {
- DISPERR("wait frame done in suspend timeout\n");
- MMProfileLogEx(ddp_mmp_get_events()->primary_suspend, MMProfileFlagPulse, 3, 2);
- primary_display_diagnose();
- ret = -1;
- }
- }
- /* for decouple mode */
- if (_is_decouple_mode(pgc->session_mode)) {
- if (dpmgr_path_is_busy(pgc->ovl2mem_path_handle))
- dpmgr_wait_event_timeout(pgc->ovl2mem_path_handle, DISP_PATH_EVENT_FRAME_COMPLETE, HZ);
- /* xuecheng, BAD WROKAROUND for decouple mode */
- msleep(30);
- }
- MMProfileLogEx(ddp_mmp_get_events()->primary_suspend, MMProfileFlagPulse, 0, 2);
- DISPCHECK("[POWER]display cmdq trigger loop stop[begin]\n");
- _cmdq_stop_trigger_loop();
- DISPCHECK("[POWER]display cmdq trigger loop stop[end]\n");
- MMProfileLogEx(ddp_mmp_get_events()->primary_suspend, MMProfileFlagPulse, 0, 3);
- #ifdef CONFIG_LCM_SEND_CMD_IN_VIDEO
- DISPCHECK("[POWER]lcm suspend[begin]\n");
- disp_lcm_suspend(pgc->plcm);
- DISPCHECK("[POWER]lcm suspend[end]\n");
- #endif
- DISPCHECK("[POWER]primary display path stop[begin]\n");
- dpmgr_path_stop(pgc->dpmgr_handle, CMDQ_DISABLE);
- DISPCHECK("[POWER]primary display path stop[end]\n");
- MMProfileLogEx(ddp_mmp_get_events()->primary_suspend, MMProfileFlagPulse, 0, 4);
- #ifdef CONFIG_SINGLE_PANEL_OUTPUT
- primary_suspend_clr_ovl_config();
- #endif
- if (dpmgr_path_is_busy(pgc->dpmgr_handle)) {
- MMProfileLogEx(ddp_mmp_get_events()->primary_suspend, MMProfileFlagPulse, 1, 4);
- DISPERR("[POWER]stop display path failed, still busy\n");
- dpmgr_path_reset(pgc->dpmgr_handle, CMDQ_DISABLE);
- ret = -1;
- /* even path is busy(stop fail), we still need to continue power off other module/devices */
- /* goto done; */
- }
- MMProfileLogEx(ddp_mmp_get_events()->primary_suspend, MMProfileFlagPulse, 0, 5);
- /* remove OVL1 from display if there is more than one session, */
- /* because the other session may use OVL1 in suspend mode */
- #if 0
- {
- /* extern int disp_get_session_number(void); */
- if (ovl_get_status() != DDP_OVL1_STATUS_SUB && disp_get_session_number() > 1) {
- unsigned int dp_handle;
- unsigned int cmdq_handle;
- DISPMSG("disable cascade before suspend!\n");
- dpmgr_path_get_handle(&dp_handle, &cmdq_handle);
- dpmgr_path_disable_cascade(dp_handle, CMDQ_DISABLE);
- if (ovl_get_status() == DDP_OVL1_STATUS_SUB_REQUESTING) {
- ovl_set_status(DDP_OVL1_STATUS_SUB);
- wake_up_interruptible(&ovl1_wait_queue);
- } else {
- ovl_set_status(DDP_OVL1_STATUS_IDLE);
- }
- _cmdq_build_trigger_loop();
- }
- }
- #else
- DISPMSG("disable cascade before suspend!\n");
- if (_is_decouple_mode(pgc->session_mode) == 0)
- dpmgr_path_disable_cascade(pgc->dpmgr_handle, CMDQ_DISABLE);
- else
- dpmgr_path_disable_cascade(pgc->ovl2mem_path_handle, CMDQ_DISABLE);
- if (ovl_get_status() == DDP_OVL1_STATUS_SUB_REQUESTING)
- dpmgr_set_ovl1_status(DDP_OVL1_STATUS_SUB);
- else if (ovl_get_status() != DDP_OVL1_STATUS_SUB)
- dpmgr_set_ovl1_status(DDP_OVL1_STATUS_IDLE);
- #endif
- #ifndef CONFIG_LCM_SEND_CMD_IN_VIDEO
- DISPCHECK("[POWER]lcm suspend[begin]\n");
- disp_lcm_suspend(pgc->plcm);
- DISPCHECK("[POWER]lcm suspend[end]\n");
- #endif
- MMProfileLogEx(ddp_mmp_get_events()->primary_suspend, MMProfileFlagPulse, 0, 6);
- DISPCHECK("[POWER]primary display path Release Fence[begin]\n");
- primary_suspend_release_fence();
- DISPCHECK("[POWER]primary display path Release Fence[end]\n");
- MMProfileLogEx(ddp_mmp_get_events()->primary_suspend, MMProfileFlagPulse, 0, 7);
- DISPCHECK("[POWER]dpmanager path power off[begin]\n");
- dpmgr_path_power_off(pgc->dpmgr_handle, CMDQ_DISABLE);
- DISPCHECK("[POWER]dpmanager path power off[end]\n");
- if (_is_decouple_mode(pgc->session_mode)) {
- dpmgr_path_power_off(pgc->ovl2mem_path_handle, CMDQ_DISABLE);
- } else if (is_mmdvfs_supported() && mmdvfs_get_mmdvfs_profile() == MMDVFS_PROFILE_D1_PLUS) {
- DISPMSG("set MMDVFS low\n");
- mmdvfs_set_step(MMDVFS_SCEN_DISP, MMDVFS_VOLTAGE_LOW); /* Vote to LPM mode */
- }
- #ifndef CONFIG_MTK_CLKMGR
- ddp_clk_unprepare(DISP_MTCMOS_CLK);
- #endif
- MMProfileLogEx(ddp_mmp_get_events()->primary_suspend, MMProfileFlagPulse, 0, 8);
- display_path_idle_cnt = 0;
- pgc->state = DISP_SLEPT;
- done:
- _primary_path_vsync_unlock();
- _primary_path_unlock(__func__);
- _primary_path_esd_check_unlock();
- disp_sw_mutex_unlock(&(pgc->capture_lock));
- #ifndef DISP_NO_AEE
- aee_kernel_wdt_kick_Powkey_api("mtkfb_early_suspend", WDT_SETBY_Display);
- #endif
- primary_trigger_cnt = 0;
- MMProfileLogEx(ddp_mmp_get_events()->primary_suspend, MMProfileFlagEnd, 0, 0);
- DISPCHECK("primary_display_suspend end\n");
- return ret;
- }
- int primary_display_get_lcm_index(void)
- {
- int index = 0;
- DISPFUNC();
- if (pgc->plcm == NULL) {
- DISPERR("lcm handle is null\n");
- return 0;
- }
- index = pgc->plcm->index;
- DISPMSG("lcm index = %d\n", index);
- return index;
- }
- int primary_display_resume(void)
- {
- DISP_STATUS ret = DISP_STATUS_OK;
- DISPFUNC();
- MMProfileLogEx(ddp_mmp_get_events()->primary_resume, MMProfileFlagStart, 0, 0);
- _primary_path_lock(__func__);
- if (pgc->state == DISP_ALIVE) {
- DISPCHECK("primary display path is already resume, skip\n");
- goto done;
- }
- MMProfileLogEx(ddp_mmp_get_events()->primary_resume, MMProfileFlagPulse, 0, 1);
- #ifdef CONFIG_MTK_CLKMGR
- #ifdef CONFIG_SINGLE_PANEL_OUTPUT
- dpmgr_reset_module_handle(pgc->dpmgr_handle);
- #endif
- /* For CCF, we move the power on control to noirq_restore in mtkfb */
- DISPCHECK("dpmanager path power on[begin]\n");
- dpmgr_path_power_on(pgc->dpmgr_handle, CMDQ_DISABLE);
- DISPCHECK("dpmanager path power on[end]\n");
- if (_is_decouple_mode(pgc->session_mode) && !pgc->force_on_wdma_path)
- dpmgr_path_power_on(pgc->ovl2mem_path_handle, CMDQ_DISABLE);
- MMProfileLogEx(ddp_mmp_get_events()->primary_resume, MMProfileFlagPulse, 0, 2);
- #endif
- #ifndef CONFIG_MTK_CLKMGR
- ddp_clk_prepare(DISP_MTCMOS_CLK);
- #endif
- if (is_ipoh_bootup) {
- DISPCHECK("[primary display path] leave primary_display_resume -- IPOH\n");
- DISPCHECK("ESD check start[begin]\n");
- primary_display_esd_check_enable(1);
- DISPCHECK("ESD check start[end]\n");
- is_ipoh_bootup = false;
- DISPCHECK("[POWER]start cmdq[begin]--IPOH\n");
- _cmdq_start_trigger_loop();
- DISPCHECK("[POWER]start cmdq[end]--IPOH\n");
- pgc->state = DISP_ALIVE;
- goto done;
- }
- #ifndef CONFIG_MTK_CLKMGR
- DISPCHECK("dpmanager path power on[begin]\n");
- dpmgr_path_power_on(pgc->dpmgr_handle, CMDQ_DISABLE);
- DISPCHECK("dpmanager path power on[end]\n");
- if (_is_decouple_mode(pgc->session_mode) && !pgc->force_on_wdma_path)
- dpmgr_path_power_on(pgc->ovl2mem_path_handle, CMDQ_DISABLE);
- MMProfileLogEx(ddp_mmp_get_events()->primary_resume, MMProfileFlagPulse, 0, 2);
- #endif
- if (primary_display_is_video_mode()) {
- DISPCHECK("mutex0 clear[begin]\n");
- ddp_mutex_clear(0, NULL);
- DISPCHECK("mutex0 clear[end]\n");
- }
- DISPCHECK("[POWER]dpmanager re-init[begin]\n");
- {
- LCM_PARAMS *lcm_param = NULL;
- disp_ddp_path_config *data_config = NULL;
- dpmgr_path_connect(pgc->dpmgr_handle, CMDQ_DISABLE);
- if (_is_decouple_mode(pgc->session_mode))
- dpmgr_path_connect(pgc->ovl2mem_path_handle, CMDQ_DISABLE);
- MMProfileLogEx(ddp_mmp_get_events()->primary_resume, MMProfileFlagPulse, 1, 2);
- lcm_param = disp_lcm_get_params(pgc->plcm);
- data_config = dpmgr_path_get_last_config(pgc->dpmgr_handle);
- data_config->dst_w = lcm_param->width;
- data_config->dst_h = lcm_param->height;
- if (lcm_param->type == LCM_TYPE_DSI) {
- if (lcm_param->dsi.data_format.format == LCM_DSI_FORMAT_RGB888)
- data_config->lcm_bpp = 24;
- else if (lcm_param->dsi.data_format.format == LCM_DSI_FORMAT_RGB565)
- data_config->lcm_bpp = 16;
- else if (lcm_param->dsi.data_format.format == LCM_DSI_FORMAT_RGB666)
- data_config->lcm_bpp = 18;
- } else if (lcm_param->type == LCM_TYPE_DPI) {
- if (lcm_param->dpi.format == LCM_DPI_FORMAT_RGB888)
- data_config->lcm_bpp = 24;
- else if (lcm_param->dpi.format == LCM_DPI_FORMAT_RGB565)
- data_config->lcm_bpp = 16;
- if (lcm_param->dpi.format == LCM_DPI_FORMAT_RGB666)
- data_config->lcm_bpp = 18;
- }
- data_config->fps = pgc->lcm_fps;
- data_config->dst_dirty = 1;
- ret = dpmgr_path_config(pgc->dpmgr_handle, data_config, NULL);
- MMProfileLogEx(ddp_mmp_get_events()->primary_resume, MMProfileFlagPulse, 2, 2);
- if (_is_decouple_mode(pgc->session_mode)) {
- data_config = dpmgr_path_get_last_config(pgc->ovl2mem_path_handle);
- data_config->fps = pgc->lcm_fps;
- data_config->dst_dirty = 1;
- data_config->wdma_dirty = 1;
- ret = dpmgr_path_config(pgc->ovl2mem_path_handle, data_config, NULL);
- MMProfileLogEx(ddp_mmp_get_events()->primary_resume, MMProfileFlagPulse, 2,
- 2);
- }
- data_config->dst_dirty = 0;
- }
- DISPCHECK("[POWER]dpmanager re-init[end]\n");
- MMProfileLogEx(ddp_mmp_get_events()->primary_resume, MMProfileFlagPulse, 0, 3);
- DISPCHECK("[POWER]lcm resume[begin]\n");
- disp_lcm_resume(pgc->plcm);
- DISPCHECK("[POWER]lcm resume[end]\n");
- MMProfileLogEx(ddp_mmp_get_events()->primary_resume, MMProfileFlagPulse, 0, 4);
- if (dpmgr_path_is_busy(pgc->dpmgr_handle)) {
- MMProfileLogEx(ddp_mmp_get_events()->primary_resume, MMProfileFlagPulse, 1, 4);
- DISPERR("[POWER]Fatal error, we didn't start display path but it's already busy\n");
- ret = -1;
- /* goto done; */
- }
- MMProfileLogEx(ddp_mmp_get_events()->primary_resume, MMProfileFlagPulse, 0, 5);
- DISPCHECK("[POWER]dpmgr path start[begin]\n");
- dpmgr_path_start(pgc->dpmgr_handle, CMDQ_DISABLE);
- if (_is_decouple_mode(pgc->session_mode))
- dpmgr_path_start(pgc->ovl2mem_path_handle, CMDQ_DISABLE);
- DISPCHECK("[POWER]dpmgr path start[end]\n");
- MMProfileLogEx(ddp_mmp_get_events()->primary_resume, MMProfileFlagPulse, 0, 6);
- if (dpmgr_path_is_busy(pgc->dpmgr_handle)) {
- MMProfileLogEx(ddp_mmp_get_events()->primary_resume, MMProfileFlagPulse, 1, 6);
- DISPERR
- ("[POWER]Fatal error, we didn't trigger display path but it's already busy\n");
- ret = -1;
- /* goto done; */
- }
- MMProfileLogEx(ddp_mmp_get_events()->primary_resume, MMProfileFlagPulse, 0, 7);
- if (primary_display_is_video_mode()) {
- MMProfileLogEx(ddp_mmp_get_events()->primary_resume, MMProfileFlagPulse, 1, 7);
- /* for video mode, we need to force trigger here */
- /* for cmd mode, just set DPREC_EVENT_CMDQ_SET_EVENT_ALLOW when trigger loop start */
- dpmgr_path_trigger(pgc->dpmgr_handle, NULL, CMDQ_DISABLE);
- /* insert a wait token to make sure first config after resume will config to HW when HW idle */
- _cmdq_insert_wait_frame_done_token();
- }
- MMProfileLogEx(ddp_mmp_get_events()->primary_resume, MMProfileFlagPulse, 0, 8);
- DISPCHECK("[POWER]start cmdq[begin]\n");
- _cmdq_start_trigger_loop();
- DISPCHECK("[POWER]start cmdq[end]\n");
- MMProfileLogEx(ddp_mmp_get_events()->primary_resume, MMProfileFlagPulse, 0, 9);
- if (!primary_display_is_video_mode()) {
- /*refresh black picture of ovl bg */
- DISPCHECK("[POWER]triggger cmdq[begin]\n");
- _trigger_display_interface(0, NULL, 0);
- DISPCHECK("[POWER]triggger cmdq[end]\n");
- }
- DISPCHECK("[POWER]wait frame done[begin]\n");
- dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE, HZ / 10);
- DISPCHECK("[POWER]wait frame done[end]\n");
- /* reinit fake timer for debug, we can enable option then press powerkey to enable thsi feature. */
- /* use fake timer to generate vsync signal for cmd mode w/o LCM(originally using LCM TE Signal as VSYNC) */
- /* so we don't need to modify display driver's behavior. */
- if (disp_helper_get_option
- (DISP_HELPER_OPTION_NO_LCM_FOR_LOW_POWER_MEASUREMENT)) {
- /* only for low power measurement */
- DISPCHECK("WARNING!!!!!! FORCE NO LCM MODE!!!\n");
- islcmconnected = 0;
- /* no need to change video mode vsync behavior */
- if (!primary_display_is_video_mode()) {
- _init_vsync_fake_monitor(pgc->lcm_fps);
- dpmgr_map_event_to_irq(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC,
- DDP_IRQ_UNKNOWN);
- }
- }
- if (is_mmdvfs_supported() && mmdvfs_get_mmdvfs_profile() == MMDVFS_PROFILE_D1_PLUS &&
- primary_display_get_width() > 800) {
- DISPMSG("set MMDVFS high\n");
- mmdvfs_set_step(MMDVFS_SCEN_DISP, MMDVFS_VOLTAGE_HIGH); /* Enter HPM mode */
- }
- #if 0
- DISPCHECK("[POWER]wakeup aal/od trigger process[begin]\n");
- wake_up_process(primary_path_aal_task);
- DISPCHECK("[POWER]wakeup aal/od trigger process[end]\n");
- #endif
- pgc->state = DISP_ALIVE;
- pgc->force_on_wdma_path = 0;
- #ifdef CONFIG_TRUSTONIC_TRUSTED_UI
- switch_set_state(&disp_switch_data, DISP_ALIVE);
- #endif
- done:
- _primary_path_unlock(__func__);
- /* primary_display_diagnose(); */
- #ifndef DISP_NO_AEE
- aee_kernel_wdt_kick_Powkey_api("mtkfb_late_resume", WDT_SETBY_Display);
- #endif
- MMProfileLogEx(ddp_mmp_get_events()->primary_resume, MMProfileFlagEnd, 0, 0);
- ddp_dump_analysis(DISP_MODULE_OVL0);
- #if defined(OVL_CASCADE_SUPPORT)
- ddp_dump_analysis(DISP_MODULE_OVL1);
- #endif
- ddp_dump_analysis(DISP_MODULE_RDMA0);
- return 0;
- }
- int primary_display_resume_ovl2mem(void)
- {
- DISP_STATUS ret = DISP_STATUS_OK;
- DISPFUNC();
- #ifdef CONFIG_MTK_CLKMGR
- if (_is_decouple_mode(pgc->session_mode))
- dpmgr_path_power_on(pgc->ovl2mem_path_handle, CMDQ_DISABLE);
- #endif
- #ifndef CONFIG_MTK_CLKMGR
- ddp_clk_prepare(DISP_MTCMOS_CLK);
- #endif
- #ifndef CONFIG_MTK_CLKMGR
- if (_is_decouple_mode(pgc->session_mode))
- dpmgr_path_power_on(pgc->ovl2mem_path_handle, CMDQ_DISABLE);
- #endif
- DISPCHECK("[POWER]dpmanager re-init[begin]\n");
- {
- LCM_PARAMS *lcm_param = NULL;
- disp_ddp_path_config *data_config = NULL;
- if (_is_decouple_mode(pgc->session_mode))
- dpmgr_path_connect(pgc->ovl2mem_path_handle, CMDQ_DISABLE);
- lcm_param = disp_lcm_get_params(pgc->plcm);
- data_config = dpmgr_path_get_last_config(pgc->dpmgr_handle);
- data_config->dst_w = lcm_param->width;
- data_config->dst_h = lcm_param->height;
- if (lcm_param->type == LCM_TYPE_DSI) {
- if (lcm_param->dsi.data_format.format == LCM_DSI_FORMAT_RGB888)
- data_config->lcm_bpp = 24;
- else if (lcm_param->dsi.data_format.format == LCM_DSI_FORMAT_RGB565)
- data_config->lcm_bpp = 16;
- else if (lcm_param->dsi.data_format.format == LCM_DSI_FORMAT_RGB666)
- data_config->lcm_bpp = 18;
- } else if (lcm_param->type == LCM_TYPE_DPI) {
- if (lcm_param->dpi.format == LCM_DPI_FORMAT_RGB888)
- data_config->lcm_bpp = 24;
- else if (lcm_param->dpi.format == LCM_DPI_FORMAT_RGB565)
- data_config->lcm_bpp = 16;
- if (lcm_param->dpi.format == LCM_DPI_FORMAT_RGB666)
- data_config->lcm_bpp = 18;
- }
- data_config->fps = pgc->lcm_fps;
- data_config->dst_dirty = 1;
- if (_is_decouple_mode(pgc->session_mode)) {
- data_config = dpmgr_path_get_last_config(pgc->ovl2mem_path_handle);
- data_config->fps = pgc->lcm_fps;
- data_config->dst_dirty = 1;
- data_config->wdma_dirty = 1;
- ret = dpmgr_path_config(pgc->ovl2mem_path_handle, data_config, NULL);
- }
- }
- DISPCHECK("[POWER]ovl2mem path start[begin]\n");
- if (_is_decouple_mode(pgc->session_mode))
- dpmgr_path_start(pgc->ovl2mem_path_handle, CMDQ_DISABLE);
- DISPCHECK("[POWER]ovl2mem path start[end]\n");
- DISPCHECK("[POWER]start cmdq[begin]\n");
- _cmdq_start_trigger_loop();
- DISPCHECK("[POWER]start cmdq[end]\n");
- if (is_mmdvfs_supported() && mmdvfs_get_mmdvfs_profile() == MMDVFS_PROFILE_D1_PLUS &&
- primary_display_get_width() > 800) {
- DISPMSG("set MMDVFS high\n");
- mmdvfs_set_step(MMDVFS_SCEN_DISP, MMDVFS_VOLTAGE_HIGH); /* Enter HPM mode */
- }
- /* primary_display_diagnose(); */
- #ifndef DISP_NO_AEE
- aee_kernel_wdt_kick_Powkey_api("mtkfb_late_resume", WDT_SETBY_Display);
- #endif
- MMProfileLogEx(ddp_mmp_get_events()->primary_resume, MMProfileFlagEnd, 0, 0);
- ddp_dump_analysis(DISP_MODULE_OVL0);
- pgc->force_on_wdma_path = 1;
- return 0;
- }
- int primary_display_ipoh_restore(void)
- {
- DISPMSG("primary_display_ipoh_restore In\n");
- DISPCHECK("ESD check stop[begin]\n");
- primary_display_esd_check_enable(0);
- DISPCHECK("ESD check stop[end]\n");
- if (NULL != pgc->cmdq_handle_trigger) {
- struct TaskStruct *pTask = pgc->cmdq_handle_trigger->pRunningTask;
- if (NULL != pTask) {
- DISPCHECK("[Primary_display]display cmdq trigger loop stop[begin]\n");
- _cmdq_stop_trigger_loop();
- DISPCHECK("[Primary_display]display cmdq trigger loop stop[end]\n");
- }
- }
- DISPMSG("primary_display_ipoh_restore Out\n");
- return 0;
- }
- int primary_display_ipoh_recover(void)
- {
- DISPMSG("%s In\n", __func__);
- _cmdq_start_trigger_loop();
- DISPMSG("%s Out\n", __func__);
- return 0;
- }
- int primary_display_start(void)
- {
- DISP_STATUS ret = DISP_STATUS_OK;
- DISPFUNC();
- _primary_path_lock(__func__);
- dpmgr_path_start(pgc->dpmgr_handle, CMDQ_DISABLE);
- if (dpmgr_path_is_busy(pgc->dpmgr_handle)) {
- DISPCHECK("Fatal error, we didn't trigger display path but it's already busy\n");
- ret = -1;
- goto done;
- }
- done:
- _primary_path_unlock(__func__);
- return ret;
- }
- int primary_display_stop(void)
- {
- DISP_STATUS ret = DISP_STATUS_OK;
- DISPFUNC();
- _primary_path_lock(__func__);
- if (dpmgr_path_is_busy(pgc->dpmgr_handle))
- dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE, HZ * 1);
- dpmgr_path_stop(pgc->dpmgr_handle, CMDQ_DISABLE);
- if (dpmgr_path_is_busy(pgc->dpmgr_handle)) {
- DISPCHECK("stop display path failed, still busy\n");
- ret = -1;
- goto done;
- }
- done:
- _primary_path_unlock(__func__);
- return ret;
- }
- static int primary_display_remove_output(void *callback, unsigned int userdata)
- {
- int ret = 0;
- static cmdqRecHandle cmdq_handle;
- static cmdqRecHandle cmdq_wait_handle;
- /*create config thread */
- if (cmdq_handle == NULL)
- ret = cmdqRecCreate(CMDQ_SCENARIO_PRIMARY_DISP, &cmdq_handle);
- if (ret == 0) {
- /* capture thread wait wdma sof */
- ret = cmdqRecCreate(CMDQ_SCENARIO_DISP_MIRROR_MODE, &cmdq_wait_handle);
- if (ret == 0) {
- cmdqRecReset(cmdq_wait_handle);
- cmdqRecWait(cmdq_wait_handle, CMDQ_EVENT_DISP_WDMA0_SOF);
- cmdqRecFlush(cmdq_wait_handle);
- /* cmdqRecDestroy(cmdq_wait_handle); */
- } else {
- DISPERR("fail to create wait handle\n");
- }
- cmdqRecReset(cmdq_handle);
- _cmdq_insert_wait_frame_done_token_mira(cmdq_handle);
- /* update output fence */
- cmdqRecBackupUpdateSlot(cmdq_handle, pgc->cur_config_fence,
- disp_sync_get_output_timeline_id(), mem_config.buff_idx);
- dpmgr_path_remove_memout(pgc->dpmgr_handle, cmdq_handle);
- cmdqRecClearEventToken(cmdq_handle, CMDQ_EVENT_DISP_WDMA0_SOF);
- _cmdq_set_config_handle_dirty_mira(cmdq_handle);
- cmdqRecFlushAsyncCallback(cmdq_handle, callback, 0);
- pgc->need_trigger_ovl1to2 = 0;
- /* cmdqRecDestroy(cmdq_handle); */
- } else {
- ret = -1;
- DISPERR("fail to remove memout out\n");
- }
- return ret;
- }
- static bool is_multipass_trigger;
- static int primary_display_config_input_multiple_nolock(disp_session_input_config *session_input);
- static int primary_display_config_output_nolock(disp_mem_output_config *output, unsigned int session_id);
- static int primary_display_merge_session_cmd(disp_session_config *config)
- {
- disp_session_input_config *session_input;
- disp_mem_output_config *primary_output;
- unsigned int output_type = config->dc_type;
- if (DISP_OUTPUT_UNKNOWN == output_type)
- output_type = DISP_OUTPUT_DECOUPLE;
- pgc->dc_type = output_type;
- #ifdef CONFIG_ALL_IN_TRIGGER_STAGE
- mutex_lock(&session_config_mutex);
- session_input = &cached_session_input[config->type - 1];
- cached_session_input[config->type - 1] = captured_session_input[config->type - 1];
- cached_session_input[config->type - 1].session_id = config->session_id;
- if (output_type == DISP_OUTPUT_MEMORY || is_multipass_trigger)
- cached_session_output[config->type - 1] = captured_session_output[config->type - 1];
- mutex_unlock(&session_config_mutex);
- session_input->config_layer_num = OVL_LAYER_NUM;
- if (isAEEEnabled) {
- int aee_layer = primary_display_get_option("ASSERT_LAYER");
- /*
- For multipass mode, the AEE layer can only be enabled at final pass when AEE enabled.
- Otherwise the AEE layer would be composed several time.
- */
- session_input->setter = SESSION_USER_AEE;
- if (config->type == DISP_SESSION_PRIMARY) {
- if (output_type == DISP_OUTPUT_MEMORY) {
- session_input->config[aee_layer].layer_enable = 0;
- DISPMSG("set the aee layer:%d en to 0\n",
- session_input->config[aee_layer].layer_id);
- } else {
- session_input->config[aee_layer].layer_enable = 1;
- }
- }
- }
- primary_display_config_input_multiple_nolock(session_input);
- if (output_type == DISP_OUTPUT_MEMORY || pgc->session_mode == DISP_SESSION_DECOUPLE_MIRROR_MODE ||
- config->type == DISP_SESSION_MEMORY) {
- mutex_lock(&session_config_mutex);
- cached_session_output[config->type - 1] = captured_session_output[config->type - 1];
- mutex_unlock(&session_config_mutex);
- primary_output = &cached_session_output[config->type - 1];
- primary_display_config_output_nolock(primary_output, config->session_id);
- }
- #endif
- return 0;
- }
- void primary_display_update_present_fence(unsigned int fence_idx)
- {
- gPresentFenceIndex = fence_idx;
- #ifdef CONFIG_SINGLE_PANEL_OUTPUT
- if (pgc->state == DISP_SLEPT)
- primary_suspend_release_present_fence();
- #endif
- }
- static int config_wdma_output(disp_path_handle disp_handle, cmdqRecHandle cmdq_handle,
- disp_mem_output_config *output, int is_multipass);
- static int _primary_display_trigger(int blocking, void *callback, unsigned int userdata, int lock)
- {
- int ret = 0;
- last_primary_trigger_time = sched_clock();
- #ifdef DISP_SWITCH_DST_MODE
- if (is_switched_dst_mode) {
- primary_display_switch_dst_mode(1); /* swith to vdo mode if trigger disp */
- is_switched_dst_mode = false;
- }
- #endif
- if (gTriggerDispMode > 0) {
- primary_display_release_fence_fake();
- return ret;
- }
- primary_trigger_cnt++;
- if (lock)
- _primary_path_lock(__func__);
- if (pgc->state == DISP_SLEPT) {
- DISPMSG("%s, skip because primary dipslay is sleep\n", __func__);
- goto done;
- }
- if (blocking)
- DISPMSG("%s, change blocking to non blocking trigger\n", __func__);
- _primary_path_set_dvfsHPM(true, 0);
- #ifdef MTK_DISP_IDLE_LP
- _disp_primary_path_exit_idle(__func__, 0);
- #endif
- dprec_logger_start(DPREC_LOGGER_PRIMARY_TRIGGER, pgc->session_mode, pgc->dc_type);
- if (pgc->session_mode == DISP_SESSION_DIRECT_LINK_MODE) {
- _trigger_display_interface(blocking, _ovl_fence_release_callback,
- DISP_SESSION_DIRECT_LINK_MODE);
- } else if (pgc->session_mode == DISP_SESSION_DIRECT_LINK_MIRROR_MODE) {
- _trigger_display_interface(0, _ovl_fence_release_callback,
- DISP_SESSION_DIRECT_LINK_MIRROR_MODE);
- if (pgc->need_trigger_ovl1to2 == 0) {
- DISPPR_ERROR("There is no output config when directlink mirror!!\n");
- } else {
- primary_display_remove_output(_wdma_fence_release_callback,
- DISP_SESSION_DIRECT_LINK_MIRROR_MODE);
- pgc->need_trigger_ovl1to2 = 0;
- }
- } else if (pgc->session_mode == DISP_SESSION_DECOUPLE_MIRROR_MODE) {
- if (pgc->need_trigger_dcMirror_out == 0) {
- if (cached_session_output[DISP_SESSION_PRIMARY - 1].security == DISP_SECURE_BUFFER)
- config_wdma_output(pgc->ovl2mem_path_handle, pgc->cmdq_handle_ovl1to2_config,
- &cached_session_output[DISP_SESSION_PRIMARY - 1], 0);
- DISPPR_ERROR("There is no output config when decouple mirror!!\n");
- } else {
- #ifdef CONFIG_ALL_IN_TRIGGER_STAGE
- is_output_buffer_set = 0;
- #endif
- pgc->need_trigger_dcMirror_out = 0;
- _trigger_ovl_to_memory_mirror(pgc->ovl2mem_path_handle,
- pgc->cmdq_handle_ovl1to2_config,
- (fence_release_callback)
- _olv_wdma_fence_release_callback,
- DISP_SESSION_DECOUPLE_MIRROR_MODE);
- }
- } else if (pgc->session_mode == DISP_SESSION_DECOUPLE_MODE) {
- if (pgc->dc_type == DISP_OUTPUT_DECOUPLE) {
- uint32_t writing_mva = 0;
- if (primary_display_is_secure_path(DISP_SESSION_PRIMARY)) {
- pgc->session_buf_id++;
- pgc->session_buf_id %= DISP_INTERNAL_BUFFER_COUNT;
- writing_mva = pgc->session_buf[pgc->session_buf_id];
- mem_config.security = DISP_SECURE_BUFFER;
- decouple_wdma_config.security = DISP_SECURE_BUFFER;
- } else {
- pgc->dc_buf_id++;
- pgc->dc_buf_id %= DISP_INTERNAL_BUFFER_COUNT;
- writing_mva = pgc->dc_buf[pgc->dc_buf_id];
- mem_config.security = DISP_NORMAL_BUFFER;
- decouple_wdma_config.security = DISP_NORMAL_BUFFER;
- }
- decouple_wdma_config.dstAddress = writing_mva;
- mem_config.addr = writing_mva;
- mem_config.fmt = decouple_wdma_config.outputFormat;
- mem_config.pitch = decouple_wdma_config.dstPitch;
- _config_wdma_output(&decouple_wdma_config, pgc->ovl2mem_path_handle,
- pgc->cmdq_handle_ovl1to2_config);
- MMProfileLogEx(ddp_mmp_get_events()->primary_wdma_config,
- MMProfileFlagPulse, pgc->dc_buf_id, writing_mva);
- DISPMSG("%s, config wdma address 0x%lx\n", __func__,
- decouple_wdma_config.dstAddress);
- /*
- * At the last round of multipass, the session mode would be configured as DECOUPLE MODE.
- * Need to set data as DISP_SESSION_DECOUPLE_MULTIPASS_MODE to _ovl_fence_release_callback.
- * Then the multipass output buffer fence would be release in _ovl_fence_release_callback.
- */
- if (is_multipass_trigger) {
- _trigger_ovl_to_memory(pgc->ovl2mem_path_handle, pgc->cmdq_handle_ovl1to2_config,
- (fence_release_callback)_ovl_fence_release_callback, 5, 0);
- is_multipass_trigger = 0;
- } else {
- if (primary_display_is_secure_path(DISP_SESSION_PRIMARY)) {
- _trigger_ovl_to_memory(pgc->ovl2mem_path_handle,
- pgc->cmdq_handle_ovl1to2_config,
- (fence_release_callback)_ovl_fence_release_callback,
- DISP_SESSION_DECOUPLE_MODE, 1);
- _ovl_fence_release_callback(DISP_SESSION_DECOUPLE_MODE);
- } else {
- _trigger_ovl_to_memory(pgc->ovl2mem_path_handle,
- pgc->cmdq_handle_ovl1to2_config,
- (fence_release_callback)_ovl_fence_release_callback,
- DISP_SESSION_DECOUPLE_MODE, 0);
- }
- }
- } else if (pgc->dc_type == DISP_OUTPUT_MEMORY) {
- is_multipass_trigger = 1;
- _trigger_ovl_to_memory(pgc->ovl2mem_path_handle, pgc->cmdq_handle_ovl1to2_config, NULL, 0, 0);
- }
- }
- dprec_logger_done(DPREC_LOGGER_PRIMARY_TRIGGER, 0, 0);
- done:
- if (lock)
- _primary_path_unlock(__func__);
- /* FIXME: find aee_kernel_Powerkey_is_press definitation */
- #ifndef DISP_NO_AEE
- if ((primary_trigger_cnt > PRIMARY_DISPLAY_TRIGGER_CNT) && aee_kernel_Powerkey_is_press()) {
- aee_kernel_wdt_kick_Powkey_api("primary_display_trigger", WDT_SETBY_Display);
- primary_trigger_cnt = 0;
- }
- #endif
- if (pgc->session_id > 0)
- update_frm_seq_info(0, 0, 0, FRM_TRIGGER);
- return ret;
- }
- int primary_display_trigger(int blocking, void *callback, unsigned int userdata)
- {
- return _primary_display_trigger(blocking, callback, userdata, 1);
- }
- int primary_display_trigger_nolock(int blocking, void *callback, unsigned int userdata)
- {
- return _primary_display_trigger(blocking, callback, userdata, 0);
- }
- int primary_display_memory_trigger_nolock(int blocking, void *callback, unsigned int userdata)
- {
- int ret = 0;
- if (pgc->state == DISP_SLEPT) {
- DISPMSG("%s, primary dipslay is sleep\n", __func__);
- if (pgc->force_on_wdma_path == 0)
- primary_display_resume_ovl2mem();
- }
- if (pgc->session_mode == DISP_SESSION_DECOUPLE_MODE || pgc->session_mode == DISP_SESSION_DECOUPLE_MIRROR_MODE) {
- if (primary_display_is_secure_path(DISP_SESSION_MEMORY)) {
- _trigger_ovl_to_memory(pgc->ovl2mem_path_handle, pgc->cmdq_handle_ovl1to2_config,
- (fence_release_callback)_ovl_ext_fence_release_callback,
- DISP_SESSION_MEMORY, 1);
- _ovl_ext_fence_release_callback(DISP_SESSION_MEMORY);
- } else {
- _trigger_ovl_to_memory(pgc->ovl2mem_path_handle, pgc->cmdq_handle_ovl1to2_config,
- (fence_release_callback)_ovl_ext_fence_release_callback,
- DISP_SESSION_MEMORY, 0);
- }
- } else {
- DISPMSG("Not support memory trigger using session_mode:%d\n", pgc->session_mode);
- }
- return ret;
- }
- void primary_display_trigger_and_merge(disp_session_config *config, int session_id)
- {
- _primary_path_lock(__func__);
- primary_display_merge_session_cmd(config);
- if (DISP_SESSION_TYPE(session_id) == DISP_SESSION_PRIMARY)
- primary_display_trigger_nolock(0, NULL, 0);
- else if (DISP_SESSION_TYPE(session_id) == DISP_SESSION_MEMORY)
- primary_display_memory_trigger_nolock(0, NULL, 0);
- else
- DISPERR("Invalid session trigger\n");
- _primary_path_unlock(__func__);
- }
- static int primary_display_ovl2mem_callback(unsigned int userdata)
- {
- disp_ddp_path_config *data_config = NULL;
- unsigned int session_id = 0;
- int fence_idx = userdata;
- WDMA0_FRAME_START_FLAG = 0;
- session_id = MAKE_DISP_SESSION(DISP_SESSION_PRIMARY, 0);
- data_config = dpmgr_path_get_last_config(pgc->dpmgr_handle);
- if (data_config) {
- WDMA_CONFIG_STRUCT wdma_layer;
- wdma_layer.dstAddress = mtkfb_query_buf_mva(session_id, 4, fence_idx);
- wdma_layer.outputFormat = data_config->wdma_config.outputFormat;
- wdma_layer.srcWidth = primary_display_get_width();
- wdma_layer.srcHeight = primary_display_get_height();
- wdma_layer.dstPitch = data_config->wdma_config.dstPitch;
- dprec_mmp_dump_wdma_layer(&wdma_layer, 0);
- }
- if (fence_idx > 0)
- mtkfb_release_fence(session_id, EXTERNAL_DISPLAY_SESSION_LAYER_COUNT, fence_idx);
- #ifdef OVL_CASCADE_SUPPORT
- if (fence_idx < NEW_BUF_IDX && ALL_LAYER_DISABLE_STEP == 1) {
- DISPMSG("primary and memout does not match!!\n");
- cmdqCoreSetEvent(CMDQ_EVENT_DISP_WDMA0_SOF);
- if (_should_set_cmdq_dirty())
- _cmdq_set_config_handle_dirty_mira(pgc->cmdq_handle_ovl1to2_config);
- if ((fence_idx + 1) == NEW_BUF_IDX)
- ALL_LAYER_DISABLE_STEP = 0;
- }
- #endif
- DISPMSG("mem_out release fence idx:0x%x\n", fence_idx);
- return 0;
- }
- /* extern unsigned int gDumpMemoutCmdq; */
- int primary_display_mem_out_trigger(int blocking, void *callback, unsigned int userdata)
- {
- int ret = 0;
- /* DISPFUNC(); */
- if (pgc->state == DISP_SLEPT || !_is_mirror_mode(pgc->session_mode)) {
- DISPMSG("mem out trigger is already slept or is not mirror mode(%d)\n",
- pgc->session_mode);
- return 0;
- }
- /* /dprec_logger_start(DPREC_LOGGER_PRIMARY_TRIGGER, 0, 0); */
- /* if(blocking) */
- _primary_path_lock(__func__);
- if (pgc->need_trigger_ovl1to2 == 0)
- goto done;
- NEW_BUF_IDX = userdata;
- ALL_LAYER_DISABLE_STEP = 0;
- if (_should_wait_path_idle())
- dpmgr_wait_event_timeout(pgc->ovl2mem_path_handle, DISP_PATH_EVENT_FRAME_DONE,
- HZ * 1);
- if (_should_trigger_path())
- ;/* /dpmgr_path_trigger(pgc->dpmgr_handle, NULL, primary_display_cmdq_enabled()); */
- if (_should_set_cmdq_dirty())
- _cmdq_set_config_handle_dirty_mira(pgc->cmdq_handle_ovl1to2_config);
- if (gDumpMemoutCmdq == 1) {
- DISPMSG("primary_display_mem_out_trigger, dump before flush 1:\n");
- cmdqRecDumpCommand(pgc->cmdq_handle_ovl1to2_config);
- }
- if (_should_flush_cmdq_config_handle())
- _cmdq_flush_config_handle_mira(pgc->cmdq_handle_ovl1to2_config, 0);
- if (_should_reset_cmdq_config_handle())
- cmdqRecReset(pgc->cmdq_handle_ovl1to2_config);
- cmdqRecWait(pgc->cmdq_handle_ovl1to2_config, CMDQ_EVENT_DISP_WDMA0_SOF);
- WDMA0_FRAME_START_FLAG = 1;
- _cmdq_insert_wait_frame_done_token_mira(pgc->cmdq_handle_ovl1to2_config);
- dpmgr_path_remove_memout(pgc->ovl2mem_path_handle, pgc->cmdq_handle_ovl1to2_config);
- if (gDumpMemoutCmdq == 1) {
- DISPMSG("primary_display_mem_out_trigger, dump before flush 2:\n");
- cmdqRecDumpCommand(pgc->cmdq_handle_ovl1to2_config);
- }
- if (_should_flush_cmdq_config_handle())
- /* _cmdq_flush_config_handle_mira(pgc->cmdq_handle_ovl1to2_config, 0); */
- cmdqRecFlushAsyncCallback(pgc->cmdq_handle_ovl1to2_config,
- (CmdqAsyncFlushCB)primary_display_ovl2mem_callback,
- userdata);
- if (_should_reset_cmdq_config_handle())
- cmdqRecReset(pgc->cmdq_handle_ovl1to2_config);
- /* _cmdq_insert_wait_frame_done_token_mira(pgc->cmdq_handle_ovl1to2_config); */
- done:
- pgc->need_trigger_ovl1to2 = 0;
- _primary_path_unlock(__func__);
- /* dprec_logger_done(DPREC_LOGGER_PRIMARY_TRIGGER, 0, 0); */
- return ret;
- }
- static int config_wdma_output(disp_path_handle disp_handle,
- cmdqRecHandle cmdq_handle,
- disp_mem_output_config *output, int is_multipass)
- {
- disp_ddp_path_config *pconfig = NULL;
- ASSERT(output != NULL);
- pconfig = dpmgr_path_get_last_config(disp_handle);
- pconfig->wdma_config.dstAddress = output->addr;
- pconfig->wdma_config.srcHeight = output->h;
- pconfig->wdma_config.srcWidth = output->w;
- pconfig->wdma_config.clipX = output->x;
- pconfig->wdma_config.clipY = output->y;
- pconfig->wdma_config.clipHeight = output->h;
- pconfig->wdma_config.clipWidth = output->w;
- pconfig->wdma_config.outputFormat = output->fmt;
- pconfig->wdma_config.alpha = 0xFF;
- pconfig->wdma_config.dstPitch = output->pitch;
- pconfig->wdma_config.security = output->security;
- pconfig->wdma_dirty = 1;
- pconfig->dst_dirty = 1;
- pconfig->dst_h = output->h;
- pconfig->dst_w = output->w;
- if (is_multipass)
- pconfig->wdma_config.useSpecifiedAlpha = 0;
- else
- pconfig->wdma_config.useSpecifiedAlpha = 1;
- return dpmgr_path_config(disp_handle, pconfig, cmdq_handle);
- }
- #ifdef CONFIG_SINGLE_PANEL_OUTPUT
- int primary_suspend_outputbuf_fence_release(void)
- {
- int layer = 0;
- layer = disp_sync_get_output_timeline_id();
- mtkfb_release_layer_fence(primary_session_id, layer);
- /* release rdma buffer */
- layer = disp_sync_get_output_interface_timeline_id();
- mtkfb_release_layer_fence(primary_session_id, layer);
- return 0;
- }
- #endif
- int _primary_display_config_output(disp_mem_output_config *output, unsigned int session_id, int lock)
- {
- int ret = 0;
- disp_path_handle disp_handle;
- cmdqRecHandle cmdq_handle = NULL;
- DISPFUNC();
- if (lock)
- _primary_path_lock(__func__);
- if (pgc->state == DISP_SLEPT && DISP_SESSION_TYPE(session_id) != DISP_SESSION_MEMORY) {
- DISPMSG("mem out is already slept or mode wrong(%d)\n", pgc->session_mode);
- #ifdef CONFIG_SINGLE_PANEL_OUTPUT
- primary_suspend_outputbuf_fence_release();
- #endif
- goto done;
- }
- #if !defined(OVL_MULTIPASS_SUPPORT) && !defined(OVL_TIME_SHARING)
- if (!_is_mirror_mode(pgc->session_mode)) {
- DISPERR("should not config output if not mirror mode!!\n");
- goto done;
- }
- #endif
- if (_is_decouple_mode(pgc->session_mode)) {
- disp_handle = pgc->ovl2mem_path_handle;
- cmdq_handle = pgc->cmdq_handle_ovl1to2_config;
- } else {
- disp_handle = pgc->dpmgr_handle;
- cmdq_handle = pgc->cmdq_handle_config;
- }
- if (_is_decouple_mode(pgc->session_mode)) {
- #ifndef CONFIG_ALL_IN_TRIGGER_STAGE
- if (_is_mirror_mode(pgc->session_mode))
- pgc->need_trigger_dcMirror_out = 1;
- #else
- if (_is_mirror_mode(pgc->session_mode) && is_output_buffer_set)
- pgc->need_trigger_dcMirror_out = 1;
- #endif
- } else {
- /* direct link mirror mode should add memout first */
- dpmgr_path_add_memout(pgc->dpmgr_handle, ENGINE_OVL0, cmdq_handle);
- pgc->need_trigger_ovl1to2 = 1;
- }
- if (_is_decouple_mode(pgc->session_mode) && !_is_mirror_mode(pgc->session_mode))
- /* Multipass Trigger */
- ret = config_wdma_output(disp_handle, cmdq_handle, output, 1);
- else
- ret = config_wdma_output(disp_handle, cmdq_handle, output, 0);
- if ((pgc->session_id > 0) && _is_decouple_mode(pgc->session_mode))
- update_frm_seq_info(output->addr, 0, mtkfb_query_frm_seq_by_addr(pgc->session_id, 0, 0), FRM_CONFIG);
- if (DISP_SESSION_TYPE(session_id) == DISP_SESSION_PRIMARY) {
- mem_config = *output;
- } else {
- int layer;
- layer = disp_sync_get_output_timeline_id();
- cmdqRecBackupUpdateSlot(cmdq_handle, pgc->cur_mem_config_fence, layer, output->buff_idx);
- layer = disp_sync_get_output_interface_timeline_id();
- cmdqRecBackupUpdateSlot(cmdq_handle, pgc->cur_mem_config_fence, layer, output->interface_idx);
- }
- MMProfileLogEx(ddp_mmp_get_events()->primary_wdma_config, MMProfileFlagPulse,
- output->buff_idx, (unsigned int)output->addr);
- done:
- if (lock)
- _primary_path_unlock(__func__);
- /* dprec_logger_done(DPREC_LOGGER_PRIMARY_CONFIG, output->src_x, output->src_y); */
- return ret;
- }
- int primary_display_config_output(disp_mem_output_config *output, unsigned int session_id)
- {
- return _primary_display_config_output(output, session_id, 1);
- }
- static int primary_display_config_output_nolock(disp_mem_output_config *output, unsigned int session_id)
- {
- return _primary_display_config_output(output, session_id, 0);
- }
- #if 0
- /**
- * Defined but not used, avoid build warning. (2015.1.30 Rynn Wu)
- */
- static int _config_interface_input(primary_disp_input_config *input)
- {
- int ret = 0;
- void *cmdq_handle = NULL;
- disp_ddp_path_config *data_config;
- /* all dirty should be cleared in dpmgr_path_get_last_config() */
- data_config = dpmgr_path_get_last_config(pgc->dpmgr_handle);
- dprec_logger_start(DPREC_LOGGER_PRIMARY_CONFIG, input->layer|(input->layer_en<<16), input->addr);
- ret = _convert_disp_input_to_rdma(&(data_config->rdma_config), (disp_input_config *)input);
- data_config->rdma_dirty = 1;
- if (_should_wait_path_idle()) {
- if (dpmgr_path_is_busy(pgc->dpmgr_handle))
- dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE, HZ*1);
- }
- if (primary_display_cmdq_enabled())
- cmdq_handle = pgc->cmdq_handle_config;
- ret = dpmgr_path_config(pgc->dpmgr_handle, data_config, cmdq_handle);
- dprec_logger_done(DPREC_LOGGER_PRIMARY_CONFIG, input->src_x, input->src_y);
- return ret;
- }
- #endif
- static void update_debug_fps_meter(disp_ddp_path_config *data_config)
- {
- int i, dst_id = 0;
- for (i = 0; i < HW_OVERLAY_COUNT; i++) {
- if (data_config->ovl_config[i].layer_en && data_config->ovl_config[i].dst_x == 0 &&
- data_config->ovl_config[i].dst_y == 0)
- dst_id = i;
- }
- _debug_fps_meter(data_config->ovl_config[dst_id].addr,
- data_config->ovl_config[dst_id].vaddr,
- data_config->ovl_config[dst_id].dst_w,
- data_config->ovl_config[dst_id].dst_h,
- data_config->ovl_config[dst_id].src_pitch, 0x00000000, dst_id,
- data_config->ovl_config[dst_id].buff_idx);
- }
- static int _config_ovl_input(disp_session_input_config *session_input,
- disp_path_handle disp_handle, cmdqRecHandle cmdq_handle)
- {
- int ret = 0, i = 0, layer = 0;
- disp_ddp_path_config *data_config = NULL;
- int max_layer_id_configed = 0;
- #ifndef MTK_FB_CMDQ_DISABLE
- int force_disable_ovl1 = 0;
- #endif
- cmdqBackupSlotHandle *p_cur_config_fence;
- cmdqBackupSlotHandle *p_subtractor_when_free;
- LCM_PARAMS *lcm_param = NULL;
- /* create new data_config for ovl input */
- data_config = dpmgr_path_get_last_config(disp_handle);
- if (DISP_SESSION_TYPE(session_input->session_id) == DISP_SESSION_MEMORY) {
- p_cur_config_fence = &(pgc->cur_mem_config_fence);
- p_subtractor_when_free = &(pgc->mem_subtractor_when_free);
- data_config->is_memory = true;
- } else {
- lcm_param = disp_lcm_get_params(pgc->plcm);
- p_cur_config_fence = &(pgc->cur_config_fence);
- p_subtractor_when_free = &(pgc->subtractor_when_free);
- data_config->dst_h = lcm_param->height;
- data_config->dst_w = lcm_param->width;
- data_config->is_memory = false;
- }
- for (i = 0; i < session_input->config_layer_num; i++) {
- disp_input_config *input_cfg = &session_input->config[i];
- OVL_CONFIG_STRUCT *ovl_cfg;
- layer = input_cfg->layer_id;
- /*security issue*/
- if (layer >= OVL_LAYER_NUM)
- continue;
- ovl_cfg = &(data_config->ovl_config[layer]);
- if (session_input->setter != SESSION_USER_AEE) {
- if (isAEEEnabled && layer == primary_display_get_option("ASSERT_LAYER")) {
- DISPMSG("skip AEE layer %d\n", layer);
- continue;
- }
- } else {
- DISPMSG("set AEE layer %d\n", layer);
- }
- _convert_disp_input_to_ovl(ovl_cfg, input_cfg);
- if (ovl_cfg->layer_en)
- _debug_pattern(ovl_cfg->addr, ovl_cfg->vaddr, ovl_cfg->dst_w,
- ovl_cfg->dst_h, ovl_cfg->src_pitch, 0x00000000,
- ovl_cfg->layer, ovl_cfg->buff_idx);
- dprec_logger_start(DPREC_LOGGER_PRIMARY_CONFIG, ovl_cfg->layer | (ovl_cfg->layer_en << 16),
- ovl_cfg->addr);
- dprec_logger_done(DPREC_LOGGER_PRIMARY_CONFIG, ovl_cfg->src_x, ovl_cfg->src_y);
- dprec_mmp_dump_ovl_layer(ovl_cfg, layer, 1);
- if ((ovl_cfg->layer == 0) && (!_is_decouple_mode(pgc->session_mode)))
- update_frm_seq_info(ovl_cfg->addr, ovl_cfg->src_x * 4 + ovl_cfg->src_y * ovl_cfg->src_pitch,
- mtkfb_query_frm_seq_by_addr(pgc->session_id, 0, 0), FRM_CONFIG);
- if (max_layer_id_configed < layer)
- max_layer_id_configed = layer;
- data_config->ovl_dirty = 1;
- #if defined(CONFIG_FOR_SOURCE_PQ)
- data_config->dst_dirty = 1;
- #endif
- #if defined(OVL_TIME_SHARING)
- data_config->roi_dirty = 1;
- #endif
- }
- #ifdef OVL_CASCADE_SUPPORT
- if (ovl_get_status() == DDP_OVL1_STATUS_SUB_REQUESTING) {
- /* disable ovl layer 4~8 to free ovl1 */
- if (max_layer_id_configed < OVL_LAYER_NUM_PER_OVL - is_DAL_Enabled()) {
- for (i = OVL_LAYER_NUM_PER_OVL; i < OVL_LAYER_NUM; i++)
- data_config->ovl_config[i].layer_en = 0;
- force_disable_ovl1 = 1;
- DISPMSG("cascade: HWC set %d layers, force disable OVL1 layers\n",
- max_layer_id_configed);
- } else {
- DISPMSG("cascade: try to split ovl1 fail: HWC set %d layers\n",
- max_layer_id_configed);
- }
- }
- #endif
- if (_should_wait_path_idle())
- dpmgr_wait_event_timeout(disp_handle, DISP_PATH_EVENT_FRAME_DONE, HZ * 1);
- /* should we use cmdq_hand_config? need to check */
- ret = dpmgr_path_config(disp_handle, data_config, cmdq_handle);
- #ifndef MTK_FB_CMDQ_DISABLE
- /* write fence_id/enable to DRAM using cmdq,
- * it will be used when release fence (put these after config registers done)
- */
- for (i = 0; i < session_input->config_layer_num; i++) {
- unsigned int last_fence, cur_fence;
- disp_input_config *input_cfg = &session_input->config[i];
- layer = input_cfg->layer_id;
- cmdqBackupReadSlot(*p_cur_config_fence, layer, &last_fence);
- cur_fence = input_cfg->next_buff_idx;
- if (cur_fence != -1 && cur_fence > last_fence)
- cmdqRecBackupUpdateSlot(cmdq_handle, *p_cur_config_fence, layer, cur_fence);
- /* for dim_layer/disable_layer/no_fence_layer, just release all fences configured */
- /* for other layers, release current_fence-1 */
- if (input_cfg->buffer_source == DISP_BUFFER_ALPHA || input_cfg->layer_enable == 0 ||
- cur_fence == -1 || DISP_SESSION_TYPE(session_input->session_id) == DISP_SESSION_MEMORY)
- cmdqRecBackupUpdateSlot(cmdq_handle, *p_subtractor_when_free, layer, 0);
- else
- cmdqRecBackupUpdateSlot(cmdq_handle, *p_subtractor_when_free, layer, 1);
- }
- if (force_disable_ovl1) {
- for (layer = OVL_LAYER_NUM_PER_OVL; layer < OVL_LAYER_NUM; layer++)
- /* will release all fences */
- cmdqRecBackupUpdateSlot(cmdq_handle, *p_subtractor_when_free, layer, 0);
- }
- #endif
- update_debug_fps_meter(data_config);
- if (DISP_SESSION_TYPE(session_input->session_id) == DISP_SESSION_PRIMARY) {
- last_primary_config = *data_config;
- is_hwc_update_frame = 1;
- }
- return ret;
- }
- #if 0
- /**
- * Defined but not used, avoid build warning. (2015.1.30 Rynn Wu)
- */
- static int _config_ovl_output(disp_mem_output_config *output)
- {
- int ret = 0;
- disp_ddp_path_config *data_config = NULL;
- disp_path_handle *handle = NULL;
- data_config = dpmgr_path_get_last_config(pgc->ovl2mem_path_handle);
- data_config->wdma_dirty = 1;
- if (_should_wait_path_idle())
- dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE, HZ*1);
- handle = pgc->ovl2mem_path_handle;
- ret = dpmgr_path_config(pgc->ovl2mem_path_handle, data_config, pgc->cmdq_handle_config);
- return ret;
- }
- #endif
- static int _config_rdma_input(disp_session_input_config *session_input, disp_path_handle *handle)
- {
- int ret;
- disp_ddp_path_config *data_config = NULL;
- /* all dirty should be cleared in dpmgr_path_get_last_config() */
- data_config = dpmgr_path_get_last_config(handle);
- data_config->dst_dirty = 0;
- data_config->ovl_dirty = 0;
- data_config->rdma_dirty = 0;
- data_config->wdma_dirty = 0;
- ret =
- _convert_disp_input_to_rdma(&(data_config->rdma_config),
- (disp_input_config *) session_input);
- data_config->rdma_dirty = 1;
- if (_should_wait_path_idle())
- dpmgr_wait_event_timeout(handle, DISP_PATH_EVENT_FRAME_DONE, HZ * 1);
- ret =
- dpmgr_path_config(handle, data_config,
- primary_display_cmdq_enabled() ? pgc->cmdq_handle_config : NULL);
- return ret;
- }
- static int _primary_display_config_input_multiple(disp_session_input_config *session_input, int lock)
- {
- int ret = 0;
- disp_path_handle disp_handle;
- cmdqRecHandle cmdq_handle;
- if (gTriggerDispMode > 0)
- return 0;
- if (lock)
- _primary_path_lock(__func__);
- if (primary_get_state() == DISP_SLEPT && DISP_SESSION_TYPE(session_input->session_id) != DISP_SESSION_MEMORY) {
- DISPMSG("%s, skip because primary dipslay is sleep\n", __func__);
- #ifdef CONFIG_SINGLE_PANEL_OUTPUT
- primary_suspend_release_ovl_fence(session_input);
- #endif
- goto done;
- }
- #ifdef MTK_DISP_IDLE_LP
- /* call this in trigger is enough, do not have to call this in config */
- _disp_primary_path_exit_idle(__func__, 0);
- #endif
- if (_is_decouple_mode(pgc->session_mode)) {
- disp_handle = pgc->ovl2mem_path_handle;
- cmdq_handle = pgc->cmdq_handle_ovl1to2_config;
- } else {
- disp_handle = pgc->dpmgr_handle;
- cmdq_handle = pgc->cmdq_handle_config;
- }
- if (_should_config_ovl_input())
- _config_ovl_input(session_input, disp_handle, cmdq_handle);
- else
- _config_rdma_input(session_input, disp_handle);
- done:
- if (lock)
- _primary_path_unlock(__func__);
- return ret;
- }
- int primary_display_config_input_multiple(disp_session_input_config *session_input)
- {
- return _primary_display_config_input_multiple(session_input, 1);
- }
- static int primary_display_config_input_multiple_nolock(disp_session_input_config *session_input)
- {
- return _primary_display_config_input_multiple(session_input, 0);
- }
- int primary_display_config_interface_input(primary_disp_input_config *input)
- {
- int ret = 0;
- void *cmdq_handle = NULL;
- disp_ddp_path_config *data_config;
- /* all dirty should be cleared in dpmgr_path_get_last_config() */
- data_config = dpmgr_path_get_last_config(pgc->dpmgr_handle);
- dprec_logger_start(DPREC_LOGGER_PRIMARY_CONFIG, input->layer | (input->layer_en << 16),
- input->addr);
- _primary_path_lock(__func__);
- if (pgc->state == DISP_SLEPT) {
- DISPMSG("%s, skip because primary dipslay is sleep\n", __func__);
- goto done;
- }
- ret = _convert_disp_input_to_rdma(&(data_config->rdma_config), (disp_input_config *) input);
- data_config->rdma_dirty = 1;
- if (_should_wait_path_idle()) {
- if (dpmgr_path_is_busy(pgc->dpmgr_handle))
- dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE,
- HZ * 1);
- }
- if (primary_display_cmdq_enabled())
- cmdq_handle = pgc->cmdq_handle_config;
- ret = dpmgr_path_config(pgc->dpmgr_handle, data_config, cmdq_handle);
- /* this is used for decouple mode, to indicate whether we need to trigger ovl */
- pgc->need_trigger_overlay = 1;
- dprec_logger_done(DPREC_LOGGER_PRIMARY_CONFIG, input->src_x, input->src_y);
- done:
- _primary_path_unlock(__func__);
- return ret;
- }
- static int Panel_Master_primary_display_config_dsi(const char *name, uint32_t config_value)
- {
- int ret = 0;
- disp_ddp_path_config *data_config;
- /* all dirty should be cleared in dpmgr_path_get_last_config() */
- data_config = dpmgr_path_get_last_config(pgc->dpmgr_handle);
- /* modify below for config dsi */
- if (!strcmp(name, "PM_CLK")) {
- pr_debug("Pmaster_config_dsi: PM_CLK:%d\n", config_value);
- data_config->dispif_config.dsi.PLL_CLOCK = config_value;
- } else if (!strcmp(name, "PM_SSC")) {
- data_config->dispif_config.dsi.ssc_range = config_value;
- }
- pr_debug("Pmaster_config_dsi: will Run path_config()\n");
- ret = dpmgr_path_config(pgc->dpmgr_handle, data_config, NULL);
- return ret;
- }
- int primary_display_user_cmd(unsigned int cmd, unsigned long arg)
- {
- int ret = 0;
- cmdqRecHandle handle = NULL;
- int cmdqsize = 0;
- MMProfileLogEx(ddp_mmp_get_events()->primary_display_cmd, MMProfileFlagStart,
- (unsigned long)handle, 0);
- #ifndef MTK_FB_CMDQ_DISABLE
- #if 0 /* CONFIG_FOR_SOURCE_PQ */
- if (primary_display_is_decouple_mode()) {
- ret = cmdqRecCreate(CMDQ_SCENARIO_DISP_COLOR, &handle);
- cmdqRecReset(handle);
- cmdqRecWait(handle, CMDQ_EVENT_DISP_WDMA0_EOF);
- } else {
- ret = cmdqRecCreate(CMDQ_SCENARIO_PRIMARY_DISP, &handle);
- cmdqRecReset(handle);
- _cmdq_insert_wait_frame_done_token_mira(handle);
- }
- #else
- ret = cmdqRecCreate(CMDQ_SCENARIO_PRIMARY_DISP, &handle);
- cmdqRecReset(handle);
- if (primary_display_is_video_mode())
- cmdqRecWaitNoClear(handle, CMDQ_EVENT_DISP_RDMA0_EOF);
- else
- cmdqRecWaitNoClear(handle, CMDQ_SYNC_TOKEN_STREAM_EOF);
- #endif
- cmdqsize = cmdqRecGetInstructionCount(handle);
- #ifdef MTK_DISP_IDLE_LP
- /* will write register in dpmgr_path_user_cmd, need to exit idle */
- last_primary_trigger_time = sched_clock();
- _disp_primary_path_exit_idle(__func__, 1);
- #endif
- #ifdef CONFIG_FOR_SOURCE_PQ
- if (primary_display_is_decouple_mode())
- ret = dpmgr_path_user_cmd(pgc->ovl2mem_path_handle, cmd, arg, handle);
- else
- ret = dpmgr_path_user_cmd(pgc->dpmgr_handle, cmd, arg, handle);
- #else
- ret = dpmgr_path_user_cmd(pgc->dpmgr_handle, cmd, arg, handle);
- #endif
- if (handle) {
- if (cmdqRecGetInstructionCount(handle) > cmdqsize) {
- _primary_path_lock(__func__);
- if (pgc->state == DISP_ALIVE) {
- #if 0 /* CONFIG_FOR_SOURCE_PQ */
- if (primary_display_is_decouple_mode()) {
- dpmgr_path_trigger(pgc->ovl2mem_path_handle, handle,
- CMDQ_ENABLE);
- cmdqRecFlushAsync(handle);
- } else {
- _cmdq_set_config_handle_dirty_mira(handle);
- /* use non-blocking flush here to avoid primary path is locked for too long */
- _cmdq_flush_config_handle_mira(handle, 0);
- }
- #else
- _cmdq_set_config_handle_dirty_mira(handle);
- /* use non-blocking flush here to avoid primary path is locked for too long */
- _cmdq_flush_config_handle_mira(handle, 0);
- #endif
- }
- _primary_path_unlock(__func__);
- }
- cmdqRecDestroy(handle);
- }
- #endif
- MMProfileLogEx(ddp_mmp_get_events()->primary_display_cmd, MMProfileFlagEnd,
- (unsigned long)handle, cmdqsize);
- return ret;
- }
- int init_ext_decouple_buffers(void)
- {
- int ret = 0;
- #if defined(CONFIG_MTK_GMO_RAM_OPTIMIZE)
- _primary_path_lock(__func__);
- if (pgc->state == DISP_SLEPT) {
- ret = -1;
- } else {
- if (decouple_buffer_info[0] == NULL)
- ret = allocate_idle_lp_dc_buffer();
- }
- _primary_path_unlock(__func__);
- #endif
- return ret;
- }
- int deinit_ext_decouple_buffers(void)
- {
- int ret = 0;
- #if defined(CONFIG_MTK_GMO_RAM_OPTIMIZE)
- _primary_path_lock(__func__);
- ret = release_idle_lp_dc_buffer(0);
- _primary_path_unlock(__func__);
- #endif
- return ret;
- }
- int primary_display_switch_mode(int sess_mode, unsigned int session, int force)
- {
- DISPDBG("primary_display_switch_mode sess_mode %d, session 0x%x\n", sess_mode, session);
- _primary_path_lock(__func__);
- MMProfileLogEx(ddp_mmp_get_events()->primary_switch_mode, MMProfileFlagStart,
- pgc->session_mode, sess_mode);
- if (primary_get_state() == DISP_BLANK)
- sess_mode = DISP_SESSION_DECOUPLE_MODE;
- if (pgc->session_mode == sess_mode)
- goto done;
- if (pgc->state == DISP_SLEPT) {
- DISPMSG("primary display switch from %s to %s in suspend state!!!\n",
- session_mode_spy(pgc->session_mode), session_mode_spy(sess_mode));
- #ifdef OVL_TIME_SHARING
- /*
- Allow system to switch mode between Deouple and Decouple Mirror when time-sharing support.
- Since system may use extension path to output data even when the primay path has suspended.
- */
- if (pgc->session_mode == DISP_SESSION_DECOUPLE_MODE
- && sess_mode == DISP_SESSION_DECOUPLE_MIRROR_MODE) {
- pgc->session_mode = sess_mode;
- DISPMSG("primary display is %s mode now\n", session_mode_spy(pgc->session_mode));
- } else if (pgc->session_mode == DISP_SESSION_DECOUPLE_MIRROR_MODE
- && sess_mode == DISP_SESSION_DECOUPLE_MODE) {
- pgc->session_mode = sess_mode;
- DISPMSG("primary display is %s mode now\n", session_mode_spy(pgc->session_mode));
- }
- #endif
- goto done;
- }
- DISPMSG("primary display will switch from %s to %s\n", session_mode_spy(pgc->session_mode),
- session_mode_spy(sess_mode));
- if (pgc->session_mode == DISP_SESSION_DIRECT_LINK_MODE
- && sess_mode == DISP_SESSION_DECOUPLE_MODE) {
- /* dl to dc */
- _DL_switch_to_DC_fast();
- pgc->session_mode = sess_mode;
- DISPMSG("primary display is %s mode now\n", session_mode_spy(pgc->session_mode));
- MMProfileLogEx(ddp_mmp_get_events()->primary_switch_mode, MMProfileFlagPulse,
- pgc->session_mode, sess_mode);
- /* primary_display_diagnose(); */
- } else if (pgc->session_mode == DISP_SESSION_DECOUPLE_MODE
- && sess_mode == DISP_SESSION_DIRECT_LINK_MODE) {
- /* dc to dl */
- _DC_switch_to_DL_fast();
- pgc->session_mode = sess_mode;
- DISPMSG("primary display is %s mode now\n", session_mode_spy(pgc->session_mode));
- MMProfileLogEx(ddp_mmp_get_events()->primary_switch_mode, MMProfileFlagPulse,
- pgc->session_mode, sess_mode);
- /* primary_display_diagnose(); */
- } else if (pgc->session_mode == DISP_SESSION_DIRECT_LINK_MODE
- && sess_mode == DISP_SESSION_DIRECT_LINK_MIRROR_MODE) {
- /* dl to dl mirror */
- /* cmdqRecCreate(CMDQ_SCENARIO_DISP_SCREEN_CAPTURE, &pgc->cmdq_handle_dl_mirror); */
- /* cmdqRecReset(pgc->cmdq_handle_dl_mirror); */
- pgc->session_mode = sess_mode;
- DISPMSG("primary display is %s mode now\n", session_mode_spy(pgc->session_mode));
- MMProfileLogEx(ddp_mmp_get_events()->primary_switch_mode, MMProfileFlagPulse,
- pgc->session_mode, sess_mode);
- } else if (pgc->session_mode == DISP_SESSION_DIRECT_LINK_MIRROR_MODE
- && sess_mode == DISP_SESSION_DIRECT_LINK_MODE) {
- /*dl mirror to dl */
- /* cmdqRecDestroy(pgc->cmdq_handle_dl_mirror); */
- /* pgc->cmdq_handle_dl_mirror = NULL; */
- pgc->session_mode = sess_mode;
- DISPMSG("primary display is %s mode now\n", session_mode_spy(pgc->session_mode));
- MMProfileLogEx(ddp_mmp_get_events()->primary_switch_mode, MMProfileFlagPulse,
- pgc->session_mode, sess_mode);
- } else if (pgc->session_mode == DISP_SESSION_DIRECT_LINK_MODE
- && sess_mode == DISP_SESSION_DECOUPLE_MIRROR_MODE) {
- /* dl to dc mirror mirror */
- #ifdef CONFIG_MTK_GMO_RAM_OPTIMIZE
- if (decouple_buffer_info[0] == NULL)
- allocate_idle_lp_dc_buffer();
- #endif
- _DL_switch_to_DC_fast();
- pgc->session_mode = sess_mode;
- DISPMSG("primary display is %s mode now\n", session_mode_spy(pgc->session_mode));
- MMProfileLogEx(ddp_mmp_get_events()->primary_switch_mode, MMProfileFlagPulse,
- pgc->session_mode, sess_mode);
- /* primary_display_diagnose(); */
- } else if (pgc->session_mode == DISP_SESSION_DECOUPLE_MIRROR_MODE
- && sess_mode == DISP_SESSION_DIRECT_LINK_MODE) {
- /*dc mirror to dl */
- _DC_switch_to_DL_fast();
- pgc->session_mode = sess_mode;
- #ifdef CONFIG_MTK_GMO_RAM_OPTIMIZE
- release_idle_lp_dc_buffer(0);
- #endif
- DISPMSG("primary display is %s mode now\n", session_mode_spy(pgc->session_mode));
- MMProfileLogEx(ddp_mmp_get_events()->primary_switch_mode, MMProfileFlagPulse,
- pgc->session_mode, sess_mode);
- /* primary_display_diagnose(); */
- } else if (pgc->session_mode == DISP_SESSION_DECOUPLE_MODE
- && sess_mode == DISP_SESSION_DECOUPLE_MIRROR_MODE) {
- /*dc to dc mirror */
- pgc->session_mode = sess_mode;
- DISPMSG("primary display is %s mode now\n", session_mode_spy(pgc->session_mode));
- MMProfileLogEx(ddp_mmp_get_events()->primary_switch_mode, MMProfileFlagPulse,
- pgc->session_mode, sess_mode);
- } else if (pgc->session_mode == DISP_SESSION_DECOUPLE_MIRROR_MODE
- && sess_mode == DISP_SESSION_DECOUPLE_MODE) {
- /*dc mirror to dc */
- pgc->session_mode = sess_mode;
- DISPMSG("primary display is %s mode now\n", session_mode_spy(pgc->session_mode));
- MMProfileLogEx(ddp_mmp_get_events()->primary_switch_mode, MMProfileFlagPulse,
- pgc->session_mode, sess_mode);
- } else {
- DISPERR("invalid mode switch from %s to %s\n", session_mode_spy(pgc->session_mode),
- session_mode_spy(sess_mode));
- }
- done:
- _primary_path_unlock(__func__);
- pgc->session_id = session;
- MMProfileLogEx(ddp_mmp_get_events()->primary_switch_mode, MMProfileFlagEnd,
- pgc->session_mode, sess_mode);
- return 0; /* avoid build warning. */
- }
- #ifdef MTK_DISP_IDLE_LP
- int primary_display_switch_mode_nolock(int sess_mode, unsigned int session, int force)
- {
- DISPCHECK("primary_display_switch_mode sess_mode %d, session 0x%x\n", sess_mode, session);
- /* if(!force && _is_decouple_mode(pgc->session_mode)) */
- /* return 0; */
- /* _primary_path_lock(__func__); */
- MMProfileLogEx(ddp_mmp_get_events()->primary_switch_mode, MMProfileFlagStart,
- pgc->session_mode, sess_mode);
- if (pgc->session_mode == sess_mode)
- goto done;
- DISPMSG("primary display will switch from %s to %s\n", session_mode_spy(pgc->session_mode),
- session_mode_spy(sess_mode));
- if (pgc->session_mode == DISP_SESSION_DIRECT_LINK_MODE && sess_mode == DISP_SESSION_DECOUPLE_MODE) {
- /* signal frame start event to switch logic in fence_release_worker_thread */
- /* dpmgr_signal_event(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_START); */
- _DL_switch_to_DC_fast();
- pgc->session_mode = sess_mode;
- DISPMSG("primary display is %s mode now\n", session_mode_spy(pgc->session_mode));
- MMProfileLogEx(ddp_mmp_get_events()->primary_switch_mode, MMProfileFlagPulse,
- pgc->session_mode, sess_mode);
- /* primary_display_diagnose(); */
- } else if (pgc->session_mode == DISP_SESSION_DECOUPLE_MODE && sess_mode == DISP_SESSION_DIRECT_LINK_MODE) {
- /* signal frame start event to switch logic in fence_release_worker_thread */
- /* dpmgr_signal_event(pgc->ovl2mem_path_handle, DISP_PATH_EVENT_FRAME_START); */
- _DC_switch_to_DL_fast();
- pgc->session_mode = sess_mode;
- DISPMSG("* primary display is %s mode now\n", session_mode_spy(pgc->session_mode));
- MMProfileLogEx(ddp_mmp_get_events()->primary_switch_mode, MMProfileFlagPulse,
- pgc->session_mode, sess_mode);
- /* primary_display_diagnose(); */
- } else if (pgc->session_mode == DISP_SESSION_DIRECT_LINK_MODE &&
- sess_mode == DISP_SESSION_DIRECT_LINK_MIRROR_MODE) {
- /*need delay switch to output */
- pgc->session_mode = sess_mode;
- } else if (pgc->session_mode == DISP_SESSION_DIRECT_LINK_MIRROR_MODE
- && sess_mode == DISP_SESSION_DIRECT_LINK_MODE) {
- /* xxx */
- pgc->session_mode = sess_mode;
- } else if (pgc->session_mode == DISP_SESSION_DIRECT_LINK_MODE &&
- sess_mode == DISP_SESSION_DECOUPLE_MIRROR_MODE) {
- /*need delay switch to output */
- _DL_switch_to_DC_fast();
- pgc->session_mode = sess_mode;
- DISPMSG("primary display is %s mode now\n", session_mode_spy(pgc->session_mode));
- MMProfileLogEx(ddp_mmp_get_events()->primary_switch_mode, MMProfileFlagPulse,
- pgc->session_mode, sess_mode);
- /* primary_display_diagnose(); */
- /* pgc->session_delay_mode = sess_mode; */
- } else if (pgc->session_mode == DISP_SESSION_DECOUPLE_MIRROR_MODE &&
- sess_mode == DISP_SESSION_DIRECT_LINK_MODE) {
- _DC_switch_to_DL_fast();
- pgc->session_mode = sess_mode;
- DISPMSG("primary display is %s mode now\n", session_mode_spy(pgc->session_mode));
- MMProfileLogEx(ddp_mmp_get_events()->primary_switch_mode, MMProfileFlagPulse,
- pgc->session_mode, sess_mode);
- /* primary_display_diagnose(); */
- } else {
- DISPERR("invalid mode switch from %s to %s\n", session_mode_spy(pgc->session_mode),
- session_mode_spy(sess_mode));
- }
- done:
- /* _primary_path_unlock(__func__); */
- pgc->session_id = session;
- MMProfileLogEx(ddp_mmp_get_events()->primary_switch_mode, MMProfileFlagEnd,
- pgc->session_mode, sess_mode);
- return 0; /* avoid build warning. */
- }
- #endif
- int primary_display_is_alive(void)
- {
- unsigned int temp = 0;
- /* DISPFUNC(); */
- _primary_path_lock(__func__);
- if (pgc->state == DISP_ALIVE)
- temp = 1;
- _primary_path_unlock(__func__);
- return temp;
- }
- int primary_display_is_sleepd_nolock(void)
- {
- unsigned int temp = 0;
- /* DISPFUNC(); */
- if (pgc->state == DISP_SLEPT)
- temp = 1;
- return temp;
- }
- int primary_display_is_sleepd(void)
- {
- unsigned int temp = 0;
- /* DISPFUNC(); */
- _primary_path_lock(__func__);
- if (pgc->state == DISP_SLEPT)
- temp = 1;
- _primary_path_unlock(__func__);
- return temp;
- }
- int primary_display_get_width(void)
- {
- if (pgc->plcm == NULL) {
- DISPERR("lcm handle is null\n");
- return 0;
- }
- if (pgc->plcm->params)
- return pgc->plcm->params->width;
- DISPERR("lcm_params is null!\n");
- return 0;
- }
- int primary_display_get_height(void)
- {
- if (pgc->plcm == NULL) {
- DISPERR("lcm handle is null\n");
- return 0;
- }
- if (pgc->plcm->params)
- return pgc->plcm->params->height;
- DISPERR("lcm_params is null!\n");
- return 0;
- }
- int primary_display_get_original_width(void)
- {
- if (pgc->plcm == NULL) {
- DISPERR("lcm handle is null\n");
- return 0;
- }
- if (pgc->plcm->params)
- return pgc->plcm->lcm_original_width;
- DISPERR("lcm_params is null!\n");
- return 0;
- }
- int primary_display_get_original_height(void)
- {
- if (pgc->plcm == NULL) {
- DISPERR("lcm handle is null\n");
- return 0;
- }
- if (pgc->plcm->params)
- return pgc->plcm->lcm_original_height;
- DISPERR("lcm_params is null!\n");
- return 0;
- }
- int primary_display_get_bpp(void)
- {
- return 32;
- }
- int primary_display_get_dc_bpp(void)
- {
- return 24;
- }
- void primary_display_set_max_layer(int maxlayer)
- {
- pgc->max_layer = maxlayer;
- }
- int primary_display_get_info(void *info)
- {
- #if 1
- /* DISPFUNC(); */
- disp_session_info *dispif_info = (disp_session_info *) info;
- LCM_PARAMS *lcm_param = disp_lcm_get_params(pgc->plcm);
- if (lcm_param == NULL) {
- DISPCHECK("lcm_param is null\n");
- return -1;
- }
- memset((void *)dispif_info, 0, sizeof(disp_session_info));
- #ifdef OVL_CASCADE_SUPPORT
- if (is_DAL_Enabled() && pgc->max_layer == OVL_LAYER_NUM) {
- /* OVL1 is used by mem session */
- if (ovl_get_status() == DDP_OVL1_STATUS_PRIMARY || ovl_get_status() == DDP_OVL1_STATUS_IDLE)
- dispif_info->maxLayerNum = pgc->max_layer - 1;
- else
- dispif_info->maxLayerNum = pgc->max_layer - 1 - 4;
- } else {
- /* OVL1 is used by mem session */
- if (ovl_get_status() == DDP_OVL1_STATUS_PRIMARY || ovl_get_status() == DDP_OVL1_STATUS_IDLE)
- dispif_info->maxLayerNum = pgc->max_layer;
- else
- dispif_info->maxLayerNum = pgc->max_layer - 4;
- }
- #else
- if (is_DAL_Enabled() && pgc->max_layer == OVL_LAYER_NUM)
- dispif_info->maxLayerNum = pgc->max_layer - 1;
- else
- dispif_info->maxLayerNum = pgc->max_layer;
- #endif
- /* DISPDBG("available layer num=%d\n", dispif_info->maxLayerNum); */
- switch (lcm_param->type) {
- case LCM_TYPE_DBI:
- {
- dispif_info->displayType = DISP_IF_TYPE_DBI;
- dispif_info->displayMode = DISP_IF_MODE_COMMAND;
- dispif_info->isHwVsyncAvailable = 1;
- /* DISPMSG("DISP Info: DBI, CMD Mode, HW Vsync enable\n"); */
- break;
- }
- case LCM_TYPE_DPI:
- {
- dispif_info->displayType = DISP_IF_TYPE_DPI;
- dispif_info->displayMode = DISP_IF_MODE_VIDEO;
- dispif_info->isHwVsyncAvailable = 1;
- /* DISPMSG("DISP Info: DPI, VDO Mode, HW Vsync enable\n"); */
- break;
- }
- case LCM_TYPE_DSI:
- {
- dispif_info->displayType = DISP_IF_TYPE_DSI0;
- if (lcm_param->dsi.mode == CMD_MODE) {
- dispif_info->displayMode = DISP_IF_MODE_COMMAND;
- dispif_info->isHwVsyncAvailable = 1;
- /* DISPMSG("DISP Info: DSI, CMD Mode, HW Vsync enable\n"); */
- } else {
- dispif_info->displayMode = DISP_IF_MODE_VIDEO;
- dispif_info->isHwVsyncAvailable = 1;
- /* DISPMSG("DISP Info: DSI, VDO Mode, HW Vsync enable\n"); */
- }
- break;
- }
- default:
- break;
- }
- dispif_info->displayFormat = DISP_IF_FORMAT_RGB888;
- dispif_info->displayWidth = primary_display_get_width();
- dispif_info->displayHeight = primary_display_get_height();
- dispif_info->physicalWidth = DISP_GetActiveWidth();
- dispif_info->physicalHeight = DISP_GetActiveHeight();
- dispif_info->vsyncFPS = pgc->lcm_fps;
- dispif_info->isConnected = 1;
- #ifdef ROME_TODO
- #error
- {
- LCM_PARAMS lcm_params_temp;
- memset((void *)&lcm_params_temp, 0, sizeof(lcm_params_temp));
- if (lcm_drv) {
- lcm_drv->get_params(&lcm_params_temp);
- dispif_info->lcmOriginalWidth = lcm_params_temp.width;
- dispif_info->lcmOriginalHeight = lcm_params_temp.height;
- DISPMSG("DISP Info: LCM Panel Original Resolution(For DFO Only): %d x %d\n",
- dispif_info->lcmOriginalWidth, dispif_info->lcmOriginalHeight);
- } else {
- DISPMSG("DISP Info: Fatal Error!!, lcm_drv is null\n");
- }
- }
- #endif
- #endif
- return 0; /* avoid build warning. */
- }
- int primary_display_get_pages(void)
- {
- return 3;
- }
- int primary_display_is_video_mode(void)
- {
- /* TODO: we should store the video/cmd mode in runtime, because we will support cmd/vdo dynamic switch */
- return disp_lcm_is_video_mode(pgc->plcm);
- }
- int primary_display_is_decouple_mode(void)
- {
- return _is_decouple_mode(pgc->session_mode);
- }
- int primary_display_is_mirror_mode(void)
- {
- return _is_mirror_mode(pgc->session_mode);
- }
- int primary_display_is_ovl1to2_handle(cmdqRecHandle *handle)
- {
- if (handle && (handle == (cmdqRecHandle *)pgc->cmdq_handle_ovl1to2_config))
- return 1;
- else
- return 0;
- }
- int primary_display_diagnose(void)
- {
- int ret = 0;
- if (pgc->dpmgr_handle != NULL)
- dpmgr_check_status(pgc->dpmgr_handle);
- if (_is_decouple_mode(pgc->session_mode) && (pgc->ovl2mem_path_handle != NULL))
- dpmgr_check_status(pgc->ovl2mem_path_handle);
- primary_display_check_path(NULL, 0);
- return ret;
- }
- CMDQ_SWITCH primary_display_cmdq_enabled(void)
- {
- return primary_display_use_cmdq;
- }
- int primary_display_switch_cmdq_cpu(CMDQ_SWITCH use_cmdq)
- {
- _primary_path_lock(__func__);
- primary_display_use_cmdq = use_cmdq;
- DISPCHECK("display driver use %s to config register now\n",
- (use_cmdq == CMDQ_ENABLE) ? "CMDQ" : "CPU");
- _primary_path_unlock(__func__);
- return primary_display_use_cmdq;
- }
- int primary_display_manual_lock(void)
- {
- _primary_path_lock(__func__);
- return 0; /* avoid build warning */
- }
- int primary_display_manual_unlock(void)
- {
- _primary_path_unlock(__func__);
- return 0;
- }
- void primary_display_reset(void)
- {
- dpmgr_path_reset(pgc->dpmgr_handle, CMDQ_DISABLE);
- }
- unsigned int primary_display_get_fps(void)
- {
- unsigned int fps = 0;
- _primary_path_lock(__func__);
- fps = pgc->lcm_fps;
- _primary_path_unlock(__func__);
- return fps;
- }
- int primary_display_force_set_vsync_fps(unsigned int fps)
- {
- int ret = 0;
- DISPMSG("force set fps to %d\n", fps);
- _primary_path_lock(__func__);
- if (fps == pgc->lcm_fps) {
- pgc->vsync_drop = 0;
- ret = 0;
- } else if (fps == 30) {
- pgc->vsync_drop = 1;
- ret = 0;
- } else {
- ret = -1;
- }
- _primary_path_unlock(__func__);
- return ret;
- }
- int primary_display_insert_session_buf(disp_session_buf_info *session_buf_info)
- {
- int i = 0;
- unsigned int *session_buf;
- session_buf = pgc->session_buf;
- pgc->session_buf_id = 0;
- for (i = 0; i < DISP_INTERNAL_BUFFER_COUNT; i++) {
- session_buf[i] = session_buf_info->buf_hnd[i];
- DISPMSG("%s buf_hnd[%d] = 0x%x\n", __func__, i, session_buf_info->buf_hnd[i]);
- }
- return 0;
- }
- int primary_display_enable_path_cg(int enable)
- {
- int ret = 0;
- #ifdef ENABLE_CLK_MGR
- DISPMSG("%s primary display's path cg\n", enable ? "enable" : "disable");
- _primary_path_lock(__func__);
- if (enable) {
- #ifdef CONFIG_MTK_CLKMGR
- ret += disable_clock(MT_CG_DISP1_DSI_ENGINE, "DSI0");
- ret += disable_clock(MT_CG_DISP1_DSI_DIGITAL, "DSI0");
- ret += disable_clock(MT_CG_DISP0_DISP_OVL0, "DDP");
- ret += disable_clock(MT_CG_DISP0_DISP_COLOR, "DDP");
- ret += disable_clock(MT_CG_DISP0_DISP_CCORR, "DDP");
- ret += disable_clock(MT_CG_DISP0_DISP_AAL, "DDP");
- ret += disable_clock(MT_CG_DISP0_DISP_GAMMA, "DDP");
- ret += disable_clock(MT_CG_DISP0_DISP_DITHER, "DDP");
- ret += disable_clock(MT_CG_DISP0_DISP_RDMA0, "DDP");
- ret += disable_clock(MT_CG_PERI_DISP_PWM, "PWM");
- /* ret += disable_clock(MT_CG_DISP0_MUTEX_32K , "Debug"); */
- ret += disable_clock(MT_CG_DISP0_SMI_LARB0, "Debug");
- ret += disable_clock(MT_CG_DISP0_SMI_COMMON, "Debug");
- /* ret += disable_clock(MT_CG_DISP0_MUTEX_32K , "Debug2"); */
- ret += disable_clock(MT_CG_DISP0_SMI_LARB0, "Debug2");
- ret += disable_clock(MT_CG_DISP0_SMI_COMMON, "Debug2");
- #else
- ddp_clk_disable(DISP1_DSI_ENGINE);
- ddp_clk_disable(DISP1_DSI_DIGITAL);
- ddp_clk_disable(DISP0_DISP_OVL0);
- ddp_clk_disable(DISP0_DISP_COLOR);
- ddp_clk_disable(DISP0_DISP_CCORR);
- ddp_clk_disable(DISP0_DISP_AAL);
- ddp_clk_disable(DISP0_DISP_GAMMA);
- ddp_clk_disable(DISP0_DISP_DITHER);
- ddp_clk_disable(DISP0_DISP_RDMA0);
- ddp_clk_disable(DISP_PWM);
- /*ddp_clk_disable(DISP0_MUTEX_32K); */
- ddp_clk_disable(DISP0_SMI_LARB0);
- ddp_clk_disable(DISP0_SMI_COMMON);
- /*ddp_clk_disable(DISP0_MUTEX_32K); */
- ddp_clk_disable(DISP0_SMI_LARB0);
- ddp_clk_disable(DISP0_SMI_COMMON);
- ddp_clk_disable(DISP_MTCMOS_CLK);
- ddp_clk_unprepare(DISP_MTCMOS_CLK);
- #endif
- } else {
- #ifdef CONFIG_MTK_CLKMGR
- ret += enable_clock(MT_CG_DISP1_DSI_ENGINE, "DSI0");
- ret += enable_clock(MT_CG_DISP1_DSI_DIGITAL, "DSI0");
- ret += enable_clock(MT_CG_DISP0_DISP_OVL0, "DDP");
- ret += enable_clock(MT_CG_DISP0_DISP_COLOR, "DDP");
- ret += enable_clock(MT_CG_DISP0_DISP_CCORR, "DDP");
- ret += enable_clock(MT_CG_DISP0_DISP_AAL, "DDP");
- ret += enable_clock(MT_CG_DISP0_DISP_GAMMA, "DDP");
- ret += enable_clock(MT_CG_DISP0_DISP_DITHER, "DDP");
- ret += enable_clock(MT_CG_DISP0_DISP_RDMA0, "DDP");
- ret += enable_clock(MT_CG_PERI_DISP_PWM, "PWM");
- /* ret += enable_clock(MT_CG_DISP0_MUTEX_32K , "Debug"); */
- ret += enable_clock(MT_CG_DISP0_SMI_LARB0, "Debug");
- ret += enable_clock(MT_CG_DISP0_SMI_COMMON, "Debug");
- /* ret += enable_clock(MT_CG_DISP0_MUTEX_32K , "Debug2"); */
- ret += enable_clock(MT_CG_DISP0_SMI_LARB0, "Debug2");
- ret += enable_clock(MT_CG_DISP0_SMI_COMMON, "Debug2");
- #else
- ddp_clk_prepare(DISP_MTCMOS_CLK);
- ret += ddp_clk_enable(DISP_MTCMOS_CLK);
- ret += ddp_clk_enable(DISP1_DSI_ENGINE);
- ret += ddp_clk_enable(DISP1_DSI_DIGITAL);
- ret += ddp_clk_enable(DISP0_DISP_OVL0);
- ret += ddp_clk_enable(DISP0_DISP_COLOR);
- ret += ddp_clk_enable(DISP0_DISP_CCORR);
- ret += ddp_clk_enable(DISP0_DISP_AAL);
- ret += ddp_clk_enable(DISP0_DISP_GAMMA);
- ret += ddp_clk_enable(DISP0_DISP_DITHER);
- ret += ddp_clk_enable(DISP0_DISP_RDMA0);
- ret += ddp_clk_enable(DISP_PWM);
- /*ret += ddp_clk_enable(DISP0_MUTEX_32K); */
- ret += ddp_clk_enable(DISP0_SMI_LARB0);
- ret += ddp_clk_enable(DISP0_SMI_COMMON);
- /*ret += ddp_clk_enable(DISP0_MUTEX_32K); */
- ret += ddp_clk_enable(DISP0_SMI_LARB0);
- ret += ddp_clk_enable(DISP0_SMI_COMMON);
- #endif
- }
- _primary_path_unlock(__func__);
- #endif
- return ret;
- }
- int _set_backlight_by_cmdq(unsigned int level)
- {
- int ret = 0;
- cmdqRecHandle cmdq_handle_backlight = NULL;
- MMProfileLogEx(ddp_mmp_get_events()->primary_set_bl, MMProfileFlagPulse, 1, 1);
- ret = cmdqRecCreate(CMDQ_SCENARIO_PRIMARY_DISP, &cmdq_handle_backlight);
- DISPCHECK("primary backlight, handle=%p\n", cmdq_handle_backlight);
- if (ret != 0) {
- DISPCHECK("fail to create primary cmdq handle for backlight\n");
- return -1;
- }
- if (primary_display_is_video_mode()) {
- MMProfileLogEx(ddp_mmp_get_events()->primary_set_bl, MMProfileFlagPulse, 1, 2);
- cmdqRecReset(cmdq_handle_backlight);
- dpmgr_path_ioctl(pgc->dpmgr_handle, cmdq_handle_backlight, DDP_BACK_LIGHT,
- (unsigned long *)&level);
- _cmdq_flush_config_handle_mira(cmdq_handle_backlight, 1);
- DISPCHECK("[BL]_set_backlight_by_cmdq ret=%d\n", ret);
- } else {
- MMProfileLogEx(ddp_mmp_get_events()->primary_set_bl, MMProfileFlagPulse, 1, 3);
- cmdqRecReset(cmdq_handle_backlight);
- _cmdq_insert_wait_frame_done_token_mira(cmdq_handle_backlight);
- cmdqRecClearEventToken(cmdq_handle_backlight, CMDQ_SYNC_TOKEN_CABC_EOF);
- dpmgr_path_ioctl(pgc->dpmgr_handle, cmdq_handle_backlight, DDP_BACK_LIGHT,
- (unsigned long *)&level);
- cmdqRecSetEventToken(cmdq_handle_backlight, CMDQ_SYNC_TOKEN_CABC_EOF);
- MMProfileLogEx(ddp_mmp_get_events()->primary_set_bl, MMProfileFlagPulse, 1, 4);
- _cmdq_flush_config_handle_mira(cmdq_handle_backlight, 1);
- MMProfileLogEx(ddp_mmp_get_events()->primary_set_bl, MMProfileFlagPulse, 1, 6);
- DISPCHECK("[BL]_set_backlight_by_cmdq ret=%d\n", ret);
- }
- cmdqRecDestroy(cmdq_handle_backlight);
- cmdq_handle_backlight = NULL;
- MMProfileLogEx(ddp_mmp_get_events()->primary_set_bl, MMProfileFlagPulse, 1, 5);
- return ret;
- }
- int _set_backlight_by_cpu(unsigned int level)
- {
- int ret = 0;
- MMProfileLogEx(ddp_mmp_get_events()->primary_set_bl, MMProfileFlagPulse, 0, 1);
- if (primary_display_is_video_mode()) {
- disp_lcm_set_backlight(pgc->plcm, level);
- } else {
- DISPCHECK("[BL]display cmdq trigger loop stop[begin]\n");
- _cmdq_stop_trigger_loop();
- DISPCHECK("[BL]display cmdq trigger loop stop[end]\n");
- if (dpmgr_path_is_busy(pgc->dpmgr_handle)) {
- DISPCHECK("[BL]primary display path is busy\n");
- ret = dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE, HZ * 1);
- DISPCHECK("[BL]wait frame done ret:%d\n", ret);
- }
- DISPCHECK("[BL]stop dpmgr path[begin]\n");
- dpmgr_path_stop(pgc->dpmgr_handle, CMDQ_DISABLE);
- DISPCHECK("[BL]stop dpmgr path[end]\n");
- if (dpmgr_path_is_busy(pgc->dpmgr_handle)) {
- DISPCHECK("[BL]primary display path is busy after stop\n");
- dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE,
- HZ * 1);
- DISPCHECK("[BL]wait frame done ret:%d\n", ret);
- }
- DISPCHECK("[BL]reset display path[begin]\n");
- dpmgr_path_reset(pgc->dpmgr_handle, CMDQ_DISABLE);
- DISPCHECK("[BL]reset display path[end]\n");
- MMProfileLogEx(ddp_mmp_get_events()->primary_set_bl, MMProfileFlagPulse, 0, 2);
- disp_lcm_set_backlight(pgc->plcm, level);
- MMProfileLogEx(ddp_mmp_get_events()->primary_set_bl, MMProfileFlagPulse, 0, 3);
- DISPCHECK("[BL]start dpmgr path[begin]\n");
- dpmgr_path_start(pgc->dpmgr_handle, CMDQ_DISABLE);
- DISPCHECK("[BL]start dpmgr path[end]\n");
- DISPCHECK("[BL]start cmdq trigger loop[begin]\n");
- _cmdq_start_trigger_loop();
- DISPCHECK("[BL]start cmdq trigger loop[end]\n");
- }
- MMProfileLogEx(ddp_mmp_get_events()->primary_set_bl, MMProfileFlagPulse, 0, 7);
- return ret;
- }
- int primary_display_setbacklight(unsigned int level)
- {
- int ret = 0;
- static unsigned int last_level;
- DISPFUNC();
- if (last_level == level)
- return 0;
- MMProfileLogEx(ddp_mmp_get_events()->primary_set_bl, MMProfileFlagStart, 0, 0);
- #ifdef DISP_SWITCH_DST_MODE
- _primary_path_switch_dst_lock();
- #endif
- _primary_path_cmd_lock();
- _primary_path_lock(__func__);
- if (pgc->state == DISP_SLEPT) {
- DISPCHECK("Sleep State set backlight invald\n");
- } else {
- disp_update_trigger_time();
- if (primary_display_cmdq_enabled()) {
- if (primary_display_is_video_mode()) {
- MMProfileLogEx(ddp_mmp_get_events()->primary_set_bl,
- MMProfileFlagPulse, 0, 7);
- disp_lcm_set_backlight(pgc->plcm, level);
- } else {
- #ifdef MTK_DISP_IDLE_LP
- /* CMD mode need to exit top clock off idle mode */
- _disp_primary_path_exit_idle("primary_display_setbacklight", 0);
- #endif
- _set_backlight_by_cmdq(level);
- }
- } else {
- #ifdef MTK_DISP_IDLE_LP
- if (primary_display_is_video_mode() == 0)
- _disp_primary_path_exit_idle("primary_display_setbacklight", 0);
- #endif
- _set_backlight_by_cpu(level);
- }
- last_level = level;
- }
- #ifndef CONFIG_FPGA_EARLY_PORTING
- #ifdef GPIO_LCM_LED_EN
- if (0 == level)
- mt_set_gpio_out(GPIO_LCM_LED_EN, GPIO_OUT_ZERO);
- else
- mt_set_gpio_out(GPIO_LCM_LED_EN, GPIO_OUT_ONE);
- #endif
- #endif
- #if 0 /* check writed success? for test after CABC */
- {
- /* extern uint32_t DSI_dcs_read_lcm_reg_v2(DISP_MODULE_ENUM module, cmdqRecHandle cmdq,
- uint8_t cmd, uint8_t *buffer, uint8_t buffer_size);
- */
- uint8_t buffer[2];
- if (primary_display_is_video_mode())
- dpmgr_path_ioctl(pgc->dpmgr_handle, NULL, DDP_STOP_VIDEO_MODE, NULL);
- DSI_dcs_read_lcm_reg_v2(DISP_MODULE_DSI0, NULL, 0x51, buffer, 1);
- pr_debug("[CABC check result 0x51 = 0x%x,0x%x]\n", buffer[0], buffer[1]);
- dpmgr_path_start(pgc->dpmgr_handle, CMDQ_DISABLE);
- if (primary_display_is_video_mode()) {
- /* for video mode, we need to force trigger here */
- /* for cmd mode, just set DPREC_EVENT_CMDQ_SET_EVENT_ALLOW when trigger loop start */
- dpmgr_path_trigger(pgc->dpmgr_handle, NULL, CMDQ_DISABLE);
- }
- }
- #endif
- _primary_path_unlock(__func__);
- _primary_path_cmd_unlock();
- #ifdef DISP_SWITCH_DST_MODE
- _primary_path_switch_dst_unlock();
- #endif
- MMProfileLogEx(ddp_mmp_get_events()->primary_set_bl, MMProfileFlagEnd, 0, 0);
- return ret;
- }
- int primary_display_set_cmd(int *lcm_cmd, unsigned int cmd_num)
- {
- int ret = 0;
- DISPFUNC();
- _primary_path_cmd_lock();
- _primary_path_lock(__func__);
- if (pgc->state == DISP_SLEPT) {
- DISPCHECK("Sleep State set cmd invald\n");
- } else {
- if (primary_display_cmdq_enabled()) { /* cmdq */
- int ret = 0;
- cmdqRecHandle cmdq_handle_cmd = NULL;
- ret = cmdqRecCreate(CMDQ_SCENARIO_PRIMARY_DISP, &cmdq_handle_cmd);
- DISPCHECK("primary set cmd, handle=%p\n", cmdq_handle_cmd);
- if (ret != 0) {
- DISPCHECK("fail to create primary cmdq handle for cmd\n");
- return -1;
- }
- if (primary_display_is_video_mode()) {
- /* video mode */
- cmdqRecReset(cmdq_handle_cmd);
- disp_lcm_set_cmd(pgc->plcm, (void *)cmdq_handle_cmd, lcm_cmd,
- cmd_num);
- _cmdq_flush_config_handle_mira(cmdq_handle_cmd, 1);
- DISPCHECK("[Display]_set_cmd_by_cmdq ret=%d\n", ret);
- } else {
- /* cmd mode */
- cmdqRecReset(cmdq_handle_cmd);
- _cmdq_insert_wait_frame_done_token_mira(cmdq_handle_cmd);
- cmdqRecClearEventToken(cmdq_handle_cmd, CMDQ_SYNC_TOKEN_CABC_EOF);
- disp_lcm_set_cmd(pgc->plcm, (void *)cmdq_handle_cmd, lcm_cmd,
- cmd_num);
- cmdqRecSetEventToken(cmdq_handle_cmd, CMDQ_SYNC_TOKEN_CABC_EOF);
- _cmdq_flush_config_handle_mira(cmdq_handle_cmd, 1);
- DISPCHECK("[Display]_set_cmd_by_cmdq ret=%d\n", ret);
- }
- cmdqRecDestroy(cmdq_handle_cmd);
- cmdq_handle_cmd = NULL;
- }
- }
- _primary_path_unlock(__func__);
- _primary_path_cmd_unlock();
- return ret;
- }
- #define LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
- /***********************/
- /*****Legacy DISP API*****/
- /***********************/
- uint32_t DISP_GetScreenWidth(void)
- {
- return primary_display_get_width();
- }
- uint32_t DISP_GetScreenHeight(void)
- {
- return primary_display_get_height();
- }
- uint32_t DISP_GetActiveHeight(void)
- {
- if (pgc->plcm == NULL) {
- DISPERR("lcm handle is null\n");
- return 0;
- }
- if (pgc->plcm->params)
- return pgc->plcm->params->physical_height;
- DISPERR("lcm_params is null!\n");
- return 0;
- }
- uint32_t DISP_GetActiveWidth(void)
- {
- if (pgc->plcm == NULL) {
- DISPERR("lcm handle is null\n");
- return 0;
- }
- if (pgc->plcm->params)
- return pgc->plcm->params->physical_width;
- DISPERR("lcm_params is null!\n");
- return 0;
- }
- LCM_PARAMS *DISP_GetLcmPara(void)
- {
- if (pgc->plcm == NULL) {
- DISPERR("lcm handle is null\n");
- return NULL;
- }
- if (pgc->plcm->params)
- return pgc->plcm->params;
- else
- return NULL;
- }
- LCM_DRIVER *DISP_GetLcmDrv(void)
- {
- if (pgc->plcm == NULL) {
- DISPERR("lcm handle is null\n");
- return NULL;
- }
- if (pgc->plcm->drv)
- return pgc->plcm->drv;
- else
- return NULL;
- }
- int primary_display_capture_framebuffer_decouple(unsigned long pbuf, unsigned int format)
- {
- unsigned int i = 0;
- int ret = 0;
- disp_ddp_path_config *pconfig = NULL;
- m4u_client_t *m4uClient = NULL;
- unsigned int mva = 0;
- unsigned long va = 0;
- unsigned int mapped_size = 0;
- unsigned int w_xres = primary_display_get_width();
- unsigned int h_yres = primary_display_get_height();
- unsigned int pixel_byte = primary_display_get_dc_bpp() / 8;/* bpp is either 32 or 16, can not be other value */
- unsigned int pitch = 0;
- int buffer_size = h_yres * w_xres * pixel_byte;
- m4uClient = m4u_create_client();
- if (m4uClient == NULL) {
- DISPCHECK("primary capture:Fail to alloc m4uClient=0x%p\n", m4uClient);
- ret = -1;
- goto out;
- }
- /* mva = pgc->dc_buf[pgc->dc_buf_id]; */
- pconfig = dpmgr_path_get_last_config(pgc->dpmgr_handle);
- if (_is_decouple_mode(pgc->session_mode) && !_is_mirror_mode(pgc->session_mode)) {
- w_xres = decouple_wdma_config.srcWidth;
- h_yres = decouple_wdma_config.srcHeight;
- pitch = decouple_wdma_config.dstPitch;
- mva = decouple_wdma_config.dstAddress;
- } else {
- w_xres = pconfig->wdma_config.srcWidth;
- h_yres = pconfig->wdma_config.srcHeight;
- pitch = pconfig->wdma_config.dstPitch;
- mva = pconfig->wdma_config.dstAddress;
- }
- buffer_size = h_yres * pitch;
- ASSERT((pitch / 4) >= w_xres);
- /* dpmgr_get_input_address(pgc->dpmgr_handle,&mva); */
- m4u_mva_map_kernel(mva, buffer_size, &va, &mapped_size);
- if (!va) {
- DISPERR("map mva 0x%08x failed\n", mva);
- goto out;
- }
- DISPMSG("map 0x%08x with %d bytes to 0x%08lx with %d bytes\n", mva, buffer_size, va,
- mapped_size);
- ret =
- m4u_cache_sync(m4uClient, M4U_PORT_DISP_WDMA0, va, buffer_size, mva,
- M4U_CACHE_FLUSH_ALL);
- #if 1
- {
- unsigned int j = 0;
- unsigned char tem_va[4];
- unsigned long src_va = va;
- for (i = 0; i < h_yres; i++) {
- for (j = 0; j < w_xres; j++) {
- memcpy((void *)tem_va, (void *)src_va, 4);
- *(unsigned long *)(pbuf + (i * w_xres + j) * 4) = 0xFF000000 | (tem_va[0] << 16) |
- (tem_va[1] << 8) | (tem_va[2]);
- src_va += 4;
- }
- src_va += (pitch - w_xres * 4);
- }
- }
- #else
- memcpy(pbuf, va, mapped_size);
- #endif
- out:
- if (mapped_size)
- m4u_mva_unmap_kernel(mva, mapped_size, va);
- if (m4uClient != NULL)
- m4u_destroy_client(m4uClient);
- DISPMSG("primary capture: end\n");
- return ret;
- }
- int primary_display_capture_framebuffer_ovl(unsigned long pbuf, unsigned int format)
- {
- int ret = 0;
- cmdqRecHandle cmdq_handle = NULL;
- cmdqRecHandle cmdq_wait_handle = NULL;
- disp_ddp_path_config *pconfig = NULL;
- m4u_client_t *m4uClient = NULL;
- unsigned int mva = 0;
- unsigned int w_xres = primary_display_get_width();
- unsigned int h_yres = primary_display_get_height();
- unsigned int pixel_byte = primary_display_get_dc_bpp() / 8; /* bpp is either 32 or 16, can not be other value */
- int buffer_size = h_yres * w_xres * pixel_byte;
- DISPMSG("primary capture: begin\n");
- disp_sw_mutex_lock(&(pgc->capture_lock));
- _primary_path_lock(__func__);
- if (pgc->state == DISP_SLEPT) {
- /*memset_io((void *)pbuf, 0, buffer_size);*/
- DISPMSG("primary capture:fill black for sleep\n");
- goto out;
- }
- if (!primary_display_cmdq_enabled()) {
- /*memset_io((void *)pbuf, 0, buffer_size);*/
- DISPMSG("primary capture:fill black to cmdq disable\n");
- goto out;
- }
- if (_is_decouple_mode(pgc->session_mode) || _is_mirror_mode(pgc->session_mode)) {
- primary_display_capture_framebuffer_decouple(pbuf, format);
- /*memset_io((void *)pbuf, 0, buffer_size);*/
- DISPMSG("primary capture: fill black for decouple & mirror mode End\n");
- goto out;
- }
- m4uClient = m4u_create_client();
- if (m4uClient == NULL) {
- DISPCHECK("primary capture:Fail to alloc m4uClient=0x%p\n", m4uClient);
- ret = -1;
- goto out;
- }
- ret = m4u_alloc_mva(m4uClient, M4U_PORT_DISP_WDMA0, pbuf, NULL, buffer_size,
- M4U_PROT_READ | M4U_PROT_WRITE, 0, (unsigned int *)&mva);
- if (ret != 0) {
- DISPCHECK("primary capture:Fail to allocate mva\n");
- ret = -1;
- goto out;
- }
- ret = m4u_cache_sync(m4uClient, M4U_PORT_DISP_WDMA0, pbuf, buffer_size, mva,
- M4U_CACHE_FLUSH_BY_RANGE);
- if (ret != 0) {
- DISPCHECK("primary capture:Fail to cach sync\n");
- ret = -1;
- goto out;
- }
- if (primary_display_cmdq_enabled()) {
- /* create config thread */
- ret = cmdqRecCreate(CMDQ_SCENARIO_PRIMARY_DISP, &cmdq_handle);
- if (ret != 0) {
- DISPCHECK("primary capture:Fail to create primary cmdq handle for capture\n");
- ret = -1;
- goto out;
- }
- cmdqRecReset(cmdq_handle);
- /* create wait thread */
- ret = cmdqRecCreate(CMDQ_SCENARIO_DISP_SCREEN_CAPTURE, &cmdq_wait_handle);
- if (ret != 0) {
- DISPCHECK("primary capture:Fail to create primary cmdq wait handle for capture\n");
- ret = -1;
- goto out;
- }
- cmdqRecReset(cmdq_wait_handle);
- /* configure config thread */
- _cmdq_insert_wait_frame_done_token_mira(cmdq_handle);
- dpmgr_path_memout_clock(pgc->dpmgr_handle, 1);
- pconfig = dpmgr_path_get_last_config(pgc->dpmgr_handle);
- pconfig->wdma_dirty = 1;
- pconfig->wdma_config.dstAddress = mva;
- pconfig->wdma_config.srcHeight = h_yres;
- pconfig->wdma_config.srcWidth = w_xres;
- pconfig->wdma_config.clipX = 0;
- pconfig->wdma_config.clipY = 0;
- pconfig->wdma_config.clipHeight = h_yres;
- pconfig->wdma_config.clipWidth = w_xres;
- pconfig->wdma_config.outputFormat = format;
- pconfig->wdma_config.useSpecifiedAlpha = 1;
- pconfig->wdma_config.alpha = 0xFF;
- pconfig->wdma_config.dstPitch = w_xres * DP_COLOR_BITS_PER_PIXEL(format) / 8;
- dpmgr_path_add_memout(pgc->dpmgr_handle, ENGINE_OVL0, cmdq_handle);
- #if 0 /* do not have to call enable_cascade here, dpmgr_path_add_memout() will add ovl1 if necessary */
- if (ovl_get_status() == DDP_OVL1_STATUS_IDLE || ovl_get_status() == DDP_OVL1_STATUS_PRIMARY) {
- DISPMSG("dpmgr_path_enable_cascade called!\n");
- dpmgr_path_enable_cascade(pgc->dpmgr_handle, cmdq_handle);
- if (ovl_get_status() != DDP_OVL1_STATUS_PRIMARY)
- pconfig->ovl_dirty = 1;
- }
- #endif
- ret = dpmgr_path_config(pgc->dpmgr_handle, pconfig, cmdq_handle);
- pconfig->wdma_dirty = 0;
- _cmdq_set_config_handle_dirty_mira(cmdq_handle);
- _cmdq_flush_config_handle_mira(cmdq_handle, 0);
- DISPMSG("primary capture:Flush add memout mva(0x%x)\n", mva);
- /* primary_display_diagnose(); */
- /* wait wdma0 sof */
- cmdqRecWait(cmdq_wait_handle, CMDQ_EVENT_DISP_WDMA0_SOF);
- cmdqRecFlush(cmdq_wait_handle);
- DISPMSG("primary capture:Flush wait wdma sof\n");
- cmdqRecReset(cmdq_handle);
- _cmdq_insert_wait_frame_done_token_mira(cmdq_handle);
- dpmgr_path_remove_memout(pgc->dpmgr_handle, cmdq_handle);
- cmdqRecClearEventToken(cmdq_handle, CMDQ_EVENT_DISP_WDMA0_SOF);
- _cmdq_set_config_handle_dirty_mira(cmdq_handle);
- /* flush remove memory to cmdq */
- _cmdq_flush_config_handle_mira(cmdq_handle, 1);
- DISPMSG("primary capture: Flush remove memout\n");
- dpmgr_path_memout_clock(pgc->dpmgr_handle, 0);
- }
- out:
- cmdqRecDestroy(cmdq_handle);
- cmdqRecDestroy(cmdq_wait_handle);
- if (mva > 0)
- m4u_dealloc_mva(m4uClient, M4U_PORT_DISP_WDMA0, mva);
- if (m4uClient != 0)
- m4u_destroy_client(m4uClient);
- _primary_path_unlock(__func__);
- disp_sw_mutex_unlock(&(pgc->capture_lock));
- DISPMSG("primary capture: end\n");
- return ret;
- }
- int primary_display_capture_framebuffer(unsigned long pbuf)
- {
- #if 1
- unsigned int fb_layer_id = primary_display_get_option("FB_LAYER");
- unsigned int w_xres = primary_display_get_width();
- unsigned int h_yres = primary_display_get_height();
- /* bpp is either 32 or 16, can not be other value */
- unsigned int pixel_bpp = primary_display_get_dc_bpp() / 8;
- unsigned int w_fb = ALIGN_TO(w_xres, MTK_FB_ALIGNMENT);
- unsigned int fbsize = w_fb * h_yres * pixel_bpp; /* frame buffer size */
- unsigned long fbaddress = dpmgr_path_get_last_config(pgc->dpmgr_handle)->ovl_config[fb_layer_id].addr;
- unsigned long fbv = 0;
- unsigned int i = 0;
- unsigned long ttt = 0;
- DISPMSG("w_res=%d, h_yres=%d, pixel_bpp=%d, w_fb=%d, fbsize=%d, fbaddress=0x%lx\n",
- w_xres, h_yres, pixel_bpp, w_fb, fbsize, fbaddress);
- fbv = (unsigned long)ioremap(fbaddress, fbsize);
- DISPMSG("w_xres = %d, h_yres = %d, w_fb = %d, pixel_bpp = %d, fbsize = %d, fbaddress = 0x%lx\n",
- w_xres, h_yres, w_fb, pixel_bpp, fbsize, fbaddress);
- if (!fbv) {
- DISPMSG("[FB Driver], Unable to allocate memory for frame buffer: address=0x%lx, size=0x%08x\n",
- fbaddress, fbsize);
- return -1;
- }
- ttt = get_current_time_us();
- for (i = 0; i < h_yres; i++) {
- /* DISPMSG("i=%d, dst=0x%08x, src=%08x\n",
- i, (pbuf + i * w_xres * pixel_bpp), (fbv + i * w_fb * pixel_bpp));
- */
- memcpy((void *)(pbuf + i * w_xres * pixel_bpp),
- (void *)(fbv + i * w_fb * pixel_bpp), w_xres * pixel_bpp);
- }
- DISPMSG("capture framebuffer cost %ld us\n", get_current_time_us() - ttt);
- iounmap((void *)fbv);
- #endif
- return -1;
- }
- uint32_t DISP_GetPanelBPP(void)
- {
- #if 0
- PANEL_COLOR_FORMAT fmt;
- disp_drv_init_context();
- if (disp_if_drv->get_panel_color_format == NULL)
- return DISP_STATUS_NOT_IMPLEMENTED;
- fmt = disp_if_drv->get_panel_color_format();
- switch (fmt) {
- case PANEL_COLOR_FORMAT_RGB332:
- return 8;
- case PANEL_COLOR_FORMAT_RGB444:
- return 12;
- case PANEL_COLOR_FORMAT_RGB565:
- return 16;
- case PANEL_COLOR_FORMAT_RGB666:
- return 18;
- case PANEL_COLOR_FORMAT_RGB888:
- return 24;
- default:
- return 0;
- }
- #else
- return 0; /* avoid build warning */
- #endif
- }
- static uint32_t disp_fb_bpp = 32;
- static uint32_t disp_fb_pages = 3;
- uint32_t DISP_GetScreenBpp(void)
- {
- return disp_fb_bpp;
- }
- uint32_t DISP_GetPages(void)
- {
- return disp_fb_pages;
- }
- uint32_t DISP_GetFBRamSize(void)
- {
- return ALIGN_TO(DISP_GetScreenWidth(), MTK_FB_ALIGNMENT) * DISP_GetScreenHeight() *
- ((DISP_GetScreenBpp() + 7) >> 3) * DISP_GetPages();
- }
- uint32_t DISP_GetVRamSize(void)
- {
- #if 0
- /* Use a local static variable to cache the calculated vram size */
- /* */
- static uint32_t vramSize;
- if (0 == vramSize) {
- disp_drv_init_context();
- /* /get framebuffer size */
- vramSize = DISP_GetFBRamSize();
- /* /get DXI working buffer size */
- vramSize += disp_if_drv->get_working_buffer_size();
- /* get assertion layer buffer size */
- vramSize += DAL_GetLayerSize();
- /* Align vramSize to 1MB */
- /* */
- vramSize = ALIGN_TO_POW_OF_2(vramSize, 0x100000);
- DISP_LOG("DISP_GetVRamSize: %u bytes\n", vramSize);
- }
- return vramSize;
- #else
- return 0; /* avoid build warning */
- #endif
- }
- uint32_t DISP_GetVRamSizeBoot(char *cmdline)
- {
- #ifdef CONFIG_OF
- /* extern unsigned int vramsize; */
- /* extern int _parse_tag_videolfb(void); */
- _parse_tag_videolfb();
- if (vramsize == 0)
- vramsize = 0x3000000;
- /* not necessary */
- /* DISPCHECK("[DT]display vram size = 0x%08x|%d\n", vramsize, vramsize); */
- return vramsize;
- #else
- int ret = 0;
- char *p = NULL;
- uint32_t vramSize = 0;
- DISPMSG("%s, cmdline=%s\n", __func__, cmdline);
- p = strstr(cmdline, "vram=");
- if (p == NULL) {
- vramSize = 0x3000000;
- DISPERR("[FB driver]can not get vram size from lk\n");
- } else {
- p += 5;
- ret = kstrtol(p, 10, &vramSize);
- if (ret)
- pr_err("DISP/%s: errno %d\n", __func__, ret);
- if (0 == vramSize)
- vramSize = 0x3000000;
- }
- DISPCHECK("display vram size = 0x%08x|%d\n", vramSize, vramSize);
- return vramSize;
- #endif
- }
- struct sg_table table;
- int disp_hal_allocate_framebuffer(phys_addr_t pa_start, phys_addr_t pa_end, unsigned long *va,
- unsigned long *mva)
- {
- #ifndef MTKFB_NO_M4U
- int ret = 0;
- #endif
- *va = (unsigned long)ioremap_nocache(pa_start, pa_end - pa_start + 1);
- /* printk("disphal_allocate_fb, pa=%p, va=0x%lx\n", &pa_start, *va); */
- /* if (_get_init_setting("M4U")) */
- /* xuecheng, m4u not enabled now */
- #ifndef MTKFB_NO_M4U
- if (1) {
- m4u_client_t *client;
- struct sg_table *sg_table = &table;
- sg_alloc_table(sg_table, 1, GFP_KERNEL);
- sg_dma_address(sg_table->sgl) = pa_start;
- sg_dma_len(sg_table->sgl) = (pa_end - pa_start + 1);
- client = m4u_create_client();
- if (IS_ERR_OR_NULL(client))
- DISPMSG("create client fail!\n");
- *mva = pa_start & 0xffffffffULL;
- ret = m4u_alloc_mva(client, M4U_PORT_DISP_OVL0, 0, sg_table, (pa_end - pa_start + 1),
- M4U_PROT_READ | M4U_PROT_WRITE, M4U_FLAGS_FIX_MVA,
- (unsigned int *)mva);
- /* m4u_alloc_mva(M4U_PORT_DISP_OVL0, pa_start, (pa_end - pa_start + 1), 0, 0, mva); */
- if (ret)
- DISPMSG("m4u_alloc_mva returns fail: %d\n", ret);
- /* printk("[DISPHAL] FB MVA is 0x%lx PA is %p\n", *mva, &pa_start);*/
- } else
- #endif
- {
- *mva = pa_start & 0xffffffffULL;
- }
- return 0;
- }
- int primary_display_remap_irq_event_map(void)
- {
- return 0; /* avoid build warning. */
- }
- unsigned int primary_display_get_option(const char *option)
- {
- if (!strcmp(option, "FB_LAYER"))
- return 0;
- if (!strcmp(option, "ASSERT_LAYER")) {
- #ifdef OVL_CASCADE_SUPPORT
- if (ovl_get_status() == DDP_OVL1_STATUS_PRIMARY
- || ovl_get_status() == DDP_OVL1_STATUS_IDLE)
- return OVL_LAYER_NUM - 1;
- else
- return OVL_LAYER_NUM - 4 - 1;
- #else
- return OVL_LAYER_NUM - 1;
- #endif
- }
- if (!strcmp(option, "M4U_ENABLE"))
- return 1;
- ASSERT(0);
- return 0; /* avoid build warning */
- }
- int primary_display_get_debug_info(char *buf)
- {
- /* resolution */
- /* cmd/video mode */
- /* display path */
- /* dsi data rate/lane number/state */
- /* primary path trigger count */
- /* frame done count */
- /* suspend/resume count */
- /* current fps 10s/5s/1s */
- /* error count and message */
- /* current state of each module on the path */
- return 0; /* avoid build warning */
- }
- #include "ddp_reg.h"
- #define IS_READY(x) ((x)?"READY\t":"Not READY")
- #define IS_VALID(x) ((x)?"VALID\t":"Not VALID")
- #define READY_BIT0(x) ((DISP_REG_GET(DISPSYS_CONFIG_BASE + 0x8a0) & (1 << x)))
- #define VALID_BIT0(x) ((DISP_REG_GET(DISPSYS_CONFIG_BASE + 0x8a4) & (1 << x)))
- #define READY_BIT1(x) ((DISP_REG_GET(DISPSYS_CONFIG_BASE + 0x8a8) & (1 << x)))
- #define VALID_BIT1(x) ((DISP_REG_GET(DISPSYS_CONFIG_BASE + 0x8ac) & (1 << x)))
- int primary_display_check_path(char *stringbuf, int buf_len)
- {
- return 0; /* status will print in config dump. */
- #if 0
- int len = 0;
- DISPMSG("primary_display_check_path() check signal status:\n");
- if (stringbuf) {
- len +=
- scnprintf(stringbuf + len, buf_len - len,
- "|--------------------------------------------------------------------------------------|\n");
- len +=
- scnprintf(stringbuf + len, buf_len - len,
- "READY0=0x%08x, READY1=0x%08x, VALID0=0x%08x, VALID1=0x%08x\n",
- DISP_REG_GET(DISPSYS_CONFIG_BASE + 0x8a0),
- DISP_REG_GET(DISPSYS_CONFIG_BASE + 0x8a4),
- DISP_REG_GET(DISPSYS_CONFIG_BASE + 0x8a8),
- DISP_REG_GET(DISPSYS_CONFIG_BASE + 0x8ac));
- len +=
- scnprintf(stringbuf + len, buf_len - len, "OVL0\t\t\t%s\t%s\n",
- IS_READY(READY_BIT0(DDP_SIGNAL_OVL0__OVL0_MOUT)),
- IS_VALID(READY_BIT0(DDP_SIGNAL_OVL0__OVL0_MOUT)));
- len +=
- scnprintf(stringbuf + len, buf_len - len, "OVL0_MOUT:\t\t%s\t%s\n",
- IS_READY(READY_BIT1(DDP_SIGNAL_OVL0_MOUT0__COLOR_SIN1)),
- IS_VALID(READY_BIT1(DDP_SIGNAL_OVL0_MOUT0__COLOR_SIN1)));
- len +=
- scnprintf(stringbuf + len, buf_len - len, "COLOR0_SEL:\t\t%s\t%s\n",
- IS_READY(READY_BIT0(DDP_SIGNAL_COLOR_SEL__COLOR)),
- IS_VALID(READY_BIT0(DDP_SIGNAL_COLOR_SEL__COLOR)));
- len +=
- scnprintf(stringbuf + len, buf_len - len, "COLOR0:\t\t\t%s\t%s\n",
- IS_READY(READY_BIT0(DDP_SIGNAL_COLOR__CCORR)),
- IS_VALID(READY_BIT0(DDP_SIGNAL_COLOR__CCORR)));
- len +=
- scnprintf(stringbuf + len, buf_len - len, "CCORR:\t\t%s\t%s\n",
- IS_READY(READY_BIT0(DDP_SIGNAL_CCORR__AAL)),
- IS_VALID(READY_BIT0(DDP_SIGNAL_CCORR__AAL)));
- len +=
- scnprintf(stringbuf + len, buf_len - len, "AAL0:\t\t\t%s\t%s\n",
- IS_READY(READY_BIT0(DDP_SIGNAL_AAL__GAMMA)),
- IS_VALID(READY_BIT0(DDP_SIGNAL_AAL__GAMMA)));
- len +=
- scnprintf(stringbuf + len, buf_len - len, "GAMMA:\t\t\t%s\t%s\n",
- IS_READY(READY_BIT1(DDP_SIGNAL_GAMMA__DITHER)),
- IS_VALID(READY_BIT1(DDP_SIGNAL_GAMMA__DITHER)));
- len +=
- scnprintf(stringbuf + len, buf_len - len, "DITHER:\t\t\t%s\t%s\n",
- IS_READY(READY_BIT1(DDP_SIGNAL_DITHER__DITHER_MOUT)),
- IS_VALID(READY_BIT1(DDP_SIGNAL_DITHER__DITHER_MOUT)));
- len +=
- scnprintf(stringbuf + len, buf_len - len, "DITHER_MOUT:\t\t%s\t%s\n",
- IS_READY(READY_BIT1(DDP_SIGNAL_DITHER_MOUT0__RDMA0)),
- IS_VALID(READY_BIT1(DDP_SIGNAL_DITHER_MOUT0__RDMA0)));
- len +=
- scnprintf(stringbuf + len, buf_len - len, "RDMA0:\t\t\t%s\t%s\n",
- IS_READY(READY_BIT1(DDP_SIGNAL_RDMA0__RDMA0_SOUT)),
- IS_VALID(READY_BIT1(DDP_SIGNAL_RDMA0__RDMA0_SOUT)));
- len +=
- scnprintf(stringbuf + len, buf_len - len, "RDMA0_SOUT:\t\t%s\t%s\n",
- IS_READY(READY_BIT1(DDP_SIGNAL_RDMA0_SOUT0__UFOE_SIN0)),
- IS_VALID(READY_BIT1(DDP_SIGNAL_RDMA0_SOUT0__UFOE_SIN0)));
- len +=
- scnprintf(stringbuf + len, buf_len - len, "UFOE_SEL:\t\t%s\t%s\n",
- IS_READY(READY_BIT0(DDP_SIGNAL_UFOE_SEL__UFOE)),
- IS_VALID(READY_BIT0(DDP_SIGNAL_UFOE_SEL__UFOE)));
- len +=
- scnprintf(stringbuf + len, buf_len - len, "UFOE:\t\t\t%s\t%s\n",
- IS_READY(READY_BIT0(DDP_SIGNAL_UFOE__UFOE_MOUT)),
- IS_VALID(READY_BIT0(DDP_SIGNAL_UFOE__UFOE_MOUT)));
- len +=
- scnprintf(stringbuf + len, buf_len - len, "UFOE_MOUT:\t\t%s\t%s\n",
- IS_READY(READY_BIT0(DDP_SIGNAL_UFOE_MOUT0__DSI0_SIN0)),
- IS_VALID(READY_BIT0(DDP_SIGNAL_UFOE_MOUT0__DSI0_SIN0)));
- len +=
- scnprintf(stringbuf + len, buf_len - len, "DSI0_SEL:\t\t%s\t%s\n",
- IS_READY(READY_BIT1(DDP_SIGNAL_DIS0_SEL__DSI0)),
- IS_VALID(READY_BIT1(DDP_SIGNAL_DIS0_SEL__DSI0)));
- } else {
- DISPMSG
- ("|--------------------------------------------------------------------------------------|\n");
- DISPMSG("READY0=0x%08x, READY1=0x%08x, VALID0=0x%08x, VALID1=0x%08x\n",
- DISP_REG_GET(DISPSYS_CONFIG_BASE + 0x8a0),
- DISP_REG_GET(DISPSYS_CONFIG_BASE + 0x8a4),
- DISP_REG_GET(DISPSYS_CONFIG_BASE + 0x8a8),
- DISP_REG_GET(DISPSYS_CONFIG_BASE + 0x8ac));
- DISPMSG("OVL0\t\t\t%s\t%s\n", IS_READY(READY_BIT0(DDP_SIGNAL_OVL0__OVL0_MOUT)),
- IS_VALID(READY_BIT0(DDP_SIGNAL_OVL0__OVL0_MOUT)));
- DISPMSG("OVL0_MOUT:\t\t%s\t%s\n",
- IS_READY(READY_BIT1(DDP_SIGNAL_OVL0_MOUT0__COLOR_SIN1)),
- IS_VALID(READY_BIT1(DDP_SIGNAL_OVL0_MOUT0__COLOR_SIN1)));
- DISPMSG("COLOR0_SEL:\t\t%s\t%s\n",
- IS_READY(READY_BIT0(DDP_SIGNAL_COLOR_SEL__COLOR)),
- IS_VALID(READY_BIT0(DDP_SIGNAL_COLOR_SEL__COLOR)));
- DISPMSG("COLOR0:\t\t\t%s\t%s\n", IS_READY(READY_BIT0(DDP_SIGNAL_COLOR__CCORR)),
- IS_VALID(READY_BIT0(DDP_SIGNAL_COLOR__CCORR)));
- DISPMSG("CCORR:\t\t%s\t%s\n", IS_READY(READY_BIT0(DDP_SIGNAL_CCORR__AAL)),
- IS_VALID(READY_BIT0(DDP_SIGNAL_CCORR__AAL)));
- DISPMSG("AAL0:\t\t\t%s\t%s\n", IS_READY(READY_BIT0(DDP_SIGNAL_AAL__GAMMA)),
- IS_VALID(READY_BIT0(DDP_SIGNAL_AAL__GAMMA)));
- DISPMSG("GAMMA:\t\t\t%s\t%s\n", IS_READY(READY_BIT1(DDP_SIGNAL_GAMMA__DITHER)),
- IS_VALID(READY_BIT1(DDP_SIGNAL_GAMMA__DITHER)));
- DISPMSG("DITHER:\t\t\t%s\t%s\n",
- IS_READY(READY_BIT1(DDP_SIGNAL_DITHER__DITHER_MOUT)),
- IS_VALID(READY_BIT1(DDP_SIGNAL_DITHER__DITHER_MOUT)));
- DISPMSG("DITHER_MOUT:\t\t%s\t%s\n",
- IS_READY(READY_BIT1(DDP_SIGNAL_DITHER_MOUT0__RDMA0)),
- IS_VALID(READY_BIT1(DDP_SIGNAL_DITHER_MOUT0__RDMA0)));
- DISPMSG("RDMA0:\t\t\t%s\t%s\n", IS_READY(READY_BIT1(DDP_SIGNAL_RDMA0__RDMA0_SOUT)),
- IS_VALID(READY_BIT1(DDP_SIGNAL_RDMA0__RDMA0_SOUT)));
- DISPMSG("RDMA0_SOUT:\t\t%s\t%s\n",
- IS_READY(READY_BIT1(DDP_SIGNAL_RDMA0_SOUT0__UFOE_SIN0)),
- IS_VALID(READY_BIT1(DDP_SIGNAL_RDMA0_SOUT0__UFOE_SIN0)));
- DISPMSG("UFOE_SEL:\t\t%s\t%s\n", IS_READY(READY_BIT0(DDP_SIGNAL_UFOE_SEL__UFOE)),
- IS_VALID(READY_BIT0(DDP_SIGNAL_UFOE_SEL__UFOE)));
- DISPMSG("UFOE:\t\t\t%s\t%s\n", IS_READY(READY_BIT0(DDP_SIGNAL_UFOE__UFOE_MOUT)),
- IS_VALID(READY_BIT0(DDP_SIGNAL_UFOE__UFOE_MOUT)));
- DISPMSG("UFOE_MOUT:\t\t%s\t%s\n",
- IS_READY(READY_BIT0(DDP_SIGNAL_UFOE_MOUT0__DSI0_SIN0)),
- IS_VALID(READY_BIT0(DDP_SIGNAL_UFOE_MOUT0__DSI0_SIN0)));
- DISPMSG("DSI0_SEL:\t\t%s\t%s\n", IS_READY(READY_BIT1(DDP_SIGNAL_DIS0_SEL__DSI0)),
- IS_VALID(READY_BIT1(DDP_SIGNAL_DIS0_SEL__DSI0)));
- }
- return len;
- #endif
- }
- int primary_display_lcm_ATA(void)
- {
- DISP_STATUS ret = DISP_STATUS_OK;
- DISPFUNC();
- _primary_path_lock(__func__);
- if (pgc->state == 0) {
- DISPCHECK("ATA_LCM, primary display path is already sleep, skip\n");
- goto done;
- }
- DISPCHECK("[ATA_LCM]primary display path stop[begin]\n");
- if (primary_display_is_video_mode())
- dpmgr_path_ioctl(pgc->dpmgr_handle, NULL, DDP_STOP_VIDEO_MODE, NULL);
- DISPCHECK("[ATA_LCM]primary display path stop[end]\n");
- ret = disp_lcm_ATA(pgc->plcm);
- dpmgr_path_start(pgc->dpmgr_handle, CMDQ_DISABLE);
- /* for video mode, we need to force trigger here
- * for cmd mode, just set DPREC_EVENT_CMDQ_SET_EVENT_ALLOW when trigger loop start
- */
- if (primary_display_is_video_mode())
- dpmgr_path_trigger(pgc->dpmgr_handle, NULL, CMDQ_DISABLE);
- done:
- _primary_path_unlock(__func__);
- return ret;
- }
- int fbconfig_get_esd_check_test(uint32_t dsi_id, uint32_t cmd, uint8_t *buffer, uint32_t num)
- {
- int ret = 0;
- /* extern int fbconfig_get_esd_check(DSI_INDEX dsi_id, uint32_t cmd, uint8_t *buffer, uint32_t num); */
- _primary_path_lock(__func__);
- if (pgc->state == DISP_SLEPT) {
- DISPCHECK("[ESD]primary display path is slept?? -- skip esd check\n");
- _primary_path_unlock(__func__);
- goto done;
- }
- /* primary_display_esd_check_enable(0); */
- /* / 1: stop path */
- _cmdq_stop_trigger_loop();
- if (dpmgr_path_is_busy(pgc->dpmgr_handle))
- DISPCHECK("[ESD]wait frame done ret:%d\n", ret);
- dpmgr_path_stop(pgc->dpmgr_handle, CMDQ_DISABLE);
- DISPCHECK("[ESD]stop dpmgr path[end]\n");
- if (dpmgr_path_is_busy(pgc->dpmgr_handle))
- DISPCHECK("[ESD]wait frame done ret:%d\n", ret);
- /* dpmgr_path_reset(pgc->dpmgr_handle, CMDQ_DISABLE); */
- ret = fbconfig_get_esd_check(dsi_id, cmd, buffer, num);
- dpmgr_path_start(pgc->dpmgr_handle, CMDQ_DISABLE);
- DISPCHECK("[ESD]start dpmgr path[end]\n");
- if (primary_display_is_video_mode()) {
- /* for video mode, we need to force trigger here */
- /* for cmd mode, just set DPREC_EVENT_CMDQ_SET_EVENT_ALLOW when trigger loop start */
- dpmgr_path_trigger(pgc->dpmgr_handle, NULL, CMDQ_DISABLE);
- }
- _cmdq_start_trigger_loop();
- DISPCHECK("[ESD]start cmdq trigger loop[end]\n");
- _primary_path_unlock(__func__);
- done:
- return ret;
- }
- int Panel_Master_dsi_config_entry(const char *name, void *config_value)
- {
- int ret = 0;
- int force_trigger_path = 0;
- uint32_t *config_dsi = (uint32_t *)config_value;
- LCM_PARAMS *lcm_param = NULL;
- LCM_DRIVER *pLcm_drv = NULL;
- int esd_check_backup = 0;
- DISPFUNC();
- pLcm_drv = DISP_GetLcmDrv();
- esd_check_backup = atomic_read(&esd_check_task_wakeup);
- if (!strcmp(name, "DRIVER_IC_RESET") || !strcmp(name, "PM_DDIC_CONFIG")) {
- primary_display_esd_check_enable(0);
- msleep(2500);
- }
- _primary_path_lock(__func__);
- lcm_param = disp_lcm_get_params(pgc->plcm);
- if (pgc->state == DISP_SLEPT) {
- DISPERR("[Pmaster]Panel_Master: primary display path is slept??\n");
- goto done;
- }
- /* / Esd Check : Read from lcm */
- /* / the following code is to */
- /* / 0: lock path */
- /* / 1: stop path */
- /* / 2: do esd check (!!!) */
- /* / 3: start path */
- /* / 4: unlock path */
- /* / 1: stop path */
- _cmdq_stop_trigger_loop();
- if (dpmgr_path_is_busy(pgc->dpmgr_handle))
- DISPCHECK("[ESD]wait frame done ret:%d\n", ret);
- dpmgr_path_stop(pgc->dpmgr_handle, CMDQ_DISABLE);
- DISPCHECK("[ESD]stop dpmgr path[end]\n");
- if (dpmgr_path_is_busy(pgc->dpmgr_handle))
- DISPCHECK("[ESD]wait frame done ret:%d\n", ret);
- dpmgr_path_reset(pgc->dpmgr_handle, CMDQ_DISABLE);
- if ((!strcmp(name, "PM_CLK")) || (!strcmp(name, "PM_SSC")))
- Panel_Master_primary_display_config_dsi(name, *config_dsi);
- else if (!strcmp(name, "PM_DDIC_CONFIG")) {
- Panel_Master_DDIC_config();
- force_trigger_path = 1;
- } else if (!strcmp(name, "DRIVER_IC_RESET")) {
- if (pLcm_drv && pLcm_drv->init_power)
- pLcm_drv->init_power();
- if (pLcm_drv)
- pLcm_drv->init();
- else
- ret = -1;
- force_trigger_path = 1;
- }
- dpmgr_path_start(pgc->dpmgr_handle, CMDQ_DISABLE);
- if (primary_display_is_video_mode()) {
- /* for video mode, we need to force trigger here */
- /* for cmd mode, just set DPREC_EVENT_CMDQ_SET_EVENT_ALLOW when trigger loop start */
- dpmgr_path_trigger(pgc->dpmgr_handle, NULL, CMDQ_DISABLE);
- force_trigger_path = 0;
- }
- _cmdq_start_trigger_loop();
- DISPCHECK("[Pmaster]start cmdq trigger loop\n");
- done:
- _primary_path_unlock(__func__);
- if (force_trigger_path) {/* command mode only */
- primary_display_trigger(0, NULL, 0);
- DISPCHECK("[Pmaster]force trigger display path\r\n");
- }
- atomic_set(&esd_check_task_wakeup, esd_check_backup);
- return ret;
- }
- /*
- mode: 0, switch to cmd mode; 1, switch to vdo mode
- */
- int primary_display_switch_dst_mode(int mode)
- {
- DISP_STATUS ret = DISP_STATUS_ERROR;
- #ifdef DISP_SWITCH_DST_MODE
- void *lcm_cmd = NULL;
- DISPFUNC();
- _primary_path_switch_dst_lock();
- disp_sw_mutex_lock(&(pgc->capture_lock));
- if (pgc->plcm->params->type != LCM_TYPE_DSI) {
- pr_debug("[primary_display_switch_dst_mode] Error, only support DSI IF\n");
- goto done;
- }
- if (pgc->state == DISP_SLEPT) {
- DISPCHECK
- ("[primary_display_switch_dst_mode], primary display path is already sleep, skip\n");
- goto done;
- }
- if (mode == primary_display_cur_dst_mode) {
- DISPCHECK("[primary_display_switch_dst_mode]not need switch, cur_mode:%d, switch_mode:%d\n",
- primary_display_cur_dst_mode, mode);
- goto done;
- }
- /* DISPCHECK("[primary_display_switch_mode]need switch, cur_mode:%d, switch_mode:%d\n",
- primary_display_cur_dst_mode, mode);
- */
- lcm_cmd = disp_lcm_switch_mode(pgc->plcm, mode);
- if (lcm_cmd == NULL) {
- DISPCHECK("[primary_display_switch_dst_mode]get lcm cmd fail %d, %d\n",
- primary_display_cur_dst_mode, mode);
- goto done;
- } else {
- int temp_mode = 0;
- if (0 != dpmgr_path_ioctl(pgc->dpmgr_handle, pgc->cmdq_handle_config,
- DDP_SWITCH_LCM_MODE, lcm_cmd)) {
- pr_debug("switch lcm mode fail, return directly\n");
- goto done;
- }
- _primary_path_lock(__func__);
- temp_mode = (int)(pgc->plcm->params->dsi.mode);
- pgc->plcm->params->dsi.mode = pgc->plcm->params->dsi.switch_mode;
- pgc->plcm->params->dsi.switch_mode = temp_mode;
- dpmgr_path_set_video_mode(pgc->dpmgr_handle, primary_display_is_video_mode());
- if (0 != dpmgr_path_ioctl(pgc->dpmgr_handle, pgc->cmdq_handle_config,
- DDP_SWITCH_DSI_MODE, lcm_cmd)) {
- pr_debug("switch dsi mode fail, return directly\n");
- _primary_path_unlock(__func__);
- goto done;
- }
- }
- primary_display_sodi_rule_init();
- _cmdq_stop_trigger_loop();
- _cmdq_build_trigger_loop();
- _cmdq_start_trigger_loop();
- _cmdq_reset_config_handle(); /* must do this */
- _cmdq_insert_wait_frame_done_token();
- primary_display_cur_dst_mode = mode;
- if (primary_display_is_video_mode())
- dpmgr_map_event_to_irq(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC,
- DDP_IRQ_RDMA0_DONE);
- else
- dpmgr_map_event_to_irq(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC,
- DDP_IRQ_DSI0_EXT_TE);
- _primary_path_unlock(__func__);
- ret = DISP_STATUS_OK;
- done:
- /* dprec_handle_option(0x0); */
- disp_sw_mutex_unlock(&(pgc->capture_lock));
- _primary_path_switch_dst_unlock();
- #else
- pr_debug("[ERROR: primary_display_switch_dst_mode]this function not enable in disp driver\n");
- #endif
- return ret;
- }
- /* warm reset ovl0 and ovl1 by CMDQ */
- void primary_display_reset_ovl_by_cmdq(unsigned int force)
- {
- cmdqRecWaitNoClear(pgc->cmdq_handle_config, CMDQ_EVENT_MUTEX0_STREAM_EOF);
- if (force == 0) { /* warm reset ovl */
- DISPMSG("warm reset ovl\n");
- /* reset ovl0 */
- DISP_REG_SET(pgc->cmdq_handle_config, DISP_REG_OVL_RST, 0x1);
- DISP_REG_SET(pgc->cmdq_handle_config, DISP_REG_OVL_RST, 0x0);
- cmdqRecPoll(pgc->cmdq_handle_config, disp_addr_convert(DISP_REG_OVL_STA), 0, 0x1);
- /* reset ovl1 */
- if (ovl_get_status() == DDP_OVL1_STATUS_PRIMARY) {
- DISP_REG_SET(pgc->cmdq_handle_config,
- DISP_REG_OVL_RST + DISP_OVL_INDEX_OFFSET, 0x1);
- DISP_REG_SET(pgc->cmdq_handle_config,
- DISP_REG_OVL_RST + DISP_OVL_INDEX_OFFSET, 0x0);
- cmdqRecPoll(pgc->cmdq_handle_config,
- disp_addr_convert(DISP_REG_OVL_STA + DISP_OVL_INDEX_OFFSET), 0, 0x1);
- }
- } else if (force == 1) { /* force reset ovl */
- DISPMSG("force reset ovl\n");
- /* reset ovl0 */
- DISP_REG_SET_FIELD(pgc->cmdq_handle_config, RST_FLD_FORCE_RST, DISP_REG_OVL_RST, 0x1);
- DISP_REG_SET_FIELD(pgc->cmdq_handle_config, RST_FLD_FORCE_RST, DISP_REG_OVL_RST, 0x0);
- cmdqRecPoll(pgc->cmdq_handle_config, disp_addr_convert(DISP_REG_OVL_STA), 0, 0x1);
- /* reset ovl1 */
- if (ovl_get_status() == DDP_OVL1_STATUS_PRIMARY) {
- DISP_REG_SET_FIELD(pgc->cmdq_handle_config, RST_FLD_FORCE_RST,
- DISP_REG_OVL_RST + DISP_OVL_INDEX_OFFSET, 0x1);
- DISP_REG_SET_FIELD(pgc->cmdq_handle_config, RST_FLD_FORCE_RST,
- DISP_REG_OVL_RST + DISP_OVL_INDEX_OFFSET, 0x0);
- cmdqRecPoll(pgc->cmdq_handle_config,
- disp_addr_convert(DISP_REG_OVL_STA + DISP_OVL_INDEX_OFFSET), 0,
- 0x1);
- }
- }
- }
- /* extern void DSI_ForceConfig(int forceconfig); */
- /* extern int DSI_set_roi(int x, int y); */
- /* extern int DSI_check_roi(void); */
- /* extern atomic_t ESDCheck_byCPU; */
- static int width_array[] = { 2560, 1440, 1920, 1280, 1200, 800, 960, 640 };
- static int heigh_array[] = { 1440, 2560, 1200, 800, 1920, 1280, 640, 960 };
- static int array_id[] = { 6, 2, 7, 4, 3, 0, 5, 1 };
- LCM_PARAMS *lcm_param2 = NULL;
- disp_ddp_path_config data_config2;
- int primary_display_te_test(void)
- {
- int ret = 0;
- int try_cnt = 3;
- int time_interval = 0;
- int time_interval_max = 0;
- long long time_te = 0;
- long long time_framedone = 0;
- pr_debug("display_test te begin\n");
- if (primary_display_is_video_mode()) {
- pr_debug("Video Mode No TE\n");
- return ret;
- }
- while (try_cnt >= 0) {
- try_cnt--;
- ret = dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC, HZ * 1);
- time_te = sched_clock();
- dpmgr_path_trigger(pgc->dpmgr_handle, NULL, CMDQ_DISABLE);
- ret = dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE, HZ * 1);
- time_framedone = sched_clock();
- time_interval = (int)(time_framedone - time_te);
- time_interval = time_interval / 1000;
- if (time_interval > time_interval_max)
- time_interval_max = time_interval;
- }
- if (time_interval_max > 20000)
- ret = 0;
- else
- ret = -1;
- if (ret >= 0)
- pr_debug("[display_test_result]==>Force On TE Open!(%d)\n", time_interval_max);
- else
- pr_debug("[display_test_result]==>Force On TE Closed!(%d)\n", time_interval_max);
- pr_debug("display_test te end\n");
- return ret;
- }
- #if 0
- int primary_display_fps_test(void)
- {
- int ret = 0;
- unsigned int w_backup = 0;
- unsigned int h_backup = 0;
- LCM_DSI_MODE_CON dsi_mode_backup = primary_display_is_video_mode();
- memset((void *)&data_config2, 0, sizeof(data_config2));
- lcm_param2 = NULL;
- memcpy((void *)&data_config2, (void *)dpmgr_path_get_last_config(pgc->dpmgr_handle),
- sizeof(disp_ddp_path_config));
- w_backup = data_config2.dst_w;
- h_backup = data_config2.dst_h;
- DISPCHECK("[display_test]w_backup %d h_backup %d dsi_mode_backup %d\n", w_backup, h_backup,
- dsi_mode_backup);
- /* for dsi config */
- DSI_ForceConfig(1);
- DISPCHECK("[display_test]FPS config[begin]\n");
- lcm_param2 = disp_lcm_get_params(pgc->plcm);
- lcm_param2->dsi.mode = SYNC_PULSE_VDO_MODE;
- lcm_param2->dsi.vertical_active_line = 1280;
- lcm_param2->dsi.horizontal_active_pixel = 360;
- data_config2.dst_w = 360;
- data_config2.dst_h = 1280;
- data_config2.dispif_config.dsi.vertical_active_line = 1280;
- data_config2.dispif_config.dsi.horizontal_active_pixel = 360;
- data_config2.dispif_config.dsi.mode = SYNC_PULSE_VDO_MODE;
- data_config2.dst_dirty = 1;
- dpmgr_path_set_video_mode(pgc->dpmgr_handle, primary_display_is_video_mode());
- DISPCHECK("[display_test]==>FPS set vdo mode done, is_vdo_mode:%d\n",
- primary_display_is_video_mode());
- dpmgr_path_connect(pgc->dpmgr_handle, CMDQ_DISABLE);
- dpmgr_path_config(pgc->dpmgr_handle, &data_config2, CMDQ_DISABLE);
- data_config2.dst_dirty = 0;
- DISPCHECK("[display_test]FPS config[end]\n");
- DISPCHECK("[display_test]Start dpmgr path[begin]\n");
- dpmgr_path_start(pgc->dpmgr_handle, CMDQ_DISABLE);
- if (dpmgr_path_is_busy(pgc->dpmgr_handle))
- DISPERR("[display_test]==>Fatal error, we didn't trigger display path but it's already busy\n");
- DISPCHECK("[display_test]Start dpmgr path[end]\n");
- DISPCHECK("[display_test]Trigger dpmgr path[begin]\n");
- dpmgr_path_trigger(pgc->dpmgr_handle, NULL, CMDQ_DISABLE);
- DISPCHECK("[display_test]Trigger dpmgr path[end]\n");
- /* check fps bonding: rdma frame end interval < 12ms */
- disp_record_rdma_end_interval(1);
- /* loop 50 times to get max rdma end interval */
- int i = 50;
- while (i--)
- dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE, HZ * 1);
- unsigned long long min_interval = disp_get_rdma_min_interval();
- unsigned long long max_interval = disp_get_rdma_max_interval();
- disp_record_rdma_end_interval(0);
- DISPCHECK("[display_test]Check RDMA frame end interval:%lld[end]\n", min_interval);
- if (min_interval < 12 * 1000000) {
- DISPCHECK("[display_test_result]=>0.No limit\n");
- } else {
- DISPCHECK("[display_test_result]=>1.limit max_interval %lld\n", max_interval);
- if (max_interval < 13 * 1000000)
- DISPCHECK("[display_test_result]=>2.naughty enable\n");
- }
- DISPCHECK("[display_test]Stop dpmgr path[begin]\n");
- dpmgr_path_stop(pgc->dpmgr_handle, CMDQ_DISABLE);
- DISPCHECK("[display_test]Stop dpmgr path[end]\n");
- DISPCHECK("[display_test]Restore path config[begin]\n");
- lcm_param2 = disp_lcm_get_params(pgc->plcm);
- lcm_param2->dsi.mode = dsi_mode_backup;
- lcm_param2->dsi.vertical_active_line = h_backup;
- lcm_param2->dsi.horizontal_active_pixel = w_backup;
- data_config2.dispif_config.dsi.vertical_active_line = h_backup;
- data_config2.dispif_config.dsi.horizontal_active_pixel = w_backup;
- data_config2.dispif_config.dsi.mode = dsi_mode_backup;
- data_config2.dst_w = w_backup;
- data_config2.dst_h = h_backup;
- data_config2.dst_dirty = 1;
- dpmgr_path_set_video_mode(pgc->dpmgr_handle, primary_display_is_video_mode());
- DISPCHECK("[display_test]==>Restore mode done, is_vdo_mode:%d\n",
- primary_display_is_video_mode());
- DISPCHECK("[display_test]==>Restore resolution done, w=%d, h=%d\n", w_backup, h_backup);
- dpmgr_path_connect(pgc->dpmgr_handle, CMDQ_DISABLE);
- dpmgr_path_config(pgc->dpmgr_handle, &data_config2, CMDQ_DISABLE);
- data_config2.dst_dirty = 0;
- DSI_ForceConfig(0);
- DISPCHECK("[display_test]Restore path config[end]\n");
- return ret;
- }
- #endif
- int primary_display_roi_test(int x, int y)
- {
- int ret = 0;
- pr_debug("display_test roi begin\n");
- pr_debug("display_test roi set roi %d, %d\n", x, y);
- DSI_set_roi(x, y);
- msleep(50);
- dpmgr_path_trigger(pgc->dpmgr_handle, NULL, CMDQ_DISABLE);
- msleep(50);
- pr_debug("display_test DSI_check_roi\n");
- ret = DSI_check_roi();
- msleep(20);
- if (ret == 0)
- pr_debug("[display_test_result]==>DSI_ROI limit!\n");
- else
- pr_debug("[display_test_result]==>DSI_ROI Normal!\n");
- pr_debug("display_test set roi %d, %d\n", 0, 0);
- DSI_set_roi(0, 0);
- msleep(20);
- DISPCHECK("display_test end\n");
- return ret;
- }
- int primary_display_resolution_test(void)
- {
- int ret = 0;
- int i = 0;
- unsigned int w_backup = 0;
- unsigned int h_backup = 0;
- int dst_width = 0;
- int dst_heigh = 0;
- LCM_DSI_MODE_CON dsi_mode_backup = primary_display_is_video_mode();
- memset((void *)&data_config2, 0, sizeof(data_config2));
- lcm_param2 = NULL;
- memcpy((void *)&data_config2, (void *)dpmgr_path_get_last_config(pgc->dpmgr_handle),
- sizeof(disp_ddp_path_config));
- w_backup = data_config2.dst_w;
- h_backup = data_config2.dst_h;
- DISPCHECK("[display_test resolution]w_backup %d h_backup %d dsi_mode_backup %d\n",
- w_backup, h_backup, dsi_mode_backup);
- /* for dsi config */
- DSI_ForceConfig(1);
- for (i = 0; i < sizeof(width_array) / sizeof(int); i++) {
- dst_width = width_array[i];
- dst_heigh = heigh_array[i];
- DISPCHECK("[display_test resolution] width %d, heigh %d\n", dst_width, dst_heigh);
- lcm_param2 = disp_lcm_get_params(pgc->plcm);
- lcm_param2->dsi.mode = CMD_MODE;
- lcm_param2->dsi.horizontal_active_pixel = dst_width;
- lcm_param2->dsi.vertical_active_line = dst_heigh;
- data_config2.dispif_config.dsi.mode = CMD_MODE;
- data_config2.dispif_config.dsi.horizontal_active_pixel = dst_width;
- data_config2.dispif_config.dsi.vertical_active_line = dst_heigh;
- data_config2.dst_w = dst_width;
- data_config2.dst_h = dst_heigh;
- data_config2.ovl_config[0].layer = 0;
- data_config2.ovl_config[0].layer_en = 0;
- data_config2.ovl_config[1].layer = 1;
- data_config2.ovl_config[1].layer_en = 0;
- data_config2.ovl_config[2].layer = 2;
- data_config2.ovl_config[2].layer_en = 0;
- data_config2.ovl_config[3].layer = 3;
- data_config2.ovl_config[3].layer_en = 0;
- data_config2.dst_dirty = 1;
- data_config2.ovl_dirty = 1;
- dpmgr_path_set_video_mode(pgc->dpmgr_handle, primary_display_is_video_mode());
- dpmgr_path_config(pgc->dpmgr_handle, &data_config2, CMDQ_DISABLE);
- data_config2.dst_dirty = 0;
- data_config2.ovl_dirty = 0;
- dpmgr_path_start(pgc->dpmgr_handle, CMDQ_DISABLE);
- if (dpmgr_path_is_busy(pgc->dpmgr_handle))
- DISPERR("[display_test]==>Fatal error, we didn't trigger display path but it's already busy\n");
- dpmgr_path_trigger(pgc->dpmgr_handle, NULL, CMDQ_DISABLE);
- ret = dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE, HZ * 1);
- if (ret > 0) {
- if (!dpmgr_path_is_busy(pgc->dpmgr_handle)) {
- if (i == 0)
- DISPCHECK("[display_test resolution] display_result 0x%x unlimited!\n",
- array_id[i]);
- else if (i == 1)
- DISPCHECK("[display_test resolution] display_result 0x%x unlimited (W<H)\n",
- array_id[i]);
- else
- DISPCHECK("[display_test resolution] display_result 0x%x(%d x %d)\n",
- array_id[i], dst_width, dst_heigh);
- break;
- }
- }
- dpmgr_path_reset(pgc->dpmgr_handle, CMDQ_DISABLE);
- }
- dpmgr_path_stop(pgc->dpmgr_handle, CMDQ_DISABLE);
- lcm_param2 = disp_lcm_get_params(pgc->plcm);
- lcm_param2->dsi.mode = dsi_mode_backup;
- lcm_param2->dsi.vertical_active_line = h_backup;
- lcm_param2->dsi.horizontal_active_pixel = w_backup;
- data_config2.dispif_config.dsi.vertical_active_line = h_backup;
- data_config2.dispif_config.dsi.horizontal_active_pixel = w_backup;
- data_config2.dispif_config.dsi.mode = dsi_mode_backup;
- data_config2.dst_w = w_backup;
- data_config2.dst_h = h_backup;
- data_config2.dst_dirty = 1;
- dpmgr_path_set_video_mode(pgc->dpmgr_handle, primary_display_is_video_mode());
- dpmgr_path_connect(pgc->dpmgr_handle, CMDQ_DISABLE);
- dpmgr_path_config(pgc->dpmgr_handle, &data_config2, CMDQ_DISABLE);
- data_config2.dst_dirty = 0;
- DSI_ForceConfig(0);
- return ret;
- }
- int primary_display_check_test(void)
- {
- int ret = 0;
- int esd_backup = 0;
- DISPCHECK("[display_test]Display test[Start]\n");
- _primary_path_lock(__func__);
- /* disable esd check */
- if (atomic_read(&esd_check_task_wakeup)) {
- esd_backup = 1;
- primary_display_esd_check_enable(0);
- msleep(2000);
- DISPCHECK("[display_test]Disable esd check end\n");
- }
- /* if suspend => return */
- if (pgc->state == DISP_SLEPT) {
- DISPCHECK("[display_test_result]======================================\n");
- DISPCHECK("[display_test_result]==>Test Fail : primary display path is slept\n");
- DISPCHECK("[display_test_result]======================================\n");
- goto done;
- }
- /* stop trigger loop */
- DISPCHECK("[display_test]Stop trigger loop[begin]\n");
- _cmdq_stop_trigger_loop();
- atomic_set(&ESDCheck_byCPU, 1);
- if (dpmgr_path_is_busy(pgc->dpmgr_handle)) {
- DISPCHECK("[display_test]==>primary display path is busy\n");
- ret = dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE, HZ * 1);
- if (ret <= 0)
- dpmgr_path_reset(pgc->dpmgr_handle, CMDQ_DISABLE);
- DISPCHECK("[display_test]==>wait frame done ret:%d\n", ret);
- }
- DISPCHECK("[display_test]Stop trigger loop[end]\n");
- /* test rdma res after reset */
- /* primary_display_rdma_res_test(); */
- /* test force te */
- primary_display_te_test();
- /* test roi */
- primary_display_roi_test(30, 30);
- /* test resolution test */
- primary_display_resolution_test();
- /* mutex fps */
- /* primary_display_fps_test(); */
- DISPCHECK("[display_test]start dpmgr path[begin]\n");
- dpmgr_path_start(pgc->dpmgr_handle, CMDQ_DISABLE);
- if (dpmgr_path_is_busy(pgc->dpmgr_handle))
- DISPERR("[display_test]==>Fatal error, we didn't trigger display path but it's already busy\n");
- DISPCHECK("[display_test]start dpmgr path[end]\n");
- DISPCHECK("[display_test]Start trigger loop[begin]\n");
- _cmdq_start_trigger_loop();
- DISPCHECK("[display_test]Start trigger loop[end]\n");
- atomic_set(&ESDCheck_byCPU, 0);
- done:
- /* restore esd */
- if (esd_backup == 1) {
- primary_display_esd_check_enable(1);
- DISPCHECK("[display_test]Restore esd check\n");
- }
- /* unlock path */
- _primary_path_unlock(__func__);
- DISPCHECK("[display_test]Display test[End]\n");
- return ret;
- }
- static DISP_POWER_STATE tui_power_stat_backup;
- static int tui_session_mode_backup;
- int display_enter_tui(void)
- {
- msleep(500);
- DISPMSG("TDDP: %s\n", __func__);
- MMProfileLogEx(ddp_mmp_get_events()->tui, MMProfileFlagStart, 0, 0);
- _primary_path_lock(__func__);
- if (primary_get_state() != DISP_ALIVE) {
- DISPERR("Can't enter tui: current_stat=%d is not alive\n", primary_get_state());
- goto err0;
- }
- tui_power_stat_backup = primary_set_state(DISP_BLANK);
- if (primary_display_is_mirror_mode()) {
- DISPERR("Can't enter tui: current_mode=%s\n", session_mode_spy(pgc->session_mode));
- goto err1;
- }
- #ifdef MTK_DISP_IDLE_LP
- _disp_primary_path_exit_idle(__func__, 0);
- #endif
- tui_session_mode_backup = pgc->session_mode;
- primary_display_switch_mode_nolock(DISP_SESSION_DECOUPLE_MODE, pgc->session_id, 0);
- MMProfileLogEx(ddp_mmp_get_events()->tui, MMProfileFlagPulse, 0, 1);
- _primary_path_unlock(__func__);
- return 0;
- err1:
- primary_set_state(tui_power_stat_backup);
- err0:
- MMProfileLogEx(ddp_mmp_get_events()->tui, MMProfileFlagEnd, 0, 0);
- _primary_path_unlock(__func__);
- return -1;
- }
- int display_exit_tui(void)
- {
- MMProfileLogEx(ddp_mmp_get_events()->tui, MMProfileFlagPulse, 1, 1);
- _primary_path_lock(__func__);
- primary_set_state(tui_power_stat_backup);
- /* trigger rdma to display last normal buffer
- _decouple_update_rdma_config_nolock();*/
- /* workaround: wait until this frame triggered to lcm */
- msleep(32);
- primary_display_switch_mode_nolock(tui_session_mode_backup, pgc->session_id, 0);
- _primary_path_unlock(__func__);
- MMProfileLogEx(ddp_mmp_get_events()->tui, MMProfileFlagEnd, 0, 0);
- DISPMSG("TDDP: %s\n", __func__);
- return 0;
- }
- #if defined(OVL_TIME_SHARING)
- int primary_display_disable_ovl2mem(void)
- {
- DISPMSG("%s\n", __func__);
- _primary_path_lock(__func__);
- if (_is_decouple_mode(pgc->session_mode) &&
- pgc->state == DISP_SLEPT &&
- pgc->force_on_wdma_path == 1) {
- /* msleep(16); */ /* wait last frame done */
- usleep_range(16000, 17000);
- if (dpmgr_path_is_busy(pgc->ovl2mem_path_handle))
- dpmgr_wait_event_timeout(pgc->ovl2mem_path_handle, DISP_PATH_EVENT_FRAME_COMPLETE, HZ);
- DISPCHECK("[POWER]stop cmdq[begin]\n");
- _cmdq_stop_trigger_loop();
- DISPCHECK("[POWER]stop cmdq[end]\n");
- dpmgr_path_power_off(pgc->ovl2mem_path_handle, CMDQ_DISABLE);
- #ifndef CONFIG_MTK_CLKMGR
- ddp_clk_unprepare(DISP_MTCMOS_CLK);
- #endif
- DISPMSG("disable ovl power\n");
- pgc->force_on_wdma_path = 0;
- }
- _primary_path_unlock(__func__);
- return 1;
- }
- #endif
|