pt_loader.c 173 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956
  1. /*
  2. * pt_loader.c
  3. * Parade TrueTouch(TM) Standard Product FW Loader Module.
  4. * For use with Parade touchscreen controllers.
  5. * Supported parts include:
  6. * TMA5XX
  7. * TMA448
  8. * TMA445A
  9. * TT21XXX
  10. * TT31XXX
  11. * TT4XXXX
  12. * TT7XXX
  13. * TC3XXX
  14. *
  15. * Copyright (C) 2015-2020 Parade Technologies
  16. *
  17. * This program is free software; you can redistribute it and/or
  18. * modify it under the terms of the GNU General Public License
  19. * version 2, and only version 2, as published by the
  20. * Free Software Foundation.
  21. *
  22. * This program is distributed in the hope that it will be useful,
  23. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25. * GNU General Public License for more details.
  26. *
  27. * Contact Parade Technologies at www.paradetech.com <[email protected]>
  28. */
  29. #include "pt_regs.h"
  30. #include <linux/firmware.h>
  31. #define PT_LOADER_NAME "pt_loader"
  32. #ifdef UPGRADE_FW_AND_CONFIG_IN_PROBE
  33. /* Enable UPGRADE_FW_AND_CONFIG_IN_PROBE definition
  34. * to perform FW and config upgrade during probe
  35. * instead of scheduling a work for it
  36. */
  37. /* #define UPGRADE_FW_AND_CONFIG_IN_PROBE */
  38. #endif
  39. #define PT_AUTO_LOAD_FOR_CORRUPTED_FW 1
  40. #define PT_LOADER_FW_UPGRADE_RETRY_COUNT 3
  41. #define PT_FW_UPGRADE \
  42. (defined(CONFIG_TOUCHSCREEN_PARADE_PLATFORM_FW_UPGRADE) \
  43. || defined(CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE))
  44. #define PT_TTCONFIG_UPGRADE \
  45. (defined(CONFIG_TOUCHSCREEN_PARADE_PLATFORM_TTCONFIG_UPGRADE) \
  46. || defined(CONFIG_TOUCHSCREEN_PARADE_MANUAL_TTCONFIG_UPGRADE))
  47. /* Timeout values in ms. */
  48. #define PT_LDR_REQUEST_EXCLUSIVE_TIMEOUT 3000
  49. #define PT_LDR_SWITCH_TO_APP_MODE_TIMEOUT 300
  50. #define PT_MAX_STATUS_SIZE 32
  51. #define PT_DATA_MAX_ROW_SIZE 256
  52. #define PT_DATA_ROW_SIZE 128
  53. #define PT_ARRAY_ID_OFFSET 0
  54. #define PT_ROW_NUM_OFFSET 1
  55. #define PT_ROW_SIZE_OFFSET 3
  56. #define PT_ROW_DATA_OFFSET 5
  57. #define PT_POST_TT_CFG_CRC_MASK 0x2
  58. static inline struct pt_loader_data *pt_get_loader_data(
  59. struct device *dev);
  60. static struct pt_core_commands *cmd;
  61. #define PIP2_LAUNCH_APP_DELAY 400
  62. struct pip2_file_read {
  63. s8 para_num;
  64. u8 file_handle;
  65. int file_offset;
  66. int file_max_size;
  67. int file_read_size;
  68. int file_print_size;
  69. u8 *file_print_buf;
  70. int file_print_left;
  71. };
  72. #ifdef TTDL_DIAGNOSTICS
  73. struct pip2_file_crc {
  74. s8 para_num;
  75. u8 file_handle;
  76. int file_offset;
  77. int file_max_size;
  78. int file_read_size;
  79. };
  80. #endif
  81. struct pip2_loader_data {
  82. struct device *dev;
  83. struct completion pip2_fw_upgrade_complete; /* mutex for loader */
  84. u8 pip2_file_handle;
  85. };
  86. struct pt_loader_data {
  87. struct device *dev;
  88. struct pt_sysinfo *si;
  89. u8 status_buf[PT_MAX_STATUS_SIZE];
  90. struct completion int_running;
  91. struct completion calibration_complete;
  92. #ifdef CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE
  93. int builtin_bin_fw_status;
  94. bool is_manual_upgrade_enabled;
  95. #endif
  96. struct work_struct fw_and_config_upgrade;
  97. struct work_struct calibration_work;
  98. struct pt_loader_platform_data *loader_pdata;
  99. #ifdef CONFIG_TOUCHSCREEN_PARADE_MANUAL_TTCONFIG_UPGRADE
  100. struct mutex config_lock;
  101. u8 *config_data;
  102. int config_size;
  103. bool config_loading;
  104. #endif
  105. struct pip2_loader_data *pip2_data;
  106. u8 pip2_load_file_no;
  107. bool pip2_load_builtin;
  108. u8 pip2_file_erase_file_no;
  109. struct pip2_file_read pip2_file_data;
  110. #ifdef TTDL_DIAGNOSTICS
  111. struct pip2_file_crc pip2_fcrc;
  112. #endif
  113. #ifdef CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE
  114. struct work_struct bl_from_file;
  115. struct work_struct pip2_bl_from_file;
  116. #endif
  117. };
  118. static u8 write_file_status;
  119. #ifndef TTDL_KERNEL_SUBMISSION
  120. static int pip2_erase_status;
  121. static int pip2_erase_rc;
  122. #endif /* !TTDL_KERNEL_SUBMISSION */
  123. /* PIP2 update fw status codes. 1-99% are "active" */
  124. enum UPDATE_FW_STATUS {
  125. UPDATE_FW_IDLE = 0,
  126. UPDATE_FW_REQUEST_EXCLUSIVE = 1,
  127. UPDATE_FW_ACTIVE_10 = 10,
  128. UPDATE_FW_ACTIVE_90 = 90,
  129. UPDATE_FW_ACTIVE_99 = 99,
  130. UPDATE_FW_COMPLETE = 100,
  131. UPDATE_FW_GENERAL_ERROR = 200,
  132. UPDATE_FW_PIP_VERSION_ERROR = 201,
  133. UPDATE_FW_VERSION_ERROR = 202,
  134. UPDATE_FW_ERASE_ERROR = 203,
  135. UPDATE_FW_FILE_CLOSE_ERROR = 204,
  136. UPDATE_FW_WRITE_ERROR = 205,
  137. UPDATE_FW_EXECUTE_ERROR = 206,
  138. UPDATE_FW_RESET_ERROR = 207,
  139. UPDATE_FW_MODE_ERROR = 208,
  140. UPDATE_FW_ENTER_BL_ERROR = 209,
  141. UPDATE_FW_FILE_OPEN_ERROR = 210,
  142. UPDATE_FW_SENTINEL_NOT_SEEN = 211,
  143. UPDATE_FW_EXCLUSIVE_ACCESS_ERROR = 212,
  144. UPDATE_FW_NO_FW_PROVIDED = 213,
  145. UPDATE_FW_INVALID_FW_IMAGE = 214,
  146. UPDATE_FW_FILE_SEEK_ERROR = 215,
  147. UPDATE_FW_MISALIGN_FW_IMAGE = 230,
  148. UPDATE_FW_SYSTEM_NOMEM = 231,
  149. UPDATE_FW_INIT_BL_ERROR = 232,
  150. UPDATE_FW_PARSE_ROW_ERROR = 233,
  151. UPDATE_FW_PROGRAM_ROW_ERROR = 234,
  152. UPDATE_FW_EXIT_BL_ERROR = 235,
  153. UPDATE_FW_CHECK_SUM_ERROR = 236,
  154. UPDATE_FW_NO_PLATFORM_DATA = 237,
  155. UPDATE_FW_NOT_SUPPORTED_FILE_NO = 238,
  156. UPDATE_FW_UNDEFINED_ERROR = 255,
  157. UPDATE_FW_INCREMENT = 300,
  158. UPDATE_FW_INCREMENT_BY_1 = 301,
  159. UPDATE_FW_INCREMENT_BY_5 = 305,
  160. UPDATE_FW_UNDEFINED_INC = 400,
  161. };
  162. enum PIP2_FILE_ERASE_STATUS {
  163. PIP2_FILE_ERASE_STATUS_DUT_BUSY = 101,
  164. PIP2_FILE_ERASE_STATUS_ENTER_BL_ERROR = 102,
  165. };
  166. struct pt_dev_id {
  167. u32 silicon_id;
  168. u8 rev_id;
  169. u32 bl_ver;
  170. };
  171. struct pt_hex_image {
  172. u8 array_id;
  173. u16 row_num;
  174. u16 row_size;
  175. u8 row_data[PT_DATA_ROW_SIZE];
  176. } __packed;
  177. #ifdef CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE
  178. static int pt_pip2_upgrade_firmware_from_builtin(struct device *dev);
  179. #endif
  180. typedef int (*PIP2_SEND_CMD)(struct device *, int,
  181. u8, u8 *, u16, u8 *, u16 *);
  182. static struct pt_module loader_module;
  183. /*******************************************************************************
  184. * FUNCTION: pt_get_loader_data
  185. *
  186. * SUMMARY: Inline function to get pt_loader_data pointer from loader module.
  187. *
  188. * RETURN:
  189. * pointer to pt_loader_data structure
  190. *
  191. * PARAMETERS:
  192. * *dev - pointer to device structure
  193. ******************************************************************************/
  194. static inline struct pt_loader_data *pt_get_loader_data(
  195. struct device *dev)
  196. {
  197. return pt_get_module_data(dev, &loader_module);
  198. }
  199. #if PT_FW_UPGRADE || PT_TTCONFIG_UPGRADE
  200. /*******************************************************************************
  201. * FUNCTION: pt_calibrate_idacs
  202. *
  203. * SUMMARY: Calibrate idac for mutual-cap,buttons,self-cap by called functions.
  204. * It needs stop panel scan during calibration.
  205. *
  206. * PARAMETERS:
  207. * *calibration_work - pointer to work_struct structure
  208. ******************************************************************************/
  209. static void pt_calibrate_idacs(struct work_struct *calibration_work)
  210. {
  211. struct pt_loader_data *ld = container_of(calibration_work,
  212. struct pt_loader_data, calibration_work);
  213. struct device *dev = ld->dev;
  214. struct pt_cal_ext_data cal_data = {0};
  215. u8 dut_gen = cmd->request_dut_generation(dev);
  216. u8 mode;
  217. u8 status;
  218. int rc;
  219. pt_debug(dev, DL_INFO, "Entering %s\n", __func__);
  220. rc = cmd->request_exclusive(dev, PT_LDR_REQUEST_EXCLUSIVE_TIMEOUT);
  221. if (rc < 0)
  222. goto exit;
  223. rc = cmd->nonhid_cmd->suspend_scanning(dev, 0);
  224. if (rc < 0)
  225. goto release;
  226. if (dut_gen == DUT_PIP1_ONLY) {
  227. for (mode = 0; mode < 3; mode++) {
  228. rc = cmd->nonhid_cmd->calibrate_idacs(dev, 0, mode,
  229. &status);
  230. if (rc < 0) {
  231. pt_debug(dev, DL_ERROR,
  232. "%s: calibrate idac error, rc = %d\n",
  233. __func__, rc);
  234. break;
  235. }
  236. }
  237. } else {
  238. /*
  239. * Manual calibration is not need after fw 3.4.932110.
  240. * Therefore, PT_LOADER_FLAG_NONE should be used to avoid
  241. * manual calibration if the FW is newer than 3.4.932110.
  242. */
  243. memset(&cal_data, 0, sizeof(struct pt_cal_ext_data));
  244. rc = cmd->nonhid_cmd->calibrate_ext(dev, 0, &cal_data,
  245. &status);
  246. if (rc < 0) {
  247. pt_debug(dev, DL_ERROR,
  248. "%s: extended calibrate error, rc = %d\n",
  249. __func__, rc);
  250. }
  251. }
  252. rc = cmd->nonhid_cmd->resume_scanning(dev, 0);
  253. if (rc < 0)
  254. goto release;
  255. pt_debug(dev, DL_WARN, "%s: Calibration Done\n", __func__);
  256. release:
  257. cmd->release_exclusive(dev);
  258. exit:
  259. complete(&ld->calibration_complete);
  260. }
  261. /*******************************************************************************
  262. * FUNCTION: pt_calibration_attention
  263. *
  264. * SUMMARY: Wrapper function to schedule calibration work used to subscribe into
  265. * TTDL attention list.Once called will unsubscribe from attention list.
  266. *
  267. * RETURN:
  268. * 0 = success
  269. * !0 = failure
  270. *
  271. * PARAMETERS:
  272. * *dev - pointer to device structure
  273. ******************************************************************************/
  274. static int pt_calibration_attention(struct device *dev)
  275. {
  276. struct pt_loader_data *ld = pt_get_loader_data(dev);
  277. int rc = 0;
  278. schedule_work(&ld->calibration_work);
  279. cmd->unsubscribe_attention(dev, PT_ATTEN_STARTUP, PT_LOADER_NAME,
  280. pt_calibration_attention, 0);
  281. return rc;
  282. }
  283. #endif /* PT_FW_UPGRADE || PT_TTCONFIG_UPGRADE */
  284. #if PT_FW_UPGRADE \
  285. || defined(CONFIG_TOUCHSCREEN_PARADE_PLATFORM_TTCONFIG_UPGRADE)
  286. /*******************************************************************************
  287. * FUNCTION: pt_get_panel_id
  288. *
  289. * SUMMARY: Get panel id from core data.
  290. *
  291. * RETURN:
  292. * panel id
  293. *
  294. * PARAMETERS:
  295. * *dev - pointer to device structure
  296. ******************************************************************************/
  297. static u8 pt_get_panel_id(struct device *dev)
  298. {
  299. struct pt_core_data *cd = dev_get_drvdata(dev);
  300. return cd->pid_for_loader;
  301. }
  302. #endif
  303. #if (PT_FW_UPGRADE || PT_TTCONFIG_UPGRADE)
  304. /*******************************************************************************
  305. * FUNCTION: pt_check_firmware_version
  306. *
  307. * SUMMARY: Compare fw's version and revision control number with fw image's.
  308. *
  309. * RETURN:
  310. * -1: Do not upgrade firmware
  311. * 0: Version info same, let caller decide
  312. * 1: Do a firmware upgrade
  313. *
  314. * PARAMETERS:
  315. * *dev - pointer to device structure
  316. * fw_ver_new - firmware version
  317. * fw_revctrl_new - firmware revision control number
  318. ******************************************************************************/
  319. static int pt_check_firmware_version(struct device *dev,
  320. u32 fw_ver_new, u32 fw_revctrl_new)
  321. {
  322. struct pt_loader_data *ld = pt_get_loader_data(dev);
  323. u32 fw_ver_img;
  324. u32 fw_revctrl_img;
  325. fw_ver_img = ld->si->ttdata.fw_ver_major << 8;
  326. fw_ver_img += ld->si->ttdata.fw_ver_minor;
  327. pt_debug(dev, DL_WARN,
  328. "%s: Current FW ver:0x%04X New FW ver:0x%04X\n", __func__,
  329. fw_ver_img, fw_ver_new);
  330. if (fw_ver_new > fw_ver_img) {
  331. pt_debug(dev, DL_WARN,
  332. "%s: Image is newer, will upgrade\n", __func__);
  333. return 1;
  334. }
  335. if (fw_ver_new < fw_ver_img) {
  336. pt_debug(dev, DL_WARN,
  337. "%s: Image is older, will NOT upgrade\n", __func__);
  338. return -1;
  339. }
  340. fw_revctrl_img = ld->si->ttdata.revctrl;
  341. pt_debug(dev, DL_WARN,
  342. "%s: Current FW rev:%d New FW rev:%d\n",
  343. __func__, fw_revctrl_img, fw_revctrl_new);
  344. if (fw_revctrl_new > fw_revctrl_img) {
  345. pt_debug(dev, DL_WARN,
  346. "%s: Image is newer, will upgrade\n", __func__);
  347. return 1;
  348. }
  349. if (fw_revctrl_new < fw_revctrl_img) {
  350. pt_debug(dev, DL_WARN,
  351. "%s: Image is older, will NOT upgrade\n", __func__);
  352. return -1;
  353. }
  354. return 0;
  355. }
  356. #endif /* PT_FW_UPGRADE || PT_TTCONFIG_UPGRADE */
  357. #if PT_FW_UPGRADE
  358. /*******************************************************************************
  359. * FUNCTION: pt_get_row_
  360. *
  361. * SUMMARY: Copy the image data to the "row_buf".
  362. *
  363. * RETURN:
  364. * pointer to image buffer plus copy size
  365. *
  366. * PARAMETERS:
  367. * *dev - pointer to device structure
  368. * *row_buf - pointer to written buffer to program chip
  369. * *image_buf - pointer to image buffer
  370. * size - size of written data
  371. ******************************************************************************/
  372. static u8 *pt_get_row_(struct device *dev, u8 *row_buf,
  373. u8 *image_buf, int size)
  374. {
  375. memcpy(row_buf, image_buf, size);
  376. return image_buf + size;
  377. }
  378. /*******************************************************************************
  379. * FUNCTION: pt_ldr_enter_
  380. *
  381. * SUMMARY: Enter bootloader state and update device id(silicon id, rev id,
  382. * bootloader version).
  383. *
  384. * RETURN:
  385. * 0 = success
  386. * !0 = failure
  387. *
  388. * PARAMETERS:
  389. * *dev - pointer to device structure
  390. * *dev_id - pointer to device id
  391. ******************************************************************************/
  392. static int pt_ldr_enter_(struct device *dev, struct pt_dev_id *dev_id)
  393. {
  394. int rc;
  395. u8 return_data[8];
  396. u8 mode = PT_MODE_OPERATIONAL;
  397. dev_id->silicon_id = 0;
  398. dev_id->rev_id = 0;
  399. dev_id->bl_ver = 0;
  400. /*
  401. * Reset to get to a known state, sleep to allow sentinel processing.
  402. *
  403. * NOTE: This msleep MUST be greater than the auto launch timeout
  404. * that is built into the FW.
  405. */
  406. cmd->request_reset(dev, PT_CORE_CMD_UNPROTECTED);
  407. msleep(20);
  408. rc = cmd->request_get_mode(dev, 0, &mode);
  409. pt_debug(dev, DL_INFO, "%s:request_get_mode rc=%d mode=%d\n",
  410. __func__, rc, mode);
  411. if (rc)
  412. return rc;
  413. if (mode == PT_MODE_UNKNOWN)
  414. return -EINVAL;
  415. if (mode == PT_MODE_OPERATIONAL) {
  416. rc = cmd->nonhid_cmd->start_bl(dev, PT_CORE_CMD_UNPROTECTED);
  417. pt_debug(dev, DL_INFO, "%s:start_bl rc=%d\n", __func__, rc);
  418. if (rc)
  419. return rc;
  420. rc = cmd->request_get_mode(dev, 0, &mode);
  421. pt_debug(dev, DL_INFO, "%s:request_get_mode rc=%d mode=%d\n",
  422. __func__, rc, mode);
  423. if (rc)
  424. return rc;
  425. if (mode != PT_MODE_BOOTLOADER)
  426. return -EINVAL;
  427. }
  428. rc = cmd->nonhid_cmd->get_bl_info(dev,
  429. PT_CORE_CMD_UNPROTECTED, return_data);
  430. pt_debug(dev, DL_INFO, "%s:get_bl_info rc=%d\n", __func__, rc);
  431. if (rc)
  432. return rc;
  433. dev_id->silicon_id = get_unaligned_le32(&return_data[0]);
  434. dev_id->rev_id = return_data[4];
  435. dev_id->bl_ver = return_data[5] + (return_data[6] << 8)
  436. + (return_data[7] << 16);
  437. return 0;
  438. }
  439. /*******************************************************************************
  440. * FUNCTION: pt_ldr_init_
  441. *
  442. * SUMMARY: Erase the entire TrueTouch application, Configuration Data block,
  443. * and Design Data block in flash and enables the host to execute the Program
  444. * and Verify Row command to bootload the application image and data.
  445. *
  446. * RETURN:
  447. * 0 = success
  448. * !0 = failure
  449. *
  450. * PARAMETERS:
  451. * *dev - pointer to device structure
  452. * *pt_hex_image - pointer to hex image structure
  453. ******************************************************************************/
  454. static int pt_ldr_init_(struct device *dev,
  455. struct pt_hex_image *row_image)
  456. {
  457. return cmd->nonhid_cmd->initiate_bl(dev, 0, 8,
  458. (u8 *)pt_data_block_security_key, row_image->row_size,
  459. row_image->row_data);
  460. }
  461. /*******************************************************************************
  462. * FUNCTION: pt_ldr_parse_row_
  463. *
  464. * SUMMARY: Parse and copy the row buffer data to hex image structure.
  465. *
  466. * RETURN:
  467. * 0 = success
  468. * !0 = failure
  469. *
  470. * PARAMETERS:
  471. * *dev - pointer to device structure
  472. * *row_buf - pointer to row buffer
  473. * *row_image - pointer to hex image structure
  474. ******************************************************************************/
  475. static int pt_ldr_parse_row_(struct device *dev, u8 *row_buf,
  476. struct pt_hex_image *row_image)
  477. {
  478. int rc = 0;
  479. row_image->array_id = row_buf[PT_ARRAY_ID_OFFSET];
  480. row_image->row_num = get_unaligned_be16(&row_buf[PT_ROW_NUM_OFFSET]);
  481. row_image->row_size = get_unaligned_be16(&row_buf[PT_ROW_SIZE_OFFSET]);
  482. if (row_image->row_size > ARRAY_SIZE(row_image->row_data)) {
  483. pt_debug(dev, DL_ERROR,
  484. "%s: row data buffer overflow\n", __func__);
  485. rc = -EOVERFLOW;
  486. goto pt_ldr_parse_row_exit;
  487. }
  488. memcpy(row_image->row_data, &row_buf[PT_ROW_DATA_OFFSET],
  489. row_image->row_size);
  490. pt_ldr_parse_row_exit:
  491. return rc;
  492. }
  493. /*******************************************************************************
  494. * FUNCTION: pt_ldr_prog_row_
  495. *
  496. * SUMMARY: Program one row that the hex image structure data to the chip.
  497. *
  498. * RETURN:
  499. * 0 = success
  500. * !0 = failure
  501. *
  502. * PARAMETERS:
  503. * *dev - pointer to device structure
  504. * *row_image - pointer to hex image structure
  505. ******************************************************************************/
  506. static int pt_ldr_prog_row_(struct device *dev,
  507. struct pt_hex_image *row_image)
  508. {
  509. int rc = 0;
  510. u16 length = row_image->row_size + 3;
  511. u8 *data = NULL;
  512. u8 offset = 0;
  513. if (length > PT_DATA_MAX_ROW_SIZE)
  514. return -EINVAL;
  515. data = kzalloc(length, GFP_KERNEL);
  516. if (!data)
  517. return -ENOMEM;
  518. data[offset++] = row_image->array_id;
  519. data[offset++] = LOW_BYTE(row_image->row_num);
  520. data[offset++] = HI_BYTE(row_image->row_num);
  521. memcpy(data + 3, row_image->row_data, row_image->row_size);
  522. rc = cmd->nonhid_cmd->prog_and_verify(dev, 0, length, data);
  523. kfree(data);
  524. return rc;
  525. }
  526. /*******************************************************************************
  527. * FUNCTION: pt_ldr_verify_chksum_
  528. *
  529. * SUMMARY: Perform a full verification of the application integrity by
  530. * calculating the CRC of the TrueTouch application image in flash and
  531. * comparing it to the expected CRC stored in the TrueTouch application CRC
  532. * value stored in the Metadata row.
  533. *
  534. * RETURN:
  535. * 0 = success
  536. * !0 = failure
  537. *
  538. * PARAMETERS:
  539. * *dev - pointer to device structure
  540. ******************************************************************************/
  541. static int pt_ldr_verify_chksum_(struct device *dev)
  542. {
  543. u8 result;
  544. int rc;
  545. rc = cmd->nonhid_cmd->verify_app_integrity(dev, 0, &result);
  546. if (rc)
  547. return rc;
  548. /* fail */
  549. if (result == 0)
  550. return -EINVAL;
  551. return 0;
  552. }
  553. /*******************************************************************************
  554. * FUNCTION: pt_ldr_exit_
  555. *
  556. * SUMMARY: Launch the application from bootloader.
  557. *
  558. * RETURN:
  559. * 0 = success
  560. * !0 = failure
  561. *
  562. * PARAMETERS:
  563. * *dev - pointer to device structure
  564. ******************************************************************************/
  565. static int pt_ldr_exit_(struct device *dev)
  566. {
  567. return cmd->nonhid_cmd->launch_app(dev, 0);
  568. }
  569. /*******************************************************************************
  570. * FUNCTION: _pt_pip2_update_bl_status
  571. *
  572. * SUMMARY: Update the value in the bl_status global by either setting to a
  573. * specific value or incrementing it ensuring we don't go out of bounds.
  574. *
  575. * PARAMETERS:
  576. * *dev - pointer to device structure
  577. * value - Value to force.
  578. ******************************************************************************/
  579. static u8 _pt_update_write_file_status(struct device *dev, u16 value)
  580. {
  581. u8 inc = 0;
  582. pt_debug(dev, DL_DEBUG,
  583. "%s: fw_status = %d, request val=%d\n",
  584. __func__, write_file_status, value);
  585. /* Reset status if value is 0 */
  586. if (value == UPDATE_FW_IDLE) {
  587. write_file_status = value;
  588. pt_debug(dev, DL_WARN, "%s: ATM - Reset BL Status to %d\n",
  589. __func__, value);
  590. return write_file_status;
  591. }
  592. /* Set to value if valid */
  593. if (value > UPDATE_FW_IDLE && value < UPDATE_FW_UNDEFINED_ERROR) {
  594. if (value <= UPDATE_FW_COMPLETE && value > write_file_status) {
  595. write_file_status = value;
  596. pt_debug(dev, DL_DEBUG, "%s: Set BL Status to %d\n",
  597. __func__, value);
  598. } else if (value >= UPDATE_FW_GENERAL_ERROR) {
  599. write_file_status = value;
  600. pt_debug(dev, DL_WARN,
  601. "%s: BL Status set to error code %d\n",
  602. __func__, value);
  603. }
  604. return write_file_status;
  605. }
  606. if (value > UPDATE_FW_INCREMENT && value < UPDATE_FW_UNDEFINED_INC) {
  607. inc = value - UPDATE_FW_INCREMENT;
  608. if (write_file_status + inc <= UPDATE_FW_COMPLETE)
  609. write_file_status += inc;
  610. else
  611. pt_debug(dev, DL_ERROR,
  612. "%s: Inc Request out of bounds: status=%d inc=%d\n",
  613. __func__, write_file_status, inc);
  614. } else
  615. pt_debug(dev, DL_ERROR,
  616. "%s: Value Request out of bounds: status=%d value=%d\n",
  617. __func__, write_file_status, value);
  618. return write_file_status;
  619. }
  620. /*******************************************************************************
  621. * FUNCTION: pt_load_app_
  622. *
  623. * SUMMARY: Program the firmware image to the chip.
  624. *
  625. * RETURN:
  626. * 0 = success
  627. * !0 = failure
  628. *
  629. * PARAMETERS:
  630. * *dev - pointer to device structure
  631. * *fw - pointer to the firmware
  632. * fw_size - size of firmware
  633. * update_status - store the update status of firmware
  634. ******************************************************************************/
  635. static int pt_load_app_(struct device *dev, const u8 *fw, int fw_size,
  636. u8 *update_status)
  637. {
  638. struct pt_core_data *cd = dev_get_drvdata(dev);
  639. struct pt_dev_id *dev_id;
  640. struct pt_hex_image *row_image;
  641. u8 *row_buf;
  642. size_t image_rec_size;
  643. size_t row_buf_size = PT_DATA_MAX_ROW_SIZE;
  644. int row_count = 0;
  645. u8 *p;
  646. u8 *last_row;
  647. int rc;
  648. int rc_tmp;
  649. int percent_cmplt;
  650. int total_row_count;
  651. if (update_status == NULL) {
  652. rc = -EINVAL;
  653. pt_debug(dev, DL_ERROR,
  654. "%s: update_status is NULL pointer %d\n",
  655. __func__, rc);
  656. return rc;
  657. } else if (*update_status > UPDATE_FW_ACTIVE_10) {
  658. pt_debug(dev, DL_WARN,
  659. "%s: update_status is illegal = %d, fixed to %d\n",
  660. __func__, *update_status, UPDATE_FW_ACTIVE_10);
  661. *update_status = UPDATE_FW_ACTIVE_10;
  662. }
  663. image_rec_size = sizeof(struct pt_hex_image);
  664. if (fw_size % image_rec_size != 0) {
  665. pt_debug(dev, DL_ERROR,
  666. "%s: Firmware image is misaligned\n", __func__);
  667. *update_status = UPDATE_FW_MISALIGN_FW_IMAGE;
  668. rc = -EINVAL;
  669. goto _pt_load_app_error;
  670. }
  671. *update_status += 1;
  672. total_row_count = fw_size / image_rec_size - 1;
  673. pt_debug(dev, DL_INFO, "%s: start load app\n", __func__);
  674. #ifdef TTHE_TUNER_SUPPORT
  675. cmd->request_tthe_print(dev, NULL, 0, "start load app");
  676. #endif
  677. row_buf = kzalloc(row_buf_size, GFP_KERNEL);
  678. row_image = kzalloc(sizeof(struct pt_hex_image), GFP_KERNEL);
  679. dev_id = kzalloc(sizeof(struct pt_dev_id), GFP_KERNEL);
  680. if (!row_buf || !row_image || !dev_id) {
  681. *update_status = UPDATE_FW_SYSTEM_NOMEM;
  682. rc = -ENOMEM;
  683. goto _pt_load_app_exit;
  684. }
  685. *update_status += 1;
  686. cmd->request_stop_wd(dev);
  687. pt_debug(dev, DL_INFO, "%s: Send BL Loader Enter\n", __func__);
  688. #ifdef TTHE_TUNER_SUPPORT
  689. cmd->request_tthe_print(dev, NULL, 0, "Send BL Loader Enter");
  690. #endif
  691. rc = pt_ldr_enter_(dev, dev_id);
  692. if (rc) {
  693. *update_status = UPDATE_FW_ENTER_BL_ERROR;
  694. pt_debug(dev, DL_ERROR, "%s: Error cannot start Loader (ret=%d)\n",
  695. __func__, rc);
  696. goto _pt_load_app_exit;
  697. }
  698. pt_debug(dev, DL_INFO,
  699. "%s: dev: silicon id=%08X rev=%02X bl=%08X\n", __func__,
  700. dev_id->silicon_id, dev_id->rev_id, dev_id->bl_ver);
  701. *update_status += 1;
  702. /*
  703. * since start loader is successful, firmware mode can be assumed
  704. * at bl mode directly. Updating this variable is helpful to detect
  705. * firmware entered application mode.
  706. */
  707. cd->mode = PT_MODE_BOOTLOADER;
  708. /* get last row */
  709. last_row = (u8 *)fw + fw_size - image_rec_size;
  710. pt_get_row_(dev, row_buf, last_row, image_rec_size);
  711. pt_ldr_parse_row_(dev, row_buf, row_image);
  712. /* initialise bootloader */
  713. rc = pt_ldr_init_(dev, row_image);
  714. if (rc) {
  715. *update_status = UPDATE_FW_ERASE_ERROR;
  716. pt_debug(dev, DL_ERROR, "%s: Error cannot init Loader (ret=%d)\n",
  717. __func__, rc);
  718. goto _pt_load_app_exit;
  719. }
  720. *update_status += 5;
  721. pt_debug(dev, DL_INFO,
  722. "%s: Send BL Loader Blocks\n", __func__);
  723. #ifdef TTHE_TUNER_SUPPORT
  724. cmd->request_tthe_print(dev, NULL, 0, "Send BL Loader Blocks");
  725. #endif
  726. p = (u8 *)fw;
  727. while (p < last_row) {
  728. /* Get row */
  729. row_count += 1;
  730. pt_debug(dev, DL_INFO, "%s: read row=%d\n",
  731. __func__, row_count);
  732. memset(row_buf, 0, row_buf_size);
  733. p = pt_get_row_(dev, row_buf, p, image_rec_size);
  734. /* Don't update BL status on every pass */
  735. if (row_count / 8 * 8 == row_count) {
  736. /* Calculate % complete for update_status sysfs */
  737. percent_cmplt = row_count * 100 / total_row_count;
  738. if (percent_cmplt > UPDATE_FW_ACTIVE_99)
  739. percent_cmplt = UPDATE_FW_ACTIVE_99;
  740. *update_status = (percent_cmplt > *update_status) ?
  741. percent_cmplt : *update_status;
  742. #ifdef TTDL_DIAGNOSTICS
  743. pt_debug(dev, DL_INFO,
  744. "Wrote row num %d of total %d\n",
  745. row_count, total_row_count);
  746. #endif
  747. }
  748. /* Parse row */
  749. pt_debug(dev, DL_INFO, "%s: p=%p buf=%p buf[0]=%02X\n",
  750. __func__, p, row_buf, row_buf[0]);
  751. rc = pt_ldr_parse_row_(dev, row_buf, row_image);
  752. pt_debug(dev, DL_INFO,
  753. "%s: array_id=%02X row_num=%04X(%d) row_size=%04X(%d)\n",
  754. __func__, row_image->array_id,
  755. row_image->row_num, row_image->row_num,
  756. row_image->row_size, row_image->row_size);
  757. if (rc) {
  758. *update_status = UPDATE_FW_PARSE_ROW_ERROR;
  759. pt_debug(dev, DL_ERROR,
  760. "%s: Parse Row Error (a=%d r=%d ret=%d\n",
  761. __func__, row_image->array_id,
  762. row_image->row_num, rc);
  763. goto _pt_load_app_exit;
  764. } else {
  765. pt_debug(dev, DL_INFO,
  766. "%s: Parse Row (a=%d r=%d ret=%d\n",
  767. __func__, row_image->array_id,
  768. row_image->row_num, rc);
  769. }
  770. /* program row */
  771. rc = pt_ldr_prog_row_(dev, row_image);
  772. if (rc) {
  773. *update_status = UPDATE_FW_PROGRAM_ROW_ERROR;
  774. pt_debug(dev, DL_ERROR,
  775. "%s: Prog Row Error (array=%d row=%d ret=%d)\n",
  776. __func__, row_image->array_id,
  777. row_image->row_num, rc);
  778. goto _pt_load_app_exit;
  779. }
  780. pt_debug(dev, DL_INFO,
  781. "%s: array=%d row_cnt=%d row_num=%04X\n",
  782. __func__, row_image->array_id, row_count,
  783. row_image->row_num);
  784. }
  785. /* exit loader */
  786. pt_debug(dev, DL_INFO, "%s: Send BL Loader Terminate\n", __func__);
  787. #ifdef TTHE_TUNER_SUPPORT
  788. cmd->request_tthe_print(dev, NULL, 0, "Send BL Loader Terminate");
  789. #endif
  790. rc = pt_ldr_exit_(dev);
  791. if (rc) {
  792. *update_status = UPDATE_FW_EXIT_BL_ERROR;
  793. pt_debug(dev, DL_ERROR, "%s: Error on exit Loader (ret=%d)\n",
  794. __func__, rc);
  795. /* verify app checksum */
  796. rc_tmp = pt_ldr_verify_chksum_(dev);
  797. if (rc_tmp) {
  798. *update_status = UPDATE_FW_CHECK_SUM_ERROR;
  799. pt_debug(dev, DL_ERROR,
  800. "%s: ldr_verify_chksum fail r=%d\n",
  801. __func__, rc_tmp);
  802. } else
  803. pt_debug(dev, DL_INFO,
  804. "%s: APP Checksum Verified\n", __func__);
  805. } else
  806. *update_status = UPDATE_FW_ACTIVE_99;
  807. _pt_load_app_exit:
  808. kfree(row_buf);
  809. kfree(row_image);
  810. kfree(dev_id);
  811. _pt_load_app_error:
  812. return rc;
  813. }
  814. /*******************************************************************************
  815. * FUNCTION: pt_upgrade_firmware
  816. *
  817. * SUMMARY: Program the firmware image and set call back for start up.
  818. *
  819. * RETURN:
  820. * 0 = success
  821. * !0 = failure
  822. *
  823. * PARAMETERS:
  824. * *dev - pointer to device structure
  825. * *fw_img - pointer to the firmware
  826. * fw_size - size of firmware
  827. * *update_status - store the update status of firmware
  828. ******************************************************************************/
  829. static int pt_upgrade_firmware(struct device *dev, const u8 *fw_img,
  830. int fw_size, u8 *update_status)
  831. {
  832. struct pt_loader_data *ld = pt_get_loader_data(dev);
  833. struct pt_core_data *cd = dev_get_drvdata(dev);
  834. int retry = PT_LOADER_FW_UPGRADE_RETRY_COUNT;
  835. bool wait_for_calibration_complete = false;
  836. int rc;
  837. int t;
  838. _pt_update_write_file_status(dev, UPDATE_FW_IDLE);
  839. if (update_status == NULL) {
  840. rc = -EINVAL;
  841. pt_debug(dev, DL_ERROR,
  842. "%s: update_status is NULL pointer %d\n",
  843. __func__, rc);
  844. return rc;
  845. } else if (*update_status > UPDATE_FW_ACTIVE_10) {
  846. pt_debug(dev, DL_WARN,
  847. "%s: update_status is illegal = %d, fixed to %d\n",
  848. __func__, *update_status, UPDATE_FW_ACTIVE_10);
  849. *update_status = UPDATE_FW_ACTIVE_10;
  850. }
  851. /* Ensure no enum task is pending */
  852. pt_debug(dev, DL_WARN, "%s: Cancel enum work thread\n", __func__);
  853. cancel_work_sync(&cd->enum_work);
  854. pm_runtime_get_sync(dev);
  855. *update_status += 1;
  856. rc = cmd->request_exclusive(dev, PT_LDR_REQUEST_EXCLUSIVE_TIMEOUT);
  857. if (rc < 0) {
  858. *update_status = UPDATE_FW_EXCLUSIVE_ACCESS_ERROR;
  859. goto exit;
  860. }
  861. *update_status += 1;
  862. t = *update_status;
  863. while (retry--) {
  864. /* Restore the update_status */
  865. *update_status = t;
  866. rc = pt_load_app_(dev, fw_img, fw_size, update_status);
  867. if (rc < 0)
  868. pt_debug(dev, DL_ERROR,
  869. "%s: Firmware update failed rc=%d, retry:%d\n",
  870. __func__, rc, retry);
  871. else
  872. break;
  873. msleep(20);
  874. }
  875. if (rc < 0) {
  876. pt_debug(dev, DL_ERROR,
  877. "%s: Firmware update failed with error code %d\n",
  878. __func__, rc);
  879. } else if (ld->loader_pdata &&
  880. (ld->loader_pdata->flags
  881. & PT_LOADER_FLAG_CALIBRATE_AFTER_FW_UPGRADE)) {
  882. #if (KERNEL_VERSION(3, 13, 0) <= LINUX_VERSION_CODE)
  883. reinit_completion(&ld->calibration_complete);
  884. #else
  885. INIT_COMPLETION(ld->calibration_complete);
  886. #endif
  887. /* set up call back for startup */
  888. pt_debug(dev, DL_INFO,
  889. "%s: Adding callback for calibration\n", __func__);
  890. rc = cmd->subscribe_attention(dev, PT_ATTEN_STARTUP,
  891. PT_LOADER_NAME, pt_calibration_attention, 0);
  892. if (rc) {
  893. pt_debug(dev, DL_ERROR,
  894. "%s: Failed adding callback for calibration\n",
  895. __func__);
  896. pt_debug(dev, DL_ERROR,
  897. "%s: No calibration will be performed\n",
  898. __func__);
  899. rc = 0;
  900. } else
  901. wait_for_calibration_complete = true;
  902. }
  903. cmd->release_exclusive(dev);
  904. exit:
  905. if (!rc) {
  906. cmd->request_enum(dev, true);
  907. /*
  908. * Wait for FW reset sentinel from reset or execute for up
  909. * to 500ms
  910. */
  911. t = wait_event_timeout(cd->wait_q,
  912. (cd->startup_status >=
  913. STARTUP_STATUS_FW_RESET_SENTINEL) &&
  914. (cd->mode == PT_MODE_OPERATIONAL),
  915. msecs_to_jiffies(PT_BL_WAIT_FOR_SENTINEL));
  916. if (IS_TMO(t)) {
  917. pt_debug(dev, DL_WARN,
  918. "%s: 0x%04X Timeout waiting for FW sentinel",
  919. __func__, cd->startup_status);
  920. }
  921. /* Double verify DUT is alive and well in Application mode */
  922. if (!(cd->startup_status & STARTUP_STATUS_FW_RESET_SENTINEL)) {
  923. pt_debug(dev, DL_ERROR,
  924. "%s FW sentinel not seen\n", __func__);
  925. *update_status = UPDATE_FW_SENTINEL_NOT_SEEN;
  926. } else if (cd->mode != PT_MODE_OPERATIONAL) {
  927. *update_status = UPDATE_FW_MODE_ERROR;
  928. pt_debug(dev, DL_ERROR,
  929. "%s ERROR: Not in App mode as expected\n",
  930. __func__);
  931. } else {
  932. *update_status = UPDATE_FW_COMPLETE;
  933. pt_debug(dev, DL_INFO,
  934. "%s == PIP1 FW upgrade finished ==\n",
  935. __func__);
  936. }
  937. } else if (*update_status < UPDATE_FW_COMPLETE) {
  938. *update_status = UPDATE_FW_UNDEFINED_ERROR;
  939. pt_debug(dev, DL_ERROR, "%s undefined error!\n", __func__);
  940. }
  941. pm_runtime_put_sync(dev);
  942. if (wait_for_calibration_complete)
  943. wait_for_completion(&ld->calibration_complete);
  944. return rc;
  945. }
  946. #endif /* PT_FW_UPGRADE */
  947. #ifdef CONFIG_TOUCHSCREEN_PARADE_PLATFORM_FW_UPGRADE
  948. /*******************************************************************************
  949. * FUNCTION: pt_check_firmware_version_platform
  950. *
  951. * SUMMARY: The caller of function pt_check_firmware_version() to determine
  952. * whether to load firmware from touch_firmware structure.
  953. *
  954. * RETURN:
  955. * 0: Don't upgrade
  956. * 1: Upgrade
  957. *
  958. * PARAMETERS:
  959. * *dev - pointer to device structure
  960. * *fw - pointer to the touch_firmware structure
  961. ******************************************************************************/
  962. static int pt_check_firmware_version_platform(struct device *dev,
  963. struct pt_touch_firmware *fw)
  964. {
  965. struct pt_loader_data *ld = pt_get_loader_data(dev);
  966. u32 fw_ver_new;
  967. u32 fw_revctrl_new;
  968. int upgrade;
  969. if (!ld->si) {
  970. pt_debug(dev, DL_WARN,
  971. "%s: No firmware info found, DUT FW may be corrupted\n",
  972. __func__);
  973. return PT_AUTO_LOAD_FOR_CORRUPTED_FW;
  974. }
  975. fw_ver_new = get_unaligned_be16(fw->ver + 2);
  976. /* 4 middle bytes are not used */
  977. fw_revctrl_new = get_unaligned_be32(fw->ver + 8);
  978. pt_debug(dev, DL_WARN, "%s: Built-in FW version 0x%04x rev %d\n",
  979. __func__, fw_ver_new, fw_revctrl_new);
  980. upgrade = pt_check_firmware_version(dev, fw_ver_new,
  981. fw_revctrl_new);
  982. if (upgrade > 0)
  983. return 1;
  984. return 0;
  985. }
  986. /*******************************************************************************
  987. * FUNCTION: pt_get_platform_firmware
  988. *
  989. * SUMMARY: To get the pointer of right touch_firmware structure by panel id.
  990. *
  991. * RETURN:
  992. * pointer to touch_firmware structure or null pointer if fail
  993. *
  994. * PARAMETERS:
  995. * *dev - pointer to device structure
  996. ******************************************************************************/
  997. static struct pt_touch_firmware *pt_get_platform_firmware(
  998. struct device *dev)
  999. {
  1000. struct pt_loader_data *ld = pt_get_loader_data(dev);
  1001. struct pt_touch_firmware **fws;
  1002. struct pt_touch_firmware *fw;
  1003. u8 panel_id;
  1004. panel_id = pt_get_panel_id(dev);
  1005. if (panel_id == PANEL_ID_NOT_ENABLED) {
  1006. pt_debug(dev, DL_WARN,
  1007. "%s: Panel ID not enabled, using legacy firmware\n",
  1008. __func__);
  1009. return ld->loader_pdata->fw;
  1010. }
  1011. fws = ld->loader_pdata->fws;
  1012. if (!fws) {
  1013. pt_debug(dev, DL_ERROR,
  1014. "%s: No firmwares provided\n", __func__);
  1015. return NULL;
  1016. }
  1017. /* Find FW according to the Panel ID */
  1018. while ((fw = *fws++)) {
  1019. if (fw->panel_id == panel_id) {
  1020. pt_debug(dev, DL_WARN,
  1021. "%s: Found matching fw:%p with Panel ID: 0x%02X\n",
  1022. __func__, fw, fw->panel_id);
  1023. return fw;
  1024. }
  1025. pt_debug(dev, DL_WARN,
  1026. "%s: Found mismatching fw:%p with Panel ID: 0x%02X\n",
  1027. __func__, fw, fw->panel_id);
  1028. }
  1029. return NULL;
  1030. }
  1031. /*******************************************************************************
  1032. * FUNCTION: upgrade_firmware_from_platform
  1033. *
  1034. * SUMMARY: Get touch_firmware structure and perform upgrade if pass the
  1035. * firmware version check.
  1036. *
  1037. * RETURN:
  1038. * 0 = success
  1039. * !0 = failure
  1040. *
  1041. * PARAMETERS:
  1042. * *dev - pointer to device structure
  1043. * forced - flag to force upgrade(1:force to upgrade)
  1044. ******************************************************************************/
  1045. static int upgrade_firmware_from_platform(struct device *dev,
  1046. bool forced)
  1047. {
  1048. struct pt_loader_data *ld = pt_get_loader_data(dev);
  1049. struct pt_core_data *cd = dev_get_drvdata(dev);
  1050. struct pt_touch_firmware *fw;
  1051. int rc = -ENODEV;
  1052. int upgrade;
  1053. int retry = 3;
  1054. retry_bl:
  1055. if (!ld->loader_pdata) {
  1056. _pt_update_write_file_status(dev, UPDATE_FW_NO_PLATFORM_DATA);
  1057. pt_debug(dev, DL_ERROR,
  1058. "%s: No loader platform data\n", __func__);
  1059. return rc;
  1060. }
  1061. fw = pt_get_platform_firmware(dev);
  1062. if (!fw || !fw->img || !fw->size) {
  1063. _pt_update_write_file_status(dev, UPDATE_FW_NO_FW_PROVIDED);
  1064. pt_debug(dev, DL_ERROR,
  1065. "%s: No platform firmware\n", __func__);
  1066. return rc;
  1067. }
  1068. if (!fw->ver || !fw->vsize) {
  1069. _pt_update_write_file_status(dev, UPDATE_FW_INVALID_FW_IMAGE);
  1070. pt_debug(dev, DL_ERROR, "%s: No platform firmware version\n",
  1071. __func__);
  1072. return rc;
  1073. }
  1074. if (forced)
  1075. upgrade = forced;
  1076. else
  1077. upgrade = pt_check_firmware_version_platform(dev, fw);
  1078. if (upgrade) {
  1079. rc = pt_upgrade_firmware(dev,
  1080. fw->img, fw->size, &write_file_status);
  1081. /* An extra BL may be needed if default PID was wrong choice */
  1082. if ((cd->panel_id_support & PT_PANEL_ID_BY_SYS_INFO) &&
  1083. !rc && !ld->si && retry--) {
  1084. pt_debug(dev, DL_WARN, "%s: ATM - An extra BL may be needed\n",
  1085. __func__);
  1086. /* Panel_ID coming from sysinfo, ensure we have it */
  1087. ld->si = cmd->request_sysinfo(dev);
  1088. goto retry_bl;
  1089. }
  1090. }
  1091. return rc;
  1092. }
  1093. #endif /* CONFIG_TOUCHSCREEN_PARADE_PLATFORM_FW_UPGRADE */
  1094. #ifdef CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE
  1095. /*******************************************************************************
  1096. * FUNCTION: _pt_pip1_bl_from_file
  1097. *
  1098. * SUMMARY: Wrapper function for _pt_firmware_cont() to perform bl with an
  1099. * image file from userspace.
  1100. *
  1101. * PARAMETERS:
  1102. * *fw - pointer to firmware structure
  1103. * forced - flag to force upgrade(1:force to upgrade)
  1104. ******************************************************************************/
  1105. static int _pt_pip1_bl_from_file(struct device *dev)
  1106. {
  1107. struct pt_core_data *cd = dev_get_drvdata(dev);
  1108. int fw_size = 0;
  1109. int rc = 0;
  1110. u8 *fw_img = NULL;
  1111. u8 header_size = 0;
  1112. _pt_update_write_file_status(dev, UPDATE_FW_IDLE);
  1113. fw_img = kzalloc(PT_PIP2_MAX_FILE_SIZE, GFP_KERNEL);
  1114. if (!fw_img) {
  1115. _pt_update_write_file_status(dev, UPDATE_FW_SYSTEM_NOMEM);
  1116. rc = -ENOMEM;
  1117. goto exit;
  1118. }
  1119. rc = cmd->nonhid_cmd->read_us_file(dev, cd->pip2_us_file_path,
  1120. fw_img, &fw_size);
  1121. if (rc) {
  1122. pt_debug(dev, DL_ERROR, "%s: No firmware provided to load\n",
  1123. __func__);
  1124. _pt_update_write_file_status(dev, UPDATE_FW_NO_FW_PROVIDED);
  1125. goto exit;
  1126. }
  1127. if (!fw_img || !fw_size) {
  1128. pt_debug(dev, DL_ERROR,
  1129. "%s: No firmware received\n", __func__);
  1130. _pt_update_write_file_status(dev, UPDATE_FW_INVALID_FW_IMAGE);
  1131. goto exit;
  1132. }
  1133. header_size = fw_img[0];
  1134. if (header_size >= (fw_size + 1)) {
  1135. pt_debug(dev, DL_ERROR,
  1136. "%s: Firmware format is invalid\n", __func__);
  1137. _pt_update_write_file_status(dev, UPDATE_FW_INVALID_FW_IMAGE);
  1138. goto exit;
  1139. }
  1140. pt_upgrade_firmware(dev, &(fw_img[header_size + 1]),
  1141. fw_size - (header_size + 1), &write_file_status);
  1142. exit:
  1143. kfree(fw_img);
  1144. return rc;
  1145. }
  1146. /*******************************************************************************
  1147. * FUNCTION: _pt_firmware_cont
  1148. *
  1149. * SUMMARY: Firmware upgrade continue function that verifies the firmware size
  1150. * in the firmware class and then upgrades the firmware.
  1151. *
  1152. * PARAMETERS:
  1153. * *fw - pointer to firmware structure
  1154. * forced - flag to force upgrade(1:force to upgrade)
  1155. ******************************************************************************/
  1156. static void _pt_firmware_cont(const struct firmware *fw, void *context)
  1157. {
  1158. struct device *dev = context;
  1159. struct pt_loader_data *ld = pt_get_loader_data(dev);
  1160. u8 header_size = 0;
  1161. _pt_update_write_file_status(dev, UPDATE_FW_IDLE);
  1162. if (!fw) {
  1163. pt_debug(dev, DL_ERROR, "%s: No firmware\n", __func__);
  1164. _pt_update_write_file_status(dev, UPDATE_FW_NO_FW_PROVIDED);
  1165. goto pt_firmware_cont_exit;
  1166. }
  1167. if (!fw->data || !fw->size) {
  1168. pt_debug(dev, DL_ERROR,
  1169. "%s: No firmware received\n", __func__);
  1170. _pt_update_write_file_status(dev, UPDATE_FW_INVALID_FW_IMAGE);
  1171. goto pt_firmware_cont_release_exit;
  1172. }
  1173. header_size = fw->data[0];
  1174. if (header_size >= (fw->size + 1)) {
  1175. pt_debug(dev, DL_ERROR,
  1176. "%s: Firmware format is invalid\n", __func__);
  1177. _pt_update_write_file_status(dev, UPDATE_FW_INVALID_FW_IMAGE);
  1178. goto pt_firmware_cont_release_exit;
  1179. }
  1180. pt_upgrade_firmware(dev, &(fw->data[header_size + 1]),
  1181. fw->size - (header_size + 1), &write_file_status);
  1182. pt_firmware_cont_release_exit:
  1183. if (fw)
  1184. release_firmware(fw);
  1185. pt_firmware_cont_exit:
  1186. ld->is_manual_upgrade_enabled = 0;
  1187. }
  1188. /*******************************************************************************
  1189. * FUNCTION: pt_check_firmware_config_version
  1190. *
  1191. * SUMMARY: Compare fw's config version with fw image's. If they are differnt
  1192. * report a FW upgrade is needed.
  1193. *
  1194. * RETURN:
  1195. * -1: Do not upgrade firmware
  1196. * 0: Version info same, let caller decide
  1197. * 1: Do a firmware upgrade
  1198. *
  1199. * PARAMETERS:
  1200. * *dev - pointer to device structure
  1201. * image_config_ver - Image's firmware config version
  1202. ******************************************************************************/
  1203. static int pt_check_firmware_config_version(struct device *dev,
  1204. u16 image_config_ver)
  1205. {
  1206. struct pt_loader_data *ld = pt_get_loader_data(dev);
  1207. u16 fw_config_ver;
  1208. fw_config_ver = ld->si->ttdata.fw_ver_conf;
  1209. pt_debug(dev, DL_WARN,
  1210. "%s: Current config ver:0x%04X New config ver:0x%04X\n",
  1211. __func__, fw_config_ver, image_config_ver);
  1212. if (image_config_ver != fw_config_ver) {
  1213. pt_debug(dev, DL_WARN,
  1214. "%s: Image config ver is different, will upgrade\n",
  1215. __func__);
  1216. return 1;
  1217. }
  1218. if (image_config_ver == fw_config_ver) {
  1219. pt_debug(dev, DL_WARN,
  1220. "%s: Image config ver is the same, will NOT upgrade\n",
  1221. __func__);
  1222. return 0;
  1223. }
  1224. return -1;
  1225. }
  1226. /*******************************************************************************
  1227. * FUNCTION: pt_check_firmware_version_builtin
  1228. *
  1229. * SUMMARY: The caller of function pt_check_firmware_version() to determine
  1230. * whether to load built-in firmware.
  1231. *
  1232. * RETURN:
  1233. * 0: Don't upgrade
  1234. * 1: Upgrade
  1235. *
  1236. * PARAMETERS:
  1237. * *dev - pointer to device structure
  1238. * *fw - pointer to the firmware structure
  1239. ******************************************************************************/
  1240. static int pt_check_firmware_version_builtin(struct device *dev,
  1241. const struct firmware *fw)
  1242. {
  1243. struct pt_loader_data *ld = pt_get_loader_data(dev);
  1244. u16 fw_config_ver_new;
  1245. u32 fw_ver_new;
  1246. u32 fw_revctrl_new;
  1247. int upgrade;
  1248. if (!ld->si) {
  1249. pt_debug(dev, DL_WARN,
  1250. "%s: No firmware info found, DUT FW may be corrupted\n",
  1251. __func__);
  1252. return PT_AUTO_LOAD_FOR_CORRUPTED_FW;
  1253. }
  1254. fw_ver_new = get_unaligned_be16(fw->data + 3);
  1255. /* 4 middle bytes are not used */
  1256. fw_revctrl_new = get_unaligned_be32(fw->data + 9);
  1257. /* Offset 17,18 is the TT Config version*/
  1258. fw_config_ver_new = get_unaligned_be16(fw->data + 17);
  1259. pt_debug(dev, DL_WARN,
  1260. "%s: Built-in FW version=0x%04x rev=%d config=0x%04X\n",
  1261. __func__, fw_ver_new, fw_revctrl_new, fw_config_ver_new);
  1262. upgrade = pt_check_firmware_version(dev, fw_ver_new,
  1263. fw_revctrl_new);
  1264. /* Only check config version if FW version was an exact match */
  1265. if (upgrade == 0)
  1266. upgrade = pt_check_firmware_config_version(dev,
  1267. fw_config_ver_new);
  1268. if (upgrade > 0)
  1269. return 1;
  1270. return 0;
  1271. }
  1272. /*******************************************************************************
  1273. * FUNCTION: _pt_firmware_cont_builtin
  1274. *
  1275. * SUMMARY: Perform upgrade if pass the firmware version check.
  1276. *
  1277. * PARAMETERS:
  1278. * *dev - pointer to device structure
  1279. * forced - flag to force upgrade(1:force to upgrade)
  1280. ******************************************************************************/
  1281. static void _pt_firmware_cont_builtin(const struct firmware *fw,
  1282. void *context)
  1283. {
  1284. struct device *dev = context;
  1285. struct pt_loader_data *ld = pt_get_loader_data(dev);
  1286. int upgrade;
  1287. if (!fw) {
  1288. pt_debug(dev, DL_INFO,
  1289. "%s: No builtin firmware\n", __func__);
  1290. goto _pt_firmware_cont_builtin_exit;
  1291. }
  1292. if (!fw->data || !fw->size) {
  1293. pt_debug(dev, DL_ERROR,
  1294. "%s: Invalid builtin firmware\n", __func__);
  1295. goto _pt_firmware_cont_builtin_exit;
  1296. }
  1297. pt_debug(dev, DL_WARN, "%s: Found firmware\n", __func__);
  1298. upgrade = pt_check_firmware_version_builtin(dev, fw);
  1299. if (upgrade) {
  1300. _pt_firmware_cont(fw, dev);
  1301. ld->builtin_bin_fw_status = 0;
  1302. return;
  1303. }
  1304. _pt_firmware_cont_builtin_exit:
  1305. if (fw)
  1306. release_firmware(fw);
  1307. ld->builtin_bin_fw_status = -EINVAL;
  1308. }
  1309. /*******************************************************************************
  1310. * FUNCTION: upgrade_firmware_from_class
  1311. *
  1312. * SUMMARY: Create the firmware class but don't actually load any FW to the
  1313. * DUT. This creates all the sysfs nodes needed for a user to bootload
  1314. * the DUT with their own bin file.
  1315. *
  1316. * RETURN:
  1317. * 0 = success
  1318. *
  1319. * PARAMETERS:
  1320. * *dev - pointer to device structure
  1321. ******************************************************************************/
  1322. static int upgrade_firmware_from_class(struct device *dev)
  1323. {
  1324. int retval;
  1325. pt_debug(dev, DL_INFO,
  1326. "%s: Enabling firmware class loader\n", __func__);
  1327. retval = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG,
  1328. dev_name(dev), dev, GFP_KERNEL, dev,
  1329. _pt_firmware_cont);
  1330. if (retval < 0) {
  1331. pt_debug(dev, DL_ERROR,
  1332. "%s: Fail request firmware class file load\n",
  1333. __func__);
  1334. return retval;
  1335. }
  1336. return 0;
  1337. }
  1338. #define FILENAME_LEN_MAX 64
  1339. /*******************************************************************************
  1340. * FUNCTION: generate_firmware_filename
  1341. *
  1342. * SUMMARY: Generate firmware file name by panel id. Generates binary FW
  1343. * filename as following:
  1344. * - Panel ID not enabled: tt_fw.bin
  1345. * - Panel ID enabled: tt_fw_pidXX.bin
  1346. *
  1347. * RETURN:
  1348. * pointer to file name or null pointer if fail
  1349. *
  1350. * PARAMETERS:
  1351. * *dev - pointer to device structure
  1352. ******************************************************************************/
  1353. static char *generate_firmware_filename(struct device *dev)
  1354. {
  1355. char *filename;
  1356. u8 panel_id;
  1357. filename = kzalloc(FILENAME_LEN_MAX, GFP_KERNEL);
  1358. if (!filename)
  1359. return NULL;
  1360. panel_id = pt_get_panel_id(dev);
  1361. if (panel_id == PANEL_ID_NOT_ENABLED)
  1362. snprintf(filename, FILENAME_LEN_MAX, "%s", PT_FW_FILE_NAME);
  1363. else
  1364. snprintf(filename, FILENAME_LEN_MAX, "%s_pid%02X%s",
  1365. PT_FW_FILE_PREFIX, panel_id, PT_FW_FILE_SUFFIX);
  1366. pt_debug(dev, DL_INFO, "%s: Filename: %s\n",
  1367. __func__, filename);
  1368. return filename;
  1369. }
  1370. /*******************************************************************************
  1371. * FUNCTION: generate_silicon_id_firmware_filename
  1372. *
  1373. * SUMMARY: Generate firmware file name with the HW version prefix followed by
  1374. * panel id. Generates binary FW filename as following (where XXXX is the
  1375. * silicon ID):
  1376. * - Panel ID not enabled: XXXX_tt_fw.bin
  1377. * - Panel ID enabled: XXXX_tt_fw_pidXX.bin
  1378. *
  1379. * RETURN:
  1380. * pointer to file name or null pointer if fail
  1381. *
  1382. * PARAMETERS:
  1383. * *dev - pointer to device structure
  1384. ******************************************************************************/
  1385. static char *generate_silicon_id_firmware_filename(struct device *dev)
  1386. {
  1387. struct pt_core_data *cd = dev_get_drvdata(dev);
  1388. char *filename;
  1389. char si_id[5] = "DEAD";
  1390. u8 panel_id;
  1391. filename = kzalloc(FILENAME_LEN_MAX, GFP_KERNEL);
  1392. if (!filename)
  1393. return NULL;
  1394. panel_id = pt_get_panel_id(dev);
  1395. memcpy(si_id, cd->hw_version, 4);
  1396. if (panel_id == PANEL_ID_NOT_ENABLED)
  1397. snprintf(filename, FILENAME_LEN_MAX, "%s_%s", si_id,
  1398. PT_FW_FILE_NAME);
  1399. else
  1400. snprintf(filename, FILENAME_LEN_MAX, "%s_%s_pid%02X%s",
  1401. si_id, PT_FW_FILE_PREFIX, panel_id, PT_FW_FILE_SUFFIX);
  1402. pt_debug(dev, DL_INFO, "%s: Filename: %s\n", __func__, filename);
  1403. return filename;
  1404. }
  1405. #define MAX_FILE_NAMES 2
  1406. /*******************************************************************************
  1407. * FUNCTION: upgrade_firmware_from_builtin
  1408. *
  1409. * SUMMARY: Create the firmware class load FW by searching the name of built-in
  1410. * file. Then perform upgrade after getting the file.
  1411. *
  1412. * RETURN:
  1413. * 0 = success
  1414. * !0 = failure
  1415. *
  1416. * PARAMETERS:
  1417. * *dev - pointer to device structure
  1418. ******************************************************************************/
  1419. static int upgrade_firmware_from_builtin(struct device *dev)
  1420. {
  1421. struct pt_loader_data *ld = pt_get_loader_data(dev);
  1422. struct pt_core_data *cd = dev_get_drvdata(dev);
  1423. char *filename[MAX_FILE_NAMES];
  1424. int index = 0;
  1425. int retval;
  1426. const struct firmware *fw_entry = NULL;
  1427. int retry = 3;
  1428. retry_bl:
  1429. pt_debug(dev, DL_WARN,
  1430. "%s: Enabling firmware class loader built-in\n",
  1431. __func__);
  1432. /* Load the supported file names in the search order */
  1433. /* 0 = Flash file name with optional PID "pt_fw<_PIDX>.bin" */
  1434. filename[0] = generate_firmware_filename(dev);
  1435. if (!filename[0]) {
  1436. pt_debug(dev, DL_ERROR,
  1437. "%s: ERROR - Could not generate filename\n", __func__);
  1438. return -ENOMEM;
  1439. }
  1440. /*
  1441. * 1 = Flash file name with Silicon ID prefix and optional PID
  1442. * "XXXX_pt_fw<_PIDX>.bin"
  1443. */
  1444. filename[1] = generate_silicon_id_firmware_filename(dev);
  1445. if (!filename[1]) {
  1446. pt_debug(dev, DL_ERROR,
  1447. "%s: ERROR - Could not generate filename\n", __func__);
  1448. return -ENOMEM;
  1449. }
  1450. mutex_lock(&cd->firmware_class_lock);
  1451. while (index < MAX_FILE_NAMES) {
  1452. pt_debug(dev, DL_WARN, "%s: Request FW file %s\n", __func__,
  1453. filename[index]);
  1454. #if (KERNEL_VERSION(3, 13, 0) > LINUX_VERSION_CODE)
  1455. retval = request_firmware(&fw_entry, filename[index], dev);
  1456. #else
  1457. retval = request_firmware_direct(&fw_entry,
  1458. filename[index], dev);
  1459. #endif
  1460. if (retval < 0) {
  1461. pt_debug(dev, DL_WARN, "%s: Fail request FW %s load\n",
  1462. __func__, filename[index]);
  1463. } else {
  1464. pt_debug(dev, DL_WARN, "%s: FW %s class file loading\n",
  1465. __func__, filename[index]);
  1466. break;
  1467. }
  1468. index++;
  1469. }
  1470. /* Proceed with the BL if a matching file was found */
  1471. if (index != MAX_FILE_NAMES) {
  1472. _pt_firmware_cont_builtin(fw_entry, dev);
  1473. /* An extra BL may be needed if default PID was wrong choice */
  1474. if ((cd->panel_id_support & PT_PANEL_ID_BY_SYS_INFO) &&
  1475. !ld->si && retry--) {
  1476. pt_debug(dev, DL_WARN, "%s: ATM - An extra BL may be needed\n",
  1477. __func__);
  1478. /* Free allocated memory */
  1479. index = 0;
  1480. while (index < MAX_FILE_NAMES)
  1481. kfree(filename[index++]);
  1482. /* Reset index to 0 */
  1483. index = 0;
  1484. mutex_unlock(&cd->firmware_class_lock);
  1485. /* Panel_ID coming from sysinfo, ensure we have it */
  1486. ld->si = cmd->request_sysinfo(dev);
  1487. goto retry_bl;
  1488. }
  1489. retval = ld->builtin_bin_fw_status;
  1490. }
  1491. index = 0;
  1492. while (index < MAX_FILE_NAMES)
  1493. kfree(filename[index++]);
  1494. mutex_unlock(&cd->firmware_class_lock);
  1495. return retval;
  1496. }
  1497. #endif /* CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE */
  1498. #ifndef TTDL_KERNEL_SUBMISSION
  1499. #if PT_TTCONFIG_UPGRADE
  1500. /*******************************************************************************
  1501. * FUNCTION: pt_write_config_row_
  1502. *
  1503. * SUMMARY: Allow to program the data block area that includes configuration
  1504. * data, manufacturing data, design data.
  1505. *
  1506. * RETURN:
  1507. * 0 = success
  1508. * !0 = failure
  1509. *
  1510. * PARAMETERS:
  1511. * *dev - pointer to device structure
  1512. * ebid - block id to determine the block name(configuration,etc)
  1513. * row_number - row number if written block
  1514. * row_size - row size of written data
  1515. * *data - pointer to the data to write
  1516. ******************************************************************************/
  1517. static int pt_write_config_row_(struct device *dev, u8 ebid,
  1518. u16 row_number, u16 row_size, u8 *data)
  1519. {
  1520. int rc;
  1521. u16 actual_write_len;
  1522. rc = cmd->nonhid_cmd->write_data_block(dev, row_number,
  1523. row_size, ebid, data, (u8 *)pt_data_block_security_key,
  1524. &actual_write_len);
  1525. if (rc) {
  1526. pt_debug(dev, DL_ERROR,
  1527. "%s: Fail Put EBID=%d row=%d cmd fail r=%d\n",
  1528. __func__, ebid, row_number, rc);
  1529. return rc;
  1530. }
  1531. if (actual_write_len != row_size) {
  1532. pt_debug(dev, DL_ERROR,
  1533. "%s: Fail Put EBID=%d row=%d wrong write size=%d\n",
  1534. __func__, ebid, row_number, actual_write_len);
  1535. rc = -EINVAL;
  1536. }
  1537. return rc;
  1538. }
  1539. /*******************************************************************************
  1540. * FUNCTION: pt_upgrade_ttconfig
  1541. *
  1542. * SUMMARY: Program ttconfig_data with following steps:
  1543. * 1) Suspend scanning
  1544. * 2) Write data to the data block
  1545. * 3) Verify the crc for data block
  1546. * 4) Resume scanning
  1547. * 5) Set up call back for calibration if required
  1548. *
  1549. * RETURN:
  1550. * 0 = success
  1551. * !0 = failure
  1552. *
  1553. * PARAMETERS:
  1554. * *dev - pointer to device structure
  1555. * *ttconfig_data - pointer to the config data to write to data block
  1556. * ttconfig_size - size of config data to write
  1557. ******************************************************************************/
  1558. static int pt_upgrade_ttconfig(struct device *dev,
  1559. const u8 *ttconfig_data, int ttconfig_size)
  1560. {
  1561. struct pt_loader_data *ld = pt_get_loader_data(dev);
  1562. bool wait_for_calibration_complete = false;
  1563. u8 ebid = PT_TCH_PARM_EBID;
  1564. u16 row_size = PT_DATA_ROW_SIZE;
  1565. u16 table_size;
  1566. u16 row_count;
  1567. u16 residue;
  1568. u8 *row_buf;
  1569. u8 verify_crc_status;
  1570. u16 calculated_crc;
  1571. u16 stored_crc;
  1572. int rc = 0;
  1573. int i;
  1574. table_size = ttconfig_size;
  1575. row_count = table_size / row_size;
  1576. row_buf = (u8 *)ttconfig_data;
  1577. pt_debug(dev, DL_INFO, "%s: size:%d row_size=%d row_count=%d\n",
  1578. __func__, table_size, row_size, row_count);
  1579. pm_runtime_get_sync(dev);
  1580. rc = cmd->request_exclusive(dev, PT_LDR_REQUEST_EXCLUSIVE_TIMEOUT);
  1581. if (rc < 0)
  1582. goto exit;
  1583. rc = cmd->nonhid_cmd->suspend_scanning(dev, 0);
  1584. if (rc < 0)
  1585. goto release;
  1586. for (i = 0; i < row_count; i++) {
  1587. pt_debug(dev, DL_INFO, "%s: row=%d size=%d\n",
  1588. __func__, i, row_size);
  1589. rc = pt_write_config_row_(dev, ebid, i, row_size,
  1590. row_buf);
  1591. if (rc) {
  1592. pt_debug(dev, DL_ERROR, "%s: Fail put row=%d r=%d\n",
  1593. __func__, i, rc);
  1594. break;
  1595. }
  1596. row_buf += row_size;
  1597. }
  1598. if (!rc) {
  1599. residue = table_size % row_size;
  1600. pt_debug(dev, DL_WARN, "%s: row=%d size=%d\n",
  1601. __func__, i, residue);
  1602. rc = pt_write_config_row_(dev, ebid, i, residue,
  1603. row_buf);
  1604. row_count++;
  1605. if (rc)
  1606. pt_debug(dev, DL_ERROR, "%s: Fail put row=%d r=%d\n",
  1607. __func__, i, rc);
  1608. }
  1609. if (!rc)
  1610. pt_debug(dev, DL_WARN,
  1611. "%s: TT_CFG updated: rows:%d bytes:%d\n",
  1612. __func__, row_count, table_size);
  1613. rc = cmd->nonhid_cmd->verify_cfg_block_crc(dev, 0, ebid,
  1614. &verify_crc_status, &calculated_crc, &stored_crc);
  1615. if (rc || verify_crc_status)
  1616. pt_debug(dev, DL_ERROR,
  1617. "%s: CRC Failed, ebid=%d, status=%d, scrc=%X ccrc=%X\n",
  1618. __func__, ebid, verify_crc_status,
  1619. calculated_crc, stored_crc);
  1620. else
  1621. pt_debug(dev, DL_INFO,
  1622. "%s: CRC PASS, ebid=%d, status=%d, scrc=%X ccrc=%X\n",
  1623. __func__, ebid, verify_crc_status,
  1624. calculated_crc, stored_crc);
  1625. rc = cmd->nonhid_cmd->resume_scanning(dev, 0);
  1626. if (rc < 0)
  1627. goto release;
  1628. if (ld->loader_pdata &&
  1629. (ld->loader_pdata->flags
  1630. & PT_LOADER_FLAG_CALIBRATE_AFTER_TTCONFIG_UPGRADE)) {
  1631. #if (KERNEL_VERSION(3, 13, 0) <= LINUX_VERSION_CODE)
  1632. reinit_completion(&ld->calibration_complete);
  1633. #else
  1634. INIT_COMPLETION(ld->calibration_complete);
  1635. #endif
  1636. /* set up call back for startup */
  1637. pt_debug(dev, DL_INFO, "%s: Adding callback for calibration\n",
  1638. __func__);
  1639. rc = cmd->subscribe_attention(dev, PT_ATTEN_STARTUP,
  1640. PT_LOADER_NAME, pt_calibration_attention, 0);
  1641. if (rc) {
  1642. pt_debug(dev, DL_ERROR,
  1643. "%s: Failed adding callback for calibration\n",
  1644. __func__);
  1645. pt_debug(dev, DL_ERROR,
  1646. "%s: No calibration will be performed\n",
  1647. __func__);
  1648. rc = 0;
  1649. } else
  1650. wait_for_calibration_complete = true;
  1651. }
  1652. release:
  1653. cmd->release_exclusive(dev);
  1654. exit:
  1655. if (!rc)
  1656. cmd->request_enum(dev, true);
  1657. pm_runtime_put_sync(dev);
  1658. if (wait_for_calibration_complete)
  1659. wait_for_completion(&ld->calibration_complete);
  1660. return rc;
  1661. }
  1662. #endif /* PT_TTCONFIG_UPGRADE */
  1663. #ifdef CONFIG_TOUCHSCREEN_PARADE_PLATFORM_TTCONFIG_UPGRADE
  1664. /*******************************************************************************
  1665. * FUNCTION: pt_get_ttconfig_crc
  1666. *
  1667. * SUMMARY: Get crc from ttconfig data.
  1668. *
  1669. * RETURN:
  1670. * 0 = success
  1671. * !0 = failure
  1672. *
  1673. * PARAMETERS:
  1674. * *dev - pointer to device structure
  1675. * *ttconfig_data - pointer to the config data
  1676. * ttconfig_size - size of config data
  1677. * *crc - pointer to the crc of configure to be stored
  1678. ******************************************************************************/
  1679. static int pt_get_ttconfig_crc(struct device *dev,
  1680. const u8 *ttconfig_data, int ttconfig_size, u16 *crc)
  1681. {
  1682. u16 crc_loc;
  1683. crc_loc = get_unaligned_le16(&ttconfig_data[2]);
  1684. if (ttconfig_size < crc_loc + 2)
  1685. return -EINVAL;
  1686. *crc = get_unaligned_le16(&ttconfig_data[crc_loc]);
  1687. return 0;
  1688. }
  1689. /*******************************************************************************
  1690. * FUNCTION: pt_get_ttconfig_version
  1691. *
  1692. * SUMMARY: Get version number from ttconfig data.
  1693. *
  1694. * RETURN:
  1695. * 0 = success
  1696. * !0 = failure
  1697. *
  1698. * PARAMETERS:
  1699. * *dev - pointer to device structure
  1700. * *ttconfig_data - pointer to the config data
  1701. * ttconfig_size - size of config data
  1702. * *version - pointer to the version of configure to be stored
  1703. ******************************************************************************/
  1704. static int pt_get_ttconfig_version(struct device *dev,
  1705. const u8 *ttconfig_data, int ttconfig_size, u16 *version)
  1706. {
  1707. if (ttconfig_size < PT_TTCONFIG_VERSION_OFFSET
  1708. + PT_TTCONFIG_VERSION_SIZE)
  1709. return -EINVAL;
  1710. *version = get_unaligned_le16(
  1711. &ttconfig_data[PT_TTCONFIG_VERSION_OFFSET]);
  1712. return 0;
  1713. }
  1714. /*******************************************************************************
  1715. * FUNCTION: pt_check_ttconfig_version
  1716. *
  1717. * SUMMARY: Check the configure version and crc value to determine whether to
  1718. * upgrade,the upgrade conditions as following:
  1719. * 1) To upgrade if the config version is newer than current config, but
  1720. * this check is based on the flag in loader plarform data.
  1721. * 2) To upgrade if config CRC is different.
  1722. * 3) Don't upgrade when can't match any of above conditions.
  1723. *
  1724. * RETURN:
  1725. * 0: Don't upgrade
  1726. * 1: Upgrade
  1727. *
  1728. * PARAMETERS:
  1729. * *dev - pointer to device structure
  1730. * *ttconfig_data - pointer to the config data
  1731. * ttconfig_size - size of config data
  1732. ******************************************************************************/
  1733. static int pt_check_ttconfig_version(struct device *dev,
  1734. const u8 *ttconfig_data, int ttconfig_size)
  1735. {
  1736. struct pt_loader_data *ld = pt_get_loader_data(dev);
  1737. u16 cfg_crc_new;
  1738. int rc;
  1739. if (!ld->si)
  1740. return 0;
  1741. /* Check for config version */
  1742. if (ld->loader_pdata->flags &
  1743. PT_LOADER_FLAG_CHECK_TTCONFIG_VERSION) {
  1744. u16 cfg_ver_new;
  1745. rc = pt_get_ttconfig_version(dev, ttconfig_data,
  1746. ttconfig_size, &cfg_ver_new);
  1747. if (rc)
  1748. return 0;
  1749. pt_debug(dev, DL_INFO, "%s: img_ver:0x%04X new_ver:0x%04X\n",
  1750. __func__, ld->si->ttdata.fw_ver_conf, cfg_ver_new);
  1751. /* Check if config version is newer */
  1752. if (cfg_ver_new > ld->si->ttdata.fw_ver_conf) {
  1753. pt_debug(dev, DL_WARN,
  1754. "%s: Config version newer, will upgrade\n", __func__);
  1755. return 1;
  1756. }
  1757. pt_debug(dev, DL_WARN,
  1758. "%s: Config version is identical or older, will NOT upgrade\n",
  1759. __func__);
  1760. /* Check for config CRC */
  1761. } else {
  1762. rc = pt_get_ttconfig_crc(dev, ttconfig_data,
  1763. ttconfig_size, &cfg_crc_new);
  1764. if (rc)
  1765. return 0;
  1766. pt_debug(dev, DL_INFO, "%s: img_crc:0x%04X new_crc:0x%04X\n",
  1767. __func__, ld->si->ttconfig.crc, cfg_crc_new);
  1768. if (cfg_crc_new != ld->si->ttconfig.crc) {
  1769. pt_debug(dev, DL_WARN,
  1770. "%s: Config CRC different, will upgrade\n",
  1771. __func__);
  1772. return 1;
  1773. }
  1774. pt_debug(dev, DL_WARN,
  1775. "%s: Config CRC equal, will NOT upgrade\n", __func__);
  1776. }
  1777. return 0;
  1778. }
  1779. /*******************************************************************************
  1780. * FUNCTION: pt_check_ttconfig_version_platform
  1781. *
  1782. * SUMMARY: To call the function pt_check_ttconfig_version() to determine
  1783. * whether to load config if the firmware version match with current firmware.
  1784. *
  1785. * RETURN:
  1786. * 0: Don't upgrade
  1787. * 1: Upgrade
  1788. *
  1789. * PARAMETERS:
  1790. * *dev - pointer to device structure
  1791. * *ttconfig - pointer to touch_config structure
  1792. ******************************************************************************/
  1793. static int pt_check_ttconfig_version_platform(struct device *dev,
  1794. struct pt_touch_config *ttconfig)
  1795. {
  1796. struct pt_loader_data *ld = pt_get_loader_data(dev);
  1797. u32 fw_ver_config;
  1798. u32 fw_revctrl_config;
  1799. if (!ld->si) {
  1800. pt_debug(dev, DL_INFO,
  1801. "%s: No firmware info found, DUT FW may be corrupted\n",
  1802. __func__);
  1803. return 0;
  1804. }
  1805. fw_ver_config = get_unaligned_be16(ttconfig->fw_ver + 2);
  1806. /* 4 middle bytes are not used */
  1807. fw_revctrl_config = get_unaligned_be32(ttconfig->fw_ver + 8);
  1808. /* FW versions should match */
  1809. if (pt_check_firmware_version(dev, fw_ver_config,
  1810. fw_revctrl_config)) {
  1811. pt_debug(dev, DL_ERROR,
  1812. "%s: FW versions mismatch\n", __func__);
  1813. return 0;
  1814. }
  1815. /* Check PowerOn Self Test, TT_CFG CRC bit */
  1816. if ((ld->si->ttdata.post_code & PT_POST_TT_CFG_CRC_MASK) == 0) {
  1817. pt_debug(dev, DL_ERROR,
  1818. "%s: POST, TT_CFG failed (%X), will upgrade\n",
  1819. __func__, ld->si->ttdata.post_code);
  1820. return 1;
  1821. }
  1822. return pt_check_ttconfig_version(dev, ttconfig->param_regs->data,
  1823. ttconfig->param_regs->size);
  1824. }
  1825. /*******************************************************************************
  1826. * FUNCTION: pt_get_platform_ttconfig
  1827. *
  1828. * SUMMARY: To get the pointer of right touch_config structure by panel id.
  1829. *
  1830. * RETURN:
  1831. * pointer to touch_config structure or null pointer if fail
  1832. *
  1833. * PARAMETERS:
  1834. * *dev - pointer to device structure
  1835. ******************************************************************************/
  1836. static struct pt_touch_config *pt_get_platform_ttconfig(
  1837. struct device *dev)
  1838. {
  1839. struct pt_loader_data *ld = pt_get_loader_data(dev);
  1840. struct pt_touch_config **ttconfigs;
  1841. struct pt_touch_config *ttconfig;
  1842. u8 panel_id;
  1843. panel_id = pt_get_panel_id(dev);
  1844. if (panel_id == PANEL_ID_NOT_ENABLED) {
  1845. /* TODO: Make debug message */
  1846. pt_debug(dev, DL_INFO,
  1847. "%s: Panel ID not enabled, using legacy ttconfig\n",
  1848. __func__);
  1849. return ld->loader_pdata->ttconfig;
  1850. }
  1851. ttconfigs = ld->loader_pdata->ttconfigs;
  1852. if (!ttconfigs)
  1853. return NULL;
  1854. /* Find TT config according to the Panel ID */
  1855. while ((ttconfig = *ttconfigs++)) {
  1856. if (ttconfig->panel_id == panel_id) {
  1857. /* TODO: Make debug message */
  1858. pt_debug(dev, DL_INFO,
  1859. "%s: Found matching ttconfig:%p with Panel ID: 0x%02X\n",
  1860. __func__, ttconfig, ttconfig->panel_id);
  1861. return ttconfig;
  1862. }
  1863. pt_debug(dev, DL_ERROR,
  1864. "%s: Found mismatching ttconfig:%p with Panel ID: 0x%02X\n",
  1865. __func__, ttconfig, ttconfig->panel_id);
  1866. }
  1867. return NULL;
  1868. }
  1869. /*******************************************************************************
  1870. * FUNCTION: upgrade_ttconfig_from_platform
  1871. *
  1872. * SUMMARY: Get touch_firmware structure and perform upgrade if pass the
  1873. * firmware version check.
  1874. *
  1875. * RETURN:
  1876. * 0 = success
  1877. * !0 = failure
  1878. *
  1879. * PARAMETERS:
  1880. * *dev - pointer to device structure
  1881. * forced - flag to force upgrade(1:force to upgrade)
  1882. ******************************************************************************/
  1883. static int upgrade_ttconfig_from_platform(struct device *dev)
  1884. {
  1885. struct pt_loader_data *ld = pt_get_loader_data(dev);
  1886. struct pt_touch_config *ttconfig;
  1887. struct touch_settings *param_regs;
  1888. int rc = -ENODEV;
  1889. int upgrade;
  1890. if (!ld->loader_pdata) {
  1891. pt_debug(dev, DL_ERROR,
  1892. "%s: No loader platform data\n", __func__);
  1893. return rc;
  1894. }
  1895. ttconfig = pt_get_platform_ttconfig(dev);
  1896. if (!ttconfig) {
  1897. pt_debug(dev, DL_ERROR, "%s: No ttconfig data\n", __func__);
  1898. return rc;
  1899. }
  1900. param_regs = ttconfig->param_regs;
  1901. if (!param_regs) {
  1902. pt_debug(dev, DL_ERROR, "%s: No touch parameters\n",
  1903. __func__);
  1904. return rc;
  1905. }
  1906. if (!param_regs->data || !param_regs->size) {
  1907. pt_debug(dev, DL_ERROR,
  1908. "%s: Invalid touch parameters\n", __func__);
  1909. return rc;
  1910. }
  1911. if (!ttconfig->fw_ver || !ttconfig->fw_vsize) {
  1912. pt_debug(dev, DL_ERROR,
  1913. "%s: Invalid FW version for touch parameters\n",
  1914. __func__);
  1915. return rc;
  1916. }
  1917. upgrade = pt_check_ttconfig_version_platform(dev, ttconfig);
  1918. if (upgrade)
  1919. return pt_upgrade_ttconfig(dev, param_regs->data,
  1920. param_regs->size);
  1921. return rc;
  1922. }
  1923. #endif /* CONFIG_TOUCHSCREEN_PARADE_PLATFORM_TTCONFIG_UPGRADE */
  1924. #ifdef CONFIG_TOUCHSCREEN_PARADE_MANUAL_TTCONFIG_UPGRADE
  1925. /*******************************************************************************
  1926. * FUNCTION: pt_config_data_write
  1927. *
  1928. * SUMMARY: The write method for the config_data sysfs node. The passed
  1929. * in data (config file) is written to the config_data buffer.
  1930. *
  1931. * RETURN: Size of passed in buffer is success
  1932. *
  1933. * PARAMETERS:
  1934. * *filp - pointer to file structure
  1935. * *kobj - pointer to kobject structure
  1936. * *bin_attr - pointer to bin_attribute structure
  1937. * buf - pointer to cmd input buffer
  1938. * offset - offset index to store input buffer
  1939. * count - size of data in buffer
  1940. ******************************************************************************/
  1941. static ssize_t pt_config_data_write(struct file *filp,
  1942. struct kobject *kobj, struct bin_attribute *bin_attr,
  1943. char *buf, loff_t offset, size_t count)
  1944. {
  1945. struct device *dev = container_of(kobj, struct device, kobj);
  1946. struct pt_loader_data *data = pt_get_loader_data(dev);
  1947. u8 *p;
  1948. pt_debug(dev, DL_INFO, "%s: offset:%lld count:%zu\n",
  1949. __func__, offset, count);
  1950. mutex_lock(&data->config_lock);
  1951. if (!data->config_loading) {
  1952. mutex_unlock(&data->config_lock);
  1953. return -ENODEV;
  1954. }
  1955. p = krealloc(data->config_data, offset + count, GFP_KERNEL);
  1956. if (!p) {
  1957. kfree(data->config_data);
  1958. data->config_data = NULL;
  1959. mutex_unlock(&data->config_lock);
  1960. return -ENOMEM;
  1961. }
  1962. data->config_data = p;
  1963. memcpy(&data->config_data[offset], buf, count);
  1964. data->config_size += count;
  1965. mutex_unlock(&data->config_lock);
  1966. return count;
  1967. }
  1968. static struct bin_attribute bin_attr_config_data = {
  1969. .attr = {
  1970. .name = "config_data",
  1971. .mode = 0200,
  1972. },
  1973. .size = 0,
  1974. .write = pt_config_data_write,
  1975. };
  1976. /*******************************************************************************
  1977. * FUNCTION: pt_verify_ttconfig_binary
  1978. *
  1979. * SUMMARY: Perform a simple size check if the firmware version match.And
  1980. * calculate the start pointer of config data to write and the size to write.
  1981. *
  1982. * RETURN:
  1983. * 0 = success
  1984. * !0 = failure
  1985. *
  1986. * PARAMETERS:
  1987. * *dev - pointer to device structure
  1988. * *bin_config_data - pointer to binary config data
  1989. * bin_config_size - size of binary config data
  1990. * **start - double pointer to config data where to be written
  1991. * *len - pointer to the size of config data to store
  1992. ******************************************************************************/
  1993. static int pt_verify_ttconfig_binary(struct device *dev,
  1994. u8 *bin_config_data, int bin_config_size, u8 **start, int *len)
  1995. {
  1996. struct pt_loader_data *ld = pt_get_loader_data(dev);
  1997. int header_size;
  1998. u16 config_size;
  1999. u32 fw_ver_config;
  2000. u32 fw_revctrl_config;
  2001. if (!ld->si) {
  2002. pt_debug(dev, DL_ERROR,
  2003. "%s: No firmware info found, DUT FW may be corrupted\n",
  2004. __func__);
  2005. return -ENODEV;
  2006. }
  2007. /*
  2008. * We need 11 bytes for FW version control info and at
  2009. * least 6 bytes in config (Length + Max Length + CRC)
  2010. */
  2011. header_size = bin_config_data[0] + 1;
  2012. if (header_size < 11 || header_size >= bin_config_size - 6) {
  2013. pt_debug(dev, DL_ERROR,
  2014. "%s: Invalid header size %d\n", __func__,
  2015. header_size);
  2016. return -EINVAL;
  2017. }
  2018. fw_ver_config = get_unaligned_be16(&bin_config_data[1]);
  2019. /* 4 middle bytes are not used */
  2020. fw_revctrl_config = get_unaligned_be32(&bin_config_data[7]);
  2021. /* FW versions should match */
  2022. if (pt_check_firmware_version(dev, fw_ver_config,
  2023. fw_revctrl_config)) {
  2024. pt_debug(dev, DL_ERROR,
  2025. "%s: FW versions mismatch\n", __func__);
  2026. return -EINVAL;
  2027. }
  2028. config_size = get_unaligned_le16(&bin_config_data[header_size]);
  2029. /* Perform a simple size check (2 bytes for CRC) */
  2030. if (config_size != bin_config_size - header_size - 2) {
  2031. pt_debug(dev, DL_ERROR,
  2032. "%s: Config size invalid\n", __func__);
  2033. return -EINVAL;
  2034. }
  2035. *start = &bin_config_data[header_size];
  2036. *len = bin_config_size - header_size;
  2037. return 0;
  2038. }
  2039. /*
  2040. * 1: Start loading TT Config
  2041. * 0: End loading TT Config and perform upgrade
  2042. *-1: Exit loading
  2043. */
  2044. /*******************************************************************************
  2045. * FUNCTION: pt_config_loading_store
  2046. *
  2047. * SUMMARY: The store method for the config_loading sysfs node. The
  2048. * passed in value controls if config loading is performed.
  2049. *
  2050. * RETURN: Size of passed in buffer is success
  2051. *
  2052. * PARAMETERS:
  2053. * *dev - pointer to device structure
  2054. * *attr - pointer to device attributes
  2055. * *buf - pointer to buffer that hold the command parameters
  2056. * size - size of buf
  2057. ******************************************************************************/
  2058. static ssize_t pt_config_loading_store(struct device *dev,
  2059. struct device_attribute *attr, const char *buf, size_t size)
  2060. {
  2061. struct pt_loader_data *ld = pt_get_loader_data(dev);
  2062. long value;
  2063. u8 *start;
  2064. int length;
  2065. int rc;
  2066. rc = kstrtol(buf, 10, &value);
  2067. if (rc < 0 || value < -1 || value > 1) {
  2068. pt_debug(dev, DL_ERROR, "%s: Invalid value\n", __func__);
  2069. return size;
  2070. }
  2071. mutex_lock(&ld->config_lock);
  2072. if (value == 1)
  2073. ld->config_loading = true;
  2074. else if (value == -1)
  2075. ld->config_loading = false;
  2076. else if (value == 0 && ld->config_loading) {
  2077. ld->config_loading = false;
  2078. if (ld->config_size == 0) {
  2079. pt_debug(dev, DL_ERROR,
  2080. "%s: No config data\n", __func__);
  2081. goto exit_free;
  2082. }
  2083. rc = pt_verify_ttconfig_binary(dev,
  2084. ld->config_data, ld->config_size,
  2085. &start, &length);
  2086. if (rc)
  2087. goto exit_free;
  2088. rc = pt_upgrade_ttconfig(dev, start, length);
  2089. }
  2090. exit_free:
  2091. kfree(ld->config_data);
  2092. ld->config_data = NULL;
  2093. ld->config_size = 0;
  2094. mutex_unlock(&ld->config_lock);
  2095. if (rc)
  2096. return rc;
  2097. return size;
  2098. }
  2099. static DEVICE_ATTR(config_loading, 0200,
  2100. NULL, pt_config_loading_store);
  2101. #endif /* CONFIG_TOUCHSCREEN_PARADE_MANUAL_TTCONFIG_UPGRADE */
  2102. #endif /* !TTDL_KERNEL_SUBMISSION */
  2103. #ifdef CONFIG_TOUCHSCREEN_PARADE_PLATFORM_FW_UPGRADE
  2104. /*******************************************************************************
  2105. * FUNCTION: pt_forced_upgrade_store
  2106. *
  2107. * SUMMARY: The store method for the forced_upgrade sysfs node. The firmware
  2108. * loading is forced to performed with platform upgrade strategy.
  2109. *
  2110. * RETURN: Size of passed in buffer is success
  2111. *
  2112. * PARAMETERS:
  2113. * *dev - pointer to device structure
  2114. * *attr - pointer to device attributes
  2115. * *buf - pointer to buffer that hold the command parameters
  2116. * size - size of buf
  2117. ******************************************************************************/
  2118. static ssize_t pt_forced_upgrade_store(struct device *dev,
  2119. struct device_attribute *attr, const char *buf, size_t size)
  2120. {
  2121. int rc = upgrade_firmware_from_platform(dev, true);
  2122. if (rc)
  2123. return rc;
  2124. return size;
  2125. }
  2126. static DEVICE_ATTR(forced_upgrade, 0200,
  2127. NULL, pt_forced_upgrade_store);
  2128. #endif
  2129. #ifdef CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE
  2130. /*******************************************************************************
  2131. * FUNCTION: pt_manual_upgrade_store
  2132. *
  2133. * SUMMARY: The store method for the forced_upgrade sysfs node that it is
  2134. * caller for function upgrade_firmware_from_class() to allow upgrade firmware
  2135. * manually.
  2136. *
  2137. * RETURN: Size of passed in buffer is success
  2138. *
  2139. * PARAMETERS:
  2140. * *dev - pointer to device structure
  2141. * *attr - pointer to device attributes
  2142. * *buf - pointer to buffer that hold the command parameters
  2143. * size - size of buf
  2144. ******************************************************************************/
  2145. static ssize_t pt_manual_upgrade_store(struct device *dev,
  2146. struct device_attribute *attr, const char *buf, size_t size)
  2147. {
  2148. struct pt_loader_data *ld = pt_get_loader_data(dev);
  2149. u32 input_data[2] = {0};
  2150. int length;
  2151. int rc = 0;
  2152. length = cmd->parse_sysfs_input(dev, buf, size, input_data,
  2153. ARRAY_SIZE(input_data));
  2154. if (length != 1) {
  2155. pt_debug(dev, DL_WARN, "%s: Invalid number of arguments\n",
  2156. __func__);
  2157. rc = -EINVAL;
  2158. goto exit;
  2159. }
  2160. if (input_data[0] < 0 || input_data[0] > 1) {
  2161. pt_debug(dev, DL_WARN, "%s: Invalid arguments\n", __func__);
  2162. rc = -EINVAL;
  2163. goto exit;
  2164. }
  2165. _pt_update_write_file_status(dev, UPDATE_FW_IDLE);
  2166. if (ld->is_manual_upgrade_enabled) {
  2167. rc = -EBUSY;
  2168. goto exit;
  2169. }
  2170. ld->is_manual_upgrade_enabled = 1;
  2171. rc = upgrade_firmware_from_class(ld->dev);
  2172. if (rc < 0)
  2173. ld->is_manual_upgrade_enabled = 0;
  2174. exit:
  2175. if (rc)
  2176. return rc;
  2177. return size;
  2178. }
  2179. #ifndef TTDL_KERNEL_SUBMISSION
  2180. static DEVICE_ATTR(manual_upgrade, 0200, NULL, pt_manual_upgrade_store);
  2181. #endif /* !TTDL_KERNEL_SUBMISSION */
  2182. #endif /* CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE */
  2183. /*******************************************************************************
  2184. * FUNCTION: pt_fw_and_config_upgrade
  2185. *
  2186. * SUMMARY: Perform all methods for firmware upgrade and config upgrade
  2187. * according to the definition of macro.
  2188. *
  2189. * PARAMETERS:
  2190. * *work_struct - pointer to work_struct structure
  2191. ******************************************************************************/
  2192. static void pt_fw_and_config_upgrade(
  2193. struct work_struct *fw_and_config_upgrade)
  2194. {
  2195. struct pt_loader_data *ld = container_of(fw_and_config_upgrade,
  2196. struct pt_loader_data, fw_and_config_upgrade);
  2197. struct device *dev = ld->dev;
  2198. struct pt_core_data *cd = dev_get_drvdata(dev);
  2199. int retry = 200;
  2200. #if PT_FW_UPGRADE \
  2201. || defined(CONFIG_TOUCHSCREEN_PARADE_PLATFORM_TTCONFIG_UPGRADE)
  2202. u8 dut_gen = cmd->request_dut_generation(dev);
  2203. #endif
  2204. /*
  2205. * Since the resume_scan command in pt_probe_complete() has
  2206. * no protection,it may cause problem for the commands in fw
  2207. * upgrade process during probe. Waiting for the probe to
  2208. * complete before performing fw upgrade can avoid this failure.
  2209. */
  2210. while (!cd->core_probe_complete && retry--)
  2211. msleep(20);
  2212. ld->si = cmd->request_sysinfo(dev);
  2213. if (!ld->si)
  2214. pt_debug(dev, DL_ERROR,
  2215. "%s: Fail get sysinfo pointer from core\n",
  2216. __func__);
  2217. #if !PT_FW_UPGRADE
  2218. pt_debug(dev, DL_INFO,
  2219. "%s: No FW upgrade method selected!\n", __func__);
  2220. #endif
  2221. #ifdef CONFIG_TOUCHSCREEN_PARADE_PLATFORM_FW_UPGRADE
  2222. if (dut_gen == DUT_PIP1_ONLY) {
  2223. if (!upgrade_firmware_from_platform(dev, false))
  2224. return;
  2225. }
  2226. #endif
  2227. #ifdef CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE
  2228. if (dut_gen == DUT_PIP2_CAPABLE) {
  2229. if (!pt_pip2_upgrade_firmware_from_builtin(dev))
  2230. return;
  2231. pt_debug(dev, DL_WARN, "%s: Builtin FW upgrade failed\n",
  2232. __func__);
  2233. } else {
  2234. if (!upgrade_firmware_from_builtin(dev))
  2235. return;
  2236. }
  2237. #endif
  2238. #ifdef CONFIG_TOUCHSCREEN_PARADE_PLATFORM_TTCONFIG_UPGRADE
  2239. if (dut_gen == DUT_PIP1_ONLY) {
  2240. if (!upgrade_ttconfig_from_platform(dev))
  2241. return;
  2242. }
  2243. #endif
  2244. }
  2245. #ifdef CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE
  2246. #ifdef TTDL_DIAGNOSTICS
  2247. /*******************************************************************************
  2248. * FUNCTION: _pt_pip2_get_flash_info
  2249. *
  2250. * SUMMARY: Sends a FLASH_INFO command to the DUT logging the results to kmsg
  2251. *
  2252. * PARAMETERS:
  2253. * *dev - pointer to device structure
  2254. * *read_buf - pointer to the read buffer array to store the response
  2255. ******************************************************************************/
  2256. static void _pt_pip2_get_flash_info(struct device *dev, u8 *read_buf)
  2257. {
  2258. u16 actual_read_len;
  2259. int ret;
  2260. /* Get flash info for debugging information */
  2261. ret = cmd->nonhid_cmd->pip2_send_cmd(dev,
  2262. PT_CORE_CMD_UNPROTECTED, PIP2_CMD_ID_FLASH_INFO,
  2263. NULL, 0, read_buf, &actual_read_len);
  2264. if (!ret) {
  2265. pt_debug(dev, DL_DEBUG,
  2266. "%s --- FLASH Information ---\n", __func__);
  2267. pt_debug(dev, DL_DEBUG,
  2268. "%s Manufacturer ID: 0x%02x\n",
  2269. __func__, read_buf[PIP2_RESP_BODY_OFFSET]);
  2270. pt_debug(dev, DL_DEBUG,
  2271. "%s Memory Type : 0x%02x\n",
  2272. __func__, read_buf[PIP2_RESP_BODY_OFFSET + 1]);
  2273. pt_debug(dev, DL_DEBUG,
  2274. "%s Num Sectors : 0x%02x%02x%02x%02x\n",
  2275. __func__, read_buf[PIP2_RESP_BODY_OFFSET + 2],
  2276. read_buf[PIP2_RESP_BODY_OFFSET + 3],
  2277. read_buf[PIP2_RESP_BODY_OFFSET + 4],
  2278. read_buf[PIP2_RESP_BODY_OFFSET + 5]);
  2279. pt_debug(dev, DL_DEBUG,
  2280. "%s Sectors Size : 0x%02x%02x%02x%02x\n",
  2281. __func__, read_buf[PIP2_RESP_BODY_OFFSET + 6],
  2282. read_buf[PIP2_RESP_BODY_OFFSET + 7],
  2283. read_buf[PIP2_RESP_BODY_OFFSET + 8],
  2284. read_buf[PIP2_RESP_BODY_OFFSET + 9]);
  2285. pt_debug(dev, DL_DEBUG,
  2286. "%s Page Size : 0x%02x%02x%02x%02x\n",
  2287. __func__, read_buf[PIP2_RESP_BODY_OFFSET + 10],
  2288. read_buf[PIP2_RESP_BODY_OFFSET + 11],
  2289. read_buf[PIP2_RESP_BODY_OFFSET + 12],
  2290. read_buf[PIP2_RESP_BODY_OFFSET + 13]);
  2291. if (actual_read_len > 21) {
  2292. pt_debug(dev, DL_DEBUG,
  2293. "%s Status Reg1 : 0x%02x\n",
  2294. __func__,
  2295. read_buf[PIP2_RESP_BODY_OFFSET + 14]);
  2296. pt_debug(dev, DL_DEBUG,
  2297. "%s Status Reg2 : 0x%02x\n",
  2298. __func__,
  2299. read_buf[PIP2_RESP_BODY_OFFSET + 15]);
  2300. }
  2301. }
  2302. }
  2303. #endif /* TTDL_DIAGNOSTICS */
  2304. /*******************************************************************************
  2305. * FUNCTION: _pt_pip2_file_write_packet
  2306. *
  2307. * SUMMARY: Using the BL PIP2 commands to write a file.
  2308. *
  2309. * NOTE#1: This function support No Interrupt Solution and switch
  2310. * "pip2_send_cmd" function according to the global variable "bl_with_no_int".
  2311. * NOTE#2: The maximum write len is limited to 256 as well as the total buffer
  2312. * size is limited as PT_MAX_PIP2_MSG_SIZE.
  2313. *
  2314. * RETURNS:
  2315. * 0 = success
  2316. * !0 = failure
  2317. *
  2318. * PARAMETERS:
  2319. * *dev - pointer to device structure
  2320. * file_hd - file handle for file operation
  2321. * *write_buf - pointer of buffer to write
  2322. * write_len - length to write
  2323. * *status - pointer to store the STATUS in response
  2324. ******************************************************************************/
  2325. static int _pt_pip2_file_write_packet(struct device *dev, u8 file_hd,
  2326. u8 *write_buf, u16 write_len, u8 *status)
  2327. {
  2328. struct pt_core_data *cd = dev_get_drvdata(dev);
  2329. PIP2_SEND_CMD pip2_send_cmd;
  2330. int ret = 0;
  2331. u16 actual_read_len = 0;
  2332. u8 read_buf[PT_MAX_PIP2_MSG_SIZE];
  2333. u8 buf[PT_MAX_PIP2_MSG_SIZE];
  2334. if (write_len > PIP2_FILE_WRITE_MAX_LEN_PER_PACKET) {
  2335. pt_debug(dev, DL_ERROR, "%s write_len (%d) is over size\n",
  2336. __func__, write_len);
  2337. return -EINVAL;
  2338. }
  2339. if (cd->bl_with_no_int)
  2340. pip2_send_cmd = cmd->nonhid_cmd->pip2_send_cmd_no_int;
  2341. else
  2342. pip2_send_cmd = cmd->nonhid_cmd->pip2_send_cmd;
  2343. buf[0] = file_hd;
  2344. memcpy(&buf[1], write_buf, write_len);
  2345. ret = pip2_send_cmd(dev, PT_CORE_CMD_UNPROTECTED,
  2346. PIP2_CMD_ID_FILE_WRITE, buf, write_len + 1,
  2347. read_buf, &actual_read_len);
  2348. if (status)
  2349. *status = read_buf[PIP2_RESP_STATUS_OFFSET];
  2350. return ret;
  2351. }
  2352. /*******************************************************************************
  2353. * FUNCTION: _pt_pip2_execute_app
  2354. *
  2355. * SUMMARY: Using the BL PIP2 commands to executes an image downloaded into the
  2356. * SRAM.
  2357. *
  2358. * RETURNS:
  2359. * 0 = success
  2360. * !0 = failure
  2361. *
  2362. * PARAMETERS:
  2363. * *dev - pointer to device structure
  2364. * *status - pointer to store the STATUS in response
  2365. ******************************************************************************/
  2366. static int _pt_pip2_execute_app(struct device *dev, u8 *status)
  2367. {
  2368. int ret = 0;
  2369. u16 actual_read_len = 0;
  2370. u8 read_buf[PT_MAX_PIP2_MSG_SIZE];
  2371. ret = cmd->nonhid_cmd->pip2_send_cmd(dev, PT_CORE_CMD_UNPROTECTED,
  2372. PIP2_CMD_ID_EXECUTE, NULL, 0,
  2373. read_buf, &actual_read_len);
  2374. if (status)
  2375. *status = read_buf[PIP2_RESP_STATUS_OFFSET];
  2376. return ret;
  2377. }
  2378. /*******************************************************************************
  2379. * FUNCTION: _pt_pip2_log_last_error
  2380. *
  2381. * SUMMARY: Sends a STATUS command to the DUT logging the results until all
  2382. * errors are cleared. Also sends a GET_LAST_ERRNO to get any Boot errors.
  2383. * This must be sent after the STATUS flush in order not to have this
  2384. * command cause another error.
  2385. *
  2386. * NOTE: This function support No Interrupt Solution and switch "pip2_send_cmd"
  2387. * function according to the global variable "bl_with_no_int".
  2388. * RETURN:
  2389. * 0 = success
  2390. * !0 = failure
  2391. *
  2392. * PARAMETERS:
  2393. * *dev - pointer to device structure
  2394. * *read_buf - pointer to the read buffer array to store the response
  2395. ******************************************************************************/
  2396. static int _pt_pip2_log_last_error(struct device *dev, u8 *read_buf)
  2397. {
  2398. u16 actual_read_len;
  2399. u8 loop = 5;
  2400. u8 info = 0xFF;
  2401. u8 error = 0xFF;
  2402. int ret;
  2403. PIP2_SEND_CMD pip2_send_cmd;
  2404. struct pt_core_data *cd = dev_get_drvdata(dev);
  2405. if (cd->bl_with_no_int)
  2406. pip2_send_cmd = cmd->nonhid_cmd->pip2_send_cmd_no_int;
  2407. else
  2408. pip2_send_cmd = cmd->nonhid_cmd->pip2_send_cmd;
  2409. /*
  2410. * Send the STATUS command until no errors are found.
  2411. * The BL will store an error code for each layer of the stack,
  2412. * and each read will return one error.
  2413. */
  2414. while (loop > 0 && error) {
  2415. ret = pip2_send_cmd(dev,
  2416. PT_CORE_CMD_UNPROTECTED, PIP2_CMD_ID_STATUS,
  2417. NULL, 0, read_buf, &actual_read_len);
  2418. if (!ret) {
  2419. info = (u8)read_buf[PIP2_RESP_BODY_OFFSET];
  2420. error = (u8)read_buf[PIP2_RESP_BODY_OFFSET + 1];
  2421. pt_debug(dev, DL_ERROR,
  2422. "%s: STATUS: Status=0x%02X BOOT=%d BUSY=%d INT=%d ERR_PHY=%d ERR_REG=%d ERROR=0x%02X",
  2423. __func__,
  2424. (u8)read_buf[PIP2_RESP_STATUS_OFFSET],
  2425. info & 0x01,
  2426. (info & 0x02) >> 1,
  2427. (info & 0x04) >> 2,
  2428. (info & 0x18) >> 3,
  2429. (info & 0xE0) >> 5,
  2430. error);
  2431. }
  2432. loop--;
  2433. }
  2434. /* Send the GET_LAST_ERROR command to get the last BL startup error */
  2435. ret = pip2_send_cmd(dev,
  2436. PT_CORE_CMD_UNPROTECTED, PIP2_CMD_ID_GET_LAST_ERRNO,
  2437. NULL, 0, read_buf, &actual_read_len);
  2438. if (!ret) {
  2439. pt_debug(dev, DL_ERROR,
  2440. "%s: GET_LAST_ERR: Status=0x%02X ERRNO=0x%02X BOOTMODE=%d\n",
  2441. __func__,
  2442. (u8)read_buf[PIP2_RESP_STATUS_OFFSET],
  2443. (u8)read_buf[PIP2_RESP_BODY_OFFSET],
  2444. (u8)read_buf[PIP2_RESP_BODY_OFFSET + 1]);
  2445. }
  2446. return ret;
  2447. }
  2448. /*******************************************************************************
  2449. * FUNCTION: _pt_pip2_file_write_packet_and_log_err
  2450. *
  2451. * SUMMARY: Wrapper function for File Write. If meet failure, it will call
  2452. * function _pt_pip2_log_last_error() and do a retry within 3x.
  2453. *
  2454. * NOTE: This function support No Interrupt Solution and switch "pip2_send_cmd"
  2455. * function according to the global variable "bl_with_no_int".
  2456. *
  2457. * RETURN:
  2458. * 0 = success
  2459. * !0 = failure
  2460. *
  2461. * PARAMETERS:
  2462. * *dev - pointer to device structure
  2463. * file_hd - file handle for file operation
  2464. * *write_buf - pointer of buffer to write
  2465. * write_len - length to write
  2466. * last_write - flag for last_write (1: is last write)
  2467. ******************************************************************************/
  2468. #define PIP2_FILE_WRITE_RETRY_MAX (3)
  2469. static int _pt_pip2_file_write_packet_and_log_err(struct device *dev,
  2470. u8 file_hd, u8 *write_buf, u16 write_len, u8 last_write)
  2471. {
  2472. struct pt_core_data *cd = dev_get_drvdata(dev);
  2473. int ret = 0;
  2474. int retry_packet = 0;
  2475. u8 read_buf[PT_MAX_PIP2_MSG_SIZE];
  2476. u8 status = 0;
  2477. do {
  2478. ret = _pt_pip2_file_write_packet(dev, file_hd, write_buf,
  2479. write_len, &status);
  2480. /* Write cmd successful with a fail status */
  2481. if (ret) {
  2482. pt_debug(dev, DL_ERROR, "%s %d - Packet cmd error\n",
  2483. __func__, ret);
  2484. } else if (status) {
  2485. /*
  2486. * The last time through the loop when remain_bytes =
  2487. * write_len, no partial payload will remain, the last
  2488. * successful write (when writing to RAM) will respond
  2489. * with EOF status, writing to FLASH will respond with a
  2490. * standard success status of 0x00
  2491. */
  2492. if (last_write && (file_hd == PIP2_RAM_FILE) &&
  2493. (status == PIP2_RSP_ERR_END_OF_FILE)) {
  2494. pt_debug(dev, DL_WARN,
  2495. "%s Last write, ret = 0x%02x\n",
  2496. __func__, status);
  2497. status = 0;
  2498. break;
  2499. }
  2500. pt_debug(dev, DL_ERROR, "%s %d - Packet status error\n",
  2501. __func__, status);
  2502. /* Manually assign ret to negative value */
  2503. ret = -EINVAL;
  2504. } else {
  2505. /* No issue is seen, and break the loop */
  2506. break;
  2507. }
  2508. #ifdef TTDL_DIAGNOSTICS
  2509. cd->bl_retry_packet_count++;
  2510. cmd->request_toggle_err_gpio(dev, PT_ERR_GPIO_BL_RETRY_PACKET);
  2511. pt_debug(dev, DL_WARN, "%s: === Retry Packet #%d ===\n",
  2512. __func__, retry_packet);
  2513. #endif
  2514. /* Get and log the last error(s) */
  2515. _pt_pip2_log_last_error(dev, read_buf);
  2516. } while (retry_packet++ < PIP2_FILE_WRITE_RETRY_MAX);
  2517. return ret;
  2518. }
  2519. /*******************************************************************************
  2520. * FUNCTION: _pt_pip2_check_fw_ver
  2521. *
  2522. * SUMMARY: Compare the FW version in the bin file to the current FW. If the
  2523. * FW version in the bin file is greater an upgrade should be done.
  2524. *
  2525. * RETURN:
  2526. * -1: Do not upgrade firmware
  2527. * 0: Version info same, let caller decide
  2528. * 1: Do a firmware upgrade
  2529. *
  2530. * PARAMETERS:
  2531. * *dev - pointer to device structure
  2532. * *fw - pointer to the new FW image to load
  2533. * *hdr - pointer to the PIP2 bin file hdr structure
  2534. ******************************************************************************/
  2535. static int _pt_pip2_check_fw_ver(struct device *dev,
  2536. const struct firmware *fw, struct pt_bin_file_hdr *hdr)
  2537. {
  2538. u8 img_app_major_ver = fw->data[3];
  2539. u8 img_app_minor_ver = fw->data[4];
  2540. u32 img_app_rev_ctrl = fw->data[9]<<24 | fw->data[10]<<16 |
  2541. fw->data[11]<<8 | fw->data[12];
  2542. pt_debug(dev, DL_WARN,
  2543. "%s ATM - BL Image Version: %02x.%02x.%d\n",
  2544. __func__, img_app_major_ver, img_app_minor_ver,
  2545. img_app_rev_ctrl);
  2546. pt_debug(dev, DL_WARN,
  2547. "%s ATM - Current FW Version: %02X.%02X.%d\n",
  2548. __func__, hdr->fw_major, hdr->fw_minor, hdr->fw_rev_ctrl);
  2549. if ((256 * img_app_major_ver + img_app_minor_ver) >
  2550. (256 * hdr->fw_major + hdr->fw_minor)) {
  2551. pt_debug(dev, DL_WARN,
  2552. "ATM - bin file version > FW, will upgrade FW");
  2553. return 1;
  2554. }
  2555. if ((256 * img_app_major_ver + img_app_minor_ver) <
  2556. (256 * hdr->fw_major + hdr->fw_minor)) {
  2557. pt_debug(dev, DL_WARN,
  2558. "ATM - bin file version < FW, will NOT upgrade FW");
  2559. return -1;
  2560. }
  2561. if (img_app_rev_ctrl > hdr->fw_rev_ctrl) {
  2562. pt_debug(dev, DL_WARN,
  2563. "bin file rev ctrl > FW, will upgrade FW");
  2564. return 1;
  2565. }
  2566. if (img_app_rev_ctrl < hdr->fw_rev_ctrl) {
  2567. pt_debug(dev, DL_WARN,
  2568. "bin file rev ctrl > FW, will NOT upgrade FW");
  2569. return -1;
  2570. }
  2571. return 0;
  2572. }
  2573. /*******************************************************************************
  2574. * FUNCTION: _pt_pip2_check_config_ver
  2575. *
  2576. * SUMMARY: Compare the Config version in the bin file to the current FW. If the
  2577. * config version in the bin file is greater an upgrade should be done.
  2578. *
  2579. * RETURN:
  2580. * -1: Do not upgrade firmware
  2581. * 0: Version info same, let caller decide
  2582. * 1: Do a firmware upgrade
  2583. *
  2584. * PARAMETERS:
  2585. * *dev - pointer to device structure
  2586. * *fw - pointer to the new FW image to load
  2587. * *hdr - pointer to the PIP2 bin file hdr structure
  2588. ******************************************************************************/
  2589. static int _pt_pip2_check_config_ver(struct device *dev,
  2590. const struct firmware *fw, struct pt_bin_file_hdr *hdr)
  2591. {
  2592. u16 fw_config_ver_new;
  2593. /* Offset 17,18 is the TT Config version*/
  2594. fw_config_ver_new = get_unaligned_be16(fw->data + 17);
  2595. pt_debug(dev, DL_WARN,
  2596. "%s ATM - BL Image Config Version: %d\n",
  2597. __func__, fw_config_ver_new);
  2598. pt_debug(dev, DL_WARN,
  2599. "%s ATM - Current Config Version: %d\n",
  2600. __func__, hdr->config_ver);
  2601. if (fw_config_ver_new > hdr->config_ver) {
  2602. pt_debug(dev, DL_WARN,
  2603. "ATM - bin file Config version > FW, will upgrade FW");
  2604. return 1;
  2605. } else
  2606. pt_debug(dev, DL_WARN,
  2607. "ATM - bin file Config version <= FW, will NOT upgrade FW");
  2608. return 0;
  2609. }
  2610. /*******************************************************************************
  2611. * FUNCTION: _pt_pip2_need_upgrade_due_to_fw_ver
  2612. *
  2613. * SUMMARY: Compare the FW version in the bin file to the current FW. If the
  2614. * FW version in the bin file is greater an upgrade should be done.
  2615. *
  2616. * PARAMETERS:
  2617. * *dev - pointer to device structure
  2618. * *fw - pointer to the new FW image to load
  2619. ******************************************************************************/
  2620. static u8 _pt_pip2_need_upgrade_due_to_fw_ver(struct device *dev,
  2621. const struct firmware *fw)
  2622. {
  2623. int ret;
  2624. u8 should_upgrade = 0;
  2625. struct pt_bin_file_hdr hdr = {0};
  2626. ret = cmd->request_pip2_bin_hdr(dev, &hdr);
  2627. if (ret != 0 || hdr.fw_major == 0xFF) {
  2628. pt_debug(dev, DL_WARN,
  2629. "App ver info not available, will upgrade FW");
  2630. should_upgrade = 1;
  2631. goto exit;
  2632. }
  2633. ret = _pt_pip2_check_fw_ver(dev, fw, &hdr);
  2634. if (ret == 0)
  2635. ret = _pt_pip2_check_config_ver(dev, fw, &hdr);
  2636. if (ret > 0)
  2637. should_upgrade = 1;
  2638. exit:
  2639. return should_upgrade;
  2640. }
  2641. /*******************************************************************************
  2642. * FUNCTION: _pt_calibrate_flashless_dut
  2643. *
  2644. * SUMMARY: On a flashless DUT the FW would need to re-calibrate on every power
  2645. * cycle, so to speed up the BL process the FW does the calibraiton on the
  2646. * first power up and TTDL will read and store it in RAM to be able to
  2647. * restore it on subsequent resets of the DUT.
  2648. *
  2649. * RETURN:
  2650. * 0 = success
  2651. * !0 = failure
  2652. *
  2653. * PARAMETERS:
  2654. * *dev - pointer to device structure
  2655. ******************************************************************************/
  2656. static int _pt_calibrate_flashless_dut(struct device *dev)
  2657. {
  2658. u8 rc = 0;
  2659. u8 cal_status = 1;
  2660. u16 cal_size = 0;
  2661. struct pt_cal_ext_data cal_data = {0};
  2662. struct pt_core_data *cd = dev_get_drvdata(dev);
  2663. struct pt_ttdata *ttdata = &cd->sysinfo.ttdata;
  2664. unsigned short cache_chip_id = 0;
  2665. unsigned short active_chip_id = 0;
  2666. cmd->nonhid_cmd->manage_cal_data(dev, PT_CAL_DATA_INFO, &cal_size,
  2667. &cache_chip_id);
  2668. pt_debug(dev, DL_WARN, "%s: Stored CAL ID=0x%04X size=%d\n",
  2669. __func__, cache_chip_id, cal_size);
  2670. active_chip_id = cmd->nonhid_cmd->calc_crc((u8 *)&ttdata->chip_rev,
  2671. 4 + PT_UID_SIZE);
  2672. pt_debug(dev, DL_WARN, "%s: Current Chip ID=0x%04X\n",
  2673. __func__, active_chip_id);
  2674. if (cal_size == 0 || active_chip_id != cache_chip_id) {
  2675. memset(&cal_data, 0, sizeof(struct pt_cal_ext_data));
  2676. /* Calibrate_ext will also save CAL Data in TTDL cache */
  2677. rc = cmd->nonhid_cmd->calibrate_ext(dev, 0, &cal_data,
  2678. &cal_status);
  2679. pt_debug(dev, DL_INFO,
  2680. "%s: Calibration Finished rc=%d\n", __func__, rc);
  2681. /* Afer successful calibration read the stored size */
  2682. if (!rc && cal_status == 0) {
  2683. rc = cmd->nonhid_cmd->manage_cal_data(dev,
  2684. PT_CAL_DATA_INFO, &cal_size, &cache_chip_id);
  2685. if (!rc) {
  2686. pt_debug(dev, DL_WARN,
  2687. "%s: First BL, Read %d Bytes of CAL\n",
  2688. __func__, cal_size);
  2689. } else {
  2690. pt_debug(dev, DL_ERROR,
  2691. "%s: First BL, Failed to read CAL\n",
  2692. __func__);
  2693. }
  2694. } else {
  2695. pt_debug(dev, DL_ERROR,
  2696. "%s: First BL, Calibration failed rc=%d\n",
  2697. __func__, rc);
  2698. }
  2699. rc = cmd->nonhid_cmd->resume_scanning(dev, 0);
  2700. if (rc)
  2701. pt_debug(dev, DL_ERROR,
  2702. "%s: First BL, Resume Scan failed rc=%d\n",
  2703. __func__, rc);
  2704. } else {
  2705. rc = cmd->nonhid_cmd->manage_cal_data(dev, PT_CAL_DATA_RESTORE,
  2706. &cal_size, &cache_chip_id);
  2707. if (!rc)
  2708. pt_debug(dev, DL_WARN, "%s: Restored CAL %d Bytes\n",
  2709. __func__, cal_size);
  2710. else
  2711. pt_debug(dev, DL_ERROR, "%s: Failed to restore CAL\n",
  2712. __func__);
  2713. rc = cmd->nonhid_cmd->resume_scanning(dev, 0);
  2714. if (rc)
  2715. pt_debug(dev, DL_ERROR,
  2716. "%s: Resume Scan failed rc=%d\n",
  2717. __func__, rc);
  2718. }
  2719. return rc;
  2720. }
  2721. /*******************************************************************************
  2722. * FUNCTION: _search_fw_from_builtin
  2723. *
  2724. * SUMMARY: Check the existence of builtin FW by filename and set the pointer
  2725. * to FW image
  2726. *
  2727. * RETURN:
  2728. * 0 = success
  2729. * !0 = failure
  2730. *
  2731. * PARAMETERS:
  2732. * *dev - pointer to device structure
  2733. * *filename - pointer of file name
  2734. * **fw - pointer to store the pointer of FW image to load
  2735. ******************************************************************************/
  2736. static int _search_fw_from_builtin(struct device *dev, char *filename,
  2737. const struct firmware **fw)
  2738. {
  2739. int ret = 0;
  2740. #if (KERNEL_VERSION(3, 13, 0) > LINUX_VERSION_CODE)
  2741. ret = request_firmware(fw, filename, dev);
  2742. #else
  2743. ret = request_firmware_direct(fw, filename, dev);
  2744. #endif
  2745. if (ret) {
  2746. pt_debug(dev, DL_WARN, "%s: ATM - Fail request FW %s load\n",
  2747. __func__, filename);
  2748. } else {
  2749. pt_debug(dev, DL_INFO, "%s: FW %s class file loading\n",
  2750. __func__, filename);
  2751. }
  2752. return ret;
  2753. }
  2754. /*******************************************************************************
  2755. * FUNCTION: _search_fw_from_us
  2756. *
  2757. * SUMMARY: Check the existence of FW from user space by file name defined in
  2758. * "pip2_us_file_path".
  2759. *
  2760. * RETURN:
  2761. * 0 = success
  2762. * !0 = failure
  2763. *
  2764. * PARAMETERS:
  2765. * *dev - pointer to device structure
  2766. ******************************************************************************/
  2767. static int _search_fw_from_us(struct device *dev)
  2768. {
  2769. struct pt_core_data *cd = dev_get_drvdata(dev);
  2770. int read_size = 16;
  2771. int ret = 0;
  2772. u8 image[16];
  2773. if (cd->pip2_us_file_path[0] == '\0') {
  2774. pt_debug(dev, DL_WARN,
  2775. "%s: US Path not defined, BL from built-in\n",
  2776. __func__);
  2777. ret = -EINVAL;
  2778. } else {
  2779. /* Read a few bytes to see if file exists */
  2780. ret = cmd->nonhid_cmd->read_us_file(dev, cd->pip2_us_file_path,
  2781. image, &read_size);
  2782. if (!ret) {
  2783. pt_debug(dev, DL_WARN, "%s: %s Found, BL from US\n",
  2784. __func__, cd->pip2_us_file_path);
  2785. } else {
  2786. pt_debug(dev, DL_WARN,
  2787. "%s: ATM - %s NOT Found, BL from built-in\n",
  2788. __func__, cd->pip2_us_file_path);
  2789. }
  2790. }
  2791. return ret;
  2792. }
  2793. /*******************************************************************************
  2794. * FUNCTION: pt_pip2_write_file
  2795. *
  2796. * SUMMARY: Compelete steps to wite a FILE in external SPI flash over PIP2 BL
  2797. * commands. It includes: Open->Erase->Write->Close.
  2798. *
  2799. * NOTE: "write_file_status" is updated from x to 99 in this scope, and higher
  2800. * level function is allowed to reset to 0 or report an error status.
  2801. *
  2802. * RETURN:
  2803. * 0 = success
  2804. * !0 = failure
  2805. *
  2806. * PARAMETERS:
  2807. * *dev - pointer to device structure
  2808. * *fw - pointer to FW image to load
  2809. * file_no - Identifies the files to write
  2810. ******************************************************************************/
  2811. static int pt_pip2_write_file(struct device *dev, const struct firmware *fw,
  2812. u8 file_no)
  2813. {
  2814. struct pt_core_data *cd = dev_get_drvdata(dev);
  2815. struct pt_loader_data *ld = pt_get_loader_data(dev);
  2816. int ret = 0;
  2817. int erase_status = 0;
  2818. u32 percent_cmplt;
  2819. u32 remain_bytes = 0;
  2820. u32 fw_size = 0;
  2821. u32 offset = 0;
  2822. u32 max_file_size = 0;
  2823. u16 packet_size = 0;
  2824. u16 sector_num = 0;
  2825. u8 *fw_img = NULL;
  2826. u8 file_handle = 0;
  2827. u8 read_buf[PT_MAX_PIP2_MSG_SIZE];
  2828. if (!fw || !fw->data || !fw->size) {
  2829. pt_debug(dev, DL_ERROR, "%s The FW is invalid\n", __func__);
  2830. return -EINVAL;
  2831. }
  2832. fw_img = (u8 *)&(fw->data[0]);
  2833. fw_size = fw->size;
  2834. if (cd->bus_ops->bustype == BUS_I2C)
  2835. packet_size = PIP2_BL_I2C_FILE_WRITE_LEN_PER_PACKET;
  2836. else
  2837. packet_size = PIP2_BL_SPI_FILE_WRITE_LEN_PER_PACKET;
  2838. /* 1. Open file before any file operation */
  2839. pt_debug(dev, DL_INFO, "%s OPEN File %d for write\n",
  2840. __func__, file_no);
  2841. ret = cmd->nonhid_cmd->pip2_file_open(dev, file_no);
  2842. if (ret < 0) {
  2843. pt_debug(dev, DL_ERROR, "%s Open file %d failed\n",
  2844. __func__, file_no);
  2845. _pt_update_write_file_status(dev, UPDATE_FW_FILE_OPEN_ERROR);
  2846. goto exit;
  2847. }
  2848. file_handle = ret;
  2849. /* Write File Status: inc to 11 */
  2850. _pt_update_write_file_status(dev, UPDATE_FW_INCREMENT_BY_1);
  2851. /*
  2852. * 2. Erase file
  2853. * 2.1 Obtain the size of FILE
  2854. * 2.2 Confirm content to be written is not too large
  2855. * 2.3 Check whether Sector Erase is valid
  2856. * 2.4 Log flash information
  2857. * 2.5 Do Sector Erase or File Erase
  2858. * 2.6 Reset FILE pointer
  2859. * NOTE: Regarding to TC3315, the size of RAM_FILE is less than fw
  2860. * image, so will not do step 2.2 for PIP2_RAM_FILE.
  2861. */
  2862. if (file_no != PIP2_RAM_FILE) {
  2863. ret = cmd->nonhid_cmd->pip2_file_get_stats(
  2864. dev, file_handle, NULL, &max_file_size);
  2865. if (ret) {
  2866. pt_debug(dev, DL_ERROR,
  2867. "%s: Failed to get_file_state ret=%d\n",
  2868. __func__, ret);
  2869. goto exit_close_file;
  2870. }
  2871. if (fw_size > max_file_size) {
  2872. pt_debug(dev, DL_ERROR,
  2873. "%s: Firmware image(%d) is over size(%d)\n",
  2874. __func__, fw_size, max_file_size);
  2875. _pt_update_write_file_status(dev,
  2876. UPDATE_FW_INVALID_FW_IMAGE);
  2877. goto exit_close_file;
  2878. }
  2879. /* calculate number of sector */
  2880. sector_num = max_file_size / PT_PIP2_FILE_SECTOR_SIZE;
  2881. if (max_file_size % PT_PIP2_FILE_SECTOR_SIZE) {
  2882. pt_debug(dev, DL_WARN,
  2883. "%s: file size %d misalign, don't use sector erase\n",
  2884. __func__, max_file_size);
  2885. /*
  2886. * TODO: Not sure whether can have this case, and this
  2887. * is a workaround to ensure the safety in logic.
  2888. * Force sector number to 0 will use the default method
  2889. * to do file erase by FILE instead of SECTOR.
  2890. */
  2891. sector_num = 0;
  2892. }
  2893. #ifdef TTDL_DIAGNOSTICS
  2894. /* Log the Flash part info */
  2895. if (cd->debug_level >= DL_DEBUG)
  2896. _pt_pip2_get_flash_info(dev, read_buf);
  2897. #endif
  2898. /* Erase file before loading */
  2899. ret = cmd->nonhid_cmd->pip2_file_erase(dev,
  2900. ld->pip2_load_file_no, sector_num, &erase_status);
  2901. if (ret < 0) {
  2902. pt_debug(dev, DL_ERROR,
  2903. "%s: File erase failed rc=%d status=%d\n",
  2904. __func__, ret, erase_status);
  2905. _pt_update_write_file_status(dev,
  2906. UPDATE_FW_ERASE_ERROR);
  2907. goto exit_close_file;
  2908. }
  2909. /* Write File Status: inc to 12 */
  2910. _pt_update_write_file_status(dev, UPDATE_FW_INCREMENT_BY_1);
  2911. /* Reset file pointer as sector erase moved it */
  2912. ret = cmd->nonhid_cmd->pip2_file_seek_offset(dev,
  2913. ld->pip2_load_file_no, 0, 0);
  2914. if (ret) {
  2915. pt_debug(dev, DL_ERROR,
  2916. "%s: Failed to seek file offset rc=%d\n",
  2917. __func__, ret);
  2918. _pt_update_write_file_status(dev,
  2919. UPDATE_FW_FILE_SEEK_ERROR);
  2920. goto exit_close_file;
  2921. }
  2922. /* Write File Status: inc to 17 */
  2923. _pt_update_write_file_status(dev, UPDATE_FW_INCREMENT_BY_5);
  2924. }
  2925. /*
  2926. * 3. Write file
  2927. * 3.1* Disable IRQ when using polling method to save BL time
  2928. * 3.2 Looping to write file, and the last packet need extra check.
  2929. * 3.3* Enable IRQ
  2930. */
  2931. pt_debug(dev, DL_WARN,
  2932. "%s: ATM - Writing %d bytes of firmware data now\n",
  2933. __func__, fw_size);
  2934. /*
  2935. * No IRQ function is used to BL to reduce BL time due to any IRQ
  2936. * latency.
  2937. */
  2938. if (cd->bl_with_no_int)
  2939. disable_irq_nosync(cd->irq);
  2940. while (offset < fw_size) {
  2941. remain_bytes = fw_size - offset;
  2942. /* Don't update BL status on every pass */
  2943. if (remain_bytes % 2000 < packet_size) {
  2944. /* Calculate % complete for write_file_status sysfs */
  2945. percent_cmplt =
  2946. (fw_size - remain_bytes) * 100 / fw_size + 1;
  2947. if (percent_cmplt > UPDATE_FW_ACTIVE_90)
  2948. percent_cmplt = UPDATE_FW_ACTIVE_90;
  2949. /*
  2950. * Write File Status: set from 1 to 90 when
  2951. * fw_size is big enough (such as 82033). But the
  2952. * function doesn't update "write_file_status" if the
  2953. * input value is less than current stored value.
  2954. */
  2955. _pt_update_write_file_status(dev, percent_cmplt);
  2956. #ifdef TTDL_DIAGNOSTICS
  2957. pt_debug(dev, DL_INFO,
  2958. "Wrote %d bytes with %d bytes remaining\n",
  2959. offset, remain_bytes);
  2960. #endif
  2961. }
  2962. if (remain_bytes > packet_size) {
  2963. /* The last para passes in with last_packet=0 (false) */
  2964. ret = _pt_pip2_file_write_packet_and_log_err(
  2965. dev, file_handle, &fw_img[offset], packet_size, 0);
  2966. offset += packet_size;
  2967. if (ret)
  2968. break;
  2969. } else {
  2970. pt_debug(dev, DL_INFO,
  2971. "Write last %d bytes to File = 0x%02x\n",
  2972. remain_bytes, ld->pip2_load_file_no);
  2973. /* The last para passes in with last_packet=1 (true) */
  2974. ret = _pt_pip2_file_write_packet_and_log_err(
  2975. dev, file_handle, &fw_img[offset], remain_bytes, 1);
  2976. offset += remain_bytes;
  2977. break;
  2978. }
  2979. }
  2980. if (cd->bl_with_no_int)
  2981. enable_irq(cd->irq);
  2982. if (!ret) {
  2983. /* Write File Status: set to 99 */
  2984. _pt_update_write_file_status(dev, UPDATE_FW_ACTIVE_99);
  2985. pt_debug(dev, DL_INFO,
  2986. "%s: BIN file write finished successfully\n", __func__);
  2987. } else
  2988. _pt_update_write_file_status(dev, UPDATE_FW_WRITE_ERROR);
  2989. exit_close_file:
  2990. /* 4. Close file */
  2991. ret = cmd->nonhid_cmd->pip2_file_close(dev, file_handle);
  2992. if (ret != ld->pip2_load_file_no) {
  2993. pt_debug(dev, DL_ERROR,
  2994. "%s file close failure\n", __func__);
  2995. _pt_update_write_file_status(dev, UPDATE_FW_FILE_CLOSE_ERROR);
  2996. ret = -EBADF;
  2997. } else
  2998. ret = 0;
  2999. exit:
  3000. return ret;
  3001. }
  3002. /*******************************************************************************
  3003. * FUNCTION: _pt_pip2_update_fw
  3004. *
  3005. * SUMMARY: Compelete steps to update FW. It includes following steps:
  3006. * 1) Enter bootloader
  3007. * 2) Compare IMG version with FW version
  3008. * 3) Write IMG to target FILE
  3009. * 4) Exit bootloader
  3010. * 5) Trigger Enum and check the sentinel
  3011. * Also includes exclusive protection, PM function, Watchdog function, and
  3012. * complete progress for "update_bl_status".
  3013. *
  3014. * NOTE: "write_file_status" is updated from 0 to 100 in this scope, and higher
  3015. * level function is allowed to reset status to 0 or report an error status.
  3016. *
  3017. * RETURN:
  3018. * 0 = success
  3019. * !0 = failure
  3020. *
  3021. * PARAMETERS:
  3022. * *dev - pointer to device structure
  3023. * *fw - pointer to FW image to load
  3024. * file_no - Identifies the files to write
  3025. ******************************************************************************/
  3026. static int _pt_pip2_update_fw(struct device *dev, const struct firmware *fw,
  3027. u8 file_no)
  3028. {
  3029. struct pt_core_data *cd = dev_get_drvdata(dev);
  3030. struct pt_loader_data *ld = pt_get_loader_data(dev);
  3031. int ret = 0;
  3032. int t = 0;
  3033. bool wait_for_calibration_complete = false;
  3034. u8 mode = PT_MODE_UNKNOWN;
  3035. u8 status = 0;
  3036. u8 read_buf[PT_MAX_PIP2_MSG_SIZE];
  3037. pt_debug(dev, DL_WARN, "%s: ATM - Begin BL\n", __func__);
  3038. /* Write File Status: reset to 0 */
  3039. _pt_update_write_file_status(dev, UPDATE_FW_IDLE);
  3040. if (file_no > PIP2_FW_FILE) {
  3041. pt_debug(dev, DL_ERROR,
  3042. "%s: Invalid File_no = %d\n", __func__, file_no);
  3043. _pt_update_write_file_status(dev,
  3044. UPDATE_FW_NOT_SUPPORTED_FILE_NO);
  3045. goto exit;
  3046. }
  3047. /* Write File Status: set to 0 */
  3048. ret = cmd->request_exclusive(dev, PT_LDR_REQUEST_EXCLUSIVE_TIMEOUT);
  3049. if (ret) {
  3050. pt_debug(dev, DL_ERROR,
  3051. "%s: Failed to aquire exclusive access\n", __func__);
  3052. _pt_update_write_file_status(dev,
  3053. UPDATE_FW_EXCLUSIVE_ACCESS_ERROR);
  3054. goto exit;
  3055. }
  3056. /* Write File Status: set to 1 */
  3057. _pt_update_write_file_status(dev, UPDATE_FW_REQUEST_EXCLUSIVE);
  3058. cd->fw_updating = true;
  3059. wake_up(&cd->wait_q);
  3060. /* Write File Status: inc to 2 */
  3061. _pt_update_write_file_status(dev, UPDATE_FW_INCREMENT_BY_1);
  3062. pt_debug(dev, DL_INFO,
  3063. "%s: Found file of size: %d bytes\n", __func__, (int)fw->size);
  3064. pm_runtime_get_sync(dev);
  3065. /* Write File Status: inc to 3 */
  3066. _pt_update_write_file_status(dev, UPDATE_FW_INCREMENT_BY_1);
  3067. cmd->request_stop_wd(dev);
  3068. /* Write File Status: inc to 4 */
  3069. _pt_update_write_file_status(dev, UPDATE_FW_INCREMENT_BY_1);
  3070. cd->bl_pip_ver_ready = false;
  3071. cd->app_pip_ver_ready = false;
  3072. /*
  3073. * 'mode' is used below, if DUT was already in BL before attempting to
  3074. * enter the BL, there was either no FW to run or the FW was corrupt
  3075. * so either way force a BL
  3076. */
  3077. ret = cmd->request_pip2_enter_bl(dev, &mode, NULL);
  3078. if (ret) {
  3079. pt_debug(dev, DL_ERROR, "%s: Failed to enter BL\n",
  3080. __func__);
  3081. _pt_update_write_file_status(dev, UPDATE_FW_ENTER_BL_ERROR);
  3082. goto exit;
  3083. }
  3084. /* Write File Status: inc to 5 */
  3085. _pt_update_write_file_status(dev, UPDATE_FW_INCREMENT_BY_1);
  3086. /* Only compare FW ver or previous mode when doing a built-in upgrade */
  3087. if (ld->pip2_load_builtin) {
  3088. if (_pt_pip2_need_upgrade_due_to_fw_ver(dev, fw) ||
  3089. mode == PT_MODE_BOOTLOADER) {
  3090. /* Write File Status: inc to 6 */
  3091. _pt_update_write_file_status(dev,
  3092. UPDATE_FW_INCREMENT_BY_1);
  3093. } else {
  3094. _pt_update_write_file_status(dev,
  3095. UPDATE_FW_VERSION_ERROR);
  3096. goto exit;
  3097. }
  3098. }
  3099. /*
  3100. * Write File Status: set to 10 before pt_pip2_write_file() is called to
  3101. * align with _pt_pip2_write_file_cont().
  3102. */
  3103. _pt_update_write_file_status(dev, UPDATE_FW_ACTIVE_10);
  3104. /* Write File Status: inc from 10, the max is not bigger than 99 */
  3105. ret = pt_pip2_write_file(dev, fw, file_no);
  3106. if (ret) {
  3107. pt_debug(dev, DL_ERROR, "%s: Failed to write FILE_%d\n",
  3108. __func__, file_no);
  3109. goto exit;
  3110. }
  3111. if ((file_no == PIP2_RAM_FILE) &&
  3112. (write_file_status < UPDATE_FW_COMPLETE)) {
  3113. /* When writing to RAM don't reset, just launch application */
  3114. pt_debug(dev, DL_INFO,
  3115. "%s Sending execute command now...\n", __func__);
  3116. cd->startup_status = STARTUP_STATUS_START;
  3117. ret = _pt_pip2_execute_app(dev, &status);
  3118. if (ret || status) {
  3119. pt_debug(dev, DL_ERROR,
  3120. "%s Execute command failure\n", __func__);
  3121. _pt_update_write_file_status(dev,
  3122. UPDATE_FW_EXECUTE_ERROR);
  3123. goto exit;
  3124. }
  3125. } else if (file_no == PIP2_FW_FILE &&
  3126. write_file_status < UPDATE_FW_COMPLETE) {
  3127. pt_debug(dev, DL_INFO,
  3128. "%s Toggle TP_XRES now...\n", __func__);
  3129. cmd->request_reset(dev, PT_CORE_CMD_UNPROTECTED);
  3130. }
  3131. pt_debug(dev, DL_INFO, "%s: APP launched\n", __func__);
  3132. /* If any error occurred simply close the file and exit */
  3133. if (write_file_status > UPDATE_FW_COMPLETE)
  3134. goto exit;
  3135. /* Wait for FW reset sentinel from reset or execute for up to 500ms */
  3136. t = wait_event_timeout(cd->wait_q,
  3137. (cd->startup_status >= STARTUP_STATUS_FW_RESET_SENTINEL),
  3138. msecs_to_jiffies(PT_BL_WAIT_FOR_SENTINEL));
  3139. if (IS_TMO(t)) {
  3140. pt_debug(dev, DL_WARN,
  3141. "%s: 0x%04X Timeout waiting for FW sentinel",
  3142. __func__, cd->startup_status);
  3143. }
  3144. /* Double verify DUT is alive and well in Application mode */
  3145. if (cd->startup_status & STARTUP_STATUS_FW_RESET_SENTINEL) {
  3146. ret = cmd->request_pip2_get_mode_sysmode(dev,
  3147. PT_CORE_CMD_UNPROTECTED, &mode, NULL);
  3148. pt_debug(dev, DL_WARN, "%s: mode = %d (Expected 2)",
  3149. __func__, mode);
  3150. if (mode != PT_MODE_OPERATIONAL) {
  3151. pt_debug(dev, DL_ERROR,
  3152. "%s ERROR: Not in App mode as expected\n",
  3153. __func__);
  3154. _pt_update_write_file_status(dev, UPDATE_FW_MODE_ERROR);
  3155. goto exit;
  3156. }
  3157. } else {
  3158. pt_debug(dev, DL_ERROR, "%s: FW sentinel not seen 0x%04X\n",
  3159. __func__, cd->startup_status);
  3160. _pt_pip2_log_last_error(dev, read_buf);
  3161. _pt_update_write_file_status(dev, UPDATE_FW_SENTINEL_NOT_SEEN);
  3162. goto exit;
  3163. }
  3164. /* On a Flashless DUT save or restore the CAL data */
  3165. if (cd->cal_cache_in_host == PT_FEATURE_ENABLE)
  3166. _pt_calibrate_flashless_dut(dev);
  3167. /* Subscribe calibration task if calibration flag is set */
  3168. if (ld->loader_pdata
  3169. && (ld->loader_pdata->flags
  3170. & PT_LOADER_FLAG_CALIBRATE_AFTER_FW_UPGRADE)
  3171. && (cd->cal_cache_in_host == PT_FEATURE_DISABLE)) {
  3172. #if (KERNEL_VERSION(3, 13, 0) <= LINUX_VERSION_CODE)
  3173. reinit_completion(&ld->calibration_complete);
  3174. #else
  3175. INIT_COMPLETION(ld->calibration_complete);
  3176. #endif
  3177. /* set up call back for startup */
  3178. pt_debug(dev, DL_INFO, "%s: Adding callback for calibration\n",
  3179. __func__);
  3180. ret = cmd->subscribe_attention(dev, PT_ATTEN_STARTUP,
  3181. PT_LOADER_NAME, pt_calibration_attention, 0);
  3182. if (ret) {
  3183. pt_debug(dev, DL_ERROR,
  3184. "%s: Failed adding callback for calibration\n",
  3185. __func__);
  3186. ret = 0;
  3187. } else
  3188. wait_for_calibration_complete = true;
  3189. }
  3190. pt_debug(dev, DL_INFO, "%s: == PIP2 FW upgrade finished ==\n",
  3191. __func__);
  3192. exit:
  3193. cd->fw_updating = false;
  3194. /*
  3195. * For built-in FW update, it should not warn builtin_bin_fw_status
  3196. * for each bootup since write_file_status would be
  3197. * UPDATE_FW_VERSION_ERROR in most situations because firmware
  3198. * should have been up to date.
  3199. */
  3200. if (ld->pip2_load_builtin) {
  3201. if ((write_file_status == UPDATE_FW_ACTIVE_99) ||
  3202. (write_file_status == UPDATE_FW_VERSION_ERROR))
  3203. ld->builtin_bin_fw_status = 0;
  3204. else
  3205. ld->builtin_bin_fw_status = -EINVAL;
  3206. }
  3207. cmd->release_exclusive(dev);
  3208. pm_runtime_put_sync(dev);
  3209. if ((write_file_status == UPDATE_FW_ACTIVE_99) ||
  3210. (write_file_status == UPDATE_FW_VERSION_ERROR)) {
  3211. pt_debug(dev, DL_WARN, "%s: Queue ENUM\n", __func__);
  3212. cmd->request_enum(dev, true);
  3213. }
  3214. /* Write File Status: set to 100 */
  3215. if (write_file_status < UPDATE_FW_COMPLETE)
  3216. _pt_update_write_file_status(dev, UPDATE_FW_COMPLETE);
  3217. if (wait_for_calibration_complete)
  3218. wait_for_completion(&ld->calibration_complete);
  3219. pt_debug(dev, DL_INFO, "%s: Starting watchdog\n", __func__);
  3220. cmd->request_start_wd(dev);
  3221. /*
  3222. * When in No-Flash mode allow auto BL after any BL.
  3223. * There is an issue where setting flashless mode via drv_debug
  3224. * can happen in the middle of pt_pip2_enter_bl() which will revert
  3225. * the flashless_auto_bl value back to what it was when the function
  3226. * started.
  3227. */
  3228. if (cd->flashless_dut)
  3229. cd->flashless_auto_bl = PT_ALLOW_AUTO_BL;
  3230. /*
  3231. * ret is not always updated, while builtin_bin_fw_status can reflect
  3232. * the result.
  3233. */
  3234. return ld->builtin_bin_fw_status;
  3235. }
  3236. /*******************************************************************************
  3237. * FUNCTION: _pt_pip2_write_file_cont
  3238. *
  3239. * SUMMARY: Write the file to either SRAM or FLASH
  3240. *
  3241. * NOTE: The DUT must stay in bootloader. This function doesn't try to
  3242. * enter/exit bootloader.
  3243. *
  3244. * PARAMETERS:
  3245. * *fw - pointer to the new FW image to load
  3246. * *context - pointer to the device
  3247. ******************************************************************************/
  3248. static void _pt_pip2_write_file_cont(const struct firmware *fw, void *context)
  3249. {
  3250. struct device *dev = context;
  3251. struct pt_core_data *cd = dev_get_drvdata(dev);
  3252. struct pt_loader_data *ld = pt_get_loader_data(dev);
  3253. int ret = 0;
  3254. if (!fw) {
  3255. pt_debug(dev, DL_ERROR, "%s: No FW is provided\n", __func__);
  3256. _pt_update_write_file_status(dev, UPDATE_FW_NO_FW_PROVIDED);
  3257. goto exit;
  3258. }
  3259. if (!fw->size) {
  3260. pt_debug(dev, DL_ERROR, "%s: Invalid fw or file size=%d\n",
  3261. __func__, (int)fw->size);
  3262. _pt_update_write_file_status(dev, UPDATE_FW_INVALID_FW_IMAGE);
  3263. goto exit_release;
  3264. }
  3265. if (ld->pip2_load_file_no == PIP2_FW_FILE) {
  3266. if (fw->data[0] >= (fw->size + 1)) {
  3267. pt_debug(dev, DL_ERROR,
  3268. "%s: Firmware format is invalid\n", __func__);
  3269. _pt_update_write_file_status(dev,
  3270. UPDATE_FW_INVALID_FW_IMAGE);
  3271. goto exit_release;
  3272. }
  3273. }
  3274. ret = cmd->request_exclusive(dev, PT_LDR_REQUEST_EXCLUSIVE_TIMEOUT);
  3275. if (ret < 0) {
  3276. pt_debug(dev, DL_ERROR,
  3277. "%s: Failed to aquire exclusive access\n", __func__);
  3278. goto exit_release;
  3279. }
  3280. /* Write File Status: set to 1 */
  3281. _pt_update_write_file_status(dev, UPDATE_FW_REQUEST_EXCLUSIVE);
  3282. cd->fw_updating = true;
  3283. /* Write File Status: inc to 2 */
  3284. _pt_update_write_file_status(dev, UPDATE_FW_INCREMENT_BY_1);
  3285. /*
  3286. * Write File Status: set to 10 before pt_pip2_write_file() is called to
  3287. * align with _pt_pip2_firmware_cont().
  3288. */
  3289. _pt_update_write_file_status(dev, UPDATE_FW_ACTIVE_10);
  3290. /* Write File Status: inc from 10, the max is not bigger than 99 */
  3291. ret = pt_pip2_write_file(dev, fw, ld->pip2_load_file_no);
  3292. if (ret) {
  3293. pt_debug(dev, DL_ERROR, "%s: Failed to write FILE_%d\n",
  3294. __func__, ld->pip2_load_file_no);
  3295. }
  3296. cd->fw_updating = false;
  3297. /* Write File Status: set to 100 */
  3298. if (write_file_status < UPDATE_FW_COMPLETE)
  3299. _pt_update_write_file_status(dev, UPDATE_FW_COMPLETE);
  3300. cmd->release_exclusive(dev);
  3301. exit_release:
  3302. if (fw)
  3303. release_firmware(fw);
  3304. exit:
  3305. ld->is_manual_upgrade_enabled = 0;
  3306. }
  3307. /*******************************************************************************
  3308. * FUNCTION: _pt_pip2_firmware_cont
  3309. *
  3310. * SUMMARY: Bootload the DUT with a FW image using the PIP2 protocol. This
  3311. * includes getting the DUT into BL mode, writing the file to either SRAM
  3312. * or FLASH, and launching the application directly in SRAM or by resetting
  3313. * the DUT without the hostmode pin asserted.
  3314. *
  3315. * NOTE: Special care must be taken to support a DUT communicating in
  3316. * PIP2.0 where the length field is defined differently.
  3317. * NOTE: The write packet len is set so that the overall packet size is
  3318. * less than 255. The overhead is 9 bytes: 2 byte address (0101),
  3319. * 4 byte header, 1 byte file no. 2 byte CRC
  3320. *
  3321. * PARAMETERS:
  3322. * *fw - pointer to the new FW image to load
  3323. * *context - pointer to the device
  3324. ******************************************************************************/
  3325. static void _pt_pip2_firmware_cont(const struct firmware *fw,
  3326. void *context)
  3327. {
  3328. struct device *dev = context;
  3329. struct pt_loader_data *ld = pt_get_loader_data(dev);
  3330. if (!fw) {
  3331. pt_debug(dev, DL_ERROR, "%s: No FW is provided\n", __func__);
  3332. _pt_update_write_file_status(dev, UPDATE_FW_NO_FW_PROVIDED);
  3333. goto pt_firmware_cont_exit;
  3334. }
  3335. if (!fw->data || !fw->size) {
  3336. pt_debug(dev, DL_ERROR, "%s: Invalid fw or file size=%d\n",
  3337. __func__, (int)fw->size);
  3338. _pt_update_write_file_status(dev, UPDATE_FW_INVALID_FW_IMAGE);
  3339. goto pt_firmware_cont_release_exit;
  3340. }
  3341. if (ld->pip2_load_file_no == PIP2_FW_FILE) {
  3342. if (fw->data[0] >= (fw->size + 1)) {
  3343. pt_debug(dev, DL_ERROR,
  3344. "%s: Firmware format is invalid\n", __func__);
  3345. _pt_update_write_file_status(
  3346. dev, UPDATE_FW_INVALID_FW_IMAGE);
  3347. goto pt_firmware_cont_release_exit;
  3348. }
  3349. }
  3350. _pt_pip2_update_fw(dev, fw, ld->pip2_load_file_no);
  3351. pt_firmware_cont_release_exit:
  3352. if (fw)
  3353. release_firmware(fw);
  3354. pt_firmware_cont_exit:
  3355. ld->is_manual_upgrade_enabled = 0;
  3356. }
  3357. /*******************************************************************************
  3358. * FUNCTION: _pt_pip2_update_fw_from_builtin
  3359. *
  3360. * SUMMARY: Bootload the DUT with a built in firmware binary image.
  3361. *
  3362. * RETURN:
  3363. * 0 = success
  3364. * !0 = failure
  3365. *
  3366. * PARAMETERS:
  3367. * *dev - pointer to the device structure
  3368. ******************************************************************************/
  3369. #define PIP2_MAX_FILE_NAMES 3
  3370. static int _pt_pip2_update_fw_from_builtin(struct device *dev)
  3371. {
  3372. struct pt_core_data *cd = dev_get_drvdata(dev);
  3373. struct pt_loader_data *ld = pt_get_loader_data(dev);
  3374. const struct firmware *fw = NULL;
  3375. int ret = 0;
  3376. int index = 0;
  3377. int file_count = 0;
  3378. char *filename[PIP2_MAX_FILE_NAMES];
  3379. /*
  3380. * 1. Generate FW Name for builtin kernel
  3381. * Load the supported filenames in the correct search order
  3382. * 0 - "tt_fw<_PIDX>.bin"
  3383. * 1 - "XXXX_tt_fw<_PIDX>.bin" where XXXX = Silicon ID
  3384. * 2 - "tt_fw.bin", default FW name
  3385. */
  3386. filename[file_count++] = generate_firmware_filename(dev);
  3387. filename[file_count++] = generate_silicon_id_firmware_filename(dev);
  3388. if (pt_get_panel_id(dev) != PANEL_ID_NOT_ENABLED) {
  3389. filename[file_count] =
  3390. kzalloc(sizeof(PT_FW_FILE_NAME), GFP_KERNEL);
  3391. memcpy(filename[file_count++], PT_FW_FILE_NAME,
  3392. sizeof(PT_FW_FILE_NAME));
  3393. }
  3394. for (index = 0; index < file_count; index++) {
  3395. if (!filename[index])
  3396. return -ENOMEM;
  3397. }
  3398. /* 2. Look for any FW file name match */
  3399. mutex_lock(&cd->firmware_class_lock);
  3400. index = 0;
  3401. while (index < file_count) {
  3402. pt_debug(dev, DL_INFO, "%s: Request FW class file: %s\n",
  3403. __func__, filename[index]);
  3404. if (_search_fw_from_builtin(dev, filename[index], &fw))
  3405. index++;
  3406. else
  3407. break;
  3408. }
  3409. /* No matching file names found */
  3410. if (index == file_count) {
  3411. pt_debug(dev, DL_WARN, "%s: No FW is found\n", __func__);
  3412. _pt_update_write_file_status(dev, UPDATE_FW_NO_FW_PROVIDED);
  3413. ret = -EINVAL;
  3414. goto exit;
  3415. }
  3416. /* 3. Validate the FW */
  3417. if (!fw) {
  3418. pt_debug(dev, DL_ERROR, "%s: No FW is provided\n", __func__);
  3419. _pt_update_write_file_status(dev, UPDATE_FW_NO_FW_PROVIDED);
  3420. ret = -EINVAL;
  3421. goto exit_release_fw;
  3422. }
  3423. if (!fw->size) {
  3424. pt_debug(dev, DL_ERROR, "%s: Invalid fw or file size=%d\n",
  3425. __func__, (int)fw->size);
  3426. _pt_update_write_file_status(dev, UPDATE_FW_INVALID_FW_IMAGE);
  3427. ret = -EINVAL;
  3428. goto exit_release_fw;
  3429. }
  3430. if (ld->pip2_load_file_no == PIP2_FW_FILE) {
  3431. if (fw->data[0] >= (fw->size + 1)) {
  3432. pt_debug(dev, DL_ERROR,
  3433. "%s: Firmware format is invalid\n", __func__);
  3434. _pt_update_write_file_status(dev,
  3435. UPDATE_FW_INVALID_FW_IMAGE);
  3436. ret = -EINVAL;
  3437. goto exit_release_fw;
  3438. }
  3439. }
  3440. /* 4. update the FW */
  3441. ret = _pt_pip2_update_fw(dev, fw, ld->pip2_load_file_no);
  3442. exit_release_fw:
  3443. /* 5. Recycle */
  3444. if (fw)
  3445. release_firmware(fw);
  3446. exit:
  3447. index = 0;
  3448. while (index < file_count)
  3449. kfree(filename[index++]);
  3450. mutex_unlock(&cd->firmware_class_lock);
  3451. return ret;
  3452. }
  3453. /*******************************************************************************
  3454. * FUNCTION: _pt_pip2_update_fw_from_us
  3455. *
  3456. * SUMMARY: Bootload the DUT with firmware binary image in user space.
  3457. *
  3458. * RETURN:
  3459. * 0 = success
  3460. * !0 = failure
  3461. *
  3462. * PARAMETERS:
  3463. * *dev - pointer to the device structure
  3464. ******************************************************************************/
  3465. static int _pt_pip2_update_fw_from_us(struct device *dev)
  3466. {
  3467. struct pt_core_data *cd = dev_get_drvdata(dev);
  3468. struct pt_loader_data *ld = pt_get_loader_data(dev);
  3469. struct firmware fw_us;
  3470. int ret = 0;
  3471. u32 fw_size = 0;
  3472. u8 *fw_img = NULL;
  3473. fw_img = kzalloc(PT_PIP2_MAX_FILE_SIZE, GFP_KERNEL);
  3474. if (!fw_img) {
  3475. _pt_update_write_file_status(dev, UPDATE_FW_NO_FW_PROVIDED);
  3476. return -ENOMEM;
  3477. }
  3478. ret = cmd->nonhid_cmd->read_us_file(dev, cd->pip2_us_file_path,
  3479. fw_img, &fw_size);
  3480. if (ret) {
  3481. pt_debug(dev, DL_ERROR, "%s: No firmware provided to load\n",
  3482. __func__);
  3483. pt_debug(dev, DL_ERROR, "%s: Exit BL\n", __func__);
  3484. _pt_update_write_file_status(dev, UPDATE_FW_NO_FW_PROVIDED);
  3485. goto exit;
  3486. }
  3487. if (!fw_size) {
  3488. pt_debug(dev, DL_ERROR, "%s: Invalid fw file size=%d\n",
  3489. __func__, (int)fw_size);
  3490. _pt_update_write_file_status(dev, UPDATE_FW_INVALID_FW_IMAGE);
  3491. goto exit;
  3492. }
  3493. if (ld->pip2_load_file_no == PIP2_FW_FILE) {
  3494. if (fw_img[0] >= (fw_size + 1)) {
  3495. pt_debug(dev, DL_ERROR,
  3496. "%s: Firmware format is invalid\n", __func__);
  3497. _pt_update_write_file_status(dev,
  3498. UPDATE_FW_INVALID_FW_IMAGE);
  3499. goto exit;
  3500. }
  3501. }
  3502. memset(&fw_us, 0, sizeof(fw_us));
  3503. fw_us.data = fw_img;
  3504. fw_us.size = fw_size;
  3505. ret = _pt_pip2_update_fw(dev, &fw_us, ld->pip2_load_file_no);
  3506. exit:
  3507. kfree(fw_img);
  3508. return ret;
  3509. }
  3510. /*******************************************************************************
  3511. * FUNCTION: pt_pip2_upgrade_firmware_from_builtin
  3512. *
  3513. * SUMMARY: Bootload the DUT with a built in firmware binary image.
  3514. * Load either a SRAM image "ttdl_fw_RAM.bin" or a FLASH image
  3515. * "ttdl_fw.bin" with the priority being the SRAM image.
  3516. *
  3517. * PARAMETERS:
  3518. * *dev - pointer to the device structure
  3519. ******************************************************************************/
  3520. static int pt_pip2_upgrade_firmware_from_builtin(struct device *dev)
  3521. {
  3522. struct pt_core_data *cd = dev_get_drvdata(dev);
  3523. struct pt_loader_data *ld = pt_get_loader_data(dev);
  3524. int ret = 0;
  3525. /* 1. Look for FW from us at first */
  3526. if (cd->flashless_dut) {
  3527. pt_debug(dev, DL_INFO, "%s: Proceed to BL flashless DUT\n",
  3528. __func__);
  3529. ld->pip2_load_file_no = PIP2_RAM_FILE;
  3530. ret = _search_fw_from_us(dev);
  3531. if (!ret) {
  3532. ld->pip2_load_builtin = false;
  3533. /* 2. Do update with fw from user space */
  3534. ret = _pt_pip2_update_fw_from_us(dev);
  3535. return ret;
  3536. } else {
  3537. ld->pip2_load_builtin = true;
  3538. }
  3539. } else {
  3540. ld->pip2_load_file_no = PIP2_FW_FILE;
  3541. ld->pip2_load_builtin = true;
  3542. }
  3543. /* 2. Do update with fw from builtin */
  3544. ret = _pt_pip2_update_fw_from_builtin(dev);
  3545. return ret;
  3546. }
  3547. /*******************************************************************************
  3548. * FUNCTION: _pt_pip2_update_fw_from_class
  3549. *
  3550. * SUMMARY: Create the firmware class but don't actually laod any FW to the
  3551. * DUT. This creates all the sysfs nodes needed for a user to bootload
  3552. * the DUT with their own bin file.
  3553. *
  3554. * PARAMETERS:
  3555. * *pip2_data - pointer to the PIP2 loader data structure
  3556. ******************************************************************************/
  3557. static int _pt_pip2_update_fw_from_class(struct device *dev)
  3558. {
  3559. struct pt_loader_data *ld = pt_get_loader_data(dev);
  3560. int ret = 0;
  3561. /*
  3562. * The file name dev_name(dev) is tied with bus name and usually
  3563. * it is "x-0024". This name is wanted to keep consistency
  3564. * (e.g. /sys/class/firmware/x-0024/) for the path of fw class
  3565. * nodes with different kernel release. Also it is an invalid bin
  3566. * file name used intentionally because request_firmware_nowait
  3567. * will not find the file which is what we want and then simply
  3568. * create the fw class nodes.
  3569. */
  3570. ld->pip2_load_builtin = false;
  3571. pt_debug(dev, DL_INFO, "%s: Request FW Class", __func__);
  3572. ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG,
  3573. dev_name(dev), dev, GFP_KERNEL, dev,
  3574. _pt_pip2_firmware_cont);
  3575. if (ret) {
  3576. pt_debug(dev, DL_ERROR,
  3577. "%s: ERROR requesting firmware class\n", __func__);
  3578. }
  3579. return ret;
  3580. }
  3581. /*******************************************************************************
  3582. * FUNCTION: _pt_pip2_write_file_from_class
  3583. *
  3584. * SUMMARY: Similar function of _pt_pip2_update_fw_from_class() but to call
  3585. * function _pt_pip2_write_file_cont() which doesn't perform enter/exit
  3586. * bootloader action.
  3587. *
  3588. * PARAMETERS:
  3589. * *pip2_data - pointer to the PIP2 loader data structure
  3590. ******************************************************************************/
  3591. static int _pt_pip2_write_file_from_class(struct device *dev)
  3592. {
  3593. int ret = 0;
  3594. struct pt_loader_data *ld = pt_get_loader_data(dev);
  3595. /*
  3596. * The file name dev_name(dev) is tied with bus name and usually
  3597. * it is "x-0024". This name is wanted to keep consistency
  3598. * (e.g. /sys/class/firmware/x-0024/) for the path of fw class
  3599. * nodes with different kernel release. Also it is an invalid bin
  3600. * file name used intentionally because request_firmware_nowait
  3601. * will not find the file which is what we want and then simply
  3602. * create the fw class nodes.
  3603. */
  3604. ld->pip2_load_builtin = false;
  3605. pt_debug(dev, DL_INFO, "%s: Request FW Class", __func__);
  3606. ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG,
  3607. dev_name(dev), dev, GFP_KERNEL, dev,
  3608. _pt_pip2_write_file_cont);
  3609. if (ret) {
  3610. pt_debug(dev, DL_ERROR,
  3611. "%s: ERROR requesting firmware class\n", __func__);
  3612. }
  3613. return ret;
  3614. }
  3615. /*******************************************************************************
  3616. * FUNCTION: pt_pip2_bl_from_file_work
  3617. *
  3618. * SUMMARY: The work function to schedule the BL work for PIP2 only.
  3619. *
  3620. * PARAMETERS:
  3621. * *bl_from_file - pointer to work_struct structure
  3622. ******************************************************************************/
  3623. static void pt_pip2_bl_from_file_work(struct work_struct *pip2_bl_from_file)
  3624. {
  3625. struct pt_loader_data *ld = container_of(pip2_bl_from_file,
  3626. struct pt_loader_data, pip2_bl_from_file);
  3627. struct device *dev = ld->dev;
  3628. _pt_pip2_update_fw_from_us(dev);
  3629. }
  3630. /*******************************************************************************
  3631. * FUNCTION: pt_bl_from_file_work
  3632. *
  3633. * SUMMARY: The work function to schedule the BL work for PIP2 or PIP1
  3634. * according to the active_dut_generation in core data.
  3635. *
  3636. * PARAMETERS:
  3637. * *bl_from_file - pointer to work_struct structure
  3638. ******************************************************************************/
  3639. static void pt_bl_from_file_work(struct work_struct *bl_from_file)
  3640. {
  3641. struct pt_loader_data *ld = container_of(bl_from_file,
  3642. struct pt_loader_data, bl_from_file);
  3643. struct device *dev = ld->dev;
  3644. u8 dut_gen = cmd->request_dut_generation(dev);
  3645. if (dut_gen == DUT_PIP2_CAPABLE)
  3646. _pt_pip2_update_fw_from_us(dev);
  3647. else if (dut_gen == DUT_PIP1_ONLY)
  3648. _pt_pip1_bl_from_file(dev);
  3649. }
  3650. /*******************************************************************************
  3651. * FUNCTION: pt_pip2_bl_from_file_show
  3652. *
  3653. * SUMMARY: The show method for the "pip2_bl_from_file" sysfs node. The
  3654. * scheduled work will perform PIP2 BL.
  3655. *
  3656. * NOTE: Since this function doesn't set pip2_load_file_no, it will use the
  3657. * value what has been stored there.
  3658. *
  3659. * PARAMETERS:
  3660. * *dev - pointer to device structure
  3661. * *attr - pointer to device attributes structure
  3662. * *buf - pointer to print output buffer
  3663. ******************************************************************************/
  3664. static ssize_t pt_pip2_bl_from_file_show(struct device *dev,
  3665. struct device_attribute *attr, char *buf)
  3666. {
  3667. struct pt_loader_data *ld = pt_get_loader_data(dev);
  3668. struct pt_core_data *cd = dev_get_drvdata(dev);
  3669. int rc = 0;
  3670. int read_size = 2;
  3671. u8 image[2];
  3672. /* Write File Status: reset to 0 */
  3673. _pt_update_write_file_status(dev, UPDATE_FW_IDLE);
  3674. mutex_lock(&cd->firmware_class_lock);
  3675. ld->pip2_load_builtin = false;
  3676. mutex_unlock(&cd->firmware_class_lock);
  3677. /* Read a few bytes to see if file exists */
  3678. rc = cmd->nonhid_cmd->read_us_file(dev,
  3679. cd->pip2_us_file_path, image, &read_size);
  3680. if (!rc) {
  3681. schedule_work(&ld->pip2_bl_from_file);
  3682. return snprintf(buf, PT_MAX_PRBUF_SIZE,
  3683. "Status: %d\n"
  3684. "BL File: %s\n",
  3685. rc, cd->pip2_us_file_path);
  3686. } else {
  3687. _pt_update_write_file_status(dev, UPDATE_FW_NO_FW_PROVIDED);
  3688. return snprintf(buf, PT_MAX_PRBUF_SIZE,
  3689. "Status: %d\n"
  3690. "BL File: '%s' - Does not exist\n",
  3691. rc, cd->pip2_us_file_path);
  3692. }
  3693. }
  3694. /*******************************************************************************
  3695. * FUNCTION: pt_bl_from_file_show
  3696. *
  3697. * SUMMARY: The show method for the "pt_bl_from_file" sysfs node. The scheduled
  3698. * work can perform either PIP1 BL and PIP2 BL according to the
  3699. * active_dut_generation of core data.
  3700. *
  3701. * NOTE: Since this function doesn't set pip2_load_file_no, it will use the
  3702. * value what has been stored there.
  3703. *
  3704. * PARAMETERS:
  3705. * *dev - pointer to device structure
  3706. * *attr - pointer to device attributes structure
  3707. * *buf - pointer to print output buffer
  3708. ******************************************************************************/
  3709. static ssize_t pt_bl_from_file_show(struct device *dev,
  3710. struct device_attribute *attr, char *buf)
  3711. {
  3712. struct pt_loader_data *ld = pt_get_loader_data(dev);
  3713. struct pt_core_data *cd = dev_get_drvdata(dev);
  3714. int rc = 0;
  3715. int read_size = 2;
  3716. u8 dut_gen = cmd->request_dut_generation(dev);
  3717. u8 image[2];
  3718. /* Write File Status: reset to 0 */
  3719. _pt_update_write_file_status(dev, UPDATE_FW_IDLE);
  3720. mutex_lock(&cd->firmware_class_lock);
  3721. ld->pip2_load_builtin = false;
  3722. mutex_unlock(&cd->firmware_class_lock);
  3723. /* Read a few bytes to see if file exists */
  3724. rc = cmd->nonhid_cmd->read_us_file(dev,
  3725. cd->pip2_us_file_path, image, &read_size);
  3726. if (dut_gen == DUT_UNKNOWN) {
  3727. _pt_update_write_file_status(dev, UPDATE_FW_MODE_ERROR);
  3728. rc = -EINVAL;
  3729. return snprintf(buf, PT_MAX_PRBUF_SIZE,
  3730. "Status: %d\n"
  3731. "BL File: '%s' - Failed, DUT Generation could not be determined\n",
  3732. rc, cd->pip2_us_file_path);
  3733. } else if (!rc) {
  3734. schedule_work(&ld->bl_from_file);
  3735. return snprintf(buf, PT_MAX_PRBUF_SIZE,
  3736. "Status: %d\n"
  3737. "BL File: %s\n",
  3738. rc, cd->pip2_us_file_path);
  3739. } else {
  3740. _pt_update_write_file_status(dev, UPDATE_FW_NO_FW_PROVIDED);
  3741. return snprintf(buf, PT_MAX_PRBUF_SIZE,
  3742. "Status: %d\n"
  3743. "BL File: '%s' - Does not exist\n",
  3744. rc, cd->pip2_us_file_path);
  3745. }
  3746. }
  3747. /*******************************************************************************
  3748. * FUNCTION: pt_pip2_bl_from_file_store
  3749. *
  3750. * SUMMARY: The store method for the "pip2_bl_from_file" and "pt_bl_from_file"
  3751. * sysfs node. Used to allow any file path[necessary] and file_no[optional] to
  3752. * be used to BL, for example: "echo /data/pt_fw 1 > pip2_bl_from_file", and
  3753. * do the "cat" will perform FW loader process.
  3754. *
  3755. * NOTE: the last char of file path in buf which is a '\n' is not copied.
  3756. * NOTE: the default file_no is PIP2_RAM_FILE.
  3757. *
  3758. * PARAMETERS:
  3759. * *dev - pointer to device structure
  3760. * *attr - pointer to device attributes
  3761. * *buf - pointer to output buffer
  3762. * size - size of data in buffer
  3763. ******************************************************************************/
  3764. static ssize_t pt_pip2_bl_from_file_store(struct device *dev,
  3765. struct device_attribute *attr, const char *buf, size_t size)
  3766. {
  3767. struct pt_loader_data *ld = pt_get_loader_data(dev);
  3768. struct pt_core_data *cd = dev_get_drvdata(dev);
  3769. const char *deli_space = " ", *deli_comma = ",";
  3770. char name_space[PT_MAX_PATH_SIZE];
  3771. char *ptr_left = NULL, *ptr_right = name_space;
  3772. u8 file_no = PIP2_RAM_FILE;
  3773. u32 input_data[2];
  3774. int length;
  3775. bool file_no_set = false;
  3776. memset(name_space, 0, PT_MAX_PATH_SIZE);
  3777. memset(cd->pip2_us_file_path, 0, PT_MAX_PATH_SIZE);
  3778. if (size <= PT_MAX_PATH_SIZE) {
  3779. memcpy(name_space, buf, size);
  3780. ptr_left = strsep(&ptr_right, deli_space);
  3781. if (ptr_right == NULL) {
  3782. ptr_right = name_space;
  3783. ptr_left = strsep(&ptr_right, deli_comma);
  3784. }
  3785. if (ptr_right != NULL) {
  3786. length = cmd->parse_sysfs_input(
  3787. dev, ptr_right, strlen(ptr_right), input_data,
  3788. ARRAY_SIZE(input_data));
  3789. if (length <= 0) {
  3790. pt_debug(dev, DL_ERROR,
  3791. "%s: Input format error!\n", __func__);
  3792. return -EINVAL;
  3793. }
  3794. file_no_set = true;
  3795. file_no = input_data[0];
  3796. }
  3797. pt_debug(dev, DL_WARN, "%s:Path=%s, File_no=%s(%d)\n", __func__,
  3798. ptr_left, ptr_right, file_no);
  3799. if ((file_no_set) && (file_no > PIP2_FW_FILE)) {
  3800. pt_debug(dev, DL_WARN, "%s:Invalid File_no = %d\n",
  3801. __func__, file_no);
  3802. return -EINVAL;
  3803. }
  3804. mutex_lock(&cd->firmware_class_lock);
  3805. ld->pip2_load_file_no = file_no;
  3806. mutex_unlock(&cd->firmware_class_lock);
  3807. if (ptr_left[strlen(ptr_left) - 1] == '\n')
  3808. memcpy(cd->pip2_us_file_path, ptr_left,
  3809. strlen(ptr_left) - 1);
  3810. else
  3811. memcpy(cd->pip2_us_file_path, ptr_left,
  3812. strlen(ptr_left));
  3813. }
  3814. return size;
  3815. }
  3816. static DEVICE_ATTR(pip2_bl_from_file, 0644,
  3817. pt_pip2_bl_from_file_show, pt_pip2_bl_from_file_store);
  3818. static DEVICE_ATTR(pt_bl_from_file, 0644,
  3819. pt_bl_from_file_show, pt_pip2_bl_from_file_store);
  3820. /*******************************************************************************
  3821. * FUNCTION: pt_pip2_manual_upgrade_store
  3822. *
  3823. * SUMMARY: Store method for the pip2_manual_upgrade sysfs node. Allows
  3824. * sysfs control of bootloading a new FW image to FLASH.
  3825. *
  3826. * PARAMETERS:
  3827. * *dev - pointer to device structure
  3828. * *attr - pointer to device attributes
  3829. * *buf - pointer to output buffer
  3830. * size - size of data in buffer
  3831. ******************************************************************************/
  3832. static ssize_t pt_pip2_manual_upgrade_store(struct device *dev,
  3833. struct device_attribute *attr, const char *buf, size_t size)
  3834. {
  3835. struct pt_loader_data *ld = pt_get_loader_data(dev);
  3836. u32 input_data[2] = {0};
  3837. int length;
  3838. int rc = 0;
  3839. length = cmd->parse_sysfs_input(dev, buf, size, input_data,
  3840. ARRAY_SIZE(input_data));
  3841. if (length != 1) {
  3842. pt_debug(dev, DL_WARN, "%s: Invalid number of arguments\n",
  3843. __func__);
  3844. rc = -EINVAL;
  3845. goto exit;
  3846. }
  3847. if (input_data[0] < 0 || input_data[0] > 1) {
  3848. pt_debug(dev, DL_WARN, "%s: Invalid arguments\n", __func__);
  3849. rc = -EINVAL;
  3850. goto exit;
  3851. }
  3852. if (ld->is_manual_upgrade_enabled) {
  3853. pt_debug(dev, DL_ERROR,
  3854. "%s: ERROR - Manual upgrade busy\n", __func__);
  3855. rc = -EBUSY;
  3856. goto exit;
  3857. }
  3858. /* Write File Status: reset to 0 */
  3859. _pt_update_write_file_status(dev, UPDATE_FW_IDLE);
  3860. ld->pip2_load_file_no = PIP2_FW_FILE;
  3861. pt_debug(dev, DL_DEBUG, "%s: ATM - File number is %d\n",
  3862. __func__, ld->pip2_load_file_no);
  3863. ld->is_manual_upgrade_enabled = 1;
  3864. rc = _pt_pip2_update_fw_from_class(dev);
  3865. ld->is_manual_upgrade_enabled = 0;
  3866. if (rc < 0)
  3867. pt_debug(dev, DL_ERROR,
  3868. "%s: ERROR - FLASH Upgrade failed\n", __func__);
  3869. exit:
  3870. if (rc)
  3871. return rc;
  3872. return size;
  3873. }
  3874. #ifndef TTDL_KERNEL_SUBMISSION
  3875. static DEVICE_ATTR(pip2_manual_upgrade, 0200,
  3876. NULL, pt_pip2_manual_upgrade_store);
  3877. /*******************************************************************************
  3878. * FUNCTION: pt_pip2_manual_ram_upgrade_store
  3879. *
  3880. * SUMMARY: Store method for the pip2_manual_ram_upgrade sysfs node. Allows
  3881. * sysfs control of bootloading a new FW image to SRAM.
  3882. *
  3883. * PARAMETERS:
  3884. * *dev - pointer to device structure
  3885. * *attr - pointer to device attributes
  3886. * *buf - pointer to output buffer
  3887. * size - size of data in buffer
  3888. ******************************************************************************/
  3889. static ssize_t pt_pip2_manual_ram_upgrade_store(struct device *dev,
  3890. struct device_attribute *attr, const char *buf, size_t size)
  3891. {
  3892. struct pt_loader_data *ld = pt_get_loader_data(dev);
  3893. u32 input_data[2] = {0};
  3894. int length;
  3895. int rc = 0;
  3896. length = cmd->parse_sysfs_input(dev, buf, size, input_data,
  3897. ARRAY_SIZE(input_data));
  3898. if (length != 1) {
  3899. pt_debug(dev, DL_WARN, "%s: Invalid number of arguments\n",
  3900. __func__);
  3901. rc = -EINVAL;
  3902. goto exit;
  3903. }
  3904. if (input_data[0] < 0 || input_data[0] > 1) {
  3905. pt_debug(dev, DL_WARN, "%s: Invalid arguments\n", __func__);
  3906. rc = -EINVAL;
  3907. goto exit;
  3908. }
  3909. if (ld->is_manual_upgrade_enabled) {
  3910. pt_debug(dev, DL_ERROR,
  3911. "%s: ERROR - Manual upgrade busy\n", __func__);
  3912. rc = -EBUSY;
  3913. goto exit;
  3914. }
  3915. /* Write File Status: reset to 0 */
  3916. _pt_update_write_file_status(dev, UPDATE_FW_IDLE);
  3917. ld->pip2_load_file_no = PIP2_RAM_FILE;
  3918. pt_debug(dev, DL_DEBUG, "%s: ATM - File number is %d\n",
  3919. __func__, ld->pip2_load_file_no);
  3920. ld->is_manual_upgrade_enabled = 1;
  3921. rc = _pt_pip2_update_fw_from_class(dev);
  3922. ld->is_manual_upgrade_enabled = 0;
  3923. if (rc < 0)
  3924. pt_debug(dev, DL_ERROR,
  3925. "%s: ERROR - RAM Upgrade failed\n", __func__);
  3926. exit:
  3927. if (rc)
  3928. return rc;
  3929. return size;
  3930. }
  3931. static DEVICE_ATTR(pip2_manual_ram_upgrade, 0200,
  3932. NULL, pt_pip2_manual_ram_upgrade_store);
  3933. /*******************************************************************************
  3934. * FUNCTION: pt_pip2_file_write_store
  3935. *
  3936. * SUMMARY: Store method for the pip2_file_write sysfs node. Allows
  3937. * sysfs control to "load" data into any file.
  3938. *
  3939. * PARAMETERS:
  3940. * *dev - pointer to device structure
  3941. * *attr - pointer to device attributes
  3942. * *buf - pointer to output buffer
  3943. * size - size of data in buffer
  3944. ******************************************************************************/
  3945. static ssize_t pt_pip2_file_write_store(struct device *dev,
  3946. struct device_attribute *attr, const char *buf, size_t size)
  3947. {
  3948. struct pt_core_data *cd = dev_get_drvdata(dev);
  3949. struct pt_loader_data *ld = pt_get_loader_data(dev);
  3950. int rc;
  3951. u32 input_data[3];
  3952. int length;
  3953. if (ld->is_manual_upgrade_enabled) {
  3954. pt_debug(dev, DL_ERROR,
  3955. "%s: ERROR - Manual upgrade busy\n", __func__);
  3956. rc = -EBUSY;
  3957. goto exit;
  3958. }
  3959. length = cmd->parse_sysfs_input(dev, buf, size, input_data,
  3960. ARRAY_SIZE(input_data));
  3961. if (length <= 0 || length > 2) {
  3962. pt_debug(dev, DL_ERROR, "%s: Invalid number of arguments\n",
  3963. __func__);
  3964. ld->pip2_file_data.para_num = 0;
  3965. rc = -EINVAL;
  3966. goto exit;
  3967. }
  3968. if (input_data[0] < PIP2_FW_FILE || input_data[0] > PIP2_FILE_MAX) {
  3969. pt_debug(dev, DL_ERROR, "%s: Invalid file handle\n", __func__);
  3970. ld->pip2_file_data.para_num = 0;
  3971. rc = -EINVAL;
  3972. goto exit;
  3973. }
  3974. /* This functionality is only available in the BL */
  3975. if (cd->mode != PT_MODE_BOOTLOADER) {
  3976. rc = -EPERM;
  3977. pt_debug(dev, DL_ERROR, "%s: Invalid DUT mode = %d\n",
  3978. __func__, cd->mode);
  3979. goto exit;
  3980. }
  3981. /* Write File Status: reset to 0 */
  3982. _pt_update_write_file_status(dev, UPDATE_FW_IDLE);
  3983. ld->pip2_load_file_no = input_data[0];
  3984. if (length == 2)
  3985. ld->pip2_file_data.file_offset = input_data[1];
  3986. ld->is_manual_upgrade_enabled = 1;
  3987. rc = _pt_pip2_write_file_from_class(dev);
  3988. ld->is_manual_upgrade_enabled = 0;
  3989. if (rc < 0)
  3990. pt_debug(dev, DL_ERROR,
  3991. "%s: ERROR - RAM Upgrade failed\n", __func__);
  3992. exit:
  3993. if (rc)
  3994. return rc;
  3995. return size;
  3996. }
  3997. static DEVICE_ATTR(pip2_file_write, 0200, NULL, pt_pip2_file_write_store);
  3998. #endif /* !TTDL_KERNEL_SUBMISSION */
  3999. /*******************************************************************************
  4000. * FUNCTION: pt_update_fw_store
  4001. *
  4002. * SUMMARY: Store method for the update_fw sysfs node. This node is required
  4003. * by ChromeOS to first determine if loading is available and then perform
  4004. * the loading if required. This function is simply a wrapper to call:
  4005. * pt_pip2_manual_upgrade_store - for the TC3XXX or TT7XXX parts
  4006. * pt_manual_upgrade_store - for the legacy Gen5/6 devices.
  4007. *
  4008. * PARAMETERS:
  4009. * *dev - pointer to device structure
  4010. * *attr - pointer to device attributes
  4011. * *buf - pointer to output buffer
  4012. * size - size of data in buffer
  4013. ******************************************************************************/
  4014. static ssize_t pt_update_fw_store(struct device *dev,
  4015. struct device_attribute *attr, const char *buf, size_t size)
  4016. {
  4017. u8 dut_gen = cmd->request_dut_generation(dev);
  4018. if (dut_gen == DUT_PIP2_CAPABLE)
  4019. size = pt_pip2_manual_upgrade_store(dev, attr, buf, size);
  4020. else if (dut_gen == DUT_PIP1_ONLY)
  4021. size = pt_manual_upgrade_store(dev, attr, buf, size);
  4022. return size;
  4023. }
  4024. static DEVICE_ATTR(update_fw, 0200, NULL, pt_update_fw_store);
  4025. #endif /* CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE */
  4026. #ifndef TTDL_KERNEL_SUBMISSION
  4027. #ifdef TTDL_DIAGNOSTICS
  4028. /*******************************************************************************
  4029. * FUNCTION: pt_pip2_file_read_show
  4030. *
  4031. * SUMMARY: The read method for the pip2_file_read sysfs node. Allows to
  4032. * perform flash read action according to stored value. This function will
  4033. * re-enter always until it returns:
  4034. * 0: No data to be written to sysfs node
  4035. * <0: Error happens
  4036. * (For kernel version large than 3.11(not tested), if the function returns
  4037. * non-zero value in previous chunk, to return 0 once can not stop re-enter.
  4038. * It needs one more time to stop read action by returned value <= 0. But for
  4039. * older version, read action will stop when returned value <= 0 once).
  4040. *
  4041. * NOTE: Up to PIP2_FILE_WRITE_LEN_PER_PACKET(245) bytes of data are read for
  4042. * each enter. When last package is read, pip2_file_data.para_num is assigned
  4043. * as negatie value(-1), then next enter can return 0 to indicate the read
  4044. * method can be finished.
  4045. *
  4046. * RETURN: Size of data written to sysfs node
  4047. *
  4048. * PARAMETERS:
  4049. * *filp - pointer to file structure
  4050. * *kobj - pointer to kobject structure
  4051. * *bin_attr - pointer to bin_attribute structure
  4052. * buf - pointer to cmd input buffer
  4053. * offset - offset index to store input buffer
  4054. * count - size of data in buffer
  4055. ******************************************************************************/
  4056. static ssize_t pt_pip2_file_read_show(struct file *filp,
  4057. struct kobject *kobj, struct bin_attribute *bin_attr,
  4058. char *buf, loff_t offset, size_t count)
  4059. {
  4060. struct device *dev = container_of(kobj, struct device, kobj);
  4061. struct pt_loader_data *ld = pt_get_loader_data(dev);
  4062. struct pt_core_data *cd = dev_get_drvdata(dev);
  4063. int rc = 0;
  4064. u8 file_handle = ld->pip2_file_data.file_handle;
  4065. u8 *pr_buf = ld->pip2_file_data.file_print_buf;
  4066. int print_idx = 0, read_size = 0, i;
  4067. u8 read_buf[PT_MAX_PIP2_MSG_SIZE];
  4068. u8 read_len;
  4069. u32 address, file_size;
  4070. if (ld->pip2_file_data.file_print_left) {
  4071. pt_debug(dev, DL_INFO, "%s: print left=%d, count=%zu\n",
  4072. __func__, ld->pip2_file_data.file_print_left, count);
  4073. print_idx = ld->pip2_file_data.file_print_left;
  4074. if (count < print_idx) {
  4075. memcpy(buf, pr_buf, count);
  4076. ld->pip2_file_data.file_print_left = print_idx - count;
  4077. for (i = 0; i < ld->pip2_file_data.file_print_left; i++)
  4078. pr_buf[i] = pr_buf[i+count];
  4079. print_idx = count;
  4080. } else {
  4081. memcpy(buf, pr_buf, print_idx);
  4082. ld->pip2_file_data.file_print_left = 0;
  4083. }
  4084. return print_idx;
  4085. }
  4086. if (ld->pip2_file_data.para_num == 0) {
  4087. /*
  4088. * When offset != 0, it means the extra call for splice out,
  4089. * don't need a warning.
  4090. */
  4091. if (offset != 0)
  4092. return 0;
  4093. print_idx += scnprintf(buf, count, "Status: %d\n"
  4094. "No input!\n", -EINVAL);
  4095. pt_debug(dev, DL_ERROR, "%s: Invalid para_num = %d!\n",
  4096. __func__, ld->pip2_file_data.para_num);
  4097. return print_idx;
  4098. } else if (ld->pip2_file_data.para_num == -1) {
  4099. ld->pip2_file_data.para_num = 0;
  4100. pt_debug(dev, DL_INFO, "%s: flash read finish!\n",
  4101. __func__);
  4102. rc = 0;
  4103. goto exit_release;
  4104. } else if (ld->pip2_file_data.para_num < -1) {
  4105. ld->pip2_file_data.para_num = 0;
  4106. pt_debug(dev, DL_ERROR, "%s: Exit directly due to errors!\n",
  4107. __func__);
  4108. return 0;
  4109. } else if (ld->pip2_file_data.para_num > 3) {
  4110. ld->pip2_file_data.para_num = 0;
  4111. pt_debug(dev, DL_ERROR,
  4112. "%s: Exit directly due to invalid parameter!\n",
  4113. __func__);
  4114. return 0;
  4115. }
  4116. if (offset == 0) {
  4117. ld->pip2_file_data.file_print_buf = kzalloc(PIPE_BUF,
  4118. GFP_KERNEL);
  4119. if (!ld->pip2_file_data.file_print_buf) {
  4120. rc = -ENOMEM;
  4121. goto exit;
  4122. }
  4123. /* This functionality is only available in the BL */
  4124. if (cd->mode != PT_MODE_BOOTLOADER) {
  4125. rc = -EPERM;
  4126. goto exit_free;
  4127. }
  4128. pr_buf = ld->pip2_file_data.file_print_buf;
  4129. rc = cmd->request_exclusive(dev,
  4130. PT_LDR_REQUEST_EXCLUSIVE_TIMEOUT);
  4131. if (rc) {
  4132. pt_debug(dev, DL_ERROR,
  4133. "%s: Failed to request exclusive rc=%d\n",
  4134. __func__, rc);
  4135. goto exit_free;
  4136. }
  4137. rc = cmd->nonhid_cmd->pip2_file_open(dev, file_handle);
  4138. if (rc < 0) {
  4139. pt_debug(dev, DL_ERROR,
  4140. "%s: Failed to file_open rc=%d\n",
  4141. __func__, rc);
  4142. goto exit_release;
  4143. }
  4144. rc = cmd->nonhid_cmd->pip2_file_get_stats(dev, file_handle,
  4145. &address, &file_size);
  4146. if (rc) {
  4147. pt_debug(dev, DL_ERROR,
  4148. "%s: Failed to get_file_state rc=%d\n",
  4149. __func__, rc);
  4150. goto exit_file_close;
  4151. }
  4152. ld->pip2_file_data.file_print_size = 0;
  4153. ld->pip2_file_data.file_max_size = file_size;
  4154. ld->pip2_file_data.file_print_left = 0;
  4155. print_idx += scnprintf(pr_buf, PIPE_BUF, "ROM_DATA:");
  4156. if (ld->pip2_file_data.para_num == 1)
  4157. ld->pip2_file_data.file_read_size = file_size;
  4158. else if (ld->pip2_file_data.para_num == 2) {
  4159. if (ld->pip2_file_data.file_offset < file_size)
  4160. ld->pip2_file_data.file_read_size = file_size -
  4161. ld->pip2_file_data.file_offset;
  4162. else {
  4163. rc = -EINVAL;
  4164. pt_debug(dev, DL_ERROR,
  4165. "%s: File read out of bounds rc=%d\n",
  4166. __func__, rc);
  4167. goto exit_file_close;
  4168. }
  4169. } else if (ld->pip2_file_data.para_num == 3) {
  4170. if ((ld->pip2_file_data.file_read_size +
  4171. ld->pip2_file_data.file_offset) > file_size) {
  4172. rc = -EINVAL;
  4173. pt_debug(dev, DL_ERROR,
  4174. "%s: File read out of bounds rc=%d\n",
  4175. __func__, rc);
  4176. goto exit_file_close;
  4177. }
  4178. } else {
  4179. pt_debug(dev, DL_ERROR,
  4180. "%s: Invalid number of parameters!\n",
  4181. __func__);
  4182. goto exit_file_close;
  4183. }
  4184. }
  4185. offset = ld->pip2_file_data.file_print_size +
  4186. ld->pip2_file_data.file_offset;
  4187. if ((offset >= ld->pip2_file_data.file_max_size) ||
  4188. (ld->pip2_file_data.file_print_size >=
  4189. ld->pip2_file_data.file_read_size))
  4190. goto exit_file_close;
  4191. else if ((ld->pip2_file_data.file_print_size +
  4192. PIP2_FILE_WRITE_LEN_PER_PACKET) >=
  4193. ld->pip2_file_data.file_read_size)
  4194. read_len = ld->pip2_file_data.file_read_size -
  4195. ld->pip2_file_data.file_print_size;
  4196. else
  4197. read_len = PIP2_FILE_WRITE_LEN_PER_PACKET;
  4198. rc = cmd->nonhid_cmd->pip2_file_seek_offset(dev,
  4199. file_handle, offset, 0);
  4200. if (rc) {
  4201. pt_debug(dev, DL_ERROR,
  4202. "%s: Failed to seek file offset rc=%d\n",
  4203. __func__, rc);
  4204. goto exit_file_close;
  4205. }
  4206. read_size = cmd->nonhid_cmd->pip2_file_read(dev,
  4207. file_handle, read_len, read_buf);
  4208. if (read_size < 0) {
  4209. pt_debug(dev, DL_ERROR, "%s: Failed to read file rc=%d\n",
  4210. __func__, read_size);
  4211. goto exit_file_close;
  4212. }
  4213. for (i = 0; i < read_size; i++)
  4214. print_idx += scnprintf(pr_buf + print_idx,
  4215. PIPE_BUF - print_idx,
  4216. "%02X ", read_buf[i + PIP2_RESP_BODY_OFFSET]);
  4217. ld->pip2_file_data.file_print_size += read_size;
  4218. if (count < print_idx) {
  4219. memcpy(buf, pr_buf, count);
  4220. ld->pip2_file_data.file_print_left = print_idx - count;
  4221. for (i = 0; i < ld->pip2_file_data.file_print_left; i++)
  4222. pr_buf[i] = pr_buf[i+count];
  4223. print_idx = count;
  4224. } else {
  4225. memcpy(buf, pr_buf, print_idx);
  4226. }
  4227. goto exit_for_next_read;
  4228. exit_file_close:
  4229. if (rc)
  4230. print_idx += scnprintf(pr_buf + print_idx,
  4231. PIPE_BUF - print_idx, "(READ ERROR)\n");
  4232. else if (ld->pip2_file_data.file_print_size)
  4233. print_idx += scnprintf(pr_buf + print_idx,
  4234. PIPE_BUF - print_idx,
  4235. ":(%d bytes)\n",
  4236. ld->pip2_file_data.file_print_size);
  4237. else
  4238. print_idx += scnprintf(pr_buf + print_idx,
  4239. PIPE_BUF - print_idx, "No Data\n");
  4240. if (count < print_idx) {
  4241. memcpy(buf, pr_buf, count);
  4242. ld->pip2_file_data.file_print_left = print_idx - count;
  4243. for (i = 0; i < ld->pip2_file_data.file_print_left; i++)
  4244. pr_buf[i] = pr_buf[i+count];
  4245. print_idx = count;
  4246. } else {
  4247. memcpy(buf, pr_buf, print_idx);
  4248. }
  4249. rc = cmd->nonhid_cmd->pip2_file_close(dev, file_handle);
  4250. if (file_handle != rc)
  4251. pt_debug(dev, DL_ERROR,
  4252. "%s Failed to close file %d, rc = %d\n", __func__,
  4253. file_handle, rc);
  4254. /*
  4255. * Mark para_num as negative value to finish read method during
  4256. * next enter.
  4257. */
  4258. ld->pip2_file_data.para_num = -1;
  4259. exit_for_next_read:
  4260. pt_debug(dev, DL_INFO,
  4261. "%s: %s=%d, %s=%d, %s=%d, %s=%d, %s=%d\n",
  4262. __func__,
  4263. "para_num", ld->pip2_file_data.para_num,
  4264. "handle", ld->pip2_file_data.file_handle,
  4265. "offset", ld->pip2_file_data.file_offset,
  4266. "read", ld->pip2_file_data.file_read_size,
  4267. "print", ld->pip2_file_data.file_print_size);
  4268. return print_idx;
  4269. exit_release:
  4270. cmd->release_exclusive(dev);
  4271. exit_free:
  4272. kfree(ld->pip2_file_data.file_print_buf);
  4273. exit:
  4274. if (rc) {
  4275. ld->pip2_file_data.para_num = -2;
  4276. print_idx = scnprintf(buf, count, "Status: %d\n", rc);
  4277. return print_idx;
  4278. } else
  4279. return 0;
  4280. }
  4281. /*******************************************************************************
  4282. * FUNCTION: pt_pip2_file_read_store
  4283. *
  4284. * SUMMARY: The write method for the pip2_file_read node. The passed
  4285. * in data is needed by read method.
  4286. *
  4287. * RETURN: Size of passed in buffer is success
  4288. *
  4289. * PARAMETERS:
  4290. * *filp - pointer to file structure
  4291. * *kobj - pointer to kobject structure
  4292. * *bin_attr - pointer to bin_attribute structure
  4293. * buf - pointer to cmd input buffer
  4294. * offset - offset index to store input buffer
  4295. * count - size of data in buffer
  4296. ******************************************************************************/
  4297. static ssize_t pt_pip2_file_read_store(struct file *filp,
  4298. struct kobject *kobj, struct bin_attribute *bin_attr,
  4299. char *buf, loff_t offset, size_t count)
  4300. {
  4301. int rc = 0;
  4302. int length;
  4303. struct device *dev = container_of(kobj, struct device, kobj);
  4304. struct pt_loader_data *ld = pt_get_loader_data(dev);
  4305. int ic_buffer[4] = {0};
  4306. length = cmd->parse_sysfs_input(dev, buf, count, ic_buffer,
  4307. ARRAY_SIZE(ic_buffer));
  4308. if (length <= 0 || length > 3) {
  4309. pt_debug(dev, DL_ERROR, "%s: Input format error!\n",
  4310. __func__);
  4311. ld->pip2_file_data.para_num = 0;
  4312. rc = -EINVAL;
  4313. goto error;
  4314. }
  4315. if (ic_buffer[0] < PIP2_FW_FILE || ic_buffer[0] > PIP2_FILE_MAX) {
  4316. pt_debug(dev, DL_ERROR, "%s: Invalid file handle!\n",
  4317. __func__);
  4318. ld->pip2_file_data.para_num = 0;
  4319. rc = -EINVAL;
  4320. goto error;
  4321. }
  4322. switch (length) {
  4323. case 1:
  4324. ld->pip2_file_data.file_handle = ic_buffer[0];
  4325. ld->pip2_file_data.file_offset = 0;
  4326. ld->pip2_file_data.file_read_size = 0;
  4327. break;
  4328. case 2:
  4329. ld->pip2_file_data.file_handle = ic_buffer[0];
  4330. ld->pip2_file_data.file_offset = ic_buffer[1];
  4331. ld->pip2_file_data.file_read_size = 0;
  4332. break;
  4333. case 3:
  4334. ld->pip2_file_data.file_handle = ic_buffer[0];
  4335. ld->pip2_file_data.file_offset = ic_buffer[1];
  4336. ld->pip2_file_data.file_read_size = ic_buffer[2];
  4337. break;
  4338. default:
  4339. break;
  4340. }
  4341. ld->pip2_file_data.para_num = length;
  4342. error:
  4343. pt_debug(dev, DL_INFO,
  4344. "%s: %s=%d, %s=%d, %s=%d, %s=%d, %s=%d\n",
  4345. __func__,
  4346. "para_num", ld->pip2_file_data.para_num,
  4347. "handle", ld->pip2_file_data.file_handle,
  4348. "offset", ld->pip2_file_data.file_offset,
  4349. "read", ld->pip2_file_data.file_read_size,
  4350. "print", ld->pip2_file_data.file_print_size);
  4351. if (rc)
  4352. return rc;
  4353. return count;
  4354. }
  4355. static struct bin_attribute bin_attr_pip2_file_read = {
  4356. .attr = {
  4357. .name = "pip2_file_read",
  4358. .mode = (0644),
  4359. },
  4360. .read = pt_pip2_file_read_show,
  4361. .write = pt_pip2_file_read_store,
  4362. };
  4363. /******************************************************************************
  4364. * FUNCTION: pt_pip2_file_crc_show
  4365. *
  4366. * SUMMARY: The show method for the "pip2_file_crc" sysfs node.
  4367. * Shows the CRC of a file or portion of the file.
  4368. *
  4369. * NOTE: If function is called when DUT is already in BL mode, the DUT
  4370. * will remain in BL mode when function exits, however if DUT is in
  4371. * normal mode when function is called, the DUT will be forced into BL
  4372. * mode and then returned to normal mode when function exits.
  4373. *
  4374. * NOTE: This sysfs node only can be used for BL version 1.8 or greater.
  4375. *
  4376. * PARAMETERS:
  4377. * *dev - pointer to device structure
  4378. * *attr - pointer to device attributes structure
  4379. * *buf - pointer to print output buffer
  4380. ******************************************************************************/
  4381. static ssize_t pt_pip2_file_crc_show(struct device *dev,
  4382. struct device_attribute *attr, char *buf)
  4383. {
  4384. struct pt_loader_data *ld = pt_get_loader_data(dev);
  4385. struct pt_core_data *cd = dev_get_drvdata(dev);
  4386. int rc = 0;
  4387. u8 file_handle;
  4388. int print_idx = 0;
  4389. u8 read_buf[PT_MAX_PIP2_MSG_SIZE];
  4390. u32 address, file_size;
  4391. u32 length;
  4392. u32 offset;
  4393. u16 file_crc;
  4394. u16 status;
  4395. if (ld->pip2_fcrc.para_num == 0 ||
  4396. ld->pip2_fcrc.file_handle == 0 ||
  4397. ld->pip2_fcrc.file_read_size < 0 ||
  4398. ld->pip2_fcrc.file_offset < 0) {
  4399. pt_debug(dev, DL_ERROR,
  4400. "%s: Invalid parameters!\n",
  4401. __func__);
  4402. print_idx = snprintf(buf, PT_MAX_PRBUF_SIZE,
  4403. "Status: %d\n"
  4404. "Invalid parameters!\n", -EINVAL);
  4405. return print_idx;
  4406. }
  4407. file_handle = ld->pip2_fcrc.file_handle;
  4408. offset = ld->pip2_fcrc.file_offset;
  4409. length = ld->pip2_fcrc.file_read_size;
  4410. /* This functionality is only available in the BL */
  4411. if (cd->mode != PT_MODE_BOOTLOADER) {
  4412. rc = -EPERM;
  4413. print_idx = snprintf(buf, PT_MAX_PRBUF_SIZE,
  4414. "Status: %d\n", rc);
  4415. goto exit;
  4416. }
  4417. rc = cmd->request_exclusive(dev, PT_LDR_REQUEST_EXCLUSIVE_TIMEOUT);
  4418. if (rc) {
  4419. pt_debug(dev, DL_ERROR,
  4420. "%s: Failed to request exclusive rc=%d\n",
  4421. __func__, rc);
  4422. print_idx = snprintf(buf, PT_MAX_PRBUF_SIZE,
  4423. "Status: %d\n", rc);
  4424. goto exit;
  4425. }
  4426. rc = cmd->nonhid_cmd->pip2_file_open(dev, file_handle);
  4427. if (rc < 0) {
  4428. pt_debug(dev, DL_ERROR,
  4429. "%s: Failed to file_open rc=%d\n",
  4430. __func__, rc);
  4431. print_idx = snprintf(buf, PT_MAX_PRBUF_SIZE,
  4432. "Status: %d\n", rc);
  4433. goto exit_release;
  4434. }
  4435. rc = cmd->nonhid_cmd->pip2_file_get_stats(dev, file_handle,
  4436. &address, &file_size);
  4437. if (rc) {
  4438. pt_debug(dev, DL_ERROR,
  4439. "%s: Failed to get_file_state rc=%d\n",
  4440. __func__, rc);
  4441. print_idx = snprintf(buf, PT_MAX_PRBUF_SIZE,
  4442. "Status: %d\n", rc);
  4443. goto exit_file_close;
  4444. }
  4445. ld->pip2_fcrc.file_max_size = file_size;
  4446. if (ld->pip2_fcrc.file_read_size > file_size
  4447. || ld->pip2_fcrc.file_offset > file_size
  4448. || ((ld->pip2_fcrc.file_offset +
  4449. ld->pip2_fcrc.file_read_size) > file_size)) {
  4450. pt_debug(dev, DL_ERROR,
  4451. "%s: Invalid parameters!\n",
  4452. __func__);
  4453. print_idx = snprintf(buf, PT_MAX_PRBUF_SIZE,
  4454. "Status: %d\n", rc);
  4455. goto exit_file_close;
  4456. }
  4457. rc = cmd->nonhid_cmd->pip2_file_crc(dev,
  4458. file_handle, offset, length, read_buf);
  4459. if (rc) {
  4460. pt_debug(dev, DL_ERROR,
  4461. "%s: Failed to get file crc, rc=%d\n",
  4462. __func__, rc);
  4463. print_idx = snprintf(buf, PT_MAX_PRBUF_SIZE,
  4464. "Status: %d\n", rc);
  4465. } else {
  4466. status = read_buf[PIP2_RESP_STATUS_OFFSET];
  4467. if (status == PIP2_RSP_ERR_NONE) {
  4468. file_crc = get_unaligned_le16(&read_buf[5]);
  4469. print_idx = snprintf(buf, PT_MAX_PRBUF_SIZE,
  4470. "Status: %d\n"
  4471. "FILE CRC: %04X\n",
  4472. status, file_crc);
  4473. } else
  4474. print_idx = snprintf(buf, PT_MAX_PRBUF_SIZE,
  4475. "Status: %d\n"
  4476. "FILE CRC: n/a\n",
  4477. status);
  4478. }
  4479. exit_file_close:
  4480. rc = cmd->nonhid_cmd->pip2_file_close(dev, file_handle);
  4481. if (file_handle != rc)
  4482. pt_debug(dev, DL_ERROR,
  4483. "%s Failed to close file %d, rc = %d\n", __func__,
  4484. file_handle, rc);
  4485. exit_release:
  4486. cmd->release_exclusive(dev);
  4487. exit:
  4488. ld->pip2_fcrc.para_num = 0;
  4489. return print_idx;
  4490. }
  4491. /*******************************************************************************
  4492. * FUNCTION: pt_pip2_file_crc_store
  4493. *
  4494. * SUMMARY: The store method for the "pip2_file_crc" sysfs node. The passed in
  4495. * data including file_handle, offset and read size are needed by show method.
  4496. *
  4497. * NOTE: This sysfs node only can be used for BL version 1.8 or greater..
  4498. *
  4499. * PARAMETERS:
  4500. * *dev - pointer to device structure
  4501. * *attr - pointer to device attributes structure
  4502. * *buf - pointer to print output buffer
  4503. * size - size of buffer
  4504. ******************************************************************************/
  4505. static ssize_t pt_pip2_file_crc_store(struct device *dev,
  4506. struct device_attribute *attr, const char *buf, size_t size)
  4507. {
  4508. struct pt_loader_data *ld = pt_get_loader_data(dev);
  4509. u32 input_data[4] = {0};
  4510. int length;
  4511. int rc = 0;
  4512. ld->pip2_fcrc.file_handle = PIP2_RAM_FILE;
  4513. ld->pip2_fcrc.file_offset = -1;
  4514. ld->pip2_fcrc.file_read_size = -1;
  4515. length = cmd->parse_sysfs_input(dev, buf, size, input_data,
  4516. ARRAY_SIZE(input_data));
  4517. if (length != 3) {
  4518. pt_debug(dev, DL_WARN, "%s: Invalid number of arguments\n",
  4519. __func__);
  4520. ld->pip2_fcrc.para_num = 0;
  4521. rc = -EINVAL;
  4522. goto exit;
  4523. }
  4524. if ((input_data[0] < PIP2_FW_FILE) || (input_data[0] > PIP2_FILE_MAX)) {
  4525. pt_debug(dev, DL_WARN, "%s: Invalid file_no %d\n",
  4526. __func__, input_data[0]);
  4527. rc = -EINVAL;
  4528. goto exit;
  4529. }
  4530. ld->pip2_fcrc.file_handle = input_data[0];
  4531. ld->pip2_fcrc.file_offset = input_data[1];
  4532. ld->pip2_fcrc.file_read_size = input_data[2];
  4533. ld->pip2_fcrc.para_num = 3;
  4534. pt_debug(dev, DL_INFO,
  4535. "%s: %s=%d, %s=%d, %s=%d, %s=%d\n",
  4536. __func__,
  4537. "para_num", ld->pip2_fcrc.para_num,
  4538. "handle", ld->pip2_fcrc.file_handle,
  4539. "offset", ld->pip2_fcrc.file_offset,
  4540. "length", ld->pip2_fcrc.file_read_size);
  4541. exit:
  4542. if (rc)
  4543. return rc;
  4544. return size;
  4545. }
  4546. static DEVICE_ATTR(pip2_file_crc, 0644,
  4547. pt_pip2_file_crc_show, pt_pip2_file_crc_store);
  4548. #endif
  4549. /*******************************************************************************
  4550. * FUNCTION: pt_pip2_file_erase_show
  4551. *
  4552. * SUMMARY: The show method for the "pip2_file_erase" sysfs node.
  4553. * Prints current erase status to output buffer.
  4554. *
  4555. * PARAMETERS:
  4556. * *dev - pointer to device structure
  4557. * *attr - pointer to device attributes structure
  4558. * *buf - pointer to print output buffer
  4559. ******************************************************************************/
  4560. static ssize_t pt_pip2_file_erase_show(struct device *dev,
  4561. struct device_attribute *attr, char *buf)
  4562. {
  4563. struct pt_loader_data *ld = pt_get_loader_data(dev);
  4564. struct pt_core_data *cd = dev_get_drvdata(dev);
  4565. u8 file_handle;
  4566. u8 file = ld->pip2_file_erase_file_no;
  4567. u16 sector_num = 0;
  4568. u32 max_file_size = 0;
  4569. int rc;
  4570. pip2_erase_status = -1;
  4571. pip2_erase_rc = 0;
  4572. if (file == PIP2_RAM_FILE) {
  4573. rc = -EINVAL;
  4574. goto exit;
  4575. }
  4576. /* This functionality is only available in the BL */
  4577. if (cd->mode != PT_MODE_BOOTLOADER) {
  4578. rc = -EPERM;
  4579. goto exit;
  4580. }
  4581. rc = cmd->request_exclusive(dev, PT_LDR_REQUEST_EXCLUSIVE_TIMEOUT);
  4582. if (rc < 0) {
  4583. pt_debug(dev, DL_ERROR,
  4584. "%s: Failed to get exclusive access rc=%d\n",
  4585. __func__, rc);
  4586. goto exit;
  4587. }
  4588. file_handle = cmd->nonhid_cmd->pip2_file_open(dev, file);
  4589. if (file_handle != file) {
  4590. rc = -EBADF;
  4591. goto exit_release;
  4592. }
  4593. rc = cmd->nonhid_cmd->pip2_file_get_stats(dev,
  4594. file, NULL, &max_file_size);
  4595. if (rc) {
  4596. pt_debug(dev, DL_ERROR,
  4597. "%s: Failed to get_file_state ret=%d\n",
  4598. __func__, rc);
  4599. goto exit_release;
  4600. }
  4601. sector_num = max_file_size / PT_PIP2_FILE_SECTOR_SIZE;
  4602. if (max_file_size % PT_PIP2_FILE_SECTOR_SIZE) {
  4603. pt_debug(dev, DL_WARN,
  4604. "%s: file size %d misalign, don't use sector erase\n",
  4605. __func__, max_file_size);
  4606. /*
  4607. * TODO: Not sure whether can have this case, and this
  4608. * is a workaround to ensure the safety in logic.
  4609. * Force sector number to 0 will use the default method
  4610. * to do file erase by FILE instead of SECTOR.
  4611. */
  4612. sector_num = 0;
  4613. }
  4614. file_handle = cmd->nonhid_cmd->pip2_file_erase(dev, file,
  4615. sector_num, &pip2_erase_status);
  4616. if (file_handle < 0) {
  4617. rc = file_handle;
  4618. pt_debug(dev, DL_INFO, "%s: File erase error rc = %d\n",
  4619. __func__, rc);
  4620. } else if (file_handle == file) {
  4621. pt_debug(dev, DL_INFO, "%s: File %d erased\n",
  4622. __func__, file_handle);
  4623. } else {
  4624. rc = -EBADF;
  4625. }
  4626. file_handle = cmd->nonhid_cmd->pip2_file_close(dev, file);
  4627. if (file_handle != file && !rc)
  4628. rc = -EBADF;
  4629. exit_release:
  4630. cmd->release_exclusive(dev);
  4631. exit:
  4632. pip2_erase_rc = rc;
  4633. if (pip2_erase_status == -1) {
  4634. return snprintf(buf, PT_MAX_PRBUF_SIZE,
  4635. "Status: %d\n"
  4636. "Erase Status: n/a\n",
  4637. pip2_erase_rc);
  4638. }
  4639. return snprintf(buf, PT_MAX_PRBUF_SIZE,
  4640. "Status: %d\n"
  4641. "Erase Status: 0x%02X\n",
  4642. pip2_erase_rc, pip2_erase_status);
  4643. }
  4644. /*******************************************************************************
  4645. * FUNCTION: pt_pip2_file_erase_store
  4646. *
  4647. * SUMMARY: The store method for the "pip2_file_erase" sysfs node. Allows the
  4648. * caller to provide the file number to erase in FLASH.
  4649. *
  4650. * NOTE: The DUT must be in BL mode before calling this function.
  4651. *
  4652. * PARAMETERS:
  4653. * *dev - pointer to device structure
  4654. * *attr - pointer to device attributes structure
  4655. * *buf - pointer to print output buffer
  4656. * size - size of buffer
  4657. ******************************************************************************/
  4658. static ssize_t pt_pip2_file_erase_store(struct device *dev,
  4659. struct device_attribute *attr, const char *buf, size_t size)
  4660. {
  4661. struct pt_loader_data *ld = pt_get_loader_data(dev);
  4662. u32 input_data[2] = {0};
  4663. int length;
  4664. int rc = 0;
  4665. length = cmd->parse_sysfs_input(dev, buf, size, input_data,
  4666. ARRAY_SIZE(input_data));
  4667. if (length != 1) {
  4668. pt_debug(dev, DL_WARN, "%s: Invalid number of arguments\n",
  4669. __func__);
  4670. rc = -EINVAL;
  4671. goto exit;
  4672. }
  4673. /* Only allow valid files to be erased */
  4674. if (input_data[0] < PIP2_FW_FILE || input_data[0] > PIP2_FILE_MAX) {
  4675. pip2_erase_status = PIP2_RSP_ERR_BAD_FILE;
  4676. pt_debug(dev, DL_ERROR, "%s: ERROR - Invalid File\n",
  4677. __func__);
  4678. rc = -EINVAL;
  4679. goto exit;
  4680. }
  4681. ld->pip2_file_erase_file_no = input_data[0];
  4682. exit:
  4683. if (rc)
  4684. return rc;
  4685. return size;
  4686. }
  4687. static DEVICE_ATTR(pip2_file_erase, 0644,
  4688. pt_pip2_file_erase_show, pt_pip2_file_erase_store);
  4689. /*******************************************************************************
  4690. * FUNCTION: pt_write_file_status_show
  4691. *
  4692. * SUMMARY: The show method for the pip2_bl_status sysfs node.
  4693. * Shows the percent completion of the current BL or an error message.
  4694. *
  4695. * PARAMETERS:
  4696. * *dev - pointer to device structure
  4697. * *attr - pointer to device attributes structure
  4698. * *buf - pointer to print output buffer
  4699. ******************************************************************************/
  4700. static ssize_t pt_write_file_status_show(struct device *dev,
  4701. struct device_attribute *attr, char *buf)
  4702. {
  4703. ssize_t ret;
  4704. u8 status = write_file_status;
  4705. if (write_file_status <= UPDATE_FW_COMPLETE) {
  4706. pt_debug(dev, DL_DEBUG,
  4707. "%s BL_STATUS = %d\n", __func__, write_file_status);
  4708. return scnprintf(buf, strlen(buf), "%d\n", write_file_status);
  4709. }
  4710. switch (status) {
  4711. case UPDATE_FW_GENERAL_ERROR:
  4712. ret = scnprintf(buf, strlen(buf),
  4713. "ERROR: %d - General programming failure\n", status);
  4714. break;
  4715. case UPDATE_FW_PIP_VERSION_ERROR:
  4716. ret = scnprintf(buf, strlen(buf),
  4717. "ERROR: %d - Wrong PIP version detected\n", status);
  4718. break;
  4719. case UPDATE_FW_VERSION_ERROR:
  4720. ret = scnprintf(buf, strlen(buf),
  4721. "ERROR: %d - FW vervion newer than bin file\n", status);
  4722. break;
  4723. case UPDATE_FW_ERASE_ERROR:
  4724. ret = scnprintf(buf, strlen(buf),
  4725. "ERROR: %d - ROM BL failed to erase FW file in FLASH\n",
  4726. status);
  4727. break;
  4728. case UPDATE_FW_FILE_CLOSE_ERROR:
  4729. ret = scnprintf(buf, strlen(buf),
  4730. "ERROR: %d - ROM BL failed to close FW file in FLASH\n",
  4731. status);
  4732. break;
  4733. case UPDATE_FW_WRITE_ERROR:
  4734. ret = scnprintf(buf, strlen(buf),
  4735. "ERROR: %d - ROM BL file write failure\n", status);
  4736. break;
  4737. case UPDATE_FW_EXECUTE_ERROR:
  4738. ret = scnprintf(buf, strlen(buf),
  4739. "ERROR: %d - ROM BL failed to execute RAM image\n",
  4740. status);
  4741. break;
  4742. case UPDATE_FW_RESET_ERROR:
  4743. ret = scnprintf(buf, strlen(buf),
  4744. "ERROR: %d - Reset DUT failure\n",
  4745. status);
  4746. break;
  4747. case UPDATE_FW_MODE_ERROR:
  4748. ret = scnprintf(buf, strlen(buf),
  4749. "ERROR: %d - Program complete, Incorrect BL/APP mode detected after reset sentinel\n",
  4750. status);
  4751. break;
  4752. case UPDATE_FW_ENTER_BL_ERROR:
  4753. ret = scnprintf(buf, strlen(buf),
  4754. "ERROR: %d - Could not enter the BL\n", status);
  4755. break;
  4756. case UPDATE_FW_FILE_OPEN_ERROR:
  4757. ret = scnprintf(buf, strlen(buf),
  4758. "ERROR: %d - ROM BL failed to open FW file in FLASH\n",
  4759. status);
  4760. break;
  4761. case UPDATE_FW_SENTINEL_NOT_SEEN:
  4762. ret = scnprintf(buf, strlen(buf),
  4763. "ERROR: %d - FW Reset Sentinel not seen after XRES\n",
  4764. status);
  4765. break;
  4766. case UPDATE_FW_EXCLUSIVE_ACCESS_ERROR:
  4767. ret = scnprintf(buf, strlen(buf),
  4768. "ERROR: %d - Failed to get DUT exclusive access\n",
  4769. status);
  4770. break;
  4771. case UPDATE_FW_NO_FW_PROVIDED:
  4772. ret = scnprintf(buf, strlen(buf),
  4773. "ERROR: %d - No FW provided to load\n", status);
  4774. break;
  4775. case UPDATE_FW_INVALID_FW_IMAGE:
  4776. ret = scnprintf(buf, strlen(buf), "ERROR: %d - Invalid FW image\n", status);
  4777. break;
  4778. case UPDATE_FW_FILE_SEEK_ERROR:
  4779. ret = scnprintf(buf, strlen(buf), "ERROR: %d - File seek failure\n", status);
  4780. break;
  4781. case UPDATE_FW_MISALIGN_FW_IMAGE:
  4782. ret = scnprintf(buf, strlen(buf),
  4783. "ERROR: %d - FW image is misaligned\n", status);
  4784. break;
  4785. case UPDATE_FW_SYSTEM_NOMEM:
  4786. ret = scnprintf(buf, strlen(buf),
  4787. "ERROR: %d - Failed to alloc memory\n", status);
  4788. break;
  4789. case UPDATE_FW_INIT_BL_ERROR:
  4790. ret = scnprintf(buf, strlen(buf),
  4791. "ERROR: %d - Failed to init bootloader\n", status);
  4792. break;
  4793. case UPDATE_FW_PARSE_ROW_ERROR:
  4794. ret = scnprintf(buf, strlen(buf),
  4795. "ERROR: %d - Failed to parse row of FW image\n",
  4796. status);
  4797. break;
  4798. case UPDATE_FW_PROGRAM_ROW_ERROR:
  4799. ret = scnprintf(buf, strlen(buf),
  4800. "ERROR: %d - Failed to progrem FW image\n", status);
  4801. break;
  4802. case UPDATE_FW_EXIT_BL_ERROR:
  4803. ret = scnprintf(buf, strlen(buf),
  4804. "ERROR: %d - Failed to exit bootloader\n", status);
  4805. break;
  4806. case UPDATE_FW_CHECK_SUM_ERROR:
  4807. ret = scnprintf(buf, strlen(buf),
  4808. "ERROR: %d - Failed to verify app checksum\n", status);
  4809. break;
  4810. case UPDATE_FW_NO_PLATFORM_DATA:
  4811. ret = scnprintf(buf, strlen(buf),
  4812. "ERROR: %d - No platform data\n", status);
  4813. break;
  4814. case UPDATE_FW_NOT_SUPPORTED_FILE_NO:
  4815. ret = scnprintf(buf, strlen(buf),
  4816. "ERROR: %d - Not supported file number\n", status);
  4817. break;
  4818. case UPDATE_FW_UNDEFINED_ERROR:
  4819. default:
  4820. ret = scnprintf(buf, strlen(buf), "ERROR: %d - Unknown error\n", status);
  4821. break;
  4822. }
  4823. return ret;
  4824. }
  4825. static DEVICE_ATTR(pip2_bl_status, 0444, pt_write_file_status_show, NULL);
  4826. #if PT_FW_UPGRADE
  4827. static DEVICE_ATTR(update_fw_status, 0444, pt_write_file_status_show, NULL);
  4828. #endif
  4829. /*******************************************************************************
  4830. * FUNCTION: pt_pip2_get_last_error_show
  4831. *
  4832. * SUMMARY: The show method for the pip2_get_last_error_show sysfs node.
  4833. * Shows the last BL error code.
  4834. *
  4835. * NOTE: If function is called when DUT is already in BL mode, the DUT
  4836. * will remain in BL mode when function exits, however if DUT is in
  4837. * normal mode when function is called, the DUT will be forced into BL
  4838. * mode and then returned to normal mode when function exits.
  4839. *
  4840. * PARAMETERS:
  4841. * *dev - pointer to device structure
  4842. * *attr - pointer to device attributes structure
  4843. * *buf - pointer to print output buffer
  4844. ******************************************************************************/
  4845. static ssize_t pt_pip2_get_last_error_show(struct device *dev,
  4846. struct device_attribute *attr, char *buf)
  4847. {
  4848. struct pt_core_data *cd = dev_get_drvdata(dev);
  4849. int rc;
  4850. u8 read_buf[256];
  4851. rc = cmd->request_exclusive(dev, PT_LDR_REQUEST_EXCLUSIVE_TIMEOUT);
  4852. if (rc)
  4853. goto exit;
  4854. cmd->request_stop_wd(dev);
  4855. /* This functionality is only available in the BL */
  4856. if (cd->mode != PT_MODE_BOOTLOADER) {
  4857. rc = -EPERM;
  4858. goto exit_release;
  4859. }
  4860. /* Get and log the last error(s) */
  4861. rc = _pt_pip2_log_last_error(dev, read_buf);
  4862. exit_release:
  4863. cmd->release_exclusive(dev);
  4864. exit:
  4865. if (rc)
  4866. return snprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n", rc);
  4867. if (read_buf[PIP2_RESP_STATUS_OFFSET] == PIP2_RSP_ERR_NONE) {
  4868. return snprintf(buf, PT_MAX_PRBUF_SIZE,
  4869. "Status: %d\n"
  4870. "Last Error No: 0x%02X\n",
  4871. PIP2_RSP_ERR_NONE,
  4872. read_buf[PIP2_RESP_BODY_OFFSET]);
  4873. } else {
  4874. return snprintf(buf, PT_MAX_PRBUF_SIZE,
  4875. "Status: %d\n"
  4876. "Last Error No: n/a\n",
  4877. read_buf[PIP2_RESP_STATUS_OFFSET]);
  4878. }
  4879. }
  4880. static DEVICE_ATTR(pip2_get_last_error, 0444,
  4881. pt_pip2_get_last_error_show, NULL);
  4882. #endif /* !TTDL_KERNEL_SUBMISSION */
  4883. #if PT_FW_UPGRADE
  4884. /*******************************************************************************
  4885. * FUNCTION: pt_loader_attention
  4886. *
  4887. * SUMMARY: Function to be registered to TTDL attention list to set up
  4888. * int_running semaphore.
  4889. *
  4890. * RETURN:
  4891. * 0 = success
  4892. *
  4893. * PARAMETERS:
  4894. * *dev - pointer to device structure
  4895. ******************************************************************************/
  4896. static int pt_loader_attention(struct device *dev)
  4897. {
  4898. struct pt_loader_data *ld = pt_get_loader_data(dev);
  4899. complete(&ld->int_running);
  4900. return 0;
  4901. }
  4902. /*******************************************************************************
  4903. * FUNCTION: pt_fw_upgrade_cb
  4904. *
  4905. * SUMMARY: Function to be registered to TTDL attention list to allow upgrade
  4906. * if host cannot get response from firmware with ping command.
  4907. * RETURN:
  4908. * 0 = success
  4909. *
  4910. * PARAMETERS:
  4911. * *dev - pointer to device structure
  4912. ******************************************************************************/
  4913. static int pt_fw_upgrade_cb(struct device *dev)
  4914. {
  4915. u8 dut_gen = cmd->request_dut_generation(dev);
  4916. #ifdef CONFIG_TOUCHSCREEN_PARADE_PLATFORM_FW_UPGRADE
  4917. if (dut_gen == DUT_PIP1_ONLY) {
  4918. pt_debug(dev, DL_WARN, "%s: Upgrade Platform FW", __func__);
  4919. if (!upgrade_firmware_from_platform(dev, false))
  4920. return 0;
  4921. }
  4922. #endif
  4923. #ifdef CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE
  4924. pt_debug(dev, DL_WARN, "%s: Upgrade Builtin FW", __func__);
  4925. if (dut_gen == DUT_PIP2_CAPABLE) {
  4926. if (!pt_pip2_upgrade_firmware_from_builtin(dev))
  4927. return 0;
  4928. pt_debug(dev, DL_WARN, "%s: Builtin FW upgrade failed",
  4929. __func__);
  4930. } else {
  4931. if (!upgrade_firmware_from_builtin(dev))
  4932. return 0;
  4933. }
  4934. #endif
  4935. return 0;
  4936. }
  4937. /*******************************************************************************
  4938. * FUNCTION: pt_cancel_fw_upgrade_cb
  4939. *
  4940. * SUMMARY: Function to be registered to TTDL attention list to allow an upgrade
  4941. * to be canceled.
  4942. * RETURN:
  4943. * 0 = success
  4944. *
  4945. * PARAMETERS:
  4946. * *dev - pointer to device structure
  4947. ******************************************************************************/
  4948. static int pt_cancel_fw_upgrade_cb(struct device *dev)
  4949. {
  4950. struct pt_loader_data *ld = pt_get_loader_data(dev);
  4951. pt_debug(dev, DL_WARN,
  4952. "%s: CANCELLING All Loader work\n", __func__);
  4953. cancel_work_sync(&ld->bl_from_file);
  4954. cancel_work_sync(&ld->pip2_bl_from_file);
  4955. cancel_work_sync(&ld->calibration_work);
  4956. cancel_work_sync(&ld->fw_and_config_upgrade);
  4957. return 0;
  4958. }
  4959. #endif /* PT_FW_UPGRADE */
  4960. /*******************************************************************************
  4961. * FUNCTION: pt_loader_probe
  4962. *
  4963. * SUMMARY: The probe function for the FW loader.
  4964. *
  4965. * PARAMETERS:
  4966. * *dev - pointer to device structure
  4967. * **data - double pointer to the loader data to be created here
  4968. ******************************************************************************/
  4969. static int pt_loader_probe(struct device *dev, void **data)
  4970. {
  4971. struct pt_loader_data *ld;
  4972. struct pip2_loader_data *pip2_data;
  4973. struct pt_platform_data *pdata = dev_get_platdata(dev);
  4974. int rc;
  4975. u8 dut_gen = cmd->request_dut_generation(dev);
  4976. #ifdef TTDL_DIAGNOSTICS
  4977. pt_debug(dev, DL_INFO,
  4978. "%s: entering %s\n", __func__, __func__);
  4979. #endif /* TTDL_DIAGNOSTICS */
  4980. ld = kzalloc(sizeof(*ld), GFP_KERNEL);
  4981. if (!ld) {
  4982. rc = -ENOMEM;
  4983. goto error_alloc_data_failed;
  4984. }
  4985. #if PT_FW_UPGRADE
  4986. /* Initialize boot loader status */
  4987. if (write_file_status != UPDATE_FW_COMPLETE)
  4988. _pt_update_write_file_status(dev, UPDATE_FW_IDLE);
  4989. #endif
  4990. if (dut_gen == DUT_PIP2_CAPABLE) {
  4991. pip2_data = kzalloc(sizeof(*pip2_data), GFP_KERNEL);
  4992. if (!pip2_data) {
  4993. rc = -ENOMEM;
  4994. goto error_alloc_data_failed;
  4995. }
  4996. pip2_data->dev = dev;
  4997. ld->pip2_data = pip2_data;
  4998. #if PT_FW_UPGRADE
  4999. rc = device_create_file(dev, &dev_attr_update_fw_status);
  5000. if (rc) {
  5001. pt_debug(dev, DL_ERROR,
  5002. "%s: Error creating update_fw_status\n",
  5003. __func__);
  5004. goto remove_files;
  5005. }
  5006. #endif
  5007. #ifdef CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE
  5008. rc = device_create_file(dev, &dev_attr_pt_bl_from_file);
  5009. if (rc) {
  5010. pt_debug(dev, DL_ERROR,
  5011. "%s: Error creating pt_bl_from_file\n",
  5012. __func__);
  5013. goto remove_files;
  5014. }
  5015. rc = device_create_file(dev, &dev_attr_update_fw);
  5016. if (rc) {
  5017. pt_debug(dev, DL_ERROR,
  5018. "%s: Error creating update_fw\n",
  5019. __func__);
  5020. goto remove_files;
  5021. }
  5022. #endif /* CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE */
  5023. #ifndef TTDL_KERNEL_SUBMISSION
  5024. #ifdef CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE
  5025. rc = device_create_file(dev, &dev_attr_pip2_manual_upgrade);
  5026. if (rc) {
  5027. pt_debug(dev, DL_ERROR,
  5028. "%s: Error creating pip2_manual_upgrade\n",
  5029. __func__);
  5030. goto remove_files;
  5031. }
  5032. rc = device_create_file(dev, &dev_attr_pip2_manual_ram_upgrade);
  5033. if (rc) {
  5034. pt_debug(dev, DL_ERROR,
  5035. "%s: Error creating pip2_manual_ram_upgrade\n",
  5036. __func__);
  5037. goto remove_files;
  5038. }
  5039. rc = device_create_file(dev, &dev_attr_pip2_file_write);
  5040. if (rc) {
  5041. pt_debug(dev, DL_ERROR,
  5042. "%s: Error creating pip2_file_write\n",
  5043. __func__);
  5044. goto remove_files;
  5045. }
  5046. rc = device_create_file(dev, &dev_attr_pip2_bl_from_file);
  5047. if (rc) {
  5048. pt_debug(dev, DL_ERROR,
  5049. "%s: Error creating pip2_bl_from_file\n",
  5050. __func__);
  5051. goto remove_files;
  5052. }
  5053. #endif /* CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE */
  5054. rc = device_create_file(dev, &dev_attr_pip2_file_erase);
  5055. if (rc) {
  5056. pt_debug(dev, DL_ERROR,
  5057. "%s: Error creating pip2_file_erase\n",
  5058. __func__);
  5059. goto remove_files;
  5060. }
  5061. rc = device_create_file(dev, &dev_attr_pip2_bl_status);
  5062. if (rc) {
  5063. pt_debug(dev, DL_ERROR,
  5064. "%s: Error creating pip2_bl_status\n",
  5065. __func__);
  5066. goto remove_files;
  5067. }
  5068. #ifdef TTDL_DIAGNOSTICS
  5069. rc = device_create_file(dev, &dev_attr_pip2_get_last_error);
  5070. if (rc) {
  5071. pt_debug(dev, DL_ERROR,
  5072. "%s: Error creating pip2_get_last_error\n",
  5073. __func__);
  5074. goto remove_files;
  5075. }
  5076. rc = device_create_bin_file(dev, &bin_attr_pip2_file_read);
  5077. if (rc) {
  5078. pt_debug(dev, DL_ERROR,
  5079. "%s: Error creating bin_attr_pip2_file_read\n",
  5080. __func__);
  5081. goto remove_files;
  5082. }
  5083. rc = device_create_file(dev, &dev_attr_pip2_file_crc);
  5084. if (rc) {
  5085. pt_debug(dev, DL_ERROR,
  5086. "%s: Error creating pip2_file_crc\n",
  5087. __func__);
  5088. goto remove_files;
  5089. }
  5090. #endif
  5091. #endif /* !TTDL_KERNEL_SUBMISSION */
  5092. } else {
  5093. #if PT_FW_UPGRADE
  5094. rc = device_create_file(dev, &dev_attr_update_fw_status);
  5095. if (rc) {
  5096. pt_debug(dev, DL_ERROR,
  5097. "%s: Error creating update_fw_status\n",
  5098. __func__);
  5099. goto remove_files;
  5100. }
  5101. #endif
  5102. #ifdef CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE
  5103. rc = device_create_file(dev, &dev_attr_pt_bl_from_file);
  5104. if (rc) {
  5105. pt_debug(dev, DL_ERROR,
  5106. "%s: Error creating pt_bl_from_file\n",
  5107. __func__);
  5108. goto remove_files;
  5109. }
  5110. rc = device_create_file(dev, &dev_attr_update_fw);
  5111. if (rc) {
  5112. pt_debug(dev, DL_ERROR,
  5113. "%s: Error creating update_fw\n",
  5114. __func__);
  5115. goto remove_files;
  5116. }
  5117. #endif /* CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE */
  5118. #ifndef TTDL_KERNEL_SUBMISSION
  5119. #ifdef CONFIG_TOUCHSCREEN_PARADE_PLATFORM_FW_UPGRADE
  5120. rc = device_create_file(dev, &dev_attr_forced_upgrade);
  5121. if (rc) {
  5122. pt_debug(dev, DL_ERROR,
  5123. "%s: Error creating forced_upgrade\n",
  5124. __func__);
  5125. goto remove_files;
  5126. }
  5127. #endif /* CONFIG_TOUCHSCREEN_PARADE_PLATFORM_FW_UPGRADE */
  5128. #ifdef CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE
  5129. rc = device_create_file(dev, &dev_attr_manual_upgrade);
  5130. if (rc) {
  5131. pt_debug(dev, DL_ERROR,
  5132. "%s: Error creating manual_upgrade\n",
  5133. __func__);
  5134. goto remove_files;
  5135. }
  5136. #endif /* CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE */
  5137. #ifdef CONFIG_TOUCHSCREEN_PARADE_MANUAL_TTCONFIG_UPGRADE
  5138. rc = device_create_file(dev, &dev_attr_config_loading);
  5139. if (rc) {
  5140. pt_debug(dev, DL_ERROR,
  5141. "%s: Error creating config_loading\n",
  5142. __func__);
  5143. goto remove_files;
  5144. }
  5145. rc = device_create_bin_file(dev, &bin_attr_config_data);
  5146. if (rc) {
  5147. pt_debug(dev, DL_ERROR,
  5148. "%s: Error creating config_data\n",
  5149. __func__);
  5150. goto remove_files;
  5151. }
  5152. #endif /* CONFIG_TOUCHSCREEN_PARADE_MANUAL_TTCONFIG_UPGRADE */
  5153. #endif /* !TTDL_KERNEL_SUBMISSION */
  5154. }
  5155. if (!pdata || !pdata->loader_pdata) {
  5156. pt_debug(dev, DL_ERROR,
  5157. "%s: Missing platform data\n", __func__);
  5158. rc = -ENODEV;
  5159. goto error_no_pdata;
  5160. }
  5161. /* Default erase file to an invalid file */
  5162. ld->pip2_file_erase_file_no = PIP2_RAM_FILE;
  5163. ld->loader_pdata = pdata->loader_pdata;
  5164. ld->dev = dev;
  5165. *data = ld;
  5166. #ifdef CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE
  5167. INIT_WORK(&ld->bl_from_file, pt_bl_from_file_work);
  5168. INIT_WORK(&ld->pip2_bl_from_file, pt_pip2_bl_from_file_work);
  5169. #endif /* CONFIG_TOUCHSCREEN_PARADE_MANUAL_TTCONFIG_UPGRADE */
  5170. #if PT_FW_UPGRADE
  5171. init_completion(&ld->int_running);
  5172. cmd->subscribe_attention(dev, PT_ATTEN_IRQ, PT_LOADER_NAME,
  5173. pt_loader_attention, PT_MODE_BOOTLOADER);
  5174. cmd->subscribe_attention(dev, PT_ATTEN_LOADER, PT_LOADER_NAME,
  5175. pt_fw_upgrade_cb, PT_MODE_UNKNOWN);
  5176. cmd->subscribe_attention(dev, PT_ATTEN_CANCEL_LOADER, PT_LOADER_NAME,
  5177. pt_cancel_fw_upgrade_cb, PT_MODE_UNKNOWN);
  5178. #endif
  5179. #if PT_FW_UPGRADE || PT_TTCONFIG_UPGRADE
  5180. pt_debug(dev, DL_INFO, "%s: INIT_WORK pt_calibrate_idacs\n",
  5181. __func__);
  5182. init_completion(&ld->calibration_complete);
  5183. INIT_WORK(&ld->calibration_work, pt_calibrate_idacs);
  5184. #endif
  5185. #ifdef CONFIG_TOUCHSCREEN_PARADE_MANUAL_TTCONFIG_UPGRADE
  5186. if (dut_gen == DUT_PIP1_ONLY)
  5187. mutex_init(&ld->config_lock);
  5188. #endif
  5189. #ifdef UPGRADE_FW_AND_CONFIG_IN_PROBE
  5190. /* Call FW and config upgrade directly in probe */
  5191. pt_fw_and_config_upgrade(&ld->fw_and_config_upgrade);
  5192. #else
  5193. pt_debug(dev, DL_INFO, "%s: Schedule FW upgrade work\n", __func__);
  5194. INIT_WORK(&ld->fw_and_config_upgrade, pt_fw_and_config_upgrade);
  5195. schedule_work(&ld->fw_and_config_upgrade);
  5196. #endif
  5197. pt_debug(dev, DL_INFO, "%s: Successful probe %s\n",
  5198. __func__, dev_name(dev));
  5199. return 0;
  5200. remove_files:
  5201. #ifndef TTDL_KERNEL_SUBMISSION
  5202. #ifdef CONFIG_TOUCHSCREEN_PARADE_MANUAL_TTCONFIG_UPGRADE
  5203. device_remove_file(dev, &dev_attr_config_loading);
  5204. #endif
  5205. #ifdef CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE
  5206. device_remove_file(dev, &dev_attr_manual_upgrade);
  5207. #endif
  5208. #ifdef CONFIG_TOUCHSCREEN_PARADE_PLATFORM_FW_UPGRADE
  5209. device_remove_file(dev, &dev_attr_forced_upgrade);
  5210. #endif
  5211. #ifdef TTDL_DIAGNOSTICS
  5212. device_remove_file(dev, &dev_attr_pip2_get_last_error);
  5213. device_remove_bin_file(dev, &bin_attr_pip2_file_read);
  5214. device_remove_file(dev, &dev_attr_pip2_file_crc);
  5215. #endif
  5216. device_remove_file(dev, &dev_attr_pip2_bl_status);
  5217. device_remove_file(dev, &dev_attr_pip2_file_erase);
  5218. #ifdef CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE
  5219. device_remove_file(dev, &dev_attr_pip2_bl_from_file);
  5220. device_remove_file(dev, &dev_attr_pip2_file_write);
  5221. device_remove_file(dev, &dev_attr_pt_bl_from_file);
  5222. device_remove_file(dev, &dev_attr_pip2_manual_ram_upgrade);
  5223. device_remove_file(dev, &dev_attr_pip2_manual_upgrade);
  5224. device_remove_file(dev, &dev_attr_update_fw);
  5225. device_remove_file(dev, &dev_attr_update_fw_status);
  5226. #endif /* CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE */
  5227. #endif /* !TTDL_KERNEL_SUBMISSION */
  5228. kfree(ld->pip2_data);
  5229. kfree(ld);
  5230. error_alloc_data_failed:
  5231. error_no_pdata:
  5232. pt_debug(dev, DL_ERROR, "%s failed.\n", __func__);
  5233. return rc;
  5234. }
  5235. /*******************************************************************************
  5236. * FUNCTION: pt_loader_release
  5237. *
  5238. * SUMMARY: Remove function for loader module that does following cleanup:
  5239. * - Unsubscibe all registered attention tasks
  5240. * - Removes all created sysfs nodes
  5241. * - Frees all pointers
  5242. *
  5243. * PARAMETERS:
  5244. * *dev - pointer to device structure
  5245. * *data - pointer to the loader data
  5246. ******************************************************************************/
  5247. static void pt_loader_release(struct device *dev, void *data)
  5248. {
  5249. struct pt_loader_data *ld = (struct pt_loader_data *)data;
  5250. u8 dut_gen = cmd->request_dut_generation(dev);
  5251. #if PT_FW_UPGRADE
  5252. cmd->unsubscribe_attention(dev, PT_ATTEN_IRQ, PT_LOADER_NAME,
  5253. pt_loader_attention, PT_MODE_BOOTLOADER);
  5254. cmd->unsubscribe_attention(dev, PT_ATTEN_LOADER, PT_LOADER_NAME,
  5255. pt_fw_upgrade_cb, PT_MODE_UNKNOWN);
  5256. cmd->unsubscribe_attention(dev, PT_ATTEN_CANCEL_LOADER, PT_LOADER_NAME,
  5257. pt_cancel_fw_upgrade_cb, PT_MODE_UNKNOWN);
  5258. #endif
  5259. #if PT_FW_UPGRADE
  5260. device_remove_file(dev, &dev_attr_update_fw_status);
  5261. #endif
  5262. if (dut_gen == DUT_PIP2_CAPABLE) {
  5263. #ifdef CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE
  5264. device_remove_file(dev, &dev_attr_update_fw);
  5265. #endif /* CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE */
  5266. #ifndef TTDL_KERNEL_SUBMISSION
  5267. #ifdef TTDL_DIAGNOSTICS
  5268. device_remove_bin_file(dev, &bin_attr_pip2_file_read);
  5269. device_remove_file(dev, &dev_attr_pip2_file_crc);
  5270. #endif
  5271. device_remove_file(dev, &dev_attr_pip2_get_last_error);
  5272. device_remove_file(dev, &dev_attr_pip2_bl_status);
  5273. device_remove_file(dev, &dev_attr_pip2_file_erase);
  5274. #ifdef CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE
  5275. device_remove_file(dev, &dev_attr_pip2_file_write);
  5276. device_remove_file(dev, &dev_attr_pip2_bl_from_file);
  5277. device_remove_file(dev, &dev_attr_pt_bl_from_file);
  5278. device_remove_file(dev, &dev_attr_pip2_manual_ram_upgrade);
  5279. device_remove_file(dev, &dev_attr_pip2_manual_upgrade);
  5280. #endif /* CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE */
  5281. #endif /* !TTDL_KERNEL_SUBMISSION */
  5282. kfree(ld->pip2_data);
  5283. } else {
  5284. #ifdef CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE
  5285. device_remove_file(dev, &dev_attr_update_fw);
  5286. #endif /* CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE */
  5287. #ifndef TTDL_KERNEL_SUBMISSION
  5288. #ifdef CONFIG_TOUCHSCREEN_PARADE_MANUAL_TTCONFIG_UPGRADE
  5289. device_remove_bin_file(dev, &bin_attr_config_data);
  5290. device_remove_file(dev, &dev_attr_config_loading);
  5291. if (!ld->config_data)
  5292. kfree(ld->config_data);
  5293. #endif /* CONFIG_TOUCHSCREEN_PARADE_MANUAL_TTCONFIG_UPGRADE */
  5294. #ifdef CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE
  5295. device_remove_file(dev, &dev_attr_pt_bl_from_file);
  5296. device_remove_file(dev, &dev_attr_manual_upgrade);
  5297. #endif /* CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE */
  5298. #ifdef CONFIG_TOUCHSCREEN_PARADE_PLATFORM_FW_UPGRADE
  5299. device_remove_file(dev, &dev_attr_forced_upgrade);
  5300. #endif /* CONFIG_TOUCHSCREEN_PARADE_PLATFORM_FW_UPGRADE */
  5301. #endif /* !TTDL_KERNEL_SUBMISSION */
  5302. }
  5303. kfree(ld);
  5304. }
  5305. static struct pt_module loader_module = {
  5306. .name = PT_LOADER_NAME,
  5307. .probe = pt_loader_probe,
  5308. .release = pt_loader_release,
  5309. };
  5310. /*******************************************************************************
  5311. * FUNCTION: pt_loader_init
  5312. *
  5313. * SUMMARY: Initialize function for loader module which to register
  5314. * loader_module into TTDL module list.
  5315. *
  5316. * RETURN:
  5317. * 0 = success
  5318. * !0 = failure
  5319. *
  5320. * PARAMETERS:
  5321. * *dev - pointer to device structure
  5322. * *data - pointer to the loader data
  5323. ******************************************************************************/
  5324. static int __init pt_loader_init(void)
  5325. {
  5326. int rc;
  5327. cmd = pt_get_commands();
  5328. if (!cmd)
  5329. return -EINVAL;
  5330. rc = pt_register_module(&loader_module);
  5331. if (rc < 0) {
  5332. pr_err("%s: Error, failed registering module\n",
  5333. __func__);
  5334. return rc;
  5335. }
  5336. pr_info("%s: Parade FW Loader Driver (Version %s) rc=%d\n",
  5337. __func__, PT_DRIVER_VERSION, rc);
  5338. return 0;
  5339. }
  5340. module_init(pt_loader_init);
  5341. /*******************************************************************************
  5342. * FUNCTION: pt_loader_exit
  5343. *
  5344. * SUMMARY: Exit function for loader module which to unregister loader_module
  5345. * from TTDL module list.
  5346. *
  5347. ******************************************************************************/
  5348. static void __exit pt_loader_exit(void)
  5349. {
  5350. pt_unregister_module(&loader_module);
  5351. }
  5352. module_exit(pt_loader_exit);
  5353. MODULE_LICENSE("GPL");
  5354. MODULE_DESCRIPTION("Parade TrueTouch(R) Standard Product FW Loader Driver");
  5355. MODULE_AUTHOR("Parade Technologies <[email protected]>");