0008-ipts.patch 198 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408
  1. From 49678a8400c73921f11b2a89b844f1baeba40739 Mon Sep 17 00:00:00 2001
  2. From: Maximilian Luz <luzmaximilian@gmail.com>
  3. Date: Wed, 18 Sep 2019 13:04:18 +0200
  4. Subject: [PATCH 08/10] ipts
  5. ---
  6. drivers/gpu/drm/i915_legacy/Makefile | 3 +
  7. drivers/gpu/drm/i915_legacy/i915_debugfs.c | 63 +-
  8. drivers/gpu/drm/i915_legacy/i915_drv.c | 7 +
  9. drivers/gpu/drm/i915_legacy/i915_drv.h | 3 +
  10. .../gpu/drm/i915_legacy/i915_gem_context.c | 12 +
  11. drivers/gpu/drm/i915_legacy/i915_irq.c | 7 +-
  12. drivers/gpu/drm/i915_legacy/i915_params.c | 5 +-
  13. drivers/gpu/drm/i915_legacy/i915_params.h | 5 +-
  14. drivers/gpu/drm/i915_legacy/intel_guc.h | 1 +
  15. .../drm/i915_legacy/intel_guc_submission.c | 89 +-
  16. .../drm/i915_legacy/intel_guc_submission.h | 4 +
  17. drivers/gpu/drm/i915_legacy/intel_ipts.c | 650 ++++++++++
  18. drivers/gpu/drm/i915_legacy/intel_ipts.h | 34 +
  19. drivers/gpu/drm/i915_legacy/intel_lrc.c | 15 +-
  20. drivers/gpu/drm/i915_legacy/intel_lrc.h | 6 +
  21. drivers/gpu/drm/i915_legacy/intel_panel.c | 7 +
  22. drivers/misc/Kconfig | 1 +
  23. drivers/misc/Makefile | 1 +
  24. drivers/misc/ipts/Kconfig | 12 +
  25. drivers/misc/ipts/Makefile | 19 +
  26. drivers/misc/ipts/companion.c | 230 ++++
  27. drivers/misc/ipts/companion.h | 26 +
  28. drivers/misc/ipts/companion/Kconfig | 8 +
  29. drivers/misc/ipts/companion/Makefile | 2 +
  30. drivers/misc/ipts/companion/ipts-surface.c | 224 ++++
  31. drivers/misc/ipts/dbgfs.c | 277 +++++
  32. drivers/misc/ipts/gfx.c | 180 +++
  33. drivers/misc/ipts/gfx.h | 25 +
  34. drivers/misc/ipts/hid.c | 496 ++++++++
  35. drivers/misc/ipts/hid.h | 21 +
  36. drivers/misc/ipts/ipts.c | 62 +
  37. drivers/misc/ipts/ipts.h | 172 +++
  38. drivers/misc/ipts/kernel.c | 1047 +++++++++++++++++
  39. drivers/misc/ipts/kernel.h | 17 +
  40. drivers/misc/ipts/mei-msgs.h | 894 ++++++++++++++
  41. drivers/misc/ipts/mei.c | 238 ++++
  42. drivers/misc/ipts/msg-handler.c | 396 +++++++
  43. drivers/misc/ipts/msg-handler.h | 28 +
  44. drivers/misc/ipts/params.c | 46 +
  45. drivers/misc/ipts/params.h | 26 +
  46. drivers/misc/ipts/resource.c | 291 +++++
  47. drivers/misc/ipts/resource.h | 26 +
  48. drivers/misc/ipts/sensor-regs.h | 827 +++++++++++++
  49. drivers/misc/ipts/state.h | 22 +
  50. drivers/misc/mei/hw-me-regs.h | 1 +
  51. drivers/misc/mei/pci-me.c | 1 +
  52. include/linux/ipts-binary.h | 140 +++
  53. include/linux/ipts-companion.h | 30 +
  54. include/linux/ipts-gfx.h | 86 ++
  55. include/linux/ipts.h | 20 +
  56. 50 files changed, 6782 insertions(+), 21 deletions(-)
  57. create mode 100644 drivers/gpu/drm/i915_legacy/intel_ipts.c
  58. create mode 100644 drivers/gpu/drm/i915_legacy/intel_ipts.h
  59. create mode 100644 drivers/misc/ipts/Kconfig
  60. create mode 100644 drivers/misc/ipts/Makefile
  61. create mode 100644 drivers/misc/ipts/companion.c
  62. create mode 100644 drivers/misc/ipts/companion.h
  63. create mode 100644 drivers/misc/ipts/companion/Kconfig
  64. create mode 100644 drivers/misc/ipts/companion/Makefile
  65. create mode 100644 drivers/misc/ipts/companion/ipts-surface.c
  66. create mode 100644 drivers/misc/ipts/dbgfs.c
  67. create mode 100644 drivers/misc/ipts/gfx.c
  68. create mode 100644 drivers/misc/ipts/gfx.h
  69. create mode 100644 drivers/misc/ipts/hid.c
  70. create mode 100644 drivers/misc/ipts/hid.h
  71. create mode 100644 drivers/misc/ipts/ipts.c
  72. create mode 100644 drivers/misc/ipts/ipts.h
  73. create mode 100644 drivers/misc/ipts/kernel.c
  74. create mode 100644 drivers/misc/ipts/kernel.h
  75. create mode 100644 drivers/misc/ipts/mei-msgs.h
  76. create mode 100644 drivers/misc/ipts/mei.c
  77. create mode 100644 drivers/misc/ipts/msg-handler.c
  78. create mode 100644 drivers/misc/ipts/msg-handler.h
  79. create mode 100644 drivers/misc/ipts/params.c
  80. create mode 100644 drivers/misc/ipts/params.h
  81. create mode 100644 drivers/misc/ipts/resource.c
  82. create mode 100644 drivers/misc/ipts/resource.h
  83. create mode 100644 drivers/misc/ipts/sensor-regs.h
  84. create mode 100644 drivers/misc/ipts/state.h
  85. create mode 100644 include/linux/ipts-binary.h
  86. create mode 100644 include/linux/ipts-companion.h
  87. create mode 100644 include/linux/ipts-gfx.h
  88. create mode 100644 include/linux/ipts.h
  89. diff --git a/drivers/gpu/drm/i915_legacy/Makefile b/drivers/gpu/drm/i915_legacy/Makefile
  90. index fbcb0904f4a8..1a273956b41c 100644
  91. --- a/drivers/gpu/drm/i915_legacy/Makefile
  92. +++ b/drivers/gpu/drm/i915_legacy/Makefile
  93. @@ -170,6 +170,9 @@ i915-y += dvo_ch7017.o \
  94. vlv_dsi_pll.o \
  95. intel_vdsc.o
  96. +# intel precise touch & stylus
  97. +i915-y += intel_ipts.o
  98. +
  99. # Post-mortem debug and GPU hang state capture
  100. i915-$(CONFIG_DRM_I915_CAPTURE_ERROR) += i915_gpu_error.o
  101. i915-$(CONFIG_DRM_I915_SELFTEST) += \
  102. diff --git a/drivers/gpu/drm/i915_legacy/i915_debugfs.c b/drivers/gpu/drm/i915_legacy/i915_debugfs.c
  103. index 5823ffb17821..97606d249aea 100644
  104. --- a/drivers/gpu/drm/i915_legacy/i915_debugfs.c
  105. +++ b/drivers/gpu/drm/i915_legacy/i915_debugfs.c
  106. @@ -39,6 +39,7 @@
  107. #include "intel_guc_submission.h"
  108. #include "intel_hdcp.h"
  109. #include "intel_hdmi.h"
  110. +#include "intel_ipts.h"
  111. #include "intel_pm.h"
  112. #include "intel_psr.h"
  113. @@ -4567,6 +4568,64 @@ static const struct file_operations i915_fifo_underrun_reset_ops = {
  114. .llseek = default_llseek,
  115. };
  116. +static ssize_t
  117. +i915_ipts_cleanup_write(struct file *filp,
  118. + const char __user *ubuf,
  119. + size_t cnt, loff_t *ppos)
  120. +{
  121. + struct drm_i915_private *dev_priv = filp->private_data;
  122. + struct drm_device *dev = &dev_priv->drm;
  123. + int ret;
  124. + bool flag;
  125. +
  126. + ret = kstrtobool_from_user(ubuf, cnt, &flag);
  127. + if (ret)
  128. + return ret;
  129. +
  130. + if (!flag)
  131. + return cnt;
  132. +
  133. + ipts_cleanup(dev);
  134. +
  135. + return cnt;
  136. +}
  137. +
  138. +static const struct file_operations i915_ipts_cleanup_ops = {
  139. + .owner = THIS_MODULE,
  140. + .open = simple_open,
  141. + .write = i915_ipts_cleanup_write,
  142. + .llseek = default_llseek,
  143. +};
  144. +
  145. +static ssize_t
  146. +i915_ipts_init_write(struct file *filp,
  147. + const char __user *ubuf,
  148. + size_t cnt, loff_t *ppos)
  149. +{
  150. + struct drm_i915_private *dev_priv = filp->private_data;
  151. + struct drm_device *dev = &dev_priv->drm;
  152. + int ret;
  153. + bool flag;
  154. +
  155. + ret = kstrtobool_from_user(ubuf, cnt, &flag);
  156. + if (ret)
  157. + return ret;
  158. +
  159. + if (!flag)
  160. + return cnt;
  161. +
  162. + ipts_init(dev);
  163. +
  164. + return cnt;
  165. +}
  166. +
  167. +static const struct file_operations i915_ipts_init_ops = {
  168. + .owner = THIS_MODULE,
  169. + .open = simple_open,
  170. + .write = i915_ipts_init_write,
  171. + .llseek = default_llseek,
  172. +};
  173. +
  174. static const struct drm_info_list i915_debugfs_list[] = {
  175. {"i915_capabilities", i915_capabilities, 0},
  176. {"i915_gem_objects", i915_gem_object_info, 0},
  177. @@ -4642,7 +4701,9 @@ static const struct i915_debugfs_files {
  178. {"i915_hpd_short_storm_ctl", &i915_hpd_short_storm_ctl_fops},
  179. {"i915_ipc_status", &i915_ipc_status_fops},
  180. {"i915_drrs_ctl", &i915_drrs_ctl_fops},
  181. - {"i915_edp_psr_debug", &i915_edp_psr_debug_fops}
  182. + {"i915_edp_psr_debug", &i915_edp_psr_debug_fops},
  183. + {"i915_ipts_cleanup", &i915_ipts_cleanup_ops},
  184. + {"i915_ipts_init", &i915_ipts_init_ops},
  185. };
  186. int i915_debugfs_register(struct drm_i915_private *dev_priv)
  187. diff --git a/drivers/gpu/drm/i915_legacy/i915_drv.c b/drivers/gpu/drm/i915_legacy/i915_drv.c
  188. index d485d49c473b..9248887b7a23 100644
  189. --- a/drivers/gpu/drm/i915_legacy/i915_drv.c
  190. +++ b/drivers/gpu/drm/i915_legacy/i915_drv.c
  191. @@ -59,6 +59,7 @@
  192. #include "intel_dp.h"
  193. #include "intel_drv.h"
  194. #include "intel_fbdev.h"
  195. +#include "intel_ipts.h"
  196. #include "intel_pm.h"
  197. #include "intel_sprite.h"
  198. #include "intel_uc.h"
  199. @@ -723,6 +724,9 @@ static int i915_load_modeset_init(struct drm_device *dev)
  200. intel_init_ipc(dev_priv);
  201. + if (INTEL_GEN(dev_priv) >= 9 && i915_modparams.enable_guc && i915_modparams.enable_ipts)
  202. + ipts_init(dev);
  203. +
  204. return 0;
  205. cleanup_gem:
  206. @@ -1918,6 +1922,9 @@ void i915_driver_unload(struct drm_device *dev)
  207. disable_rpm_wakeref_asserts(dev_priv);
  208. + if (INTEL_GEN(dev_priv) >= 9 && i915_modparams.enable_guc && i915_modparams.enable_ipts)
  209. + ipts_cleanup(dev);
  210. +
  211. i915_driver_unregister(dev_priv);
  212. /*
  213. diff --git a/drivers/gpu/drm/i915_legacy/i915_drv.h b/drivers/gpu/drm/i915_legacy/i915_drv.h
  214. index 066fd2a12851..2a872d8725b5 100644
  215. --- a/drivers/gpu/drm/i915_legacy/i915_drv.h
  216. +++ b/drivers/gpu/drm/i915_legacy/i915_drv.h
  217. @@ -3184,6 +3184,9 @@ void i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj,
  218. void i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj,
  219. struct sg_table *pages);
  220. +struct i915_gem_context *
  221. +i915_gem_context_create_ipts(struct drm_device *dev);
  222. +
  223. static inline struct i915_gem_context *
  224. __i915_gem_context_lookup_rcu(struct drm_i915_file_private *file_priv, u32 id)
  225. {
  226. diff --git a/drivers/gpu/drm/i915_legacy/i915_gem_context.c b/drivers/gpu/drm/i915_legacy/i915_gem_context.c
  227. index fb5e2784d3c7..41f569c649bd 100644
  228. --- a/drivers/gpu/drm/i915_legacy/i915_gem_context.c
  229. +++ b/drivers/gpu/drm/i915_legacy/i915_gem_context.c
  230. @@ -562,6 +562,18 @@ static bool needs_preempt_context(struct drm_i915_private *i915)
  231. return HAS_EXECLISTS(i915);
  232. }
  233. +struct i915_gem_context *i915_gem_context_create_ipts(struct drm_device *dev)
  234. +{
  235. + struct drm_i915_private *dev_priv = to_i915(dev);
  236. + struct i915_gem_context *ctx;
  237. +
  238. + BUG_ON(!mutex_is_locked(&dev->struct_mutex));
  239. +
  240. + ctx = i915_gem_create_context(dev_priv, 0);
  241. +
  242. + return ctx;
  243. +}
  244. +
  245. int i915_gem_contexts_init(struct drm_i915_private *dev_priv)
  246. {
  247. struct i915_gem_context *ctx;
  248. diff --git a/drivers/gpu/drm/i915_legacy/i915_irq.c b/drivers/gpu/drm/i915_legacy/i915_irq.c
  249. index b92cfd69134b..4d20c509876a 100644
  250. --- a/drivers/gpu/drm/i915_legacy/i915_irq.c
  251. +++ b/drivers/gpu/drm/i915_legacy/i915_irq.c
  252. @@ -40,6 +40,7 @@
  253. #include "i915_drv.h"
  254. #include "i915_trace.h"
  255. #include "intel_drv.h"
  256. +#include "intel_ipts.h"
  257. #include "intel_psr.h"
  258. /**
  259. @@ -1520,6 +1521,9 @@ gen8_cs_irq_handler(struct intel_engine_cs *engine, u32 iir)
  260. tasklet |= intel_engine_needs_breadcrumb_tasklet(engine);
  261. }
  262. + if (iir & GT_RENDER_PIPECTL_NOTIFY_INTERRUPT && i915_modparams.enable_ipts)
  263. + ipts_notify_complete();
  264. +
  265. if (tasklet)
  266. tasklet_hi_schedule(&engine->execlists.tasklet);
  267. }
  268. @@ -4055,7 +4059,8 @@ static void gen8_gt_irq_postinstall(struct drm_i915_private *dev_priv)
  269. /* These are interrupts we'll toggle with the ring mask register */
  270. u32 gt_interrupts[] = {
  271. - (GT_RENDER_USER_INTERRUPT << GEN8_RCS_IRQ_SHIFT |
  272. + (GT_RENDER_PIPECTL_NOTIFY_INTERRUPT << GEN8_RCS_IRQ_SHIFT |
  273. + GT_RENDER_USER_INTERRUPT << GEN8_RCS_IRQ_SHIFT |
  274. GT_CONTEXT_SWITCH_INTERRUPT << GEN8_RCS_IRQ_SHIFT |
  275. GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT |
  276. GT_CONTEXT_SWITCH_INTERRUPT << GEN8_BCS_IRQ_SHIFT),
  277. diff --git a/drivers/gpu/drm/i915_legacy/i915_params.c b/drivers/gpu/drm/i915_legacy/i915_params.c
  278. index b5be0abbba35..831f2bcae687 100644
  279. --- a/drivers/gpu/drm/i915_legacy/i915_params.c
  280. +++ b/drivers/gpu/drm/i915_legacy/i915_params.c
  281. @@ -143,7 +143,10 @@ i915_param_named_unsafe(edp_vswing, int, 0400,
  282. i915_param_named_unsafe(enable_guc, int, 0400,
  283. "Enable GuC load for GuC submission and/or HuC load. "
  284. "Required functionality can be selected using bitmask values. "
  285. - "(-1=auto, 0=disable [default], 1=GuC submission, 2=HuC load)");
  286. + "(-1=auto [default], 0=disable, 1=GuC submission, 2=HuC load)");
  287. +
  288. +i915_param_named_unsafe(enable_ipts, int, 0400,
  289. + "Enable IPTS Touchscreen and Pen support (default: 1)");
  290. i915_param_named(guc_log_level, int, 0400,
  291. "GuC firmware logging level. Requires GuC to be loaded. "
  292. diff --git a/drivers/gpu/drm/i915_legacy/i915_params.h b/drivers/gpu/drm/i915_legacy/i915_params.h
  293. index 3f14e9881a0d..e314a2414041 100644
  294. --- a/drivers/gpu/drm/i915_legacy/i915_params.h
  295. +++ b/drivers/gpu/drm/i915_legacy/i915_params.h
  296. @@ -54,7 +54,7 @@ struct drm_printer;
  297. param(int, disable_power_well, -1) \
  298. param(int, enable_ips, 1) \
  299. param(int, invert_brightness, 0) \
  300. - param(int, enable_guc, 0) \
  301. + param(int, enable_guc, -1) \
  302. param(int, guc_log_level, -1) \
  303. param(char *, guc_firmware_path, NULL) \
  304. param(char *, huc_firmware_path, NULL) \
  305. @@ -76,7 +76,8 @@ struct drm_printer;
  306. param(bool, nuclear_pageflip, false) \
  307. param(bool, enable_dp_mst, true) \
  308. param(bool, enable_dpcd_backlight, false) \
  309. - param(bool, enable_gvt, false)
  310. + param(bool, enable_gvt, false) \
  311. + param(int, enable_ipts, 1)
  312. #define MEMBER(T, member, ...) T member;
  313. struct i915_params {
  314. diff --git a/drivers/gpu/drm/i915_legacy/intel_guc.h b/drivers/gpu/drm/i915_legacy/intel_guc.h
  315. index 2c59ff8d9f39..d7f91693972f 100644
  316. --- a/drivers/gpu/drm/i915_legacy/intel_guc.h
  317. +++ b/drivers/gpu/drm/i915_legacy/intel_guc.h
  318. @@ -67,6 +67,7 @@ struct intel_guc {
  319. struct intel_guc_client *execbuf_client;
  320. struct intel_guc_client *preempt_client;
  321. + struct intel_guc_client *ipts_client;
  322. struct guc_preempt_work preempt_work[I915_NUM_ENGINES];
  323. struct workqueue_struct *preempt_wq;
  324. diff --git a/drivers/gpu/drm/i915_legacy/intel_guc_submission.c b/drivers/gpu/drm/i915_legacy/intel_guc_submission.c
  325. index 46cd0e70aecb..e84c805f7340 100644
  326. --- a/drivers/gpu/drm/i915_legacy/intel_guc_submission.c
  327. +++ b/drivers/gpu/drm/i915_legacy/intel_guc_submission.c
  328. @@ -93,12 +93,17 @@ static inline struct i915_priolist *to_priolist(struct rb_node *rb)
  329. static inline bool is_high_priority(struct intel_guc_client *client)
  330. {
  331. - return (client->priority == GUC_CLIENT_PRIORITY_KMD_HIGH ||
  332. - client->priority == GUC_CLIENT_PRIORITY_HIGH);
  333. + return (client->priority == GUC_CLIENT_PRIORITY_HIGH);
  334. +}
  335. +
  336. +static inline bool is_high_priority_kmd(struct intel_guc_client *client)
  337. +{
  338. + return (client->priority == GUC_CLIENT_PRIORITY_KMD_HIGH);
  339. }
  340. static int reserve_doorbell(struct intel_guc_client *client)
  341. {
  342. + struct drm_i915_private *dev_priv = guc_to_i915(client->guc);
  343. unsigned long offset;
  344. unsigned long end;
  345. u16 id;
  346. @@ -111,10 +116,14 @@ static int reserve_doorbell(struct intel_guc_client *client)
  347. * priority contexts, the second half for high-priority ones.
  348. */
  349. offset = 0;
  350. - end = GUC_NUM_DOORBELLS / 2;
  351. - if (is_high_priority(client)) {
  352. - offset = end;
  353. - end += offset;
  354. + if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
  355. + end = GUC_NUM_DOORBELLS;
  356. + } else {
  357. + end = GUC_NUM_DOORBELLS/2;
  358. + if (is_high_priority(client)) {
  359. + offset = end;
  360. + end += offset;
  361. + }
  362. }
  363. id = find_next_zero_bit(client->guc->doorbell_bitmap, end, offset);
  364. @@ -372,9 +381,15 @@ static void guc_stage_desc_init(struct intel_guc_client *client)
  365. desc = __get_stage_desc(client);
  366. memset(desc, 0, sizeof(*desc));
  367. - desc->attribute = GUC_STAGE_DESC_ATTR_ACTIVE |
  368. - GUC_STAGE_DESC_ATTR_KERNEL;
  369. - if (is_high_priority(client))
  370. + desc->attribute = GUC_STAGE_DESC_ATTR_ACTIVE;
  371. + if ((client->priority == GUC_CLIENT_PRIORITY_KMD_NORMAL) ||
  372. + (client->priority == GUC_CLIENT_PRIORITY_KMD_HIGH)) {
  373. + desc->attribute |= GUC_STAGE_DESC_ATTR_KERNEL;
  374. + } else {
  375. + desc->attribute |= GUC_STAGE_DESC_ATTR_PCH;
  376. + }
  377. +
  378. + if (is_high_priority_kmd(client))
  379. desc->attribute |= GUC_STAGE_DESC_ATTR_PREEMPT;
  380. desc->stage_id = client->stage_id;
  381. desc->priority = client->priority;
  382. @@ -1302,7 +1317,8 @@ static void guc_interrupts_capture(struct drm_i915_private *dev_priv)
  383. I915_WRITE(RING_MODE_GEN7(engine), irqs);
  384. /* route USER_INTERRUPT to Host, all others are sent to GuC. */
  385. - irqs = GT_RENDER_USER_INTERRUPT << GEN8_RCS_IRQ_SHIFT |
  386. + irqs = (GT_RENDER_USER_INTERRUPT | GT_RENDER_PIPECTL_NOTIFY_INTERRUPT)
  387. + << GEN8_RCS_IRQ_SHIFT |
  388. GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT;
  389. /* These three registers have the same bit definitions */
  390. I915_WRITE(GUC_BCS_RCS_IER, ~irqs);
  391. @@ -1449,6 +1465,59 @@ void intel_guc_submission_disable(struct intel_guc *guc)
  392. guc_clients_disable(guc);
  393. }
  394. +int i915_guc_ipts_submission_enable(struct drm_i915_private *dev_priv,
  395. + struct i915_gem_context *ctx)
  396. +{
  397. + struct intel_guc *guc = &dev_priv->guc;
  398. + struct intel_guc_client *client;
  399. + int err;
  400. + int ret;
  401. +
  402. + /* client for execbuf submission */
  403. + client = guc_client_alloc(dev_priv,
  404. + INTEL_INFO(dev_priv)->engine_mask,
  405. + IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv) ? GUC_CLIENT_PRIORITY_HIGH : GUC_CLIENT_PRIORITY_NORMAL,
  406. + ctx);
  407. + if (IS_ERR(client)) {
  408. + DRM_ERROR("Failed to create normal GuC client!\n");
  409. + return -ENOMEM;
  410. + }
  411. +
  412. + guc->ipts_client = client;
  413. +
  414. + err = intel_guc_sample_forcewake(guc);
  415. + if (err)
  416. + return err;
  417. +
  418. + ret = __guc_client_enable(guc->ipts_client);
  419. + if (ret)
  420. + return ret;
  421. +
  422. + return 0;
  423. +}
  424. +
  425. +void i915_guc_ipts_submission_disable(struct drm_i915_private *dev_priv)
  426. +{
  427. + struct intel_guc *guc = &dev_priv->guc;
  428. +
  429. + if (!guc->ipts_client)
  430. + return;
  431. +
  432. + __guc_client_disable(guc->ipts_client);
  433. + guc_client_free(guc->ipts_client);
  434. + guc->ipts_client = NULL;
  435. +}
  436. +
  437. +void i915_guc_ipts_reacquire_doorbell(struct drm_i915_private *dev_priv)
  438. +{
  439. + struct intel_guc *guc = &dev_priv->guc;
  440. +
  441. + int err = __guc_allocate_doorbell(guc, guc->ipts_client->stage_id);
  442. +
  443. + if (err)
  444. + DRM_ERROR("Not able to reacquire IPTS doorbell\n");
  445. +}
  446. +
  447. #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
  448. #include "selftests/intel_guc.c"
  449. #endif
  450. diff --git a/drivers/gpu/drm/i915_legacy/intel_guc_submission.h b/drivers/gpu/drm/i915_legacy/intel_guc_submission.h
  451. index aa5e6749c925..c9e5c14e7f67 100644
  452. --- a/drivers/gpu/drm/i915_legacy/intel_guc_submission.h
  453. +++ b/drivers/gpu/drm/i915_legacy/intel_guc_submission.h
  454. @@ -84,5 +84,9 @@ void intel_guc_submission_disable(struct intel_guc *guc);
  455. void intel_guc_submission_fini(struct intel_guc *guc);
  456. int intel_guc_preempt_work_create(struct intel_guc *guc);
  457. void intel_guc_preempt_work_destroy(struct intel_guc *guc);
  458. +int i915_guc_ipts_submission_enable(struct drm_i915_private *dev_priv,
  459. + struct i915_gem_context *ctx);
  460. +void i915_guc_ipts_submission_disable(struct drm_i915_private *dev_priv);
  461. +void i915_guc_ipts_reacquire_doorbell(struct drm_i915_private *dev_priv);
  462. #endif
  463. diff --git a/drivers/gpu/drm/i915_legacy/intel_ipts.c b/drivers/gpu/drm/i915_legacy/intel_ipts.c
  464. new file mode 100644
  465. index 000000000000..77147cfeb740
  466. --- /dev/null
  467. +++ b/drivers/gpu/drm/i915_legacy/intel_ipts.c
  468. @@ -0,0 +1,650 @@
  469. +/*
  470. + * Copyright 2016 Intel Corporation
  471. + *
  472. + * Permission is hereby granted, free of charge, to any person obtaining a
  473. + * copy of this software and associated documentation files (the "Software"),
  474. + * to deal in the Software without restriction, including without limitation
  475. + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  476. + * and/or sell copies of the Software, and to permit persons to whom the
  477. + * Software is furnished to do so, subject to the following conditions:
  478. + *
  479. + * The above copyright notice and this permission notice (including the next
  480. + * paragraph) shall be included in all copies or substantial portions of the
  481. + * Software.
  482. + *
  483. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  484. + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  485. + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  486. + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  487. + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  488. + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  489. + * IN THE SOFTWARE.
  490. + *
  491. + */
  492. +
  493. +#include <drm/drmP.h>
  494. +#include <linux/ipts-gfx.h>
  495. +#include <linux/kernel.h>
  496. +#include <linux/module.h>
  497. +#include <linux/types.h>
  498. +
  499. +#include "intel_guc_submission.h"
  500. +#include "i915_drv.h"
  501. +
  502. +#define SUPPORTED_IPTS_INTERFACE_VERSION 1
  503. +
  504. +#define REACQUIRE_DB_THRESHOLD 10
  505. +
  506. +#define DB_LOST_CHECK_STEP1_INTERVAL 2500 // ms
  507. +#define DB_LOST_CHECK_STEP2_INTERVAL 1000 // ms
  508. +
  509. +// CTX for ipts support
  510. +struct ipts {
  511. + struct drm_device *dev;
  512. + struct i915_gem_context *ipts_context;
  513. + struct ipts_callback ipts_clbks;
  514. +
  515. + // buffers' list
  516. + struct {
  517. + spinlock_t lock;
  518. + struct list_head list;
  519. + } buffers;
  520. +
  521. + void *data;
  522. +
  523. + struct delayed_work reacquire_db_work;
  524. + struct ipts_wq_info wq_info;
  525. + u32 old_tail;
  526. + u32 old_head;
  527. + bool need_reacquire_db;
  528. +
  529. + bool connected;
  530. + bool initialized;
  531. +};
  532. +
  533. +struct ipts ipts;
  534. +
  535. +struct ipts_object {
  536. + struct list_head list;
  537. + struct drm_i915_gem_object *gem_obj;
  538. + void *cpu_addr;
  539. +};
  540. +
  541. +static struct ipts_object *ipts_object_create(size_t size, u32 flags)
  542. +{
  543. + struct drm_i915_private *dev_priv = to_i915(ipts.dev);
  544. + struct ipts_object *obj = NULL;
  545. + struct drm_i915_gem_object *gem_obj = NULL;
  546. + int ret = 0;
  547. +
  548. + obj = kzalloc(sizeof(*obj), GFP_KERNEL);
  549. + if (!obj)
  550. + return NULL;
  551. +
  552. + size = roundup(size, PAGE_SIZE);
  553. + if (size == 0) {
  554. + ret = -EINVAL;
  555. + goto err_out;
  556. + }
  557. +
  558. + // Allocate the new object
  559. + gem_obj = i915_gem_object_create(dev_priv, size);
  560. + if (gem_obj == NULL) {
  561. + ret = -ENOMEM;
  562. + goto err_out;
  563. + }
  564. +
  565. + if (flags & IPTS_BUF_FLAG_CONTIGUOUS) {
  566. + ret = i915_gem_object_attach_phys(gem_obj, PAGE_SIZE);
  567. + if (ret) {
  568. + pr_info(">> ipts no contiguous : %d\n", ret);
  569. + goto err_out;
  570. + }
  571. + }
  572. +
  573. + obj->gem_obj = gem_obj;
  574. +
  575. + spin_lock(&ipts.buffers.lock);
  576. + list_add_tail(&obj->list, &ipts.buffers.list);
  577. + spin_unlock(&ipts.buffers.lock);
  578. +
  579. + return obj;
  580. +
  581. +err_out:
  582. +
  583. + if (gem_obj)
  584. + i915_gem_free_object(&gem_obj->base);
  585. +
  586. + kfree(obj);
  587. +
  588. + return NULL;
  589. +}
  590. +
  591. +static void ipts_object_free(struct ipts_object *obj)
  592. +{
  593. + spin_lock(&ipts.buffers.lock);
  594. + list_del(&obj->list);
  595. + spin_unlock(&ipts.buffers.lock);
  596. +
  597. + i915_gem_free_object(&obj->gem_obj->base);
  598. + kfree(obj);
  599. +}
  600. +
  601. +static int ipts_object_pin(struct ipts_object *obj,
  602. + struct i915_gem_context *ipts_ctx)
  603. +{
  604. + struct i915_address_space *vm = NULL;
  605. + struct i915_vma *vma = NULL;
  606. + struct drm_i915_private *dev_priv = to_i915(ipts.dev);
  607. + int ret = 0;
  608. +
  609. + if (ipts_ctx->ppgtt)
  610. + vm = &ipts_ctx->ppgtt->vm;
  611. + else
  612. + vm = &dev_priv->ggtt.vm;
  613. +
  614. + vma = i915_vma_instance(obj->gem_obj, vm, NULL);
  615. + if (IS_ERR(vma)) {
  616. + DRM_ERROR("cannot find or create vma\n");
  617. + return -1;
  618. + }
  619. +
  620. + ret = i915_vma_pin(vma, 0, PAGE_SIZE, PIN_USER);
  621. +
  622. + return ret;
  623. +}
  624. +
  625. +static void ipts_object_unpin(struct ipts_object *obj)
  626. +{
  627. + // TODO: Add support
  628. +}
  629. +
  630. +static void *ipts_object_map(struct ipts_object *obj)
  631. +{
  632. + return i915_gem_object_pin_map(obj->gem_obj, I915_MAP_WB);
  633. +}
  634. +
  635. +static void ipts_object_unmap(struct ipts_object *obj)
  636. +{
  637. + i915_gem_object_unpin_map(obj->gem_obj);
  638. + obj->cpu_addr = NULL;
  639. +}
  640. +
  641. +static int create_ipts_context(void)
  642. +{
  643. + struct i915_gem_context *ipts_ctx = NULL;
  644. + struct drm_i915_private *dev_priv = to_i915(ipts.dev);
  645. + struct intel_context *ce = NULL;
  646. + int ret = 0;
  647. +
  648. + // Initialize the context right away.
  649. + ret = i915_mutex_lock_interruptible(ipts.dev);
  650. + if (ret) {
  651. + DRM_ERROR("i915_mutex_lock_interruptible failed\n");
  652. + return ret;
  653. + }
  654. +
  655. + ipts_ctx = i915_gem_context_create_ipts(ipts.dev);
  656. + if (IS_ERR(ipts_ctx)) {
  657. + DRM_ERROR("Failed to create IPTS context (error %ld)\n",
  658. + PTR_ERR(ipts_ctx));
  659. + ret = PTR_ERR(ipts_ctx);
  660. + goto err_unlock;
  661. + }
  662. +
  663. + ce = intel_context_pin(ipts_ctx, dev_priv->engine[RCS0]);
  664. + if (IS_ERR(ce)) {
  665. + DRM_ERROR("Failed to create intel context (error %ld)\n",
  666. + PTR_ERR(ce));
  667. + ret = PTR_ERR(ce);
  668. + goto err_unlock;
  669. + }
  670. +
  671. + ret = execlists_context_deferred_alloc(ce, ce->engine);
  672. + if (ret) {
  673. + DRM_DEBUG("lr context allocation failed: %d\n", ret);
  674. + goto err_ctx;
  675. + }
  676. +
  677. + ret = execlists_context_pin(ce);
  678. + if (ret) {
  679. + DRM_DEBUG("lr context pinning failed: %d\n", ret);
  680. + goto err_ctx;
  681. + }
  682. +
  683. + // Release the mutex
  684. + mutex_unlock(&ipts.dev->struct_mutex);
  685. +
  686. + spin_lock_init(&ipts.buffers.lock);
  687. + INIT_LIST_HEAD(&ipts.buffers.list);
  688. +
  689. + ipts.ipts_context = ipts_ctx;
  690. +
  691. + return 0;
  692. +
  693. +err_ctx:
  694. + if (ipts_ctx)
  695. + i915_gem_context_put(ipts_ctx);
  696. +
  697. +err_unlock:
  698. + mutex_unlock(&ipts.dev->struct_mutex);
  699. +
  700. + return ret;
  701. +}
  702. +
  703. +static void destroy_ipts_context(void)
  704. +{
  705. + struct i915_gem_context *ipts_ctx = NULL;
  706. + struct drm_i915_private *dev_priv = to_i915(ipts.dev);
  707. + struct intel_context *ce = NULL;
  708. + int ret = 0;
  709. +
  710. + ipts_ctx = ipts.ipts_context;
  711. +
  712. + ce = intel_context_lookup(ipts_ctx, dev_priv->engine[RCS0]);
  713. +
  714. + // Initialize the context right away.
  715. + ret = i915_mutex_lock_interruptible(ipts.dev);
  716. + if (ret) {
  717. + DRM_ERROR("i915_mutex_lock_interruptible failed\n");
  718. + return;
  719. + }
  720. +
  721. + execlists_context_unpin(ce);
  722. + intel_context_unpin(ce);
  723. + i915_gem_context_put(ipts_ctx);
  724. +
  725. + mutex_unlock(&ipts.dev->struct_mutex);
  726. +}
  727. +
  728. +int ipts_notify_complete(void)
  729. +{
  730. + if (ipts.ipts_clbks.workload_complete)
  731. + ipts.ipts_clbks.workload_complete(ipts.data);
  732. +
  733. + return 0;
  734. +}
  735. +
  736. +int ipts_notify_backlight_status(bool backlight_on)
  737. +{
  738. + if (ipts.ipts_clbks.notify_gfx_status) {
  739. + if (backlight_on) {
  740. + ipts.ipts_clbks.notify_gfx_status(
  741. + IPTS_NOTIFY_STA_BACKLIGHT_ON, ipts.data);
  742. + schedule_delayed_work(&ipts.reacquire_db_work,
  743. + msecs_to_jiffies(DB_LOST_CHECK_STEP1_INTERVAL));
  744. + } else {
  745. + ipts.ipts_clbks.notify_gfx_status(
  746. + IPTS_NOTIFY_STA_BACKLIGHT_OFF, ipts.data);
  747. + cancel_delayed_work(&ipts.reacquire_db_work);
  748. + }
  749. + }
  750. +
  751. + return 0;
  752. +}
  753. +
  754. +static void ipts_reacquire_db(struct ipts *ipts_p)
  755. +{
  756. + int ret = 0;
  757. +
  758. + ret = i915_mutex_lock_interruptible(ipts_p->dev);
  759. + if (ret) {
  760. + DRM_ERROR("i915_mutex_lock_interruptible failed\n");
  761. + return;
  762. + }
  763. +
  764. + // Reacquire the doorbell
  765. + i915_guc_ipts_reacquire_doorbell(ipts_p->dev->dev_private);
  766. +
  767. + mutex_unlock(&ipts_p->dev->struct_mutex);
  768. +}
  769. +
  770. +static int ipts_get_wq_info(uint64_t gfx_handle,
  771. + struct ipts_wq_info *wq_info)
  772. +{
  773. + if (gfx_handle != (uint64_t)&ipts) {
  774. + DRM_ERROR("invalid gfx handle\n");
  775. + return -EINVAL;
  776. + }
  777. +
  778. + *wq_info = ipts.wq_info;
  779. +
  780. + ipts_reacquire_db(&ipts);
  781. + schedule_delayed_work(&ipts.reacquire_db_work,
  782. + msecs_to_jiffies(DB_LOST_CHECK_STEP1_INTERVAL));
  783. +
  784. + return 0;
  785. +}
  786. +
  787. +static int set_wq_info(void)
  788. +{
  789. + struct drm_i915_private *dev_priv = to_i915(ipts.dev);
  790. + struct intel_guc *guc = &dev_priv->guc;
  791. + struct intel_guc_client *client;
  792. + struct guc_process_desc *desc;
  793. + struct ipts_wq_info *wq_info;
  794. + void *base = NULL;
  795. + u64 phy_base = 0;
  796. +
  797. + wq_info = &ipts.wq_info;
  798. +
  799. + client = guc->ipts_client;
  800. + if (!client) {
  801. + DRM_ERROR("IPTS GuC client is NOT available\n");
  802. + return -EINVAL;
  803. + }
  804. +
  805. + base = client->vaddr;
  806. + desc = (struct guc_process_desc *)
  807. + ((u64)base + client->proc_desc_offset);
  808. +
  809. + desc->wq_base_addr = (u64)base + GUC_DB_SIZE;
  810. + desc->db_base_addr = (u64)base + client->doorbell_offset;
  811. +
  812. + // IPTS expects physical addresses to pass it to ME
  813. + phy_base = sg_dma_address(client->vma->pages->sgl);
  814. +
  815. + wq_info->db_addr = desc->db_base_addr;
  816. + wq_info->db_phy_addr = phy_base + client->doorbell_offset;
  817. + wq_info->db_cookie_offset = offsetof(struct guc_doorbell_info, cookie);
  818. + wq_info->wq_addr = desc->wq_base_addr;
  819. + wq_info->wq_phy_addr = phy_base + GUC_DB_SIZE;
  820. + wq_info->wq_head_addr = (u64)&desc->head;
  821. + wq_info->wq_tail_addr = (u64)&desc->tail;
  822. + wq_info->wq_size = desc->wq_size_bytes;
  823. +
  824. + wq_info->wq_head_phy_addr = phy_base + client->proc_desc_offset +
  825. + offsetof(struct guc_process_desc, head);
  826. +
  827. + wq_info->wq_tail_phy_addr = phy_base + client->proc_desc_offset +
  828. + offsetof(struct guc_process_desc, tail);
  829. +
  830. + return 0;
  831. +}
  832. +
  833. +static int ipts_init_wq(void)
  834. +{
  835. + int ret = 0;
  836. +
  837. + ret = i915_mutex_lock_interruptible(ipts.dev);
  838. + if (ret) {
  839. + DRM_ERROR("i915_mutex_lock_interruptible failed\n");
  840. + return ret;
  841. + }
  842. +
  843. + // disable IPTS submission
  844. + i915_guc_ipts_submission_disable(ipts.dev->dev_private);
  845. +
  846. + // enable IPTS submission
  847. + ret = i915_guc_ipts_submission_enable(ipts.dev->dev_private,
  848. + ipts.ipts_context);
  849. + if (ret) {
  850. + DRM_ERROR("i915_guc_ipts_submission_enable failed: %d\n", ret);
  851. + goto out;
  852. + }
  853. +
  854. + ret = set_wq_info();
  855. + if (ret) {
  856. + DRM_ERROR("set_wq_info failed\n");
  857. + goto out;
  858. + }
  859. +
  860. +out:
  861. + mutex_unlock(&ipts.dev->struct_mutex);
  862. +
  863. + return ret;
  864. +}
  865. +
  866. +static void ipts_release_wq(void)
  867. +{
  868. + int ret = 0;
  869. +
  870. + ret = i915_mutex_lock_interruptible(ipts.dev);
  871. + if (ret) {
  872. + DRM_ERROR("i915_mutex_lock_interruptible failed\n");
  873. + return;
  874. + }
  875. +
  876. + // disable IPTS submission
  877. + i915_guc_ipts_submission_disable(ipts.dev->dev_private);
  878. +
  879. + mutex_unlock(&ipts.dev->struct_mutex);
  880. +}
  881. +
  882. +static int ipts_map_buffer(u64 gfx_handle, struct ipts_mapbuffer *mapbuf)
  883. +{
  884. + struct ipts_object *obj;
  885. + struct i915_gem_context *ipts_ctx = NULL;
  886. + struct drm_i915_private *dev_priv = to_i915(ipts.dev);
  887. + struct i915_address_space *vm = NULL;
  888. + struct i915_vma *vma = NULL;
  889. + int ret = 0;
  890. +
  891. + if (gfx_handle != (uint64_t)&ipts) {
  892. + DRM_ERROR("invalid gfx handle\n");
  893. + return -EINVAL;
  894. + }
  895. +
  896. + // Acquire mutex first
  897. + ret = i915_mutex_lock_interruptible(ipts.dev);
  898. + if (ret) {
  899. + DRM_ERROR("i915_mutex_lock_interruptible failed\n");
  900. + return -EINVAL;
  901. + }
  902. +
  903. + obj = ipts_object_create(mapbuf->size, mapbuf->flags);
  904. + if (!obj)
  905. + return -ENOMEM;
  906. +
  907. + ipts_ctx = ipts.ipts_context;
  908. + ret = ipts_object_pin(obj, ipts_ctx);
  909. + if (ret) {
  910. + DRM_ERROR("Not able to pin iTouch obj\n");
  911. + ipts_object_free(obj);
  912. + mutex_unlock(&ipts.dev->struct_mutex);
  913. + return -ENOMEM;
  914. + }
  915. +
  916. + if (mapbuf->flags & IPTS_BUF_FLAG_CONTIGUOUS)
  917. + obj->cpu_addr = obj->gem_obj->phys_handle->vaddr;
  918. + else
  919. + obj->cpu_addr = ipts_object_map(obj);
  920. +
  921. + if (ipts_ctx->ppgtt)
  922. + vm = &ipts_ctx->ppgtt->vm;
  923. + else
  924. + vm = &dev_priv->ggtt.vm;
  925. +
  926. + vma = i915_vma_instance(obj->gem_obj, vm, NULL);
  927. + if (IS_ERR(vma)) {
  928. + DRM_ERROR("cannot find or create vma\n");
  929. + return -EINVAL;
  930. + }
  931. +
  932. + mapbuf->gfx_addr = (void *)vma->node.start;
  933. + mapbuf->cpu_addr = (void *)obj->cpu_addr;
  934. + mapbuf->buf_handle = (u64)obj;
  935. + if (mapbuf->flags & IPTS_BUF_FLAG_CONTIGUOUS)
  936. + mapbuf->phy_addr = (u64)obj->gem_obj->phys_handle->busaddr;
  937. +
  938. + // Release the mutex
  939. + mutex_unlock(&ipts.dev->struct_mutex);
  940. +
  941. + return 0;
  942. +}
  943. +
  944. +static int ipts_unmap_buffer(uint64_t gfx_handle, uint64_t buf_handle)
  945. +{
  946. + struct ipts_object *obj = (struct ipts_object *)buf_handle;
  947. +
  948. + if (gfx_handle != (uint64_t)&ipts) {
  949. + DRM_ERROR("invalid gfx handle\n");
  950. + return -EINVAL;
  951. + }
  952. +
  953. + if (!obj->gem_obj->phys_handle)
  954. + ipts_object_unmap(obj);
  955. +
  956. + ipts_object_unpin(obj);
  957. + ipts_object_free(obj);
  958. +
  959. + return 0;
  960. +}
  961. +
  962. +int ipts_connect(struct ipts_connect *ipts_connect)
  963. +{
  964. + u32 flags = DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_CONSUMER;
  965. + struct drm_i915_private *dev_priv = to_i915(ipts.dev);
  966. +
  967. + if (!ipts.initialized)
  968. + return -EIO;
  969. +
  970. + if (!ipts_connect)
  971. + return -EINVAL;
  972. +
  973. + if (ipts_connect->if_version > SUPPORTED_IPTS_INTERFACE_VERSION)
  974. + return -EINVAL;
  975. +
  976. + // set up device-link for PM
  977. + if (!device_link_add(ipts_connect->client, ipts.dev->dev, flags))
  978. + return -EFAULT;
  979. +
  980. + // return gpu operations for ipts
  981. + ipts_connect->ipts_ops.get_wq_info = ipts_get_wq_info;
  982. + ipts_connect->ipts_ops.map_buffer = ipts_map_buffer;
  983. + ipts_connect->ipts_ops.unmap_buffer = ipts_unmap_buffer;
  984. + ipts_connect->gfx_version = INTEL_INFO(dev_priv)->gen;
  985. + ipts_connect->gfx_handle = (uint64_t)&ipts;
  986. +
  987. + // save callback and data
  988. + ipts.data = ipts_connect->data;
  989. + ipts.ipts_clbks = ipts_connect->ipts_cb;
  990. +
  991. + ipts.connected = true;
  992. +
  993. + return 0;
  994. +}
  995. +EXPORT_SYMBOL_GPL(ipts_connect);
  996. +
  997. +void ipts_disconnect(uint64_t gfx_handle)
  998. +{
  999. + if (!ipts.initialized)
  1000. + return;
  1001. +
  1002. + if (gfx_handle != (uint64_t)&ipts || !ipts.connected) {
  1003. + DRM_ERROR("invalid gfx handle\n");
  1004. + return;
  1005. + }
  1006. +
  1007. + ipts.data = 0;
  1008. + memset(&ipts.ipts_clbks, 0, sizeof(struct ipts_callback));
  1009. +
  1010. + ipts.connected = false;
  1011. +}
  1012. +EXPORT_SYMBOL_GPL(ipts_disconnect);
  1013. +
  1014. +static void reacquire_db_work_func(struct work_struct *work)
  1015. +{
  1016. + struct delayed_work *d_work = container_of(work,
  1017. + struct delayed_work, work);
  1018. + struct ipts *ipts_p = container_of(d_work,
  1019. + struct ipts, reacquire_db_work);
  1020. + u32 head;
  1021. + u32 tail;
  1022. + u32 size;
  1023. + u32 load;
  1024. +
  1025. + head = *(u32 *)ipts_p->wq_info.wq_head_addr;
  1026. + tail = *(u32 *)ipts_p->wq_info.wq_tail_addr;
  1027. + size = ipts_p->wq_info.wq_size;
  1028. +
  1029. + if (head >= tail)
  1030. + load = head - tail;
  1031. + else
  1032. + load = head + size - tail;
  1033. +
  1034. + if (load < REACQUIRE_DB_THRESHOLD) {
  1035. + ipts_p->need_reacquire_db = false;
  1036. + goto reschedule_work;
  1037. + }
  1038. +
  1039. + if (ipts_p->need_reacquire_db) {
  1040. + if (ipts_p->old_head == head &&
  1041. + ipts_p->old_tail == tail)
  1042. + ipts_reacquire_db(ipts_p);
  1043. + ipts_p->need_reacquire_db = false;
  1044. + } else {
  1045. + ipts_p->old_head = head;
  1046. + ipts_p->old_tail = tail;
  1047. + ipts_p->need_reacquire_db = true;
  1048. +
  1049. + // recheck
  1050. + schedule_delayed_work(&ipts_p->reacquire_db_work,
  1051. + msecs_to_jiffies(DB_LOST_CHECK_STEP2_INTERVAL));
  1052. + return;
  1053. + }
  1054. +
  1055. +reschedule_work:
  1056. + schedule_delayed_work(&ipts_p->reacquire_db_work,
  1057. + msecs_to_jiffies(DB_LOST_CHECK_STEP1_INTERVAL));
  1058. +}
  1059. +
  1060. +/**
  1061. + * ipts_init - Initialize ipts support
  1062. + * @dev: drm device
  1063. + *
  1064. + * Setup the required structures for ipts.
  1065. + */
  1066. +int ipts_init(struct drm_device *dev)
  1067. +{
  1068. + int ret = 0;
  1069. +
  1070. + pr_info("ipts: initializing ipts\n");
  1071. +
  1072. + ipts.dev = dev;
  1073. + INIT_DELAYED_WORK(&ipts.reacquire_db_work,
  1074. + reacquire_db_work_func);
  1075. +
  1076. + ret = create_ipts_context();
  1077. + if (ret)
  1078. + return -ENOMEM;
  1079. +
  1080. + ret = ipts_init_wq();
  1081. + if (ret)
  1082. + return ret;
  1083. +
  1084. + ipts.initialized = true;
  1085. + pr_info("ipts: Intel iTouch framework initialized\n");
  1086. +
  1087. + return ret;
  1088. +}
  1089. +
  1090. +void ipts_cleanup(struct drm_device *dev)
  1091. +{
  1092. + struct ipts_object *obj, *n;
  1093. +
  1094. + if (ipts.dev != dev)
  1095. + return;
  1096. +
  1097. + list_for_each_entry_safe(obj, n, &ipts.buffers.list, list) {
  1098. + struct i915_vma *vma, *vn;
  1099. +
  1100. + list_for_each_entry_safe(vma, vn, &obj->list, obj_link) {
  1101. + vma->flags &= ~I915_VMA_PIN_MASK;
  1102. + i915_vma_destroy(vma);
  1103. + }
  1104. +
  1105. + list_del(&obj->list);
  1106. +
  1107. + if (!obj->gem_obj->phys_handle)
  1108. + ipts_object_unmap(obj);
  1109. +
  1110. + ipts_object_unpin(obj);
  1111. + i915_gem_free_object(&obj->gem_obj->base);
  1112. + kfree(obj);
  1113. + }
  1114. +
  1115. + ipts_release_wq();
  1116. + destroy_ipts_context();
  1117. + cancel_delayed_work(&ipts.reacquire_db_work);
  1118. +}
  1119. diff --git a/drivers/gpu/drm/i915_legacy/intel_ipts.h b/drivers/gpu/drm/i915_legacy/intel_ipts.h
  1120. new file mode 100644
  1121. index 000000000000..67f90b72f237
  1122. --- /dev/null
  1123. +++ b/drivers/gpu/drm/i915_legacy/intel_ipts.h
  1124. @@ -0,0 +1,34 @@
  1125. +/*
  1126. + * Copyright © 2016 Intel Corporation
  1127. + *
  1128. + * Permission is hereby granted, free of charge, to any person obtaining a
  1129. + * copy of this software and associated documentation files (the "Software"),
  1130. + * to deal in the Software without restriction, including without limitation
  1131. + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  1132. + * and/or sell copies of the Software, and to permit persons to whom the
  1133. + * Software is furnished to do so, subject to the following conditions:
  1134. + *
  1135. + * The above copyright notice and this permission notice (including the next
  1136. + * paragraph) shall be included in all copies or substantial portions of the
  1137. + * Software.
  1138. + *
  1139. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  1140. + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  1141. + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  1142. + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  1143. + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  1144. + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  1145. + * IN THE SOFTWARE.
  1146. + *
  1147. + */
  1148. +#ifndef _INTEL_IPTS_H_
  1149. +#define _INTEL_IPTS_H_
  1150. +
  1151. +#include <drm/drm_device.h>
  1152. +
  1153. +int ipts_init(struct drm_device *dev);
  1154. +void ipts_cleanup(struct drm_device *dev);
  1155. +int ipts_notify_backlight_status(bool backlight_on);
  1156. +int ipts_notify_complete(void);
  1157. +
  1158. +#endif //_INTEL_IPTS_H_
  1159. diff --git a/drivers/gpu/drm/i915_legacy/intel_lrc.c b/drivers/gpu/drm/i915_legacy/intel_lrc.c
  1160. index 11e5a86610bf..4adf38cad6da 100644
  1161. --- a/drivers/gpu/drm/i915_legacy/intel_lrc.c
  1162. +++ b/drivers/gpu/drm/i915_legacy/intel_lrc.c
  1163. @@ -166,8 +166,8 @@
  1164. #define ACTIVE_PRIORITY (I915_PRIORITY_NOSEMAPHORE)
  1165. -static int execlists_context_deferred_alloc(struct intel_context *ce,
  1166. - struct intel_engine_cs *engine);
  1167. +int execlists_context_deferred_alloc(struct intel_context *ce,
  1168. + struct intel_engine_cs *engine);
  1169. static void execlists_init_reg_state(u32 *reg_state,
  1170. struct intel_context *ce,
  1171. struct intel_engine_cs *engine,
  1172. @@ -1183,7 +1183,7 @@ static void __context_unpin(struct i915_vma *vma)
  1173. __i915_vma_unpin(vma);
  1174. }
  1175. -static void execlists_context_unpin(struct intel_context *ce)
  1176. +void execlists_context_unpin(struct intel_context *ce)
  1177. {
  1178. struct intel_engine_cs *engine;
  1179. @@ -1285,7 +1285,7 @@ __execlists_context_pin(struct intel_context *ce,
  1180. return ret;
  1181. }
  1182. -static int execlists_context_pin(struct intel_context *ce)
  1183. +int execlists_context_pin(struct intel_context *ce)
  1184. {
  1185. return __execlists_context_pin(ce, ce->engine);
  1186. }
  1187. @@ -2520,6 +2520,9 @@ int logical_render_ring_init(struct intel_engine_cs *engine)
  1188. engine->emit_flush = gen8_emit_flush_render;
  1189. engine->emit_fini_breadcrumb = gen8_emit_fini_breadcrumb_rcs;
  1190. + engine->irq_keep_mask |= GT_RENDER_PIPECTL_NOTIFY_INTERRUPT
  1191. + << GEN8_RCS_IRQ_SHIFT;
  1192. +
  1193. ret = logical_ring_init(engine);
  1194. if (ret)
  1195. return ret;
  1196. @@ -2881,8 +2884,8 @@ static struct i915_timeline *get_timeline(struct i915_gem_context *ctx)
  1197. return i915_timeline_create(ctx->i915, NULL);
  1198. }
  1199. -static int execlists_context_deferred_alloc(struct intel_context *ce,
  1200. - struct intel_engine_cs *engine)
  1201. +int execlists_context_deferred_alloc(struct intel_context *ce,
  1202. + struct intel_engine_cs *engine)
  1203. {
  1204. struct drm_i915_gem_object *ctx_obj;
  1205. struct i915_vma *vma;
  1206. diff --git a/drivers/gpu/drm/i915_legacy/intel_lrc.h b/drivers/gpu/drm/i915_legacy/intel_lrc.h
  1207. index 84aa230ea27b..0e8008eb0f3a 100644
  1208. --- a/drivers/gpu/drm/i915_legacy/intel_lrc.h
  1209. +++ b/drivers/gpu/drm/i915_legacy/intel_lrc.h
  1210. @@ -115,6 +115,12 @@ void intel_execlists_show_requests(struct intel_engine_cs *engine,
  1211. const char *prefix),
  1212. unsigned int max);
  1213. +int execlists_context_pin(struct intel_context *ce);
  1214. +void execlists_context_unpin(struct intel_context *ce);
  1215. +int execlists_context_deferred_alloc(struct intel_context *ce,
  1216. + struct intel_engine_cs *engine);
  1217. +
  1218. +
  1219. u32 gen8_make_rpcs(struct drm_i915_private *i915, struct intel_sseu *ctx_sseu);
  1220. #endif /* _INTEL_LRC_H_ */
  1221. diff --git a/drivers/gpu/drm/i915_legacy/intel_panel.c b/drivers/gpu/drm/i915_legacy/intel_panel.c
  1222. index 4ab4ce6569e7..f191292388ef 100644
  1223. --- a/drivers/gpu/drm/i915_legacy/intel_panel.c
  1224. +++ b/drivers/gpu/drm/i915_legacy/intel_panel.c
  1225. @@ -37,6 +37,7 @@
  1226. #include "intel_connector.h"
  1227. #include "intel_drv.h"
  1228. #include "intel_panel.h"
  1229. +#include "intel_ipts.h"
  1230. #define CRC_PMIC_PWM_PERIOD_NS 21333
  1231. @@ -730,6 +731,9 @@ static void lpt_disable_backlight(const struct drm_connector_state *old_conn_sta
  1232. struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
  1233. u32 tmp;
  1234. + if (INTEL_GEN(dev_priv) >= 9 && i915_modparams.enable_guc && i915_modparams.enable_ipts)
  1235. + ipts_notify_backlight_status(false);
  1236. +
  1237. intel_panel_actually_set_backlight(old_conn_state, 0);
  1238. /*
  1239. @@ -917,6 +921,9 @@ static void lpt_enable_backlight(const struct intel_crtc_state *crtc_state,
  1240. /* This won't stick until the above enable. */
  1241. intel_panel_actually_set_backlight(conn_state, panel->backlight.level);
  1242. +
  1243. + if (INTEL_GEN(dev_priv) >= 9 && i915_modparams.enable_guc && i915_modparams.enable_ipts)
  1244. + ipts_notify_backlight_status(true);
  1245. }
  1246. static void pch_enable_backlight(const struct intel_crtc_state *crtc_state,
  1247. diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
  1248. index 16900357afc2..b44910a839e8 100644
  1249. --- a/drivers/misc/Kconfig
  1250. +++ b/drivers/misc/Kconfig
  1251. @@ -495,6 +495,7 @@ source "drivers/misc/ti-st/Kconfig"
  1252. source "drivers/misc/lis3lv02d/Kconfig"
  1253. source "drivers/misc/altera-stapl/Kconfig"
  1254. source "drivers/misc/mei/Kconfig"
  1255. +source "drivers/misc/ipts/Kconfig"
  1256. source "drivers/misc/vmw_vmci/Kconfig"
  1257. source "drivers/misc/mic/Kconfig"
  1258. source "drivers/misc/genwqe/Kconfig"
  1259. diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
  1260. index abd8ae249746..40c8683b4ce6 100644
  1261. --- a/drivers/misc/Makefile
  1262. +++ b/drivers/misc/Makefile
  1263. @@ -44,6 +44,7 @@ obj-y += ti-st/
  1264. obj-y += lis3lv02d/
  1265. obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/
  1266. obj-$(CONFIG_INTEL_MEI) += mei/
  1267. +obj-$(CONFIG_INTEL_IPTS) += ipts/
  1268. obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/
  1269. obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o
  1270. obj-$(CONFIG_SRAM) += sram.o
  1271. diff --git a/drivers/misc/ipts/Kconfig b/drivers/misc/ipts/Kconfig
  1272. new file mode 100644
  1273. index 000000000000..900d2c58ca74
  1274. --- /dev/null
  1275. +++ b/drivers/misc/ipts/Kconfig
  1276. @@ -0,0 +1,12 @@
  1277. +# SPDX-License-Identifier: GPL-2.0-or-later
  1278. +config INTEL_IPTS
  1279. + tristate "Intel Precise Touch & Stylus"
  1280. + select INTEL_MEI
  1281. + depends on X86 && PCI && HID && DRM_I915
  1282. + help
  1283. + Intel Precise Touch & Stylus support
  1284. + Supported SoCs:
  1285. + Intel Skylake
  1286. + Intel Kabylake
  1287. +
  1288. +source "drivers/misc/ipts/companion/Kconfig"
  1289. diff --git a/drivers/misc/ipts/Makefile b/drivers/misc/ipts/Makefile
  1290. new file mode 100644
  1291. index 000000000000..bb3982f48afc
  1292. --- /dev/null
  1293. +++ b/drivers/misc/ipts/Makefile
  1294. @@ -0,0 +1,19 @@
  1295. +# SPDX-License-Identifier: GPL-2.0-or-later
  1296. +#
  1297. +# Makefile - Intel Precise Touch & Stylus device driver
  1298. +# Copyright (c) 2016 Intel Corporation
  1299. +#
  1300. +
  1301. +obj-$(CONFIG_INTEL_IPTS)+= intel-ipts.o
  1302. +intel-ipts-objs += companion.o
  1303. +intel-ipts-objs += ipts.o
  1304. +intel-ipts-objs += mei.o
  1305. +intel-ipts-objs += hid.o
  1306. +intel-ipts-objs += msg-handler.o
  1307. +intel-ipts-objs += kernel.o
  1308. +intel-ipts-objs += params.o
  1309. +intel-ipts-objs += resource.o
  1310. +intel-ipts-objs += gfx.o
  1311. +intel-ipts-$(CONFIG_DEBUG_FS) += dbgfs.o
  1312. +
  1313. +obj-y += companion/
  1314. diff --git a/drivers/misc/ipts/companion.c b/drivers/misc/ipts/companion.c
  1315. new file mode 100644
  1316. index 000000000000..c8199d8be5d6
  1317. --- /dev/null
  1318. +++ b/drivers/misc/ipts/companion.c
  1319. @@ -0,0 +1,230 @@
  1320. +// SPDX-License-Identifier: GPL-2.0-or-later
  1321. +/*
  1322. + *
  1323. + * Intel Precise Touch & Stylus
  1324. + * Copyright (c) 2016 Intel Corporation
  1325. + *
  1326. + */
  1327. +
  1328. +#include <linux/firmware.h>
  1329. +#include <linux/ipts.h>
  1330. +#include <linux/ipts-binary.h>
  1331. +#include <linux/ipts-companion.h>
  1332. +#include <linux/mutex.h>
  1333. +
  1334. +#include "companion.h"
  1335. +#include "ipts.h"
  1336. +#include "params.h"
  1337. +
  1338. +#define IPTS_FW_PATH_FMT "intel/ipts/%s"
  1339. +#define IPTS_FW_CONFIG_FILE "ipts_fw_config.bin"
  1340. +
  1341. +struct ipts_companion *ipts_companion;
  1342. +DEFINE_MUTEX(ipts_companion_lock);
  1343. +
  1344. +bool ipts_companion_available(void)
  1345. +{
  1346. + bool ret;
  1347. +
  1348. + mutex_lock(&ipts_companion_lock);
  1349. +
  1350. + ret = ipts_companion != NULL;
  1351. +
  1352. + mutex_unlock(&ipts_companion_lock);
  1353. +
  1354. + return ret;
  1355. +}
  1356. +
  1357. +/*
  1358. + * General purpose API for adding or removing a companion driver
  1359. + * A companion driver is a driver that implements hardware specific
  1360. + * behaviour into IPTS, so it doesn't have to be hardcoded into the
  1361. + * main driver. All requests to the companion driver should be wrapped,
  1362. + * with a fallback in case a companion driver cannot be found.
  1363. + */
  1364. +
  1365. +int ipts_add_companion(struct ipts_companion *companion)
  1366. +{
  1367. + int ret;
  1368. +
  1369. + // Make sure that access to the companion is synchronized
  1370. + mutex_lock(&ipts_companion_lock);
  1371. +
  1372. + if (ipts_companion == NULL) {
  1373. + ret = 0;
  1374. + ipts_companion = companion;
  1375. + } else {
  1376. + ret = -EBUSY;
  1377. + }
  1378. +
  1379. + mutex_unlock(&ipts_companion_lock);
  1380. +
  1381. + return ret;
  1382. +}
  1383. +EXPORT_SYMBOL_GPL(ipts_add_companion);
  1384. +
  1385. +int ipts_remove_companion(struct ipts_companion *companion)
  1386. +{
  1387. + int ret;
  1388. +
  1389. + // Make sure that access to the companion is synchronized
  1390. + mutex_lock(&ipts_companion_lock);
  1391. +
  1392. + if (ipts_companion != NULL && companion != NULL &&
  1393. + ipts_companion->name != companion->name) {
  1394. + ret = -EPERM;
  1395. + } else {
  1396. + ret = 0;
  1397. + ipts_companion = NULL;
  1398. + }
  1399. +
  1400. + mutex_unlock(&ipts_companion_lock);
  1401. + return ret;
  1402. +}
  1403. +EXPORT_SYMBOL_GPL(ipts_remove_companion);
  1404. +
  1405. +/*
  1406. + * Utility functions for IPTS. These functions replace codepaths in the IPTS
  1407. + * driver, and redirect them to the companion driver, if one was found.
  1408. + * Otherwise the legacy code gets executed as a fallback.
  1409. + */
  1410. +
  1411. +int ipts_request_firmware(const struct firmware **fw, const char *name,
  1412. + struct device *device)
  1413. +{
  1414. + int ret = 0;
  1415. + char fw_path[MAX_IOCL_FILE_PATH_LEN];
  1416. +
  1417. + // Make sure that access to the companion is synchronized
  1418. + mutex_lock(&ipts_companion_lock);
  1419. +
  1420. + // Check if a companion was registered. If not, skip
  1421. + // forward and try to load the firmware from the legacy path
  1422. + if (ipts_companion == NULL || ipts_modparams.ignore_companion)
  1423. + goto request_firmware_fallback;
  1424. +
  1425. + ret = ipts_companion->firmware_request(ipts_companion, fw,
  1426. + name, device);
  1427. + if (!ret)
  1428. + goto request_firmware_return;
  1429. +
  1430. +request_firmware_fallback:
  1431. +
  1432. + // If fallback loading for firmware was disabled, abort.
  1433. + // Return -ENOENT as no firmware file was found.
  1434. + if (ipts_modparams.ignore_fw_fallback) {
  1435. + ret = -ENOENT;
  1436. + goto request_firmware_return;
  1437. + }
  1438. +
  1439. + // No firmware was found by the companion driver, try the generic path.
  1440. + snprintf(fw_path, MAX_IOCL_FILE_PATH_LEN, IPTS_FW_PATH_FMT, name);
  1441. + ret = request_firmware(fw, fw_path, device);
  1442. +
  1443. +request_firmware_return:
  1444. +
  1445. + mutex_unlock(&ipts_companion_lock);
  1446. +
  1447. + return ret;
  1448. +}
  1449. +
  1450. +static struct ipts_bin_fw_list *ipts_alloc_fw_list(
  1451. + struct ipts_bin_fw_info **fw)
  1452. +{
  1453. + int size, len, i, j;
  1454. + struct ipts_bin_fw_list *fw_list;
  1455. + char *itr;
  1456. +
  1457. + // Figure out the amount of firmware files inside of the array
  1458. + len = 0;
  1459. + while (fw[len] != NULL)
  1460. + len++;
  1461. +
  1462. + // Determine the size that the final list will need in memory
  1463. + size = sizeof(struct ipts_bin_fw_list);
  1464. + for (i = 0; i < len; i++) {
  1465. + size += sizeof(struct ipts_bin_fw_info);
  1466. + size += sizeof(struct ipts_bin_data_file_info) *
  1467. + fw[i]->num_of_data_files;
  1468. + }
  1469. +
  1470. + fw_list = kmalloc(size, GFP_KERNEL);
  1471. + fw_list->num_of_fws = len;
  1472. +
  1473. + itr = (char *)fw_list->fw_info;
  1474. + for (i = 0; i < len; i++) {
  1475. + *(struct ipts_bin_fw_info *)itr = *fw[i];
  1476. +
  1477. + itr += sizeof(struct ipts_bin_fw_info);
  1478. +
  1479. + for (j = 0; j < fw[i]->num_of_data_files; j++) {
  1480. + *(struct ipts_bin_data_file_info *)itr =
  1481. + fw[i]->data_file[j];
  1482. +
  1483. + itr += sizeof(struct ipts_bin_data_file_info);
  1484. + }
  1485. + }
  1486. +
  1487. + return fw_list;
  1488. +}
  1489. +
  1490. +int ipts_request_firmware_config(struct ipts_info *ipts,
  1491. + struct ipts_bin_fw_list **cfg)
  1492. +{
  1493. + int ret;
  1494. + const struct firmware *config_fw = NULL;
  1495. +
  1496. + // Make sure that access to the companion is synchronized
  1497. + mutex_lock(&ipts_companion_lock);
  1498. +
  1499. + // Check if a companion was registered. If not, skip
  1500. + // forward and try to load the firmware config from a file
  1501. + if (ipts_modparams.ignore_companion || ipts_companion == NULL) {
  1502. + mutex_unlock(&ipts_companion_lock);
  1503. + goto config_fallback;
  1504. + }
  1505. +
  1506. + if (ipts_companion->firmware_config != NULL) {
  1507. + *cfg = ipts_alloc_fw_list(ipts_companion->firmware_config);
  1508. + mutex_unlock(&ipts_companion_lock);
  1509. + return 0;
  1510. + }
  1511. +
  1512. +config_fallback:
  1513. +
  1514. + // If fallback loading for the firmware config was disabled, abort.
  1515. + // Return -ENOENT as no config file was found.
  1516. + if (ipts_modparams.ignore_config_fallback)
  1517. + return -ENOENT;
  1518. +
  1519. + // No firmware config was found by the companion driver,
  1520. + // try loading it from a file now
  1521. + ret = ipts_request_firmware(&config_fw, IPTS_FW_CONFIG_FILE,
  1522. + &ipts->cldev->dev);
  1523. + if (!ret)
  1524. + *cfg = (struct ipts_bin_fw_list *)config_fw->data;
  1525. + else
  1526. + release_firmware(config_fw);
  1527. +
  1528. + return ret;
  1529. +
  1530. +}
  1531. +
  1532. +unsigned int ipts_get_quirks(void)
  1533. +{
  1534. + unsigned int ret;
  1535. +
  1536. + // Make sure that access to the companion is synchronized
  1537. + mutex_lock(&ipts_companion_lock);
  1538. +
  1539. + // If the companion is ignored, or doesn't exist, assume that
  1540. + // the device doesn't have any quirks
  1541. + if (ipts_modparams.ignore_companion || ipts_companion == NULL)
  1542. + ret = IPTS_QUIRK_NONE;
  1543. + else
  1544. + ret = ipts_companion->get_quirks(ipts_companion);
  1545. +
  1546. + mutex_unlock(&ipts_companion_lock);
  1547. +
  1548. + return ret;
  1549. +}
  1550. diff --git a/drivers/misc/ipts/companion.h b/drivers/misc/ipts/companion.h
  1551. new file mode 100644
  1552. index 000000000000..bb3368b41a38
  1553. --- /dev/null
  1554. +++ b/drivers/misc/ipts/companion.h
  1555. @@ -0,0 +1,26 @@
  1556. +/* SPDX-License-Identifier: GPL-2.0-or-later */
  1557. +/*
  1558. + *
  1559. + * Intel Precise Touch & Stylus
  1560. + * Copyright (c) 2016 Intel Corporation
  1561. + *
  1562. + */
  1563. +
  1564. +#ifndef _IPTS_COMPANION_H_
  1565. +#define _IPTS_COMPANION_H_
  1566. +
  1567. +#include <linux/firmware.h>
  1568. +#include <linux/ipts-binary.h>
  1569. +
  1570. +#include "ipts.h"
  1571. +
  1572. +bool ipts_companion_available(void);
  1573. +unsigned int ipts_get_quirks(void);
  1574. +
  1575. +int ipts_request_firmware(const struct firmware **fw, const char *name,
  1576. + struct device *device);
  1577. +
  1578. +int ipts_request_firmware_config(struct ipts_info *ipts,
  1579. + struct ipts_bin_fw_list **firmware_config);
  1580. +
  1581. +#endif // _IPTS_COMPANION_H_
  1582. diff --git a/drivers/misc/ipts/companion/Kconfig b/drivers/misc/ipts/companion/Kconfig
  1583. new file mode 100644
  1584. index 000000000000..ef17d9bb5242
  1585. --- /dev/null
  1586. +++ b/drivers/misc/ipts/companion/Kconfig
  1587. @@ -0,0 +1,8 @@
  1588. +# SPDX-License-Identifier: GPL-2.0-or-later
  1589. +config INTEL_IPTS_SURFACE
  1590. + tristate "IPTS companion driver for Microsoft Surface"
  1591. + depends on INTEL_IPTS && ACPI
  1592. + help
  1593. + IPTS companion driver for Microsoft Surface. This driver is
  1594. + responsible for loading firmware using surface-specific hardware IDs.
  1595. + If you have a Microsoft Surface using IPTS, select y or m here.
  1596. diff --git a/drivers/misc/ipts/companion/Makefile b/drivers/misc/ipts/companion/Makefile
  1597. new file mode 100644
  1598. index 000000000000..b37f2f59937a
  1599. --- /dev/null
  1600. +++ b/drivers/misc/ipts/companion/Makefile
  1601. @@ -0,0 +1,2 @@
  1602. +# SPDX-License-Identifier: GPL-2.0-or-later
  1603. +obj-$(CONFIG_INTEL_IPTS_SURFACE)+= ipts-surface.o
  1604. diff --git a/drivers/misc/ipts/companion/ipts-surface.c b/drivers/misc/ipts/companion/ipts-surface.c
  1605. new file mode 100644
  1606. index 000000000000..1a151538b898
  1607. --- /dev/null
  1608. +++ b/drivers/misc/ipts/companion/ipts-surface.c
  1609. @@ -0,0 +1,224 @@
  1610. +// SPDX-License-Identifier: GPL-2.0-or-later
  1611. +/*
  1612. + *
  1613. + * Intel Precise Touch & Stylus
  1614. + * Copyright (c) 2016 Intel Corporation
  1615. + * Copyright (c) 2019 Dorian Stoll
  1616. + *
  1617. + */
  1618. +
  1619. +#include <linux/acpi.h>
  1620. +#include <linux/firmware.h>
  1621. +#include <linux/ipts.h>
  1622. +#include <linux/ipts-companion.h>
  1623. +#include <linux/module.h>
  1624. +#include <linux/platform_device.h>
  1625. +
  1626. +#define IPTS_SURFACE_FW_PATH_FMT "intel/ipts/%s/%s"
  1627. +
  1628. +/*
  1629. + * checkpatch complains about this and wants it wrapped with do { } while(0);
  1630. + * Since this would absolutely not work, just ignore checkpatch in this case.
  1631. + */
  1632. +#define IPTS_SURFACE_FIRMWARE(X) \
  1633. + MODULE_FIRMWARE("intel/ipts/" X "/config.bin"); \
  1634. + MODULE_FIRMWARE("intel/ipts/" X "/intel_desc.bin"); \
  1635. + MODULE_FIRMWARE("intel/ipts/" X "/vendor_desc.bin"); \
  1636. + MODULE_FIRMWARE("intel/ipts/" X "/vendor_kernel.bin")
  1637. +
  1638. +struct ipts_surface_data {
  1639. + const char *hid;
  1640. + unsigned int quirks;
  1641. +};
  1642. +
  1643. +// Surface Book 1 / Surface Studio
  1644. +static const struct ipts_surface_data ipts_surface_mshw0076 = {
  1645. + .hid = "MSHW0076",
  1646. + .quirks = IPTS_QUIRK_NO_FEEDBACK,
  1647. +};
  1648. +
  1649. +// Surface Pro 4
  1650. +static const struct ipts_surface_data ipts_surface_mshw0078 = {
  1651. + .hid = "MSHW0078",
  1652. + .quirks = IPTS_QUIRK_NO_FEEDBACK,
  1653. +};
  1654. +
  1655. +// Surface Laptop 1 / 2
  1656. +static const struct ipts_surface_data ipts_surface_mshw0079 = {
  1657. + .hid = "MSHW0079",
  1658. + .quirks = IPTS_QUIRK_NONE,
  1659. +};
  1660. +
  1661. +// Surface Pro 5 / 6
  1662. +static const struct ipts_surface_data ipts_surface_mshw0101 = {
  1663. + .hid = "MSHW0101",
  1664. + .quirks = IPTS_QUIRK_NONE,
  1665. +};
  1666. +
  1667. +// Surface Book 2 15"
  1668. +static const struct ipts_surface_data ipts_surface_mshw0102 = {
  1669. + .hid = "MSHW0102",
  1670. + .quirks = IPTS_QUIRK_NONE,
  1671. +};
  1672. +
  1673. +// Unknown, but firmware exists
  1674. +static const struct ipts_surface_data ipts_surface_mshw0103 = {
  1675. + .hid = "MSHW0103",
  1676. + .quirks = IPTS_QUIRK_NONE,
  1677. +};
  1678. +
  1679. +// Surface Book 2 13"
  1680. +static const struct ipts_surface_data ipts_surface_mshw0137 = {
  1681. + .hid = "MSHW0137",
  1682. + .quirks = IPTS_QUIRK_NONE,
  1683. +};
  1684. +
  1685. +/*
  1686. + * Checkpatch complains about the following lines because it sees them as
  1687. + * header files mixed with .c files. However, forward declaration is perfectly
  1688. + * fine in C, and this allows us to seperate the companion data from the
  1689. + * functions for the companion.
  1690. + */
  1691. +int ipts_surface_request_firmware(struct ipts_companion *companion,
  1692. + const struct firmware **fw, const char *name,
  1693. + struct device *device);
  1694. +
  1695. +unsigned int ipts_surface_get_quirks(struct ipts_companion *companion);
  1696. +
  1697. +static struct ipts_bin_fw_info ipts_surface_vendor_kernel = {
  1698. + .fw_name = "vendor_kernel.bin",
  1699. + .vendor_output = -1,
  1700. + .num_of_data_files = 3,
  1701. + .data_file = {
  1702. + {
  1703. + .io_buffer_type = IPTS_CONFIGURATION,
  1704. + .flags = IPTS_DATA_FILE_FLAG_NONE,
  1705. + .file_name = "config.bin",
  1706. + },
  1707. +
  1708. + // The following files are part of the config, but they don't
  1709. + // exist, and the driver never requests them.
  1710. + {
  1711. + .io_buffer_type = IPTS_CALIBRATION,
  1712. + .flags = IPTS_DATA_FILE_FLAG_NONE,
  1713. + .file_name = "calib.bin",
  1714. + },
  1715. + {
  1716. + .io_buffer_type = IPTS_FEATURE,
  1717. + .flags = IPTS_DATA_FILE_FLAG_SHARE,
  1718. + .file_name = "feature.bin",
  1719. + },
  1720. + },
  1721. +};
  1722. +
  1723. +static struct ipts_bin_fw_info *ipts_surface_fw_config[] = {
  1724. + &ipts_surface_vendor_kernel,
  1725. + NULL,
  1726. +};
  1727. +
  1728. +static struct ipts_companion ipts_surface_companion = {
  1729. + .firmware_request = &ipts_surface_request_firmware,
  1730. + .firmware_config = ipts_surface_fw_config,
  1731. + .get_quirks = &ipts_surface_get_quirks,
  1732. + .name = "ipts_surface",
  1733. +};
  1734. +
  1735. +int ipts_surface_request_firmware(struct ipts_companion *companion,
  1736. + const struct firmware **fw, const char *name,
  1737. + struct device *device)
  1738. +{
  1739. + char fw_path[MAX_IOCL_FILE_PATH_LEN];
  1740. + struct ipts_surface_data *data;
  1741. +
  1742. + if (companion == NULL || companion->data == NULL)
  1743. + return -ENOENT;
  1744. +
  1745. + data = (struct ipts_surface_data *)companion->data;
  1746. +
  1747. + snprintf(fw_path, MAX_IOCL_FILE_PATH_LEN, IPTS_SURFACE_FW_PATH_FMT,
  1748. + data->hid, name);
  1749. + return request_firmware(fw, fw_path, device);
  1750. +}
  1751. +
  1752. +unsigned int ipts_surface_get_quirks(struct ipts_companion *companion)
  1753. +{
  1754. + struct ipts_surface_data *data;
  1755. +
  1756. + // In case something went wrong, assume that the
  1757. + // device doesn't have any quirks
  1758. + if (companion == NULL || companion->data == NULL)
  1759. + return IPTS_QUIRK_NONE;
  1760. +
  1761. + data = (struct ipts_surface_data *)companion->data;
  1762. +
  1763. + return data->quirks;
  1764. +}
  1765. +
  1766. +static int ipts_surface_probe(struct platform_device *pdev)
  1767. +{
  1768. + int r;
  1769. + const struct ipts_surface_data *data =
  1770. + acpi_device_get_match_data(&pdev->dev);
  1771. +
  1772. + if (!data) {
  1773. + dev_err(&pdev->dev, "Unable to find ACPI info for device\n");
  1774. + return -ENODEV;
  1775. + }
  1776. +
  1777. + ipts_surface_companion.data = (void *)data;
  1778. +
  1779. + r = ipts_add_companion(&ipts_surface_companion);
  1780. + if (r) {
  1781. + dev_warn(&pdev->dev, "Adding IPTS companion failed: %d\n", r);
  1782. + return r;
  1783. + }
  1784. +
  1785. + return 0;
  1786. +}
  1787. +
  1788. +static int ipts_surface_remove(struct platform_device *pdev)
  1789. +{
  1790. + int r = ipts_remove_companion(&ipts_surface_companion);
  1791. +
  1792. + if (r) {
  1793. + dev_warn(&pdev->dev, "Removing IPTS companion failed: %d\n", r);
  1794. + return r;
  1795. + }
  1796. +
  1797. + return 0;
  1798. +}
  1799. +
  1800. +static const struct acpi_device_id ipts_surface_acpi_match[] = {
  1801. + { "MSHW0076", (unsigned long)&ipts_surface_mshw0076 },
  1802. + { "MSHW0078", (unsigned long)&ipts_surface_mshw0078 },
  1803. + { "MSHW0079", (unsigned long)&ipts_surface_mshw0079 },
  1804. + { "MSHW0101", (unsigned long)&ipts_surface_mshw0101 },
  1805. + { "MSHW0102", (unsigned long)&ipts_surface_mshw0102 },
  1806. + { "MSHW0103", (unsigned long)&ipts_surface_mshw0103 },
  1807. + { "MSHW0137", (unsigned long)&ipts_surface_mshw0137 },
  1808. + { },
  1809. +};
  1810. +MODULE_DEVICE_TABLE(acpi, ipts_surface_acpi_match);
  1811. +
  1812. +static struct platform_driver ipts_surface_driver = {
  1813. + .probe = ipts_surface_probe,
  1814. + .remove = ipts_surface_remove,
  1815. + .driver = {
  1816. + .name = "ipts_surface",
  1817. + .acpi_match_table = ACPI_PTR(ipts_surface_acpi_match),
  1818. + },
  1819. +};
  1820. +module_platform_driver(ipts_surface_driver);
  1821. +
  1822. +MODULE_AUTHOR("Dorian Stoll <dorian.stoll@tmsp.io>");
  1823. +MODULE_DESCRIPTION("IPTS companion driver for Microsoft Surface");
  1824. +MODULE_LICENSE("GPL v2");
  1825. +
  1826. +IPTS_SURFACE_FIRMWARE("MSHW0076");
  1827. +IPTS_SURFACE_FIRMWARE("MSHW0078");
  1828. +IPTS_SURFACE_FIRMWARE("MSHW0079");
  1829. +IPTS_SURFACE_FIRMWARE("MSHW0101");
  1830. +IPTS_SURFACE_FIRMWARE("MSHW0102");
  1831. +IPTS_SURFACE_FIRMWARE("MSHW0103");
  1832. +
  1833. +IPTS_SURFACE_FIRMWARE("MSHW0137");
  1834. diff --git a/drivers/misc/ipts/dbgfs.c b/drivers/misc/ipts/dbgfs.c
  1835. new file mode 100644
  1836. index 000000000000..fd9388de17e7
  1837. --- /dev/null
  1838. +++ b/drivers/misc/ipts/dbgfs.c
  1839. @@ -0,0 +1,277 @@
  1840. +// SPDX-License-Identifier: GPL-2.0-or-later
  1841. +/*
  1842. + *
  1843. + * Intel Precise Touch & Stylus
  1844. + * Copyright (c) 2016 Intel Corporation
  1845. + *
  1846. + */
  1847. +
  1848. +#include <linux/ctype.h>
  1849. +#include <linux/debugfs.h>
  1850. +#include <linux/uaccess.h>
  1851. +
  1852. +#include "ipts.h"
  1853. +#include "msg-handler.h"
  1854. +#include "sensor-regs.h"
  1855. +#include "state.h"
  1856. +#include "../mei/mei_dev.h"
  1857. +
  1858. +static const char ipts_status_fmt[] = "ipts state : %01d\n";
  1859. +static const char ipts_debug_fmt[] = ">> tdt : fw status : %s\n"
  1860. + ">> == Doorbell status:%x, count:%x ==\n"
  1861. + ">> == Workqueue head:%u, tail:%u ==\n";
  1862. +
  1863. +static ssize_t ipts_dbgfs_status_read(struct file *fp, char __user *ubuf,
  1864. + size_t cnt, loff_t *ppos)
  1865. +{
  1866. + struct ipts_info *ipts = fp->private_data;
  1867. + char status[256];
  1868. + int len = 0;
  1869. +
  1870. + if (cnt < sizeof(ipts_status_fmt) - 3)
  1871. + return -EINVAL;
  1872. +
  1873. + len = scnprintf(status, 256, ipts_status_fmt, ipts->state);
  1874. + if (len < 0)
  1875. + return -EIO;
  1876. +
  1877. + return simple_read_from_buffer(ubuf, cnt, ppos, status, len);
  1878. +}
  1879. +
  1880. +static const struct file_operations ipts_status_dbgfs_fops = {
  1881. + .open = simple_open,
  1882. + .read = ipts_dbgfs_status_read,
  1883. + .llseek = generic_file_llseek,
  1884. +};
  1885. +
  1886. +static ssize_t ipts_dbgfs_quiesce_io_cmd_write(struct file *fp,
  1887. + const char __user *ubuf, size_t cnt, loff_t *ppos)
  1888. +{
  1889. + struct ipts_info *ipts = fp->private_data;
  1890. + bool result;
  1891. + int rc;
  1892. +
  1893. + rc = kstrtobool_from_user(ubuf, cnt, &result);
  1894. + if (rc)
  1895. + return rc;
  1896. +
  1897. + if (!result)
  1898. + return -EINVAL;
  1899. +
  1900. + ipts_send_sensor_quiesce_io_cmd(ipts);
  1901. + return cnt;
  1902. +}
  1903. +
  1904. +static const struct file_operations ipts_quiesce_io_cmd_dbgfs_fops = {
  1905. + .open = simple_open,
  1906. + .write = ipts_dbgfs_quiesce_io_cmd_write,
  1907. + .llseek = generic_file_llseek,
  1908. +};
  1909. +
  1910. +static ssize_t ipts_dbgfs_clear_mem_window_cmd_write(struct file *fp,
  1911. + const char __user *ubuf, size_t cnt, loff_t *ppos)
  1912. +{
  1913. + struct ipts_info *ipts = fp->private_data;
  1914. + bool result;
  1915. + int rc;
  1916. +
  1917. + rc = kstrtobool_from_user(ubuf, cnt, &result);
  1918. + if (rc)
  1919. + return rc;
  1920. +
  1921. + if (!result)
  1922. + return -EINVAL;
  1923. +
  1924. + ipts_send_sensor_clear_mem_window_cmd(ipts);
  1925. +
  1926. + return cnt;
  1927. +}
  1928. +
  1929. +static const struct file_operations ipts_clear_mem_window_cmd_dbgfs_fops = {
  1930. + .open = simple_open,
  1931. + .write = ipts_dbgfs_clear_mem_window_cmd_write,
  1932. + .llseek = generic_file_llseek,
  1933. +};
  1934. +
  1935. +static ssize_t ipts_dbgfs_debug_read(struct file *fp, char __user *ubuf,
  1936. + size_t cnt, loff_t *ppos)
  1937. +{
  1938. + struct ipts_info *ipts = fp->private_data;
  1939. + char dbg_info[1024];
  1940. + int len = 0;
  1941. +
  1942. + char fw_sts_str[MEI_FW_STATUS_STR_SZ];
  1943. + u32 *db, *head, *tail;
  1944. + struct ipts_wq_info *wq_info;
  1945. +
  1946. + wq_info = &ipts->resource.wq_info;
  1947. + mei_fw_status_str(ipts->cldev->bus, fw_sts_str, MEI_FW_STATUS_STR_SZ);
  1948. +
  1949. + db = (u32 *)wq_info->db_addr;
  1950. + head = (u32 *)wq_info->wq_head_addr;
  1951. + tail = (u32 *)wq_info->wq_tail_addr;
  1952. +
  1953. + if (cnt < sizeof(ipts_debug_fmt) - 3)
  1954. + return -EINVAL;
  1955. +
  1956. + len = scnprintf(dbg_info, 1024, ipts_debug_fmt,
  1957. + fw_sts_str, *db, *(db+1), *head, *tail);
  1958. +
  1959. + if (len < 0)
  1960. + return -EIO;
  1961. +
  1962. + return simple_read_from_buffer(ubuf, cnt, ppos, dbg_info, len);
  1963. +}
  1964. +
  1965. +static const struct file_operations ipts_debug_dbgfs_fops = {
  1966. + .open = simple_open,
  1967. + .read = ipts_dbgfs_debug_read,
  1968. + .llseek = generic_file_llseek,
  1969. +};
  1970. +
  1971. +static ssize_t ipts_dbgfs_ipts_restart_write(struct file *fp,
  1972. + const char __user *ubuf, size_t cnt, loff_t *ppos)
  1973. +{
  1974. + struct ipts_info *ipts = fp->private_data;
  1975. + bool result;
  1976. + int rc;
  1977. +
  1978. + rc = kstrtobool_from_user(ubuf, cnt, &result);
  1979. + if (rc)
  1980. + return rc;
  1981. + if (!result)
  1982. + return -EINVAL;
  1983. +
  1984. + ipts_restart(ipts);
  1985. + return cnt;
  1986. +}
  1987. +
  1988. +static const struct file_operations ipts_ipts_restart_dbgfs_fops = {
  1989. + .open = simple_open,
  1990. + .write = ipts_dbgfs_ipts_restart_write,
  1991. + .llseek = generic_file_llseek,
  1992. +};
  1993. +
  1994. +static ssize_t ipts_dbgfs_ipts_stop_write(struct file *fp,
  1995. + const char __user *ubuf, size_t cnt, loff_t *ppos)
  1996. +{
  1997. + struct ipts_info *ipts = fp->private_data;
  1998. + bool result;
  1999. + int rc;
  2000. +
  2001. + rc = kstrtobool_from_user(ubuf, cnt, &result);
  2002. + if (rc)
  2003. + return rc;
  2004. +
  2005. + if (!result)
  2006. + return -EINVAL;
  2007. +
  2008. + ipts_stop(ipts);
  2009. + return cnt;
  2010. +}
  2011. +
  2012. +static const struct file_operations ipts_ipts_stop_dbgfs_fops = {
  2013. + .open = simple_open,
  2014. + .write = ipts_dbgfs_ipts_stop_write,
  2015. + .llseek = generic_file_llseek,
  2016. +};
  2017. +
  2018. +static ssize_t ipts_dbgfs_ipts_start_write(struct file *fp,
  2019. + const char __user *ubuf, size_t cnt, loff_t *ppos)
  2020. +{
  2021. + struct ipts_info *ipts = fp->private_data;
  2022. + bool result;
  2023. + int rc;
  2024. +
  2025. + rc = kstrtobool_from_user(ubuf, cnt, &result);
  2026. + if (rc)
  2027. + return rc;
  2028. +
  2029. + if (!result)
  2030. + return -EINVAL;
  2031. +
  2032. + ipts_start(ipts);
  2033. + return cnt;
  2034. +}
  2035. +
  2036. +static const struct file_operations ipts_ipts_start_dbgfs_fops = {
  2037. + .open = simple_open,
  2038. + .write = ipts_dbgfs_ipts_start_write,
  2039. + .llseek = generic_file_llseek,
  2040. +};
  2041. +
  2042. +void ipts_dbgfs_deregister(struct ipts_info *ipts)
  2043. +{
  2044. + if (!ipts->dbgfs_dir)
  2045. + return;
  2046. +
  2047. + debugfs_remove_recursive(ipts->dbgfs_dir);
  2048. + ipts->dbgfs_dir = NULL;
  2049. +}
  2050. +
  2051. +int ipts_dbgfs_register(struct ipts_info *ipts, const char *name)
  2052. +{
  2053. + struct dentry *dir, *f;
  2054. +
  2055. + dir = debugfs_create_dir(name, NULL);
  2056. + if (!dir)
  2057. + return -ENOMEM;
  2058. +
  2059. + f = debugfs_create_file("status", 0200, dir, ipts,
  2060. + &ipts_status_dbgfs_fops);
  2061. + if (!f) {
  2062. + ipts_err(ipts, "debugfs status creation failed\n");
  2063. + goto err;
  2064. + }
  2065. +
  2066. + f = debugfs_create_file("quiesce_io_cmd", 0200, dir, ipts,
  2067. + &ipts_quiesce_io_cmd_dbgfs_fops);
  2068. + if (!f) {
  2069. + ipts_err(ipts, "debugfs quiesce_io_cmd creation failed\n");
  2070. + goto err;
  2071. + }
  2072. +
  2073. + f = debugfs_create_file("clear_mem_window_cmd", 0200, dir, ipts,
  2074. + &ipts_clear_mem_window_cmd_dbgfs_fops);
  2075. + if (!f) {
  2076. + ipts_err(ipts, "debugfs clear_mem_window_cmd creation failed\n");
  2077. + goto err;
  2078. + }
  2079. +
  2080. + f = debugfs_create_file("debug", 0200, dir, ipts,
  2081. + &ipts_debug_dbgfs_fops);
  2082. + if (!f) {
  2083. + ipts_err(ipts, "debugfs debug creation failed\n");
  2084. + goto err;
  2085. + }
  2086. +
  2087. + f = debugfs_create_file("ipts_restart", 0200, dir, ipts,
  2088. + &ipts_ipts_restart_dbgfs_fops);
  2089. + if (!f) {
  2090. + ipts_err(ipts, "debugfs ipts_restart creation failed\n");
  2091. + goto err;
  2092. + }
  2093. +
  2094. + f = debugfs_create_file("ipts_stop", 0200, dir, ipts,
  2095. + &ipts_ipts_stop_dbgfs_fops);
  2096. + if (!f) {
  2097. + ipts_err(ipts, "debugfs ipts_stop creation failed\n");
  2098. + goto err;
  2099. + }
  2100. +
  2101. + f = debugfs_create_file("ipts_start", 0200, dir, ipts,
  2102. + &ipts_ipts_start_dbgfs_fops);
  2103. + if (!f) {
  2104. + ipts_err(ipts, "debugfs ipts_start creation failed\n");
  2105. + goto err;
  2106. + }
  2107. +
  2108. + ipts->dbgfs_dir = dir;
  2109. +
  2110. + return 0;
  2111. +
  2112. +err:
  2113. + ipts_dbgfs_deregister(ipts);
  2114. +
  2115. + return -ENODEV;
  2116. +}
  2117. diff --git a/drivers/misc/ipts/gfx.c b/drivers/misc/ipts/gfx.c
  2118. new file mode 100644
  2119. index 000000000000..b8900f514c75
  2120. --- /dev/null
  2121. +++ b/drivers/misc/ipts/gfx.c
  2122. @@ -0,0 +1,180 @@
  2123. +// SPDX-License-Identifier: GPL-2.0-or-later
  2124. +/*
  2125. + *
  2126. + * Intel Precise Touch & Stylus
  2127. + * Copyright (c) 2016 Intel Corporation
  2128. + *
  2129. + */
  2130. +
  2131. +#include <linux/delay.h>
  2132. +#include <linux/kthread.h>
  2133. +
  2134. +#include "ipts.h"
  2135. +#include "msg-handler.h"
  2136. +#include "params.h"
  2137. +#include "state.h"
  2138. +#include "../mei/mei_dev.h"
  2139. +
  2140. +static void gfx_processing_complete(void *data)
  2141. +{
  2142. + struct ipts_info *ipts = data;
  2143. +
  2144. + if (ipts_get_state(ipts) == IPTS_STA_RAW_DATA_STARTED) {
  2145. + schedule_work(&ipts->raw_data_work);
  2146. + return;
  2147. + }
  2148. +
  2149. + ipts_dbg(ipts, "not ready to handle gfx event\n");
  2150. +}
  2151. +
  2152. +static void notify_gfx_status(u32 status, void *data)
  2153. +{
  2154. + struct ipts_info *ipts = data;
  2155. +
  2156. + ipts->gfx_status = status;
  2157. + schedule_work(&ipts->gfx_status_work);
  2158. +}
  2159. +
  2160. +static int connect_gfx(struct ipts_info *ipts)
  2161. +{
  2162. + int ret = 0;
  2163. + struct ipts_connect connect;
  2164. +
  2165. + connect.client = ipts->cldev->dev.parent;
  2166. + connect.if_version = IPTS_INTERFACE_V1;
  2167. + connect.ipts_cb.workload_complete = gfx_processing_complete;
  2168. + connect.ipts_cb.notify_gfx_status = notify_gfx_status;
  2169. + connect.data = (void *)ipts;
  2170. +
  2171. + ret = ipts_connect(&connect);
  2172. + if (ret)
  2173. + return ret;
  2174. +
  2175. + // TODO: GFX version check
  2176. + ipts->gfx_info.gfx_handle = connect.gfx_handle;
  2177. + ipts->gfx_info.ipts_ops = connect.ipts_ops;
  2178. +
  2179. + return ret;
  2180. +}
  2181. +
  2182. +static void disconnect_gfx(struct ipts_info *ipts)
  2183. +{
  2184. + ipts_disconnect(ipts->gfx_info.gfx_handle);
  2185. +}
  2186. +
  2187. +static struct task_struct *dbg_thread;
  2188. +
  2189. +static void ipts_print_dbg_info(struct ipts_info *ipts)
  2190. +{
  2191. + char fw_sts_str[MEI_FW_STATUS_STR_SZ];
  2192. + u32 *db, *head, *tail;
  2193. + struct ipts_wq_info *wq_info;
  2194. +
  2195. + wq_info = &ipts->resource.wq_info;
  2196. +
  2197. + mei_fw_status_str(ipts->cldev->bus, fw_sts_str, MEI_FW_STATUS_STR_SZ);
  2198. + pr_info(">> tdt : fw status : %s\n", fw_sts_str);
  2199. +
  2200. + db = (u32 *)wq_info->db_addr;
  2201. + head = (u32 *)wq_info->wq_head_addr;
  2202. + tail = (u32 *)wq_info->wq_tail_addr;
  2203. +
  2204. + // Every time the ME has filled up the touch input buffer, and the GuC
  2205. + // doorbell is rang, the doorbell count will increase by one
  2206. + // The workqueue is the queue of touch events that the GuC has to
  2207. + // process. Head is the currently processed event, while tail is
  2208. + // the last one that is currently available. If head and tail are
  2209. + // not equal, this can be an indicator for GuC / GPU hang.
  2210. + pr_info(">> == Doorbell status:%x, count:%x ==\n", *db, *(db+1));
  2211. + pr_info(">> == Workqueue head:%u, tail:%u ==\n", *head, *tail);
  2212. +}
  2213. +
  2214. +static int ipts_dbg_thread(void *data)
  2215. +{
  2216. + struct ipts_info *ipts = (struct ipts_info *)data;
  2217. +
  2218. + pr_info(">> start debug thread\n");
  2219. +
  2220. + while (!kthread_should_stop()) {
  2221. + if (ipts_get_state(ipts) != IPTS_STA_RAW_DATA_STARTED) {
  2222. + pr_info("state is not IPTS_STA_RAW_DATA_STARTED : %d\n",
  2223. + ipts_get_state(ipts));
  2224. +
  2225. + msleep(5000);
  2226. + continue;
  2227. + }
  2228. +
  2229. + ipts_print_dbg_info(ipts);
  2230. + msleep(3000);
  2231. + }
  2232. +
  2233. + return 0;
  2234. +}
  2235. +
  2236. +int ipts_open_gpu(struct ipts_info *ipts)
  2237. +{
  2238. + int ret = 0;
  2239. +
  2240. + ret = connect_gfx(ipts);
  2241. + if (ret) {
  2242. + ipts_dbg(ipts, "cannot connect GPU\n");
  2243. + return ret;
  2244. + }
  2245. +
  2246. + ret = ipts->gfx_info.ipts_ops.get_wq_info(ipts->gfx_info.gfx_handle,
  2247. + &ipts->resource.wq_info);
  2248. + if (ret) {
  2249. + ipts_dbg(ipts, "error in get_wq_info\n");
  2250. + return ret;
  2251. + }
  2252. +
  2253. + if (ipts_modparams.debug_thread)
  2254. + dbg_thread = kthread_run(
  2255. + ipts_dbg_thread, (void *)ipts, "ipts_debug");
  2256. +
  2257. + return 0;
  2258. +}
  2259. +
  2260. +void ipts_close_gpu(struct ipts_info *ipts)
  2261. +{
  2262. + disconnect_gfx(ipts);
  2263. +
  2264. + if (ipts_modparams.debug_thread)
  2265. + kthread_stop(dbg_thread);
  2266. +}
  2267. +
  2268. +struct ipts_mapbuffer *ipts_map_buffer(struct ipts_info *ipts,
  2269. + u32 size, u32 flags)
  2270. +{
  2271. + struct ipts_mapbuffer *buf;
  2272. + u64 handle;
  2273. + int ret;
  2274. +
  2275. + buf = devm_kzalloc(&ipts->cldev->dev, sizeof(*buf), GFP_KERNEL);
  2276. + if (!buf)
  2277. + return NULL;
  2278. +
  2279. + buf->size = size;
  2280. + buf->flags = flags;
  2281. +
  2282. + handle = ipts->gfx_info.gfx_handle;
  2283. + ret = ipts->gfx_info.ipts_ops.map_buffer(handle, buf);
  2284. + if (ret) {
  2285. + devm_kfree(&ipts->cldev->dev, buf);
  2286. + return NULL;
  2287. + }
  2288. +
  2289. + return buf;
  2290. +}
  2291. +
  2292. +void ipts_unmap_buffer(struct ipts_info *ipts, struct ipts_mapbuffer *buf)
  2293. +{
  2294. + u64 handle;
  2295. +
  2296. + if (!buf)
  2297. + return;
  2298. +
  2299. + handle = ipts->gfx_info.gfx_handle;
  2300. + ipts->gfx_info.ipts_ops.unmap_buffer(handle, buf->buf_handle);
  2301. + devm_kfree(&ipts->cldev->dev, buf);
  2302. +}
  2303. diff --git a/drivers/misc/ipts/gfx.h b/drivers/misc/ipts/gfx.h
  2304. new file mode 100644
  2305. index 000000000000..2880e122e9f9
  2306. --- /dev/null
  2307. +++ b/drivers/misc/ipts/gfx.h
  2308. @@ -0,0 +1,25 @@
  2309. +/* SPDX-License-Identifier: GPL-2.0-or-later */
  2310. +/*
  2311. + *
  2312. + * Intel Precise Touch & Stylus
  2313. + * Copyright (c) 2016 Intel Corporation
  2314. + *
  2315. + */
  2316. +
  2317. +#ifndef _IPTS_GFX_H_
  2318. +#define _IPTS_GFX_H_
  2319. +
  2320. +#include <linux/ipts-gfx.h>
  2321. +
  2322. +#include "ipts.h"
  2323. +
  2324. +int ipts_open_gpu(struct ipts_info *ipts);
  2325. +void ipts_close_gpu(struct ipts_info *ipts);
  2326. +
  2327. +struct ipts_mapbuffer *ipts_map_buffer(struct ipts_info *ipts,
  2328. + u32 size, u32 flags);
  2329. +
  2330. +void ipts_unmap_buffer(struct ipts_info *ipts,
  2331. + struct ipts_mapbuffer *buf);
  2332. +
  2333. +#endif // _IPTS_GFX_H_
  2334. diff --git a/drivers/misc/ipts/hid.c b/drivers/misc/ipts/hid.c
  2335. new file mode 100644
  2336. index 000000000000..a9e7e7378145
  2337. --- /dev/null
  2338. +++ b/drivers/misc/ipts/hid.c
  2339. @@ -0,0 +1,496 @@
  2340. +// SPDX-License-Identifier: GPL-2.0-or-later
  2341. +/*
  2342. + *
  2343. + * Intel Precise Touch & Stylus
  2344. + * Copyright (c) 2016 Intel Corporation
  2345. + *
  2346. + */
  2347. +
  2348. +#include <linux/dmi.h>
  2349. +#include <linux/firmware.h>
  2350. +#include <linux/hid.h>
  2351. +#include <linux/ipts.h>
  2352. +#include <linux/module.h>
  2353. +#include <linux/vmalloc.h>
  2354. +
  2355. +#include "companion.h"
  2356. +#include "hid.h"
  2357. +#include "ipts.h"
  2358. +#include "msg-handler.h"
  2359. +#include "params.h"
  2360. +#include "resource.h"
  2361. +#include "sensor-regs.h"
  2362. +
  2363. +#define HID_DESC_INTEL "intel_desc.bin"
  2364. +#define HID_DESC_VENDOR "vendor_desc.bin"
  2365. +
  2366. +enum output_buffer_payload_type {
  2367. + OUTPUT_BUFFER_PAYLOAD_ERROR = 0,
  2368. + OUTPUT_BUFFER_PAYLOAD_HID_INPUT_REPORT,
  2369. + OUTPUT_BUFFER_PAYLOAD_HID_FEATURE_REPORT,
  2370. + OUTPUT_BUFFER_PAYLOAD_KERNEL_LOAD,
  2371. + OUTPUT_BUFFER_PAYLOAD_FEEDBACK_BUFFER
  2372. +};
  2373. +
  2374. +struct kernel_output_buffer_header {
  2375. + u16 length;
  2376. + u8 payload_type;
  2377. + u8 reserved1;
  2378. + struct touch_hid_private_data hid_private_data;
  2379. + u8 reserved2[28];
  2380. + u8 data[0];
  2381. +};
  2382. +
  2383. +struct kernel_output_payload_error {
  2384. + u16 severity;
  2385. + u16 source;
  2386. + u8 code[4];
  2387. + char string[128];
  2388. +};
  2389. +
  2390. +static int ipts_hid_get_descriptor(struct ipts_info *ipts,
  2391. + u8 **desc, int *size)
  2392. +{
  2393. + u8 *buf;
  2394. + int hid_size = 0, ret = 0;
  2395. + const struct firmware *intel_desc = NULL;
  2396. + const struct firmware *vendor_desc = NULL;
  2397. +
  2398. + ret = ipts_request_firmware(&intel_desc, HID_DESC_INTEL,
  2399. + &ipts->cldev->dev);
  2400. + if (ret)
  2401. + goto no_hid;
  2402. +
  2403. + hid_size = intel_desc->size;
  2404. +
  2405. + ret = ipts_request_firmware(&vendor_desc, HID_DESC_VENDOR,
  2406. + &ipts->cldev->dev);
  2407. + if (ret)
  2408. + ipts_dbg(ipts, "error in reading HID Vendor Descriptor\n");
  2409. + else
  2410. + hid_size += vendor_desc->size;
  2411. +
  2412. + ipts_dbg(ipts, "HID descriptor size = %d\n", hid_size);
  2413. +
  2414. + buf = vmalloc(hid_size);
  2415. + if (buf == NULL) {
  2416. + ret = -ENOMEM;
  2417. + goto no_mem;
  2418. + }
  2419. +
  2420. + memcpy(buf, intel_desc->data, intel_desc->size);
  2421. + if (vendor_desc) {
  2422. + memcpy(&buf[intel_desc->size], vendor_desc->data,
  2423. + vendor_desc->size);
  2424. + release_firmware(vendor_desc);
  2425. + }
  2426. + release_firmware(intel_desc);
  2427. +
  2428. + *desc = buf;
  2429. + *size = hid_size;
  2430. +
  2431. + return 0;
  2432. +
  2433. +no_mem:
  2434. + if (vendor_desc)
  2435. + release_firmware(vendor_desc);
  2436. +
  2437. + release_firmware(intel_desc);
  2438. +
  2439. +no_hid:
  2440. + return ret;
  2441. +}
  2442. +
  2443. +static int ipts_hid_parse(struct hid_device *hid)
  2444. +{
  2445. + struct ipts_info *ipts = hid->driver_data;
  2446. + int ret = 0, size;
  2447. + u8 *buf;
  2448. +
  2449. + ipts_dbg(ipts, "%s() start\n", __func__);
  2450. +
  2451. + ret = ipts_hid_get_descriptor(ipts, &buf, &size);
  2452. + if (ret != 0) {
  2453. + ipts_dbg(ipts, "ipts_hid_get_descriptor: %d\n",
  2454. + ret);
  2455. + return -EIO;
  2456. + }
  2457. +
  2458. + ret = hid_parse_report(hid, buf, size);
  2459. + vfree(buf);
  2460. + if (ret) {
  2461. + ipts_err(ipts, "hid_parse_report error : %d\n", ret);
  2462. + return ret;
  2463. + }
  2464. +
  2465. + ipts->hid_desc_ready = true;
  2466. +
  2467. + return 0;
  2468. +}
  2469. +
  2470. +static int ipts_hid_start(struct hid_device *hid)
  2471. +{
  2472. + return 0;
  2473. +}
  2474. +
  2475. +static void ipts_hid_stop(struct hid_device *hid)
  2476. +{
  2477. +
  2478. +}
  2479. +
  2480. +static int ipts_hid_open(struct hid_device *hid)
  2481. +{
  2482. + return 0;
  2483. +}
  2484. +
  2485. +static void ipts_hid_close(struct hid_device *hid)
  2486. +{
  2487. + struct ipts_info *ipts = hid->driver_data;
  2488. +
  2489. + ipts->hid_desc_ready = false;
  2490. +}
  2491. +
  2492. +static int ipts_hid_send_hid2me_feedback(struct ipts_info *ipts,
  2493. + u32 fb_data_type, __u8 *buf, size_t count)
  2494. +{
  2495. + struct ipts_buffer_info *fb_buf;
  2496. + struct touch_feedback_hdr *feedback;
  2497. + enum ipts_state state;
  2498. + u8 *payload;
  2499. + int header_size;
  2500. +
  2501. + header_size = sizeof(struct touch_feedback_hdr);
  2502. +
  2503. + if (count > ipts->resource.hid2me_buffer_size - header_size)
  2504. + return -EINVAL;
  2505. +
  2506. + state = ipts_get_state(ipts);
  2507. + if (state != IPTS_STA_RAW_DATA_STARTED &&
  2508. + state != IPTS_STA_HID_STARTED)
  2509. + return 0;
  2510. +
  2511. + fb_buf = ipts_get_hid2me_buffer(ipts);
  2512. + feedback = (struct touch_feedback_hdr *)fb_buf->addr;
  2513. + payload = fb_buf->addr + header_size;
  2514. + memset(feedback, 0, header_size);
  2515. +
  2516. + feedback->feedback_data_type = fb_data_type;
  2517. + feedback->feedback_cmd_type = TOUCH_FEEDBACK_CMD_TYPE_NONE;
  2518. + feedback->payload_size_bytes = count;
  2519. + feedback->buffer_id = TOUCH_HID_2_ME_BUFFER_ID;
  2520. + feedback->protocol_ver = 0;
  2521. + feedback->reserved[0] = 0xAC;
  2522. +
  2523. + // copy payload
  2524. + memcpy(payload, buf, count);
  2525. +
  2526. + ipts_send_feedback(ipts, TOUCH_HID_2_ME_BUFFER_ID, 0);
  2527. +
  2528. + return 0;
  2529. +}
  2530. +
  2531. +static int ipts_hid_raw_request(struct hid_device *hid,
  2532. + unsigned char report_number, __u8 *buf, size_t count,
  2533. + unsigned char report_type, int reqtype)
  2534. +{
  2535. + struct ipts_info *ipts = hid->driver_data;
  2536. + u32 fb_data_type;
  2537. +
  2538. + ipts_dbg(ipts, "hid raw request => report %d, request %d\n",
  2539. + (int)report_type, reqtype);
  2540. +
  2541. + if (report_type != HID_FEATURE_REPORT)
  2542. + return 0;
  2543. +
  2544. + switch (reqtype) {
  2545. + case HID_REQ_GET_REPORT:
  2546. + fb_data_type = TOUCH_FEEDBACK_DATA_TYPE_GET_FEATURES;
  2547. + break;
  2548. + case HID_REQ_SET_REPORT:
  2549. + fb_data_type = TOUCH_FEEDBACK_DATA_TYPE_SET_FEATURES;
  2550. + break;
  2551. + default:
  2552. + ipts_err(ipts, "raw request not supprted: %d\n", reqtype);
  2553. + return -EIO;
  2554. + }
  2555. +
  2556. + return ipts_hid_send_hid2me_feedback(ipts, fb_data_type, buf, count);
  2557. +}
  2558. +
  2559. +static int ipts_hid_output_report(struct hid_device *hid,
  2560. + __u8 *buf, size_t count)
  2561. +{
  2562. + struct ipts_info *ipts = hid->driver_data;
  2563. + u32 fb_data_type;
  2564. +
  2565. + ipts_dbg(ipts, "hid output report\n");
  2566. +
  2567. + fb_data_type = TOUCH_FEEDBACK_DATA_TYPE_OUTPUT_REPORT;
  2568. +
  2569. + return ipts_hid_send_hid2me_feedback(ipts, fb_data_type, buf, count);
  2570. +}
  2571. +
  2572. +static struct hid_ll_driver ipts_hid_ll_driver = {
  2573. + .parse = ipts_hid_parse,
  2574. + .start = ipts_hid_start,
  2575. + .stop = ipts_hid_stop,
  2576. + .open = ipts_hid_open,
  2577. + .close = ipts_hid_close,
  2578. + .raw_request = ipts_hid_raw_request,
  2579. + .output_report = ipts_hid_output_report,
  2580. +};
  2581. +
  2582. +int ipts_hid_init(struct ipts_info *ipts)
  2583. +{
  2584. + int ret = 0;
  2585. + struct hid_device *hid;
  2586. +
  2587. + hid = hid_allocate_device();
  2588. + if (IS_ERR(hid))
  2589. + return PTR_ERR(hid);
  2590. +
  2591. + hid->driver_data = ipts;
  2592. + hid->ll_driver = &ipts_hid_ll_driver;
  2593. + hid->dev.parent = &ipts->cldev->dev;
  2594. + hid->bus = BUS_MEI;
  2595. + hid->version = ipts->device_info.fw_rev;
  2596. + hid->vendor = ipts->device_info.vendor_id;
  2597. + hid->product = ipts->device_info.device_id;
  2598. +
  2599. + snprintf(hid->phys, sizeof(hid->phys), "heci3");
  2600. + snprintf(hid->name, sizeof(hid->name),
  2601. + "ipts %04hX:%04hX", hid->vendor, hid->product);
  2602. +
  2603. + ret = hid_add_device(hid);
  2604. + if (ret) {
  2605. + if (ret != -ENODEV)
  2606. + ipts_err(ipts, "can't add hid device: %d\n", ret);
  2607. +
  2608. + hid_destroy_device(hid);
  2609. +
  2610. + return ret;
  2611. + }
  2612. +
  2613. + ipts->hid = hid;
  2614. +
  2615. + return 0;
  2616. +}
  2617. +
  2618. +void ipts_hid_release(struct ipts_info *ipts)
  2619. +{
  2620. + if (!ipts->hid)
  2621. + return;
  2622. +
  2623. + hid_destroy_device(ipts->hid);
  2624. +}
  2625. +
  2626. +int ipts_handle_hid_data(struct ipts_info *ipts,
  2627. + struct touch_sensor_hid_ready_for_data_rsp_data *hid_rsp)
  2628. +{
  2629. + struct touch_raw_data_hdr *raw_header;
  2630. + struct ipts_buffer_info *buffer_info;
  2631. + struct touch_feedback_hdr *feedback;
  2632. + u8 *raw_data;
  2633. + int touch_data_buffer_index;
  2634. + int transaction_id;
  2635. + int ret = 0;
  2636. +
  2637. + touch_data_buffer_index = (int)hid_rsp->touch_data_buffer_index;
  2638. + buffer_info = ipts_get_touch_data_buffer_hid(ipts);
  2639. + raw_header = (struct touch_raw_data_hdr *)buffer_info->addr;
  2640. + transaction_id = raw_header->hid_private_data.transaction_id;
  2641. + raw_data = (u8 *)raw_header + sizeof(struct touch_raw_data_hdr);
  2642. +
  2643. + switch (raw_header->data_type) {
  2644. + case TOUCH_RAW_DATA_TYPE_HID_REPORT: {
  2645. + memcpy(ipts->hid_input_report, raw_data,
  2646. + raw_header->raw_data_size_bytes);
  2647. +
  2648. + ret = hid_input_report(ipts->hid, HID_INPUT_REPORT,
  2649. + (u8 *)ipts->hid_input_report,
  2650. + raw_header->raw_data_size_bytes, 1);
  2651. + if (ret)
  2652. + ipts_err(ipts, "error in hid_input_report: %d\n", ret);
  2653. +
  2654. + break;
  2655. + }
  2656. + case TOUCH_RAW_DATA_TYPE_GET_FEATURES: {
  2657. + // TODO: implement together with "get feature ioctl"
  2658. + break;
  2659. + }
  2660. + case TOUCH_RAW_DATA_TYPE_ERROR: {
  2661. + struct touch_error *touch_err = (struct touch_error *)raw_data;
  2662. +
  2663. + ipts_err(ipts, "error type: %d, me error: %x, err reg: %x\n",
  2664. + touch_err->touch_error_type,
  2665. + touch_err->touch_me_fw_error.value,
  2666. + touch_err->touch_error_register.reg_value);
  2667. +
  2668. + break;
  2669. + }
  2670. + default:
  2671. + break;
  2672. + }
  2673. +
  2674. + // send feedback data for HID mode
  2675. + buffer_info = ipts_get_feedback_buffer(ipts, touch_data_buffer_index);
  2676. + feedback = (struct touch_feedback_hdr *)buffer_info->addr;
  2677. + memset(feedback, 0, sizeof(struct touch_feedback_hdr));
  2678. + feedback->feedback_cmd_type = TOUCH_FEEDBACK_CMD_TYPE_NONE;
  2679. + feedback->payload_size_bytes = 0;
  2680. + feedback->buffer_id = touch_data_buffer_index;
  2681. + feedback->protocol_ver = 0;
  2682. + feedback->reserved[0] = 0xAC;
  2683. +
  2684. + ret = ipts_send_feedback(ipts, touch_data_buffer_index, transaction_id);
  2685. +
  2686. + return ret;
  2687. +}
  2688. +
  2689. +static int handle_outputs(struct ipts_info *ipts, int parallel_idx)
  2690. +{
  2691. + struct kernel_output_buffer_header *out_buf_hdr;
  2692. + struct ipts_buffer_info *output_buf, *fb_buf = NULL;
  2693. + u8 *input_report, *payload;
  2694. + u32 tr_id;
  2695. + int i, payload_size, ret = 0, header_size;
  2696. +
  2697. + header_size = sizeof(struct kernel_output_buffer_header);
  2698. + output_buf = ipts_get_output_buffers_by_parallel_id(ipts,
  2699. + parallel_idx);
  2700. +
  2701. + for (i = 0; i < ipts->resource.num_of_outputs; i++) {
  2702. + out_buf_hdr = (struct kernel_output_buffer_header *)
  2703. + output_buf[i].addr;
  2704. +
  2705. + if (out_buf_hdr->length < header_size)
  2706. + continue;
  2707. +
  2708. + payload_size = out_buf_hdr->length - header_size;
  2709. + payload = out_buf_hdr->data;
  2710. +
  2711. + switch (out_buf_hdr->payload_type) {
  2712. + case OUTPUT_BUFFER_PAYLOAD_HID_INPUT_REPORT: {
  2713. + input_report = ipts->hid_input_report;
  2714. + memcpy(input_report, payload, payload_size);
  2715. +
  2716. + hid_input_report(ipts->hid, HID_INPUT_REPORT,
  2717. + input_report, payload_size, 1);
  2718. +
  2719. + break;
  2720. + }
  2721. + case OUTPUT_BUFFER_PAYLOAD_HID_FEATURE_REPORT: {
  2722. + ipts_dbg(ipts, "output hid feature report\n");
  2723. + break;
  2724. + }
  2725. + case OUTPUT_BUFFER_PAYLOAD_KERNEL_LOAD: {
  2726. + ipts_dbg(ipts, "output kernel load\n");
  2727. + break;
  2728. + }
  2729. + case OUTPUT_BUFFER_PAYLOAD_FEEDBACK_BUFFER: {
  2730. + // send feedback data for raw data mode
  2731. + fb_buf = ipts_get_feedback_buffer(ipts, parallel_idx);
  2732. + tr_id = out_buf_hdr->hid_private_data.transaction_id;
  2733. +
  2734. + memcpy(fb_buf->addr, payload, payload_size);
  2735. +
  2736. + break;
  2737. + }
  2738. + case OUTPUT_BUFFER_PAYLOAD_ERROR: {
  2739. + struct kernel_output_payload_error *err_payload;
  2740. +
  2741. + if (payload_size == 0)
  2742. + break;
  2743. +
  2744. + err_payload = (struct kernel_output_payload_error *)
  2745. + payload;
  2746. +
  2747. + ipts_err(ipts, "severity: %d, source: %d ",
  2748. + err_payload->severity,
  2749. + err_payload->source);
  2750. + ipts_err(ipts, "code : %d:%d:%d:%d\nstring %s\n",
  2751. + err_payload->code[0],
  2752. + err_payload->code[1],
  2753. + err_payload->code[2],
  2754. + err_payload->code[3],
  2755. + err_payload->string);
  2756. +
  2757. + break;
  2758. + }
  2759. + default:
  2760. + ipts_err(ipts, "invalid output buffer payload\n");
  2761. + break;
  2762. + }
  2763. + }
  2764. +
  2765. + /*
  2766. + * XXX: Calling the "ipts_send_feedback" function repeatedly seems to
  2767. + * be what is causing touch to crash (found by sebanc, see the link
  2768. + * below for the comment) on some models, especially on Surface Pro 4
  2769. + * and Surface Book 1.
  2770. + * The most desirable fix could be done by raising IPTS GuC priority.
  2771. + * Until we find a better solution, use this workaround.
  2772. + *
  2773. + * The decision which devices have no_feedback enabled by default is
  2774. + * made by the companion driver. If no companion driver was loaded,
  2775. + * no_feedback is disabled and the default behaviour is used.
  2776. + *
  2777. + * Link to the comment where sebanc found this workaround:
  2778. + * https://github.com/jakeday/linux-surface/issues/374#issuecomment-508234110
  2779. + * (Touch and pen issue persists · Issue #374 · jakeday/linux-surface)
  2780. + *
  2781. + * Link to the usage from kitakar5525 who made this change:
  2782. + * https://github.com/jakeday/linux-surface/issues/374#issuecomment-517289171
  2783. + * (Touch and pen issue persists · Issue #374 · jakeday/linux-surface)
  2784. + */
  2785. + if (fb_buf) {
  2786. + // A negative value means "decide by dmi table"
  2787. + if (ipts_modparams.no_feedback < 0) {
  2788. + if (ipts_get_quirks() & IPTS_QUIRK_NO_FEEDBACK)
  2789. + ipts_modparams.no_feedback = true;
  2790. + else
  2791. + ipts_modparams.no_feedback = false;
  2792. + }
  2793. +
  2794. + if (ipts_modparams.no_feedback)
  2795. + return 0;
  2796. +
  2797. + ret = ipts_send_feedback(ipts, parallel_idx, tr_id);
  2798. + if (ret)
  2799. + return ret;
  2800. + }
  2801. +
  2802. + return 0;
  2803. +}
  2804. +
  2805. +static int handle_output_buffers(struct ipts_info *ipts,
  2806. + int cur_idx, int end_idx)
  2807. +{
  2808. + int max_num_of_buffers = ipts_get_num_of_parallel_buffers(ipts);
  2809. +
  2810. + do {
  2811. + cur_idx++; // cur_idx has last completed so starts with +1
  2812. + cur_idx %= max_num_of_buffers;
  2813. + handle_outputs(ipts, cur_idx);
  2814. + } while (cur_idx != end_idx);
  2815. +
  2816. + return 0;
  2817. +}
  2818. +
  2819. +int ipts_handle_processed_data(struct ipts_info *ipts)
  2820. +{
  2821. + int ret = 0;
  2822. + int current_buffer_idx;
  2823. + int last_buffer_idx;
  2824. +
  2825. + current_buffer_idx = *ipts->last_submitted_id;
  2826. + last_buffer_idx = ipts->last_buffer_completed;
  2827. +
  2828. + if (current_buffer_idx == last_buffer_idx)
  2829. + return 0;
  2830. +
  2831. + ipts->last_buffer_completed = current_buffer_idx;
  2832. + handle_output_buffers(ipts, last_buffer_idx, current_buffer_idx);
  2833. +
  2834. + return ret;
  2835. +}
  2836. diff --git a/drivers/misc/ipts/hid.h b/drivers/misc/ipts/hid.h
  2837. new file mode 100644
  2838. index 000000000000..c943979e0198
  2839. --- /dev/null
  2840. +++ b/drivers/misc/ipts/hid.h
  2841. @@ -0,0 +1,21 @@
  2842. +/* SPDX-License-Identifier: GPL-2.0-or-later */
  2843. +/*
  2844. + *
  2845. + * Intel Precise Touch & Stylus
  2846. + * Copyright (c) 2016 Intel Corporation
  2847. + *
  2848. + */
  2849. +
  2850. +#ifndef _IPTS_HID_H_
  2851. +#define _IPTS_HID_H_
  2852. +
  2853. +#include "ipts.h"
  2854. +
  2855. +#define BUS_MEI 0x44
  2856. +
  2857. +int ipts_hid_init(struct ipts_info *ipts);
  2858. +void ipts_hid_release(struct ipts_info *ipts);
  2859. +int ipts_handle_hid_data(struct ipts_info *ipts,
  2860. + struct touch_sensor_hid_ready_for_data_rsp_data *hid_rsp);
  2861. +
  2862. +#endif // _IPTS_HID_H_
  2863. diff --git a/drivers/misc/ipts/ipts.c b/drivers/misc/ipts/ipts.c
  2864. new file mode 100644
  2865. index 000000000000..dfafabf8dd94
  2866. --- /dev/null
  2867. +++ b/drivers/misc/ipts/ipts.c
  2868. @@ -0,0 +1,62 @@
  2869. +// SPDX-License-Identifier: GPL-2.0-or-later
  2870. +/*
  2871. + *
  2872. + * Intel Precise Touch & Stylus
  2873. + * Copyright (c) 2016 Intel Corporation
  2874. + *
  2875. + */
  2876. +
  2877. +#include <linux/device.h>
  2878. +#include <stdarg.h>
  2879. +
  2880. +#include "ipts.h"
  2881. +#include "params.h"
  2882. +
  2883. +static void ipts_printk(const char *level, const struct device *dev,
  2884. + struct va_format *vaf)
  2885. +{
  2886. + if (dev) {
  2887. + dev_printk_emit(level[1] - '0', dev, "%s %s: %pV",
  2888. + dev_driver_string(dev), dev_name(dev), vaf);
  2889. + } else {
  2890. + // checkpatch wants this to be prefixed with KERN_*, but
  2891. + // since the level is passed as a parameter, ignore it
  2892. + printk("%s(NULL device *): %pV", level, vaf);
  2893. + }
  2894. +}
  2895. +
  2896. +void ipts_info(struct ipts_info *ipts, const char *fmt, ...)
  2897. +{
  2898. + va_list args;
  2899. + struct va_format vaf;
  2900. +
  2901. + if (!ipts_modparams.debug)
  2902. + return;
  2903. +
  2904. + va_start(args, fmt);
  2905. +
  2906. + vaf.fmt = fmt;
  2907. + vaf.va = &args;
  2908. +
  2909. + ipts_printk(KERN_INFO, &ipts->cldev->dev, &vaf);
  2910. +
  2911. + va_end(args);
  2912. +}
  2913. +
  2914. +void ipts_dbg(struct ipts_info *ipts, const char *fmt, ...)
  2915. +{
  2916. + va_list args;
  2917. + struct va_format vaf;
  2918. +
  2919. + if (!ipts_modparams.debug)
  2920. + return;
  2921. +
  2922. + va_start(args, fmt);
  2923. +
  2924. + vaf.fmt = fmt;
  2925. + vaf.va = &args;
  2926. +
  2927. + ipts_printk(KERN_DEBUG, &ipts->cldev->dev, &vaf);
  2928. +
  2929. + va_end(args);
  2930. +}
  2931. diff --git a/drivers/misc/ipts/ipts.h b/drivers/misc/ipts/ipts.h
  2932. new file mode 100644
  2933. index 000000000000..32eb3ffd68a3
  2934. --- /dev/null
  2935. +++ b/drivers/misc/ipts/ipts.h
  2936. @@ -0,0 +1,172 @@
  2937. +/* SPDX-License-Identifier: GPL-2.0-or-later */
  2938. +/*
  2939. + *
  2940. + * Intel Precise Touch & Stylus
  2941. + * Copyright (c) 2016 Intel Corporation
  2942. + *
  2943. + */
  2944. +
  2945. +#ifndef _IPTS_H_
  2946. +#define _IPTS_H_
  2947. +
  2948. +#include <linux/hid.h>
  2949. +#include <linux/ipts-binary.h>
  2950. +#include <linux/ipts-gfx.h>
  2951. +#include <linux/mei_cl_bus.h>
  2952. +#include <linux/types.h>
  2953. +
  2954. +#include "mei-msgs.h"
  2955. +#include "state.h"
  2956. +
  2957. +#define HID_PARALLEL_DATA_BUFFERS TOUCH_SENSOR_MAX_DATA_BUFFERS
  2958. +
  2959. +#define IPTS_MAX_RETRY 3
  2960. +
  2961. +struct ipts_buffer_info {
  2962. + char *addr;
  2963. + dma_addr_t dma_addr;
  2964. +};
  2965. +
  2966. +struct ipts_gfx_info {
  2967. + u64 gfx_handle;
  2968. + struct ipts_ops ipts_ops;
  2969. +};
  2970. +
  2971. +struct ipts_resource {
  2972. + // ME & GFX resource
  2973. + struct ipts_buffer_info touch_data_buffer_raw
  2974. + [HID_PARALLEL_DATA_BUFFERS];
  2975. + struct ipts_buffer_info touch_data_buffer_hid;
  2976. + struct ipts_buffer_info feedback_buffer[HID_PARALLEL_DATA_BUFFERS];
  2977. + struct ipts_buffer_info hid2me_buffer;
  2978. + u32 hid2me_buffer_size;
  2979. +
  2980. + u8 wq_item_size;
  2981. + struct ipts_wq_info wq_info;
  2982. +
  2983. + // ME2HID buffer
  2984. + char *me2hid_buffer;
  2985. +
  2986. + // GFX specific resource
  2987. + struct ipts_buffer_info raw_data_mode_output_buffer
  2988. + [HID_PARALLEL_DATA_BUFFERS][MAX_NUM_OUTPUT_BUFFERS];
  2989. +
  2990. + int num_of_outputs;
  2991. + bool default_resource_ready;
  2992. + bool raw_data_resource_ready;
  2993. +};
  2994. +
  2995. +struct ipts_info {
  2996. + struct mei_cl_device *cldev;
  2997. + struct hid_device *hid;
  2998. +
  2999. + struct work_struct init_work;
  3000. + struct work_struct raw_data_work;
  3001. + struct work_struct gfx_status_work;
  3002. +
  3003. + struct task_struct *event_loop;
  3004. +
  3005. +#if IS_ENABLED(CONFIG_DEBUG_FS)
  3006. + struct dentry *dbgfs_dir;
  3007. +#endif
  3008. +
  3009. + enum ipts_state state;
  3010. +
  3011. + enum touch_sensor_mode sensor_mode;
  3012. + struct touch_sensor_get_device_info_rsp_data device_info;
  3013. + struct ipts_resource resource;
  3014. + u8 hid_input_report[HID_MAX_BUFFER_SIZE];
  3015. + int num_of_parallel_data_buffers;
  3016. + bool hid_desc_ready;
  3017. +
  3018. + int current_buffer_index;
  3019. + int last_buffer_completed;
  3020. + int *last_submitted_id;
  3021. +
  3022. + struct ipts_gfx_info gfx_info;
  3023. + u64 kernel_handle;
  3024. + int gfx_status;
  3025. + bool display_status;
  3026. +
  3027. + bool restart;
  3028. +};
  3029. +
  3030. +#if IS_ENABLED(CONFIG_DEBUG_FS)
  3031. +int ipts_dbgfs_register(struct ipts_info *ipts, const char *name);
  3032. +void ipts_dbgfs_deregister(struct ipts_info *ipts);
  3033. +#else
  3034. +static int ipts_dbgfs_register(struct ipts_info *ipts, const char *name);
  3035. +static void ipts_dbgfs_deregister(struct ipts_info *ipts);
  3036. +#endif
  3037. +
  3038. +void ipts_info(struct ipts_info *ipts, const char *fmt, ...);
  3039. +void ipts_dbg(struct ipts_info *ipts, const char *fmt, ...);
  3040. +
  3041. +// Because ipts_err is unconditional, this can stay a macro for now
  3042. +#define ipts_err(ipts, format, arg...) \
  3043. + dev_err(&ipts->cldev->dev, format, ##arg)
  3044. +
  3045. +/*
  3046. + * Inline functions
  3047. + */
  3048. +static inline void ipts_set_state(struct ipts_info *ipts,
  3049. + enum ipts_state state)
  3050. +{
  3051. + ipts->state = state;
  3052. +}
  3053. +
  3054. +static inline enum ipts_state ipts_get_state(const struct ipts_info *ipts)
  3055. +{
  3056. + return ipts->state;
  3057. +}
  3058. +
  3059. +static inline bool ipts_is_default_resource_ready(const struct ipts_info *ipts)
  3060. +{
  3061. + return ipts->resource.default_resource_ready;
  3062. +}
  3063. +
  3064. +static inline bool ipts_is_raw_data_resource_ready(const struct ipts_info *ipts)
  3065. +{
  3066. + return ipts->resource.raw_data_resource_ready;
  3067. +}
  3068. +
  3069. +static inline struct ipts_buffer_info *ipts_get_feedback_buffer(
  3070. + struct ipts_info *ipts, int buffer_idx)
  3071. +{
  3072. + return &ipts->resource.feedback_buffer[buffer_idx];
  3073. +}
  3074. +
  3075. +static inline struct ipts_buffer_info *ipts_get_touch_data_buffer_hid(
  3076. + struct ipts_info *ipts)
  3077. +{
  3078. + return &ipts->resource.touch_data_buffer_hid;
  3079. +}
  3080. +
  3081. +static inline struct ipts_buffer_info *ipts_get_output_buffers_by_parallel_id(
  3082. + struct ipts_info *ipts, int parallel_idx)
  3083. +{
  3084. + return &ipts->resource.raw_data_mode_output_buffer[parallel_idx][0];
  3085. +}
  3086. +
  3087. +static inline struct ipts_buffer_info *ipts_get_hid2me_buffer(
  3088. + struct ipts_info *ipts)
  3089. +{
  3090. + return &ipts->resource.hid2me_buffer;
  3091. +}
  3092. +
  3093. +static inline void ipts_set_wq_item_size(struct ipts_info *ipts, u8 size)
  3094. +{
  3095. + ipts->resource.wq_item_size = size;
  3096. +}
  3097. +
  3098. +static inline u8 ipts_get_wq_item_size(const struct ipts_info *ipts)
  3099. +{
  3100. + return ipts->resource.wq_item_size;
  3101. +}
  3102. +
  3103. +static inline int ipts_get_num_of_parallel_buffers(const struct ipts_info *ipts)
  3104. +{
  3105. + return ipts->num_of_parallel_data_buffers;
  3106. +}
  3107. +
  3108. +#endif // _IPTS_H_
  3109. diff --git a/drivers/misc/ipts/kernel.c b/drivers/misc/ipts/kernel.c
  3110. new file mode 100644
  3111. index 000000000000..a2c43228e2c7
  3112. --- /dev/null
  3113. +++ b/drivers/misc/ipts/kernel.c
  3114. @@ -0,0 +1,1047 @@
  3115. +// SPDX-License-Identifier: GPL-2.0-or-later
  3116. +/*
  3117. + *
  3118. + * Intel Precise Touch & Stylus
  3119. + * Copyright (c) 2016 Intel Corporation
  3120. + *
  3121. + */
  3122. +
  3123. +#include <linux/module.h>
  3124. +#include <linux/firmware.h>
  3125. +#include <linux/ipts.h>
  3126. +#include <linux/ipts-binary.h>
  3127. +#include <linux/vmalloc.h>
  3128. +
  3129. +#include "companion.h"
  3130. +#include "gfx.h"
  3131. +#include "ipts.h"
  3132. +#include "msg-handler.h"
  3133. +#include "resource.h"
  3134. +#include "state.h"
  3135. +
  3136. +#define BDW_SURFACE_BASE_ADDRESS 0x6101000e
  3137. +#define SURFACE_STATE_OFFSET_WORD 4
  3138. +#define SBA_OFFSET_BYTES 16384
  3139. +#define LASTSUBMITID_DEFAULT_VALUE -1
  3140. +
  3141. +#define IPTS_INPUT_ON ((u32)1 << IPTS_INPUT)
  3142. +#define IPTS_OUTPUT_ON ((u32)1 << IPTS_OUTPUT)
  3143. +#define IPTS_CONFIGURATION_ON ((u32)1 << IPTS_CONFIGURATION)
  3144. +#define IPTS_CALIBRATION_ON ((u32)1 << IPTS_CALIBRATION)
  3145. +#define IPTS_FEATURE_ON ((u32)1 << IPTS_FEATURE)
  3146. +
  3147. +// OpenCL kernel
  3148. +struct bin_workload {
  3149. + int cmdbuf_index;
  3150. + int iobuf_input;
  3151. + int iobuf_output[MAX_NUM_OUTPUT_BUFFERS];
  3152. +};
  3153. +
  3154. +struct bin_buffer {
  3155. + unsigned int handle;
  3156. + struct ipts_mapbuffer *buf;
  3157. +
  3158. + // only releasing vendor kernel unmaps output buffers
  3159. + bool no_unmap;
  3160. +};
  3161. +
  3162. +struct bin_alloc_info {
  3163. + struct bin_buffer *buffs;
  3164. + int num_of_allocations;
  3165. + int num_of_outputs;
  3166. +
  3167. + int num_of_buffers;
  3168. +};
  3169. +
  3170. +struct bin_guc_wq_item {
  3171. + unsigned int batch_offset;
  3172. + unsigned int size;
  3173. + char data[];
  3174. +};
  3175. +
  3176. +struct bin_kernel_info {
  3177. + struct bin_workload *wl;
  3178. + struct bin_alloc_info *alloc_info;
  3179. + struct bin_guc_wq_item *guc_wq_item;
  3180. + struct ipts_bin_bufid_patch bufid_patch;
  3181. +
  3182. + // 1: vendor, 0: postprocessing
  3183. + bool is_vendor;
  3184. +};
  3185. +
  3186. +struct bin_kernel_list {
  3187. + struct ipts_mapbuffer *bufid_buf;
  3188. + int num_of_kernels;
  3189. + struct bin_kernel_info kernels[];
  3190. +};
  3191. +
  3192. +struct bin_parse_info {
  3193. + u8 *data;
  3194. + int size;
  3195. + int parsed;
  3196. +
  3197. + struct ipts_bin_fw_info *fw_info;
  3198. +
  3199. + // only used by postprocessing
  3200. + struct bin_kernel_info *vendor_kernel;
  3201. +
  3202. + // interested vendor output index
  3203. + u32 interested_vendor_output;
  3204. +};
  3205. +
  3206. +static int bin_read_fw(struct ipts_info *ipts, const char *fw_name,
  3207. + u8 *data, int size)
  3208. +{
  3209. + const struct firmware *fw = NULL;
  3210. + int ret = 0;
  3211. +
  3212. + ret = ipts_request_firmware(&fw, fw_name, &ipts->cldev->dev);
  3213. + if (ret) {
  3214. + ipts_err(ipts, "cannot read fw %s\n", fw_name);
  3215. + return ret;
  3216. + }
  3217. +
  3218. + if (fw->size > size) {
  3219. + ipts_dbg(ipts, "too small buffer to contain fw data\n");
  3220. + ret = -EINVAL;
  3221. + } else {
  3222. + memcpy(data, fw->data, fw->size);
  3223. + }
  3224. +
  3225. + release_firmware(fw);
  3226. +
  3227. + return ret;
  3228. +}
  3229. +
  3230. +
  3231. +static struct ipts_bin_data_file_info *bin_get_data_file_info(
  3232. + struct ipts_bin_fw_info *fw_info, u32 io_buffer_type)
  3233. +{
  3234. + int i;
  3235. +
  3236. + for (i = 0; i < fw_info->num_of_data_files; i++) {
  3237. + if (fw_info->data_file[i].io_buffer_type == io_buffer_type)
  3238. + break;
  3239. + }
  3240. +
  3241. + if (i == fw_info->num_of_data_files)
  3242. + return NULL;
  3243. +
  3244. + return &fw_info->data_file[i];
  3245. +}
  3246. +
  3247. +static inline bool is_shared_data(
  3248. + const struct ipts_bin_data_file_info *data_file)
  3249. +{
  3250. + if (!data_file)
  3251. + return false;
  3252. +
  3253. + return (!!(data_file->flags & IPTS_DATA_FILE_FLAG_SHARE));
  3254. +}
  3255. +
  3256. +static inline bool is_alloc_cont_data(
  3257. + const struct ipts_bin_data_file_info *data_file)
  3258. +{
  3259. + if (!data_file)
  3260. + return false;
  3261. +
  3262. + return (!!(data_file->flags & IPTS_DATA_FILE_FLAG_ALLOC_CONTIGUOUS));
  3263. +}
  3264. +
  3265. +static inline bool is_parsing_vendor_kernel(
  3266. + const struct bin_parse_info *parse_info)
  3267. +{
  3268. + // vendor_kernel == null while loading itself
  3269. + return parse_info->vendor_kernel == NULL;
  3270. +}
  3271. +
  3272. +static int bin_read_allocation_list(struct ipts_info *ipts,
  3273. + struct bin_parse_info *parse_info,
  3274. + struct bin_alloc_info *alloc_info)
  3275. +{
  3276. + struct ipts_bin_alloc_list *alloc_list;
  3277. + int aidx, pidx, num_of_parallels, bidx, num_of_buffers;
  3278. + int parsed, size;
  3279. +
  3280. + parsed = parse_info->parsed;
  3281. + size = parse_info->size;
  3282. +
  3283. + alloc_list = (struct ipts_bin_alloc_list *)&parse_info->data[parsed];
  3284. +
  3285. + // validation check
  3286. + if (sizeof(alloc_list->num) > size - parsed)
  3287. + return -EINVAL;
  3288. +
  3289. + // read the number of aloocations
  3290. + parsed += sizeof(alloc_list->num);
  3291. +
  3292. + // validation check
  3293. + if (sizeof(alloc_list->alloc[0]) * alloc_list->num > size - parsed)
  3294. + return -EINVAL;
  3295. +
  3296. + num_of_parallels = ipts_get_num_of_parallel_buffers(ipts);
  3297. + num_of_buffers = num_of_parallels * alloc_list->num + num_of_parallels;
  3298. + alloc_info->buffs = vmalloc(sizeof(struct bin_buffer) *
  3299. + num_of_buffers);
  3300. +
  3301. + if (alloc_info->buffs == NULL)
  3302. + return -ENOMEM;
  3303. +
  3304. + memset(alloc_info->buffs, 0, sizeof(struct bin_buffer) *
  3305. + num_of_buffers);
  3306. +
  3307. + for (aidx = 0; aidx < alloc_list->num; aidx++) {
  3308. + for (pidx = 0; pidx < num_of_parallels; pidx++) {
  3309. + bidx = aidx + (pidx * alloc_list->num);
  3310. + alloc_info->buffs[bidx].handle =
  3311. + alloc_list->alloc[aidx].handle;
  3312. + }
  3313. +
  3314. + parsed += sizeof(alloc_list->alloc[0]);
  3315. + }
  3316. +
  3317. + parse_info->parsed = parsed;
  3318. + alloc_info->num_of_allocations = alloc_list->num;
  3319. + alloc_info->num_of_buffers = num_of_buffers;
  3320. +
  3321. + ipts_dbg(ipts, "number of allocations = %d, buffers = %d\n",
  3322. + alloc_info->num_of_allocations,
  3323. + alloc_info->num_of_buffers);
  3324. +
  3325. + return 0;
  3326. +}
  3327. +
  3328. +static void patch_SBA(u32 *buf_addr, u64 gpu_addr, int size)
  3329. +{
  3330. + u64 *stateBase;
  3331. + u64 SBA;
  3332. + u32 inst;
  3333. + int i;
  3334. +
  3335. + SBA = gpu_addr + SBA_OFFSET_BYTES;
  3336. +
  3337. + for (i = 0; i < size / 4; i++) {
  3338. + inst = buf_addr[i];
  3339. + if (inst == BDW_SURFACE_BASE_ADDRESS) {
  3340. + stateBase = (u64 *)&buf_addr
  3341. + [i + SURFACE_STATE_OFFSET_WORD];
  3342. + *stateBase |= SBA;
  3343. + *stateBase |= 0x01; // enable
  3344. + break;
  3345. + }
  3346. + }
  3347. +}
  3348. +
  3349. +static int bin_read_cmd_buffer(struct ipts_info *ipts,
  3350. + struct bin_parse_info *parse_info,
  3351. + struct bin_alloc_info *alloc_info, struct bin_workload *wl)
  3352. +{
  3353. + struct ipts_bin_cmdbuf *cmd;
  3354. + struct ipts_mapbuffer *buf;
  3355. + int cidx, size, parsed, pidx, num_of_parallels;
  3356. +
  3357. + size = parse_info->size;
  3358. + parsed = parse_info->parsed;
  3359. +
  3360. + cmd = (struct ipts_bin_cmdbuf *)&parse_info->data[parsed];
  3361. +
  3362. + if (sizeof(cmd->size) > size - parsed)
  3363. + return -EINVAL;
  3364. +
  3365. + parsed += sizeof(cmd->size);
  3366. + if (cmd->size > size - parsed)
  3367. + return -EINVAL;
  3368. +
  3369. + ipts_dbg(ipts, "cmd buf size = %d\n", cmd->size);
  3370. + num_of_parallels = ipts_get_num_of_parallel_buffers(ipts);
  3371. +
  3372. + // command buffers are located after the other allocations
  3373. + cidx = num_of_parallels * alloc_info->num_of_allocations;
  3374. + for (pidx = 0; pidx < num_of_parallels; pidx++) {
  3375. + buf = ipts_map_buffer(ipts, cmd->size, 0);
  3376. +
  3377. + if (buf == NULL)
  3378. + return -ENOMEM;
  3379. +
  3380. + ipts_dbg(ipts, "cmd_idx[%d] = %d, g:0x%p, c:0x%p\n", pidx,
  3381. + cidx, buf->gfx_addr, buf->cpu_addr);
  3382. +
  3383. + memcpy((void *)buf->cpu_addr, &(cmd->data[0]), cmd->size);
  3384. + patch_SBA(buf->cpu_addr, (u64)buf->gfx_addr, cmd->size);
  3385. +
  3386. + alloc_info->buffs[cidx].buf = buf;
  3387. + wl[pidx].cmdbuf_index = cidx;
  3388. + cidx++;
  3389. + }
  3390. +
  3391. + parsed += cmd->size;
  3392. + parse_info->parsed = parsed;
  3393. +
  3394. + return 0;
  3395. +}
  3396. +
  3397. +static int bin_find_alloc(struct ipts_info *ipts,
  3398. + struct bin_alloc_info *alloc_info, u32 handle)
  3399. +{
  3400. + int i;
  3401. +
  3402. + for (i = 0; i < alloc_info->num_of_allocations; i++) {
  3403. + if (alloc_info->buffs[i].handle == handle)
  3404. + return i;
  3405. + }
  3406. +
  3407. + return -1;
  3408. +}
  3409. +
  3410. +static struct ipts_mapbuffer *bin_get_vendor_kernel_output(
  3411. + struct bin_parse_info *parse_info, int pidx)
  3412. +{
  3413. + struct bin_kernel_info *vendor = parse_info->vendor_kernel;
  3414. + struct bin_alloc_info *alloc_info;
  3415. + int bidx, vidx;
  3416. +
  3417. + alloc_info = vendor->alloc_info;
  3418. + vidx = parse_info->interested_vendor_output;
  3419. +
  3420. + if (vidx >= alloc_info->num_of_outputs)
  3421. + return NULL;
  3422. +
  3423. + bidx = vendor->wl[pidx].iobuf_output[vidx];
  3424. +
  3425. + return alloc_info->buffs[bidx].buf;
  3426. +}
  3427. +
  3428. +static int bin_read_res_list(struct ipts_info *ipts,
  3429. + struct bin_parse_info *parse_info,
  3430. + struct bin_alloc_info *alloc_info, struct bin_workload *wl)
  3431. +{
  3432. + struct ipts_bin_res_list *res_list;
  3433. + struct ipts_bin_res *res;
  3434. + struct ipts_mapbuffer *buf;
  3435. + struct ipts_bin_data_file_info *data_file;
  3436. + u8 *bin_data;
  3437. + int i, size, parsed, pidx, num_of_parallels, oidx = -1;
  3438. + int bidx, num_of_alloc;
  3439. + u32 buf_size, flags, io_buf_type;
  3440. + bool initialize;
  3441. +
  3442. + parsed = parse_info->parsed;
  3443. + size = parse_info->size;
  3444. + bin_data = parse_info->data;
  3445. +
  3446. + res_list = (struct ipts_bin_res_list *)&parse_info->data[parsed];
  3447. +
  3448. + if (sizeof(res_list->num) > (size - parsed))
  3449. + return -EINVAL;
  3450. +
  3451. + parsed += sizeof(res_list->num);
  3452. + num_of_parallels = ipts_get_num_of_parallel_buffers(ipts);
  3453. +
  3454. + ipts_dbg(ipts, "number of resources %u\n", res_list->num);
  3455. +
  3456. + for (i = 0; i < res_list->num; i++) {
  3457. + struct ipts_bin_io_header *io_hdr;
  3458. +
  3459. + initialize = false;
  3460. + io_buf_type = 0;
  3461. + flags = 0;
  3462. +
  3463. + // initial data
  3464. + data_file = NULL;
  3465. +
  3466. + res = (struct ipts_bin_res *)(&(bin_data[parsed]));
  3467. + if (sizeof(res[0]) > (size - parsed))
  3468. + return -EINVAL;
  3469. +
  3470. + ipts_dbg(ipts, "Resource(%d): handle 0x%08x type %u init %u size %u alsigned %u\n",
  3471. + i, res->handle, res->type, res->initialize,
  3472. + res->size, res->aligned_size);
  3473. +
  3474. + parsed += sizeof(res[0]);
  3475. +
  3476. + if (res->initialize) {
  3477. + if (res->size > (size - parsed))
  3478. + return -EINVAL;
  3479. + parsed += res->size;
  3480. + }
  3481. +
  3482. + initialize = res->initialize;
  3483. + if (!initialize || res->size <=
  3484. + sizeof(struct ipts_bin_io_header))
  3485. + goto read_res_list_no_init;
  3486. +
  3487. + io_hdr = (struct ipts_bin_io_header *)(&res->data[0]);
  3488. +
  3489. + if (strncmp(io_hdr->str, "INTELTOUCH", 10) != 0)
  3490. + goto read_res_list_no_init;
  3491. +
  3492. + data_file = bin_get_data_file_info(parse_info->fw_info,
  3493. + (u32)io_hdr->type);
  3494. +
  3495. + switch (io_hdr->type) {
  3496. + case IPTS_INPUT: {
  3497. + ipts_dbg(ipts, "input detected\n");
  3498. + io_buf_type = IPTS_INPUT_ON;
  3499. + flags = IPTS_BUF_FLAG_CONTIGUOUS;
  3500. + break;
  3501. + }
  3502. + case IPTS_OUTPUT: {
  3503. + ipts_dbg(ipts, "output detected\n");
  3504. + io_buf_type = IPTS_OUTPUT_ON;
  3505. + oidx++;
  3506. + break;
  3507. + }
  3508. + default: {
  3509. + if ((u32)io_hdr->type > 31) {
  3510. + ipts_err(ipts, "invalid io buffer : %u\n",
  3511. + (u32)io_hdr->type);
  3512. + continue;
  3513. + }
  3514. +
  3515. + if (is_alloc_cont_data(data_file))
  3516. + flags = IPTS_BUF_FLAG_CONTIGUOUS;
  3517. +
  3518. + io_buf_type = ((u32)1 << (u32)io_hdr->type);
  3519. + ipts_dbg(ipts, "special io buffer %u\n",
  3520. + io_hdr->type);
  3521. +
  3522. + break;
  3523. + }
  3524. + }
  3525. +
  3526. + initialize = false;
  3527. +
  3528. +read_res_list_no_init:
  3529. + num_of_alloc = alloc_info->num_of_allocations;
  3530. + bidx = bin_find_alloc(ipts, alloc_info, res->handle);
  3531. +
  3532. + if (bidx == -1) {
  3533. + ipts_dbg(ipts, "cannot find alloc info\n");
  3534. + return -EINVAL;
  3535. + }
  3536. +
  3537. + for (pidx = 0; pidx < num_of_parallels; pidx++,
  3538. + bidx += num_of_alloc) {
  3539. + if (!res->aligned_size)
  3540. + continue;
  3541. +
  3542. + if (!(pidx == 0 || (io_buf_type &&
  3543. + !is_shared_data(data_file))))
  3544. + continue;
  3545. +
  3546. + buf_size = res->aligned_size;
  3547. + if (io_buf_type & IPTS_INPUT_ON) {
  3548. + buf_size = max_t(u32, buf_size,
  3549. + ipts->device_info.frame_size);
  3550. +
  3551. + wl[pidx].iobuf_input = bidx;
  3552. + } else if (io_buf_type & IPTS_OUTPUT_ON) {
  3553. + wl[pidx].iobuf_output[oidx] = bidx;
  3554. +
  3555. + if (is_parsing_vendor_kernel(parse_info) ||
  3556. + oidx == 0)
  3557. + goto read_res_list_no_inout_err;
  3558. +
  3559. + ipts_err(ipts, "postproc with >1 inout is not supported: %d\n",
  3560. + oidx);
  3561. +
  3562. + return -EINVAL;
  3563. + }
  3564. +
  3565. +read_res_list_no_inout_err:
  3566. + if (!is_parsing_vendor_kernel(parse_info) &&
  3567. + io_buf_type & IPTS_OUTPUT_ON) {
  3568. + buf = bin_get_vendor_kernel_output(
  3569. + parse_info, pidx);
  3570. +
  3571. + alloc_info->buffs[bidx].no_unmap = true;
  3572. + } else {
  3573. + buf = ipts_map_buffer(ipts, buf_size, flags);
  3574. + }
  3575. +
  3576. + if (buf == NULL) {
  3577. + ipts_dbg(ipts, "ipts_map_buffer failed\n");
  3578. + return -ENOMEM;
  3579. + }
  3580. +
  3581. + if (initialize) {
  3582. + memcpy((void *)buf->cpu_addr, &(res->data[0]),
  3583. + res->size);
  3584. + } else if (data_file && strlen(data_file->file_name)) {
  3585. + bin_read_fw(ipts, data_file->file_name,
  3586. + buf->cpu_addr, buf_size);
  3587. + } else if (is_parsing_vendor_kernel(parse_info) ||
  3588. + !(io_buf_type & IPTS_OUTPUT_ON)) {
  3589. + memset((void *)buf->cpu_addr, 0, res->size);
  3590. + }
  3591. +
  3592. + alloc_info->buffs[bidx].buf = buf;
  3593. + }
  3594. + }
  3595. +
  3596. + alloc_info->num_of_outputs = oidx + 1;
  3597. + parse_info->parsed = parsed;
  3598. +
  3599. + return 0;
  3600. +}
  3601. +
  3602. +static int bin_read_patch_list(struct ipts_info *ipts,
  3603. + struct bin_parse_info *parse_info,
  3604. + struct bin_alloc_info *alloc_info, struct bin_workload *wl)
  3605. +{
  3606. + struct ipts_bin_patch_list *patch_list;
  3607. + struct ipts_bin_patch *patch;
  3608. + struct ipts_mapbuffer *cmd = NULL;
  3609. + u8 *batch;
  3610. + int parsed, size, i, pidx, num_of_parallels, cidx, bidx;
  3611. + unsigned int gtt_offset;
  3612. +
  3613. + parsed = parse_info->parsed;
  3614. + size = parse_info->size;
  3615. + patch_list = (struct ipts_bin_patch_list *)&parse_info->data[parsed];
  3616. +
  3617. + if (sizeof(patch_list->num) > (size - parsed))
  3618. + return -EFAULT;
  3619. + parsed += sizeof(patch_list->num);
  3620. +
  3621. + num_of_parallels = ipts_get_num_of_parallel_buffers(ipts);
  3622. + patch = (struct ipts_bin_patch *)(&patch_list->patch[0]);
  3623. +
  3624. + for (i = 0; i < patch_list->num; i++) {
  3625. + if (sizeof(patch_list->patch[0]) > (size - parsed))
  3626. + return -EFAULT;
  3627. +
  3628. + for (pidx = 0; pidx < num_of_parallels; pidx++) {
  3629. + cidx = wl[pidx].cmdbuf_index;
  3630. + bidx = patch[i].index + pidx *
  3631. + alloc_info->num_of_allocations;
  3632. +
  3633. + // buffer is shared
  3634. + if (alloc_info->buffs[bidx].buf == NULL)
  3635. + bidx = patch[i].index;
  3636. +
  3637. + cmd = alloc_info->buffs[cidx].buf;
  3638. + batch = (char *)(u64)cmd->cpu_addr;
  3639. +
  3640. + gtt_offset = 0;
  3641. + if (alloc_info->buffs[bidx].buf != NULL) {
  3642. + gtt_offset = (u32)(u64)alloc_info->buffs
  3643. + [bidx].buf->gfx_addr;
  3644. + }
  3645. + gtt_offset += patch[i].alloc_offset;
  3646. +
  3647. + batch += patch[i].patch_offset;
  3648. + *(u32 *)batch = gtt_offset;
  3649. + }
  3650. +
  3651. + parsed += sizeof(patch_list->patch[0]);
  3652. + }
  3653. +
  3654. + parse_info->parsed = parsed;
  3655. +
  3656. + return 0;
  3657. +}
  3658. +
  3659. +static int bin_read_guc_wq_item(struct ipts_info *ipts,
  3660. + struct bin_parse_info *parse_info,
  3661. + struct bin_guc_wq_item **guc_wq_item)
  3662. +{
  3663. + struct ipts_bin_guc_wq_info *bin_guc_wq;
  3664. + struct bin_guc_wq_item *item;
  3665. + u8 *wi_data;
  3666. + int size, parsed, hdr_size, wi_size;
  3667. + int i, batch_offset;
  3668. +
  3669. + parsed = parse_info->parsed;
  3670. + size = parse_info->size;
  3671. + bin_guc_wq = (struct ipts_bin_guc_wq_info *)&parse_info->data[parsed];
  3672. +
  3673. + wi_size = bin_guc_wq->size;
  3674. + wi_data = bin_guc_wq->data;
  3675. + batch_offset = bin_guc_wq->batch_offset;
  3676. +
  3677. + ipts_dbg(ipts, "wi size = %d, bt offset = %d\n", wi_size, batch_offset);
  3678. +
  3679. + for (i = 0; i < wi_size / sizeof(u32); i++)
  3680. + ipts_dbg(ipts, "wi[%d] = 0x%08x\n", i, *((u32 *)wi_data + i));
  3681. +
  3682. + hdr_size = sizeof(bin_guc_wq->size) + sizeof(bin_guc_wq->batch_offset);
  3683. +
  3684. + if (hdr_size > (size - parsed))
  3685. + return -EINVAL;
  3686. +
  3687. + parsed += hdr_size;
  3688. + item = vmalloc(sizeof(struct bin_guc_wq_item) + wi_size);
  3689. +
  3690. + if (item == NULL)
  3691. + return -ENOMEM;
  3692. +
  3693. + item->size = wi_size;
  3694. + item->batch_offset = batch_offset;
  3695. + memcpy(item->data, wi_data, wi_size);
  3696. +
  3697. + *guc_wq_item = item;
  3698. +
  3699. + parsed += wi_size;
  3700. + parse_info->parsed = parsed;
  3701. +
  3702. + return 0;
  3703. +}
  3704. +
  3705. +static int bin_setup_guc_workqueue(struct ipts_info *ipts,
  3706. + struct bin_kernel_list *kernel_list)
  3707. +{
  3708. + struct bin_alloc_info *alloc_info;
  3709. + struct bin_workload *wl;
  3710. + struct bin_kernel_info *kernel;
  3711. + struct bin_buffer *bin_buf;
  3712. + u8 *wq_start, *wq_addr, *wi_data;
  3713. + int wq_size, wi_size, pidx, cidx, kidx, iter_size;
  3714. + int i, num_of_parallels, batch_offset, k_num, total_workload;
  3715. +
  3716. + wq_addr = (u8 *)ipts->resource.wq_info.wq_addr;
  3717. + wq_size = ipts->resource.wq_info.wq_size;
  3718. + num_of_parallels = ipts_get_num_of_parallel_buffers(ipts);
  3719. + total_workload = ipts_get_wq_item_size(ipts);
  3720. + k_num = kernel_list->num_of_kernels;
  3721. +
  3722. + iter_size = total_workload * num_of_parallels;
  3723. + if (wq_size % iter_size) {
  3724. + ipts_err(ipts, "wq item cannot fit into wq\n");
  3725. + return -EINVAL;
  3726. + }
  3727. +
  3728. + wq_start = wq_addr;
  3729. + for (pidx = 0; pidx < num_of_parallels; pidx++) {
  3730. + kernel = &kernel_list->kernels[0];
  3731. +
  3732. + for (kidx = 0; kidx < k_num; kidx++, kernel++) {
  3733. + wl = kernel->wl;
  3734. + alloc_info = kernel->alloc_info;
  3735. +
  3736. + batch_offset = kernel->guc_wq_item->batch_offset;
  3737. + wi_size = kernel->guc_wq_item->size;
  3738. + wi_data = &kernel->guc_wq_item->data[0];
  3739. +
  3740. + cidx = wl[pidx].cmdbuf_index;
  3741. + bin_buf = &alloc_info->buffs[cidx];
  3742. +
  3743. + // Patch the WQ Data with proper batch buffer offset
  3744. + *(u32 *)(wi_data + batch_offset) =
  3745. + (u32)(unsigned long)(bin_buf->buf->gfx_addr);
  3746. +
  3747. + memcpy(wq_addr, wi_data, wi_size);
  3748. + wq_addr += wi_size;
  3749. + }
  3750. + }
  3751. +
  3752. + for (i = 0; i < (wq_size / iter_size) - 1; i++) {
  3753. + memcpy(wq_addr, wq_start, iter_size);
  3754. + wq_addr += iter_size;
  3755. + }
  3756. +
  3757. + return 0;
  3758. +}
  3759. +
  3760. +static int bin_read_bufid_patch(struct ipts_info *ipts,
  3761. + struct bin_parse_info *parse_info,
  3762. + struct ipts_bin_bufid_patch *bufid_patch)
  3763. +{
  3764. + struct ipts_bin_bufid_patch *patch;
  3765. + int size, parsed;
  3766. +
  3767. + parsed = parse_info->parsed;
  3768. + size = parse_info->size;
  3769. + patch = (struct ipts_bin_bufid_patch *)&parse_info->data[parsed];
  3770. +
  3771. + if (sizeof(struct ipts_bin_bufid_patch) > (size - parsed)) {
  3772. + ipts_dbg(ipts, "invalid bufid info\n");
  3773. + return -EINVAL;
  3774. + }
  3775. +
  3776. + parsed += sizeof(struct ipts_bin_bufid_patch);
  3777. + parse_info->parsed = parsed;
  3778. +
  3779. + memcpy(bufid_patch, patch, sizeof(struct ipts_bin_bufid_patch));
  3780. +
  3781. + return 0;
  3782. +}
  3783. +
  3784. +static int bin_setup_bufid_buffer(struct ipts_info *ipts,
  3785. + struct bin_kernel_list *kernel_list)
  3786. +{
  3787. + struct ipts_mapbuffer *buf, *cmd_buf;
  3788. + struct bin_kernel_info *last_kernel;
  3789. + struct bin_alloc_info *alloc_info;
  3790. + struct bin_workload *wl;
  3791. + u8 *batch;
  3792. + int pidx, num_of_parallels, cidx;
  3793. + u32 mem_offset, imm_offset;
  3794. +
  3795. + buf = ipts_map_buffer(ipts, PAGE_SIZE, 0);
  3796. + if (!buf)
  3797. + return -ENOMEM;
  3798. +
  3799. + last_kernel = &kernel_list->kernels[kernel_list->num_of_kernels - 1];
  3800. +
  3801. + mem_offset = last_kernel->bufid_patch.mem_offset;
  3802. + imm_offset = last_kernel->bufid_patch.imm_offset;
  3803. + wl = last_kernel->wl;
  3804. + alloc_info = last_kernel->alloc_info;
  3805. +
  3806. + // Initialize the buffer with default value
  3807. + *((u32 *)buf->cpu_addr) = LASTSUBMITID_DEFAULT_VALUE;
  3808. + ipts->current_buffer_index = LASTSUBMITID_DEFAULT_VALUE;
  3809. + ipts->last_buffer_completed = LASTSUBMITID_DEFAULT_VALUE;
  3810. + ipts->last_submitted_id = (int *)buf->cpu_addr;
  3811. +
  3812. + num_of_parallels = ipts_get_num_of_parallel_buffers(ipts);
  3813. +
  3814. + for (pidx = 0; pidx < num_of_parallels; pidx++) {
  3815. + cidx = wl[pidx].cmdbuf_index;
  3816. + cmd_buf = alloc_info->buffs[cidx].buf;
  3817. + batch = (u8 *)(u64)cmd_buf->cpu_addr;
  3818. +
  3819. + *((u32 *)(batch + mem_offset)) = (u32)(u64)(buf->gfx_addr);
  3820. + *((u32 *)(batch + imm_offset)) = pidx;
  3821. + }
  3822. +
  3823. + kernel_list->bufid_buf = buf;
  3824. +
  3825. + return 0;
  3826. +}
  3827. +
  3828. +static void unmap_buffers(struct ipts_info *ipts,
  3829. + struct bin_alloc_info *alloc_info)
  3830. +{
  3831. + struct bin_buffer *buffs;
  3832. + int i, num_of_buffers;
  3833. +
  3834. + num_of_buffers = alloc_info->num_of_buffers;
  3835. + buffs = &alloc_info->buffs[0];
  3836. +
  3837. + for (i = 0; i < num_of_buffers; i++) {
  3838. + if (buffs[i].no_unmap != true && buffs[i].buf != NULL)
  3839. + ipts_unmap_buffer(ipts, buffs[i].buf);
  3840. + }
  3841. +}
  3842. +
  3843. +static int load_kernel(struct ipts_info *ipts,
  3844. + struct bin_parse_info *parse_info,
  3845. + struct bin_kernel_info *kernel)
  3846. +{
  3847. + struct ipts_bin_header *hdr;
  3848. + struct bin_workload *wl;
  3849. + struct bin_alloc_info *alloc_info;
  3850. + struct bin_guc_wq_item *guc_wq_item = NULL;
  3851. + struct ipts_bin_bufid_patch bufid_patch;
  3852. + int num_of_parallels, ret;
  3853. +
  3854. + num_of_parallels = ipts_get_num_of_parallel_buffers(ipts);
  3855. +
  3856. + // check header version and magic numbers
  3857. + hdr = (struct ipts_bin_header *)parse_info->data;
  3858. + if (hdr->version != IPTS_BIN_HEADER_VERSION ||
  3859. + strncmp(hdr->str, "IOCL", 4) != 0) {
  3860. + ipts_err(ipts, "binary header is not correct version = %d, ",
  3861. + hdr->version);
  3862. +
  3863. + ipts_err(ipts, "string = %c%c%c%c\n", hdr->str[0], hdr->str[1],
  3864. + hdr->str[2], hdr->str[3]);
  3865. +
  3866. + return -EINVAL;
  3867. + }
  3868. +
  3869. + parse_info->parsed = sizeof(struct ipts_bin_header);
  3870. + wl = vmalloc(sizeof(struct bin_workload) * num_of_parallels);
  3871. +
  3872. + if (wl == NULL)
  3873. + return -ENOMEM;
  3874. +
  3875. + memset(wl, 0, sizeof(struct bin_workload) * num_of_parallels);
  3876. + alloc_info = vmalloc(sizeof(struct bin_alloc_info));
  3877. +
  3878. + if (alloc_info == NULL) {
  3879. + vfree(wl);
  3880. + return -ENOMEM;
  3881. + }
  3882. +
  3883. + memset(alloc_info, 0, sizeof(struct bin_alloc_info));
  3884. +
  3885. + ipts_dbg(ipts, "kernel setup(size : %d)\n", parse_info->size);
  3886. +
  3887. + ret = bin_read_allocation_list(ipts, parse_info, alloc_info);
  3888. + if (ret) {
  3889. + ipts_dbg(ipts, "error read_allocation_list\n");
  3890. + goto setup_error;
  3891. + }
  3892. +
  3893. + ret = bin_read_cmd_buffer(ipts, parse_info, alloc_info, wl);
  3894. + if (ret) {
  3895. + ipts_dbg(ipts, "error read_cmd_buffer\n");
  3896. + goto setup_error;
  3897. + }
  3898. +
  3899. + ret = bin_read_res_list(ipts, parse_info, alloc_info, wl);
  3900. + if (ret) {
  3901. + ipts_dbg(ipts, "error read_res_list\n");
  3902. + goto setup_error;
  3903. + }
  3904. +
  3905. + ret = bin_read_patch_list(ipts, parse_info, alloc_info, wl);
  3906. + if (ret) {
  3907. + ipts_dbg(ipts, "error read_patch_list\n");
  3908. + goto setup_error;
  3909. + }
  3910. +
  3911. + ret = bin_read_guc_wq_item(ipts, parse_info, &guc_wq_item);
  3912. + if (ret) {
  3913. + ipts_dbg(ipts, "error read_guc_workqueue\n");
  3914. + goto setup_error;
  3915. + }
  3916. +
  3917. + memset(&bufid_patch, 0, sizeof(bufid_patch));
  3918. +
  3919. + ret = bin_read_bufid_patch(ipts, parse_info, &bufid_patch);
  3920. + if (ret) {
  3921. + ipts_dbg(ipts, "error read_bufid_patch\n");
  3922. + goto setup_error;
  3923. + }
  3924. +
  3925. + kernel->wl = wl;
  3926. + kernel->alloc_info = alloc_info;
  3927. + kernel->is_vendor = is_parsing_vendor_kernel(parse_info);
  3928. + kernel->guc_wq_item = guc_wq_item;
  3929. +
  3930. + memcpy(&kernel->bufid_patch, &bufid_patch, sizeof(bufid_patch));
  3931. +
  3932. + return 0;
  3933. +
  3934. +setup_error:
  3935. + vfree(guc_wq_item);
  3936. +
  3937. + unmap_buffers(ipts, alloc_info);
  3938. +
  3939. + vfree(alloc_info->buffs);
  3940. + vfree(alloc_info);
  3941. + vfree(wl);
  3942. +
  3943. + return ret;
  3944. +}
  3945. +
  3946. +void bin_setup_input_output(struct ipts_info *ipts,
  3947. + struct bin_kernel_list *kernel_list)
  3948. +{
  3949. + struct bin_kernel_info *vendor_kernel;
  3950. + struct bin_workload *wl;
  3951. + struct ipts_mapbuffer *buf;
  3952. + struct bin_alloc_info *alloc_info;
  3953. + int pidx, num_of_parallels, i, bidx;
  3954. +
  3955. + vendor_kernel = &kernel_list->kernels[0];
  3956. +
  3957. + wl = vendor_kernel->wl;
  3958. + alloc_info = vendor_kernel->alloc_info;
  3959. + ipts->resource.num_of_outputs = alloc_info->num_of_outputs;
  3960. + num_of_parallels = ipts_get_num_of_parallel_buffers(ipts);
  3961. +
  3962. + for (pidx = 0; pidx < num_of_parallels; pidx++) {
  3963. + bidx = wl[pidx].iobuf_input;
  3964. + buf = alloc_info->buffs[bidx].buf;
  3965. +
  3966. + ipts_dbg(ipts, "in_buf[%d](%d) c:%p, p:%p, g:%p\n",
  3967. + pidx, bidx, (void *)buf->cpu_addr,
  3968. + (void *)buf->phy_addr, (void *)buf->gfx_addr);
  3969. +
  3970. + ipts_set_input_buffer(ipts, pidx, buf->cpu_addr, buf->phy_addr);
  3971. +
  3972. + for (i = 0; i < alloc_info->num_of_outputs; i++) {
  3973. + bidx = wl[pidx].iobuf_output[i];
  3974. + buf = alloc_info->buffs[bidx].buf;
  3975. +
  3976. + ipts_dbg(ipts, "out_buf[%d][%d] c:%p, p:%p, g:%p\n",
  3977. + pidx, i, (void *)buf->cpu_addr,
  3978. + (void *)buf->phy_addr, (void *)buf->gfx_addr);
  3979. +
  3980. + ipts_set_output_buffer(ipts, pidx, i,
  3981. + buf->cpu_addr, buf->phy_addr);
  3982. + }
  3983. + }
  3984. +}
  3985. +
  3986. +static void unload_kernel(struct ipts_info *ipts,
  3987. + struct bin_kernel_info *kernel)
  3988. +{
  3989. + struct bin_alloc_info *alloc_info = kernel->alloc_info;
  3990. + struct bin_guc_wq_item *guc_wq_item = kernel->guc_wq_item;
  3991. +
  3992. + if (guc_wq_item)
  3993. + vfree(guc_wq_item);
  3994. +
  3995. + if (alloc_info) {
  3996. + unmap_buffers(ipts, alloc_info);
  3997. +
  3998. + vfree(alloc_info->buffs);
  3999. + vfree(alloc_info);
  4000. + }
  4001. +}
  4002. +
  4003. +static int setup_kernel(struct ipts_info *ipts,
  4004. + struct ipts_bin_fw_list *fw_list)
  4005. +{
  4006. + struct bin_kernel_list *kernel_list = NULL;
  4007. + struct bin_kernel_info *kernel = NULL;
  4008. + const struct firmware *fw = NULL;
  4009. + struct bin_workload *wl;
  4010. + struct ipts_bin_fw_info *fw_info;
  4011. + char *fw_name, *fw_data;
  4012. + struct bin_parse_info parse_info;
  4013. + int ret = 0, kidx = 0, num_of_kernels = 0;
  4014. + int vidx, total_workload = 0;
  4015. +
  4016. + num_of_kernels = fw_list->num_of_fws;
  4017. + kernel_list = vmalloc(sizeof(*kernel) *
  4018. + num_of_kernels + sizeof(*kernel_list));
  4019. +
  4020. + if (kernel_list == NULL)
  4021. + return -ENOMEM;
  4022. +
  4023. + memset(kernel_list, 0, sizeof(*kernel) *
  4024. + num_of_kernels + sizeof(*kernel_list));
  4025. +
  4026. + kernel_list->num_of_kernels = num_of_kernels;
  4027. + kernel = &kernel_list->kernels[0];
  4028. +
  4029. + fw_data = (char *)&fw_list->fw_info[0];
  4030. + for (kidx = 0; kidx < num_of_kernels; kidx++) {
  4031. + fw_info = (struct ipts_bin_fw_info *)fw_data;
  4032. + fw_name = &fw_info->fw_name[0];
  4033. + vidx = fw_info->vendor_output;
  4034. +
  4035. + ret = ipts_request_firmware(&fw, fw_name, &ipts->cldev->dev);
  4036. + if (ret) {
  4037. + ipts_err(ipts, "cannot read fw %s\n", fw_name);
  4038. + goto error_exit;
  4039. + }
  4040. +
  4041. + parse_info.data = (u8 *)fw->data;
  4042. + parse_info.size = fw->size;
  4043. + parse_info.parsed = 0;
  4044. + parse_info.fw_info = fw_info;
  4045. + parse_info.vendor_kernel = (kidx == 0) ? NULL : &kernel[0];
  4046. + parse_info.interested_vendor_output = vidx;
  4047. +
  4048. + ret = load_kernel(ipts, &parse_info, &kernel[kidx]);
  4049. + if (ret) {
  4050. + ipts_err(ipts, "do_setup_kernel error : %d\n", ret);
  4051. + release_firmware(fw);
  4052. + goto error_exit;
  4053. + }
  4054. +
  4055. + release_firmware(fw);
  4056. +
  4057. + total_workload += kernel[kidx].guc_wq_item->size;
  4058. +
  4059. + // advance to the next kernel
  4060. + fw_data += sizeof(struct ipts_bin_fw_info);
  4061. + fw_data += sizeof(struct ipts_bin_data_file_info) *
  4062. + fw_info->num_of_data_files;
  4063. + }
  4064. +
  4065. + ipts_set_wq_item_size(ipts, total_workload);
  4066. +
  4067. + ret = bin_setup_guc_workqueue(ipts, kernel_list);
  4068. + if (ret) {
  4069. + ipts_dbg(ipts, "error setup_guc_workqueue\n");
  4070. + goto error_exit;
  4071. + }
  4072. +
  4073. + ret = bin_setup_bufid_buffer(ipts, kernel_list);
  4074. + if (ret) {
  4075. + ipts_dbg(ipts, "error setup_lastbubmit_buffer\n");
  4076. + goto error_exit;
  4077. + }
  4078. +
  4079. + bin_setup_input_output(ipts, kernel_list);
  4080. +
  4081. + // workload is not needed during run-time so free them
  4082. + for (kidx = 0; kidx < num_of_kernels; kidx++) {
  4083. + wl = kernel[kidx].wl;
  4084. + vfree(wl);
  4085. + }
  4086. +
  4087. + ipts->kernel_handle = (u64)kernel_list;
  4088. +
  4089. + return 0;
  4090. +
  4091. +error_exit:
  4092. +
  4093. + for (kidx = 0; kidx < num_of_kernels; kidx++) {
  4094. + wl = kernel[kidx].wl;
  4095. + vfree(wl);
  4096. + unload_kernel(ipts, &kernel[kidx]);
  4097. + }
  4098. +
  4099. + vfree(kernel_list);
  4100. +
  4101. + return ret;
  4102. +}
  4103. +
  4104. +
  4105. +static void release_kernel(struct ipts_info *ipts)
  4106. +{
  4107. + struct bin_kernel_list *kernel_list;
  4108. + struct bin_kernel_info *kernel;
  4109. + int kidx, knum;
  4110. +
  4111. + kernel_list = (struct bin_kernel_list *)ipts->kernel_handle;
  4112. + knum = kernel_list->num_of_kernels;
  4113. + kernel = &kernel_list->kernels[0];
  4114. +
  4115. + for (kidx = 0; kidx < knum; kidx++) {
  4116. + unload_kernel(ipts, kernel);
  4117. + kernel++;
  4118. + }
  4119. +
  4120. + ipts_unmap_buffer(ipts, kernel_list->bufid_buf);
  4121. +
  4122. + vfree(kernel_list);
  4123. + ipts->kernel_handle = 0;
  4124. +}
  4125. +
  4126. +int ipts_init_kernels(struct ipts_info *ipts)
  4127. +{
  4128. + struct ipts_bin_fw_list *fw_list;
  4129. + int ret;
  4130. +
  4131. + ret = ipts_open_gpu(ipts);
  4132. + if (ret) {
  4133. + ipts_err(ipts, "open gpu error : %d\n", ret);
  4134. + return ret;
  4135. + }
  4136. +
  4137. + ret = ipts_request_firmware_config(ipts, &fw_list);
  4138. + if (ret) {
  4139. + ipts_err(ipts, "request firmware config error : %d\n", ret);
  4140. + goto close_gpu;
  4141. + }
  4142. +
  4143. + ret = setup_kernel(ipts, fw_list);
  4144. + if (ret) {
  4145. + ipts_err(ipts, "setup kernel error : %d\n", ret);
  4146. + goto close_gpu;
  4147. + }
  4148. +
  4149. + return ret;
  4150. +
  4151. +close_gpu:
  4152. + ipts_close_gpu(ipts);
  4153. +
  4154. + return ret;
  4155. +}
  4156. +
  4157. +void ipts_release_kernels(struct ipts_info *ipts)
  4158. +{
  4159. + release_kernel(ipts);
  4160. + ipts_close_gpu(ipts);
  4161. +}
  4162. diff --git a/drivers/misc/ipts/kernel.h b/drivers/misc/ipts/kernel.h
  4163. new file mode 100644
  4164. index 000000000000..7be45da01cfc
  4165. --- /dev/null
  4166. +++ b/drivers/misc/ipts/kernel.h
  4167. @@ -0,0 +1,17 @@
  4168. +/* SPDX-License-Identifier: GPL-2.0-or-later */
  4169. +/*
  4170. + *
  4171. + * Intel Precise Touch & Stylus
  4172. + * Copyright (c) 2016 Intel Corporation
  4173. + *
  4174. + */
  4175. +
  4176. +#ifndef _IPTS_KERNEL_H_
  4177. +#define _IPTS_KERNEL_H_
  4178. +
  4179. +#include "ipts.h"
  4180. +
  4181. +int ipts_init_kernels(struct ipts_info *ipts);
  4182. +void ipts_release_kernels(struct ipts_info *ipts);
  4183. +
  4184. +#endif // _IPTS_KERNEL_H_
  4185. diff --git a/drivers/misc/ipts/mei-msgs.h b/drivers/misc/ipts/mei-msgs.h
  4186. new file mode 100644
  4187. index 000000000000..4759a28dbdee
  4188. --- /dev/null
  4189. +++ b/drivers/misc/ipts/mei-msgs.h
  4190. @@ -0,0 +1,894 @@
  4191. +/* SPDX-License-Identifier: GPL-2.0-or-later */
  4192. +/*
  4193. + *
  4194. + * Intel Precise Touch & Stylus
  4195. + * Copyright (c) 2013-2016 Intel Corporation
  4196. + *
  4197. + */
  4198. +
  4199. +#ifndef _IPTS_MEI_MSGS_H_
  4200. +#define _IPTS_MEI_MSGS_H_
  4201. +
  4202. +#include <linux/build_bug.h>
  4203. +
  4204. +#include "sensor-regs.h"
  4205. +
  4206. +#pragma pack(1)
  4207. +
  4208. +// Initial protocol version
  4209. +#define TOUCH_HECI_CLIENT_PROTOCOL_VERSION 10
  4210. +
  4211. +// GUID that identifies the Touch HECI client.
  4212. +#define TOUCH_HECI_CLIENT_GUID \
  4213. + {0x3e8d0870, 0x271a, 0x4208, \
  4214. + {0x8e, 0xb5, 0x9a, 0xcb, 0x94, 0x02, 0xae, 0x04} }
  4215. +
  4216. +#define TOUCH_SENSOR_GET_DEVICE_INFO_CMD 0x00000001
  4217. +#define TOUCH_SENSOR_GET_DEVICE_INFO_RSP 0x80000001
  4218. +
  4219. +#define TOUCH_SENSOR_SET_MODE_CMD 0x00000002
  4220. +#define TOUCH_SENSOR_SET_MODE_RSP 0x80000002
  4221. +
  4222. +#define TOUCH_SENSOR_SET_MEM_WINDOW_CMD 0x00000003
  4223. +#define TOUCH_SENSOR_SET_MEM_WINDOW_RSP 0x80000003
  4224. +
  4225. +#define TOUCH_SENSOR_QUIESCE_IO_CMD 0x00000004
  4226. +#define TOUCH_SENSOR_QUIESCE_IO_RSP 0x80000004
  4227. +
  4228. +#define TOUCH_SENSOR_HID_READY_FOR_DATA_CMD 0x00000005
  4229. +#define TOUCH_SENSOR_HID_READY_FOR_DATA_RSP 0x80000005
  4230. +
  4231. +#define TOUCH_SENSOR_FEEDBACK_READY_CMD 0x00000006
  4232. +#define TOUCH_SENSOR_FEEDBACK_READY_RSP 0x80000006
  4233. +
  4234. +#define TOUCH_SENSOR_CLEAR_MEM_WINDOW_CMD 0x00000007
  4235. +#define TOUCH_SENSOR_CLEAR_MEM_WINDOW_RSP 0x80000007
  4236. +
  4237. +#define TOUCH_SENSOR_NOTIFY_DEV_READY_CMD 0x00000008
  4238. +#define TOUCH_SENSOR_NOTIFY_DEV_READY_RSP 0x80000008
  4239. +
  4240. +#define TOUCH_SENSOR_SET_POLICIES_CMD 0x00000009
  4241. +#define TOUCH_SENSOR_SET_POLICIES_RSP 0x80000009
  4242. +
  4243. +#define TOUCH_SENSOR_GET_POLICIES_CMD 0x0000000A
  4244. +#define TOUCH_SENSOR_GET_POLICIES_RSP 0x8000000A
  4245. +
  4246. +#define TOUCH_SENSOR_RESET_CMD 0x0000000B
  4247. +#define TOUCH_SENSOR_RESET_RSP 0x8000000B
  4248. +
  4249. +#define TOUCH_SENSOR_READ_ALL_REGS_CMD 0x0000000C
  4250. +#define TOUCH_SENSOR_READ_ALL_REGS_RSP 0x8000000C
  4251. +
  4252. +// ME sends this message to indicate previous command was unrecognized
  4253. +#define TOUCH_SENSOR_CMD_ERROR_RSP 0x8FFFFFFF
  4254. +
  4255. +#define TOUCH_SENSOR_MAX_DATA_BUFFERS 16
  4256. +#define TOUCH_HID_2_ME_BUFFER_ID TOUCH_SENSOR_MAX_DATA_BUFFERS
  4257. +#define TOUCH_HID_2_ME_BUFFER_SIZE_MAX 1024
  4258. +#define TOUCH_INVALID_BUFFER_ID 0xFF
  4259. +
  4260. +#define TOUCH_DEFAULT_DOZE_TIMER_SECONDS 30
  4261. +
  4262. +#define TOUCH_MSG_SIZE_MAX_BYTES \
  4263. + (MAX(sizeof(struct touch_sensor_msg_m2h), \
  4264. + sizeof(struct touch_sensor_msg_h2m)))
  4265. +
  4266. +// indicates GuC got reset and ME must re-read GuC data such as
  4267. +// TailOffset and Doorbell Cookie values
  4268. +#define TOUCH_SENSOR_QUIESCE_FLAG_GUC_RESET BIT(0)
  4269. +
  4270. +/*
  4271. + * Debug Policy bits used by TOUCH_POLICY_DATA.DebugOverride
  4272. + */
  4273. +
  4274. +// Disable sensor startup timer
  4275. +#define TOUCH_DBG_POLICY_OVERRIDE_STARTUP_TIMER_DIS BIT(0)
  4276. +
  4277. +// Disable Sync Byte check
  4278. +#define TOUCH_DBG_POLICY_OVERRIDE_SYNC_BYTE_DIS BIT(1)
  4279. +
  4280. +// Disable error resets
  4281. +#define TOUCH_DBG_POLICY_OVERRIDE_ERR_RESET_DIS BIT(2)
  4282. +
  4283. +/*
  4284. + * Touch Sensor Status Codes
  4285. + */
  4286. +enum touch_status {
  4287. + // Requested operation was successful
  4288. + TOUCH_STATUS_SUCCESS = 0,
  4289. +
  4290. + // Invalid parameter(s) sent
  4291. + TOUCH_STATUS_INVALID_PARAMS,
  4292. +
  4293. + // Unable to validate address range
  4294. + TOUCH_STATUS_ACCESS_DENIED,
  4295. +
  4296. + // HECI message incorrect size for specified command
  4297. + TOUCH_STATUS_CMD_SIZE_ERROR,
  4298. +
  4299. + // Memory window not set or device is not armed for operation
  4300. + TOUCH_STATUS_NOT_READY,
  4301. +
  4302. + // There is already an outstanding message of the same type, must
  4303. + // wait for response before sending another request of that type
  4304. + TOUCH_STATUS_REQUEST_OUTSTANDING,
  4305. +
  4306. + // Sensor could not be found. Either no sensor is connected,
  4307. + // the sensor has not yet initialized, or the system is
  4308. + // improperly configured.
  4309. + TOUCH_STATUS_NO_SENSOR_FOUND,
  4310. +
  4311. + // Not enough memory/storage for requested operation
  4312. + TOUCH_STATUS_OUT_OF_MEMORY,
  4313. +
  4314. + // Unexpected error occurred
  4315. + TOUCH_STATUS_INTERNAL_ERROR,
  4316. +
  4317. + // Used in TOUCH_SENSOR_HID_READY_FOR_DATA_RSP to indicate sensor
  4318. + // has been disabled or reset and must be reinitialized.
  4319. + TOUCH_STATUS_SENSOR_DISABLED,
  4320. +
  4321. + // Used to indicate compatibility revision check between sensor and ME
  4322. + // failed, or protocol ver between ME/HID/Kernels failed.
  4323. + TOUCH_STATUS_COMPAT_CHECK_FAIL,
  4324. +
  4325. + // Indicates sensor went through a reset initiated by ME
  4326. + TOUCH_STATUS_SENSOR_EXPECTED_RESET,
  4327. +
  4328. + // Indicates sensor went through an unexpected reset
  4329. + TOUCH_STATUS_SENSOR_UNEXPECTED_RESET,
  4330. +
  4331. + // Requested sensor reset failed to complete
  4332. + TOUCH_STATUS_RESET_FAILED,
  4333. +
  4334. + // Operation timed out
  4335. + TOUCH_STATUS_TIMEOUT,
  4336. +
  4337. + // Test mode pattern did not match expected values
  4338. + TOUCH_STATUS_TEST_MODE_FAIL,
  4339. +
  4340. + // Indicates sensor reported fatal error during reset sequence.
  4341. + // Further progress is not possible.
  4342. + TOUCH_STATUS_SENSOR_FAIL_FATAL,
  4343. +
  4344. + // Indicates sensor reported non-fatal error during reset sequence.
  4345. + // HID/BIOS logs error and attempts to continue.
  4346. + TOUCH_STATUS_SENSOR_FAIL_NONFATAL,
  4347. +
  4348. + // Indicates sensor reported invalid capabilities, such as not
  4349. + // supporting required minimum frequency or I/O mode.
  4350. + TOUCH_STATUS_INVALID_DEVICE_CAPS,
  4351. +
  4352. + // Indicates that command cannot be complete until ongoing Quiesce I/O
  4353. + // flow has completed.
  4354. + TOUCH_STATUS_QUIESCE_IO_IN_PROGRESS,
  4355. +
  4356. + // Invalid value, never returned
  4357. + TOUCH_STATUS_MAX
  4358. +};
  4359. +static_assert(sizeof(enum touch_status) == 4);
  4360. +
  4361. +/*
  4362. + * Defines for message structures used for Host to ME communication
  4363. + */
  4364. +enum touch_sensor_mode {
  4365. + // Set mode to HID mode
  4366. + TOUCH_SENSOR_MODE_HID = 0,
  4367. +
  4368. + // Set mode to Raw Data mode
  4369. + TOUCH_SENSOR_MODE_RAW_DATA,
  4370. +
  4371. + // Used like TOUCH_SENSOR_MODE_HID but data coming from sensor is
  4372. + // not necessarily a HID packet.
  4373. + TOUCH_SENSOR_MODE_SENSOR_DEBUG = 4,
  4374. +
  4375. + // Invalid value
  4376. + TOUCH_SENSOR_MODE_MAX
  4377. +};
  4378. +static_assert(sizeof(enum touch_sensor_mode) == 4);
  4379. +
  4380. +struct touch_sensor_set_mode_cmd_data {
  4381. + // Indicate desired sensor mode
  4382. + enum touch_sensor_mode sensor_mode;
  4383. +
  4384. + // For future expansion
  4385. + u32 Reserved[3];
  4386. +};
  4387. +static_assert(sizeof(struct touch_sensor_set_mode_cmd_data) == 16);
  4388. +
  4389. +struct touch_sensor_set_mem_window_cmd_data {
  4390. + // Lower 32 bits of Touch Data Buffer physical address. Size of each
  4391. + // buffer should be TOUCH_SENSOR_GET_DEVICE_INFO_RSP_DATA.FrameSize
  4392. + u32 touch_data_buffer_addr_lower[TOUCH_SENSOR_MAX_DATA_BUFFERS];
  4393. +
  4394. + // Upper 32 bits of Touch Data Buffer physical address. Size of each
  4395. + // buffer should be TOUCH_SENSOR_GET_DEVICE_INFO_RSP_DATA.FrameSize
  4396. + u32 touch_data_buffer_addr_upper[TOUCH_SENSOR_MAX_DATA_BUFFERS];
  4397. +
  4398. + // Lower 32 bits of Tail Offset physical address
  4399. + u32 tail_offset_addr_lower;
  4400. +
  4401. + // Upper 32 bits of Tail Offset physical address, always 32 bit,
  4402. + // increment by WorkQueueItemSize
  4403. + u32 tail_offset_addr_upper;
  4404. +
  4405. + // Lower 32 bits of Doorbell register physical address
  4406. + u32 doorbell_cookie_addr_lower;
  4407. +
  4408. + // Upper 32 bits of Doorbell register physical address, always 32 bit,
  4409. + // increment as integer, rollover to 1
  4410. + u32 doorbell_cookie_addr_upper;
  4411. +
  4412. + // Lower 32 bits of Feedback Buffer physical address. Size of each
  4413. + // buffer should be TOUCH_SENSOR_GET_DEVICE_INFO_RSP_DATA.FeedbackSize
  4414. + u32 feedback_buffer_addr_lower[TOUCH_SENSOR_MAX_DATA_BUFFERS];
  4415. +
  4416. + // Upper 32 bits of Feedback Buffer physical address. Size of each
  4417. + // buffer should be TOUCH_SENSOR_GET_DEVICE_INFO_RSP_DATA.FeedbackSize
  4418. + u32 feedback_buffer_addr_upper[TOUCH_SENSOR_MAX_DATA_BUFFERS];
  4419. +
  4420. + // Lower 32 bits of dedicated HID to ME communication buffer.
  4421. + // Size is Hid2MeBufferSize.
  4422. + u32 hid2me_buffer_addr_lower;
  4423. +
  4424. + // Upper 32 bits of dedicated HID to ME communication buffer.
  4425. + // Size is Hid2MeBufferSize.
  4426. + u32 hid2me_buffer_addr_upper;
  4427. +
  4428. + // Size in bytes of Hid2MeBuffer, can be no bigger than
  4429. + // TOUCH_HID_2_ME_BUFFER_SIZE_MAX
  4430. + u32 hid2me_buffer_size;
  4431. +
  4432. + // For future expansion
  4433. + u8 reserved1;
  4434. +
  4435. + // Size in bytes of the GuC Work Queue Item pointed to by TailOffset
  4436. + u8 work_queue_item_size;
  4437. +
  4438. + // Size in bytes of the entire GuC Work Queue
  4439. + u16 work_queue_size;
  4440. +
  4441. + // For future expansion
  4442. + u32 reserved[8];
  4443. +};
  4444. +static_assert(sizeof(struct touch_sensor_set_mem_window_cmd_data) == 320);
  4445. +
  4446. +struct touch_sensor_quiesce_io_cmd_data {
  4447. + // Optionally set TOUCH_SENSOR_QUIESCE_FLAG_GUC_RESET
  4448. + u32 quiesce_flags;
  4449. + u32 reserved[2];
  4450. +};
  4451. +static_assert(sizeof(struct touch_sensor_quiesce_io_cmd_data) == 12);
  4452. +
  4453. +struct touch_sensor_feedback_ready_cmd_data {
  4454. + // Index value from 0 to TOUCH_HID_2_ME_BUFFER_ID used to indicate
  4455. + // which Feedback Buffer to use. Using special value
  4456. + // TOUCH_HID_2_ME_BUFFER_ID is an indication to ME to
  4457. + // get feedback data from the Hid2Me buffer instead of one
  4458. + // of the standard Feedback buffers.
  4459. + u8 feedback_index;
  4460. +
  4461. + // For future expansion
  4462. + u8 reserved1[3];
  4463. +
  4464. + // Transaction ID that was originally passed to host in
  4465. + // TOUCH_HID_PRIVATE_DATA. Used to track round trip of a given
  4466. + // transaction for performance measurements.
  4467. + u32 transaction_id;
  4468. +
  4469. + // For future expansion
  4470. + u32 reserved2[2];
  4471. +};
  4472. +static_assert(sizeof(struct touch_sensor_feedback_ready_cmd_data) == 16);
  4473. +
  4474. +enum touch_freq_override {
  4475. + // Do not apply any override
  4476. + TOUCH_FREQ_OVERRIDE_NONE,
  4477. +
  4478. + // Force frequency to 10MHz (not currently supported)
  4479. + TOUCH_FREQ_OVERRIDE_10MHZ,
  4480. +
  4481. + // Force frequency to 17MHz
  4482. + TOUCH_FREQ_OVERRIDE_17MHZ,
  4483. +
  4484. + // Force frequency to 30MHz
  4485. + TOUCH_FREQ_OVERRIDE_30MHZ,
  4486. +
  4487. + // Force frequency to 50MHz (not currently supported)
  4488. + TOUCH_FREQ_OVERRIDE_50MHZ,
  4489. +
  4490. + // Invalid value
  4491. + TOUCH_FREQ_OVERRIDE_MAX
  4492. +};
  4493. +static_assert(sizeof(enum touch_freq_override) == 4);
  4494. +
  4495. +enum touch_spi_io_mode_override {
  4496. + // Do not apply any override
  4497. + TOUCH_SPI_IO_MODE_OVERRIDE_NONE,
  4498. +
  4499. + // Force Single I/O
  4500. + TOUCH_SPI_IO_MODE_OVERRIDE_SINGLE,
  4501. +
  4502. + // Force Dual I/O
  4503. + TOUCH_SPI_IO_MODE_OVERRIDE_DUAL,
  4504. +
  4505. + // Force Quad I/O
  4506. + TOUCH_SPI_IO_MODE_OVERRIDE_QUAD,
  4507. +
  4508. + // Invalid value
  4509. + TOUCH_SPI_IO_MODE_OVERRIDE_MAX
  4510. +};
  4511. +static_assert(sizeof(enum touch_spi_io_mode_override) == 4);
  4512. +
  4513. +struct touch_policy_data {
  4514. + // For future expansion.
  4515. + u32 reserved0;
  4516. +
  4517. + // Value in seconds, after which ME will put the sensor into Doze power
  4518. + // state if no activity occurs. Set to 0 to disable Doze mode
  4519. + // (not recommended). Value will be set to
  4520. + // TOUCH_DEFAULT_DOZE_TIMER_SECONDS by default
  4521. + u32 doze_timer:16;
  4522. +
  4523. + // Override frequency requested by sensor
  4524. + enum touch_freq_override freq_override:3;
  4525. +
  4526. + // Override IO mode requested by sensor
  4527. + enum touch_spi_io_mode_override spi_io_override :3;
  4528. +
  4529. + // For future expansion
  4530. + u32 reserved1:10;
  4531. +
  4532. + // For future expansion
  4533. + u32 reserved2;
  4534. +
  4535. + // Normally all bits will be zero. Bits will be defined as needed
  4536. + // for enabling special debug features
  4537. + u32 debug_override;
  4538. +};
  4539. +static_assert(sizeof(struct touch_policy_data) == 16);
  4540. +
  4541. +struct touch_sensor_set_policies_cmd_data {
  4542. + // Contains the desired policy to be set
  4543. + struct touch_policy_data policy_data;
  4544. +};
  4545. +static_assert(sizeof(struct touch_sensor_set_policies_cmd_data) == 16);
  4546. +
  4547. +enum touch_sensor_reset_type {
  4548. + // Hardware Reset using dedicated GPIO pin
  4549. + TOUCH_SENSOR_RESET_TYPE_HARD,
  4550. +
  4551. + // Software Reset using command written over SPI interface
  4552. + TOUCH_SENSOR_RESET_TYPE_SOFT,
  4553. +
  4554. + // Invalid value
  4555. + TOUCH_SENSOR_RESET_TYPE_MAX
  4556. +};
  4557. +static_assert(sizeof(enum touch_sensor_reset_type) == 4);
  4558. +
  4559. +struct touch_sensor_reset_cmd_data {
  4560. + // Indicate desired reset type
  4561. + enum touch_sensor_reset_type reset_type;
  4562. +
  4563. + // For future expansion
  4564. + u32 reserved;
  4565. +};
  4566. +static_assert(sizeof(struct touch_sensor_reset_cmd_data) == 8);
  4567. +
  4568. +/*
  4569. + * Host to ME message
  4570. + */
  4571. +union touch_sensor_data_h2m {
  4572. + struct touch_sensor_set_mode_cmd_data set_mode_cmd_data;
  4573. + struct touch_sensor_set_mem_window_cmd_data set_window_cmd_data;
  4574. + struct touch_sensor_quiesce_io_cmd_data quiesce_io_cmd_data;
  4575. + struct touch_sensor_feedback_ready_cmd_data feedback_ready_cmd_data;
  4576. + struct touch_sensor_set_policies_cmd_data set_policies_cmd_data;
  4577. + struct touch_sensor_reset_cmd_data reset_cmd_data;
  4578. +};
  4579. +struct touch_sensor_msg_h2m {
  4580. + u32 command_code;
  4581. + union touch_sensor_data_h2m h2m_data;
  4582. +};
  4583. +static_assert(sizeof(struct touch_sensor_msg_h2m) == 324);
  4584. +
  4585. +/*
  4586. + * Message structures used for ME to Host communication
  4587. + */
  4588. +
  4589. +// I/O mode values used by TOUCH_SENSOR_GET_DEVICE_INFO_RSP_DATA.
  4590. +enum touch_spi_io_mode {
  4591. + // Sensor set for Single I/O SPI
  4592. + TOUCH_SPI_IO_MODE_SINGLE = 0,
  4593. +
  4594. + // Sensor set for Dual I/O SPI
  4595. + TOUCH_SPI_IO_MODE_DUAL,
  4596. +
  4597. + // Sensor set for Quad I/O SPI
  4598. + TOUCH_SPI_IO_MODE_QUAD,
  4599. +
  4600. + // Invalid value
  4601. + TOUCH_SPI_IO_MODE_MAX
  4602. +};
  4603. +static_assert(sizeof(enum touch_spi_io_mode) == 4);
  4604. +
  4605. +/*
  4606. + * TOUCH_SENSOR_GET_DEVICE_INFO_RSP code is sent in response to
  4607. + * TOUCH_SENSOR_GET_DEVICE_INFO_CMD. This code will be followed by
  4608. + * TOUCH_SENSOR_GET_DEVICE_INFO_RSP_DATA.
  4609. + *
  4610. + * Possible Status values:
  4611. + * TOUCH_STATUS_SUCCESS:
  4612. + * Command was processed successfully and sensor
  4613. + * details are reported.
  4614. + *
  4615. + * TOUCH_STATUS_CMD_SIZE_ERROR:
  4616. + * Command sent did not match expected size. Other fields will
  4617. + * not contain valid data.
  4618. + *
  4619. + * TOUCH_STATUS_NO_SENSOR_FOUND:
  4620. + * Sensor has not yet been detected. Other fields will
  4621. + * not contain valid data.
  4622. + *
  4623. + * TOUCH_STATUS_INVALID_DEVICE_CAPS:
  4624. + * Indicates sensor does not support minimum required Frequency
  4625. + * or I/O Mode. ME firmware will choose best possible option for
  4626. + * the errant field. Caller should attempt to continue.
  4627. + *
  4628. + * TOUCH_STATUS_COMPAT_CHECK_FAIL:
  4629. + * Indicates TouchIC/ME compatibility mismatch. Caller should
  4630. + * attempt to continue.
  4631. + */
  4632. +struct touch_sensor_get_device_info_rsp_data {
  4633. + // Touch Sensor vendor ID
  4634. + u16 vendor_id;
  4635. +
  4636. + // Touch Sensor device ID
  4637. + u16 device_id;
  4638. +
  4639. + // Touch Sensor Hardware Revision
  4640. + u32 hw_rev;
  4641. +
  4642. + // Touch Sensor Firmware Revision
  4643. + u32 fw_rev;
  4644. +
  4645. + // Max size of one frame returned by Touch IC in bytes. This data
  4646. + // will be TOUCH_RAW_DATA_HDR followed by a payload. The payload can be
  4647. + // raw data or a HID structure depending on mode.
  4648. + u32 frame_size;
  4649. +
  4650. + // Max size of one Feedback structure in bytes
  4651. + u32 feedback_size;
  4652. +
  4653. + // Current operating mode of the sensor
  4654. + enum touch_sensor_mode sensor_mode;
  4655. +
  4656. + // Maximum number of simultaneous touch points that
  4657. + // can be reported by sensor
  4658. + u32 max_touch_points:8;
  4659. +
  4660. + // SPI bus Frequency supported by sensor and ME firmware
  4661. + enum touch_freq spi_frequency:8;
  4662. +
  4663. + // SPI bus I/O Mode supported by sensor and ME firmware
  4664. + enum touch_spi_io_mode spi_io_mode:8;
  4665. +
  4666. + // For future expansion
  4667. + u32 reserved0:8;
  4668. +
  4669. + // Minor version number of EDS spec supported by
  4670. + // sensor (from Compat Rev ID Reg)
  4671. + u8 sensor_minor_eds_rev;
  4672. +
  4673. + // Major version number of EDS spec supported by
  4674. + // sensor (from Compat Rev ID Reg)
  4675. + u8 sensor_major_eds_rev;
  4676. +
  4677. + // Minor version number of EDS spec supported by ME
  4678. + u8 me_minor_eds_rev;
  4679. +
  4680. + // Major version number of EDS spec supported by ME
  4681. + u8 me_major_eds_rev;
  4682. +
  4683. + // EDS Interface Revision Number supported by
  4684. + // sensor (from Compat Rev ID Reg)
  4685. + u8 sensor_eds_intf_rev;
  4686. +
  4687. + // EDS Interface Revision Number supported by ME
  4688. + u8 me_eds_intf_rev;
  4689. +
  4690. + // EU Kernel Compatibility Version (from Compat Rev ID Reg)
  4691. + u8 kernel_compat_ver;
  4692. +
  4693. + // For future expansion
  4694. + u8 reserved1;
  4695. +
  4696. + // For future expansion
  4697. + u32 reserved2[2];
  4698. +};
  4699. +static_assert(sizeof(struct touch_sensor_get_device_info_rsp_data) == 44);
  4700. +
  4701. +/*
  4702. + * TOUCH_SENSOR_SET_MODE_RSP code is sent in response to
  4703. + * TOUCH_SENSOR_SET_MODE_CMD. This code will be followed by
  4704. + * TOUCH_SENSOR_SET_MODE_RSP_DATA.
  4705. + *
  4706. + * Possible Status values:
  4707. + * TOUCH_STATUS_SUCCESS:
  4708. + * Command was processed successfully and mode was set.
  4709. + *
  4710. + * TOUCH_STATUS_CMD_SIZE_ERROR:
  4711. + * Command sent did not match expected size. Other fields will
  4712. + * not contain valid data.
  4713. + *
  4714. + * TOUCH_STATUS_INVALID_PARAMS:
  4715. + * Input parameters are out of range.
  4716. + */
  4717. +struct touch_sensor_set_mode_rsp_data {
  4718. + // For future expansion
  4719. + u32 reserved[3];
  4720. +};
  4721. +static_assert(sizeof(struct touch_sensor_set_mode_rsp_data) == 12);
  4722. +
  4723. +/*
  4724. + * TOUCH_SENSOR_SET_MEM_WINDOW_RSP code is sent in response to
  4725. + * TOUCH_SENSOR_SET_MEM_WINDOW_CMD. This code will be followed
  4726. + * by TOUCH_SENSOR_SET_MEM_WINDOW_RSP_DATA.
  4727. + *
  4728. + * Possible Status values:
  4729. + * TOUCH_STATUS_SUCCESS:
  4730. + * Command was processed successfully and memory window was set.
  4731. + *
  4732. + * TOUCH_STATUS_CMD_SIZE_ERROR:
  4733. + * Command sent did not match expected size. Other fields will
  4734. + * not contain valid data.
  4735. + *
  4736. + * TOUCH_STATUS_INVALID_PARAMS:
  4737. + * Input parameters are out of range.
  4738. + *
  4739. + * TOUCH_STATUS_ACCESS_DENIED:
  4740. + * Unable to map host address ranges for DMA.
  4741. + *
  4742. + * TOUCH_STATUS_OUT_OF_MEMORY:
  4743. + * Unable to allocate enough space for needed buffers.
  4744. + */
  4745. +struct touch_sensor_set_mem_window_rsp_data {
  4746. + // For future expansion
  4747. + u32 reserved[3];
  4748. +};
  4749. +static_assert(sizeof(struct touch_sensor_set_mem_window_rsp_data) == 12);
  4750. +
  4751. +/*
  4752. + * TOUCH_SENSOR_QUIESCE_IO_RSP code is sent in response to
  4753. + * TOUCH_SENSOR_QUIESCE_IO_CMD. This code will be followed
  4754. + * by TOUCH_SENSOR_QUIESCE_IO_RSP_DATA.
  4755. + *
  4756. + * Possible Status values:
  4757. + * TOUCH_STATUS_SUCCESS:
  4758. + * Command was processed successfully and touch flow has stopped.
  4759. + *
  4760. + * TOUCH_STATUS_CMD_SIZE_ERROR:
  4761. + * Command sent did not match expected size. Other fields will
  4762. + * not contain valid data.
  4763. + *
  4764. + * TOUCH_STATUS_QUIESCE_IO_IN_PROGRESS:
  4765. + * Indicates that Quiesce I/O is already in progress and this
  4766. + * command cannot be accepted at this time.
  4767. + *
  4768. + * TOUCH_STATIS_TIMEOUT:
  4769. + * Indicates ME timed out waiting for Quiesce I/O flow to complete.
  4770. + */
  4771. +struct touch_sensor_quiesce_io_rsp_data {
  4772. + // For future expansion
  4773. + u32 reserved[3];
  4774. +};
  4775. +static_assert(sizeof(struct touch_sensor_quiesce_io_rsp_data) == 12);
  4776. +
  4777. +// Reset Reason values used in TOUCH_SENSOR_HID_READY_FOR_DATA_RSP_DATA
  4778. +enum touch_reset_reason {
  4779. + // Reason for sensor reset is not known
  4780. + TOUCH_RESET_REASON_UNKNOWN = 0,
  4781. +
  4782. + // Reset was requested as part of TOUCH_SENSOR_FEEDBACK_READY_CMD
  4783. + TOUCH_RESET_REASON_FEEDBACK_REQUEST,
  4784. +
  4785. + // Reset was requested via TOUCH_SENSOR_RESET_CMD
  4786. + TOUCH_RESET_REASON_HECI_REQUEST,
  4787. +
  4788. + TOUCH_RESET_REASON_MAX
  4789. +};
  4790. +static_assert(sizeof(enum touch_reset_reason) == 4);
  4791. +
  4792. +/*
  4793. + * TOUCH_SENSOR_HID_READY_FOR_DATA_RSP code is sent in response to
  4794. + * TOUCH_SENSOR_HID_READY_FOR_DATA_CMD. This code will be followed
  4795. + * by TOUCH_SENSOR_HID_READY_FOR_DATA_RSP_DATA.
  4796. + *
  4797. + * Possible Status values:
  4798. + * TOUCH_STATUS_SUCCESS:
  4799. + * Command was processed successfully and HID data was sent by DMA.
  4800. + * This will only be sent in HID mode.
  4801. + *
  4802. + * TOUCH_STATUS_CMD_SIZE_ERROR:
  4803. + * Command sent did not match expected size. Other fields will
  4804. + * not contain valid data.
  4805. + *
  4806. + * TOUCH_STATUS_REQUEST_OUTSTANDING:
  4807. + * Previous request is still outstanding, ME FW cannot handle
  4808. + * another request for the same command.
  4809. + *
  4810. + * TOUCH_STATUS_NOT_READY:
  4811. + * Indicates memory window has not yet been set by BIOS/HID.
  4812. + *
  4813. + * TOUCH_STATUS_SENSOR_DISABLED:
  4814. + * Indicates that ME to HID communication has been stopped either
  4815. + * by TOUCH_SENSOR_QUIESCE_IO_CMD or
  4816. + * TOUCH_SENSOR_CLEAR_MEM_WINDOW_CMD.
  4817. + *
  4818. + * TOUCH_STATUS_SENSOR_UNEXPECTED_RESET:
  4819. + * Sensor signaled a Reset Interrupt. ME did not expect this and
  4820. + * has no info about why this occurred.
  4821. + *
  4822. + * TOUCH_STATUS_SENSOR_EXPECTED_RESET:
  4823. + * Sensor signaled a Reset Interrupt. ME either directly requested
  4824. + * this reset, or it was expected as part of a defined flow
  4825. + * in the EDS.
  4826. + *
  4827. + * TOUCH_STATUS_QUIESCE_IO_IN_PROGRESS:
  4828. + * Indicates that Quiesce I/O is already in progress and this
  4829. + * command cannot be accepted at this time.
  4830. + *
  4831. + * TOUCH_STATUS_TIMEOUT:
  4832. + * Sensor did not generate a reset interrupt in the time allotted.
  4833. + * Could indicate sensor is not connected or malfunctioning.
  4834. + */
  4835. +struct touch_sensor_hid_ready_for_data_rsp_data {
  4836. + // Size of the data the ME DMA'd into a RawDataBuffer.
  4837. + // Valid only when Status == TOUCH_STATUS_SUCCESS
  4838. + u32 data_size;
  4839. +
  4840. + // Index to indicate which RawDataBuffer was used.
  4841. + // Valid only when Status == TOUCH_STATUS_SUCCESS
  4842. + u8 touch_data_buffer_index;
  4843. +
  4844. + // If Status is TOUCH_STATUS_SENSOR_EXPECTED_RESET, ME will provide
  4845. + // the cause. See TOUCH_RESET_REASON.
  4846. + u8 reset_reason;
  4847. +
  4848. + // For future expansion
  4849. + u8 reserved1[2];
  4850. + u32 reserved2[5];
  4851. +};
  4852. +static_assert(sizeof(struct touch_sensor_hid_ready_for_data_rsp_data) == 28);
  4853. +
  4854. +/*
  4855. + * TOUCH_SENSOR_FEEDBACK_READY_RSP code is sent in response to
  4856. + * TOUCH_SENSOR_FEEDBACK_READY_CMD. This code will be followed
  4857. + * by TOUCH_SENSOR_FEEDBACK_READY_RSP_DATA.
  4858. + *
  4859. + * Possible Status values:
  4860. + * TOUCH_STATUS_SUCCESS:
  4861. + * Command was processed successfully and any feedback or
  4862. + * commands were sent to sensor.
  4863. + *
  4864. + * TOUCH_STATUS_CMD_SIZE_ERROR:
  4865. + * Command sent did not match expected size. Other fields will
  4866. + * not contain valid data.
  4867. + *
  4868. + * TOUCH_STATUS_INVALID_PARAMS:
  4869. + * Input parameters are out of range.
  4870. + *
  4871. + * TOUCH_STATUS_COMPAT_CHECK_FAIL:
  4872. + * Indicates ProtocolVer does not match ME supported
  4873. + * version. (non-fatal error)
  4874. + *
  4875. + * TOUCH_STATUS_INTERNAL_ERROR:
  4876. + * Unexpected error occurred. This should not normally be seen.
  4877. + *
  4878. + * TOUCH_STATUS_OUT_OF_MEMORY:
  4879. + * Insufficient space to store Calibration Data
  4880. + */
  4881. +struct touch_sensor_feedback_ready_rsp_data {
  4882. + // Index value from 0 to TOUCH_SENSOR_MAX_DATA_BUFFERS used
  4883. + // to indicate which Feedback Buffer to use
  4884. + u8 feedback_index;
  4885. +
  4886. + // For future expansion
  4887. + u8 reserved1[3];
  4888. + u32 reserved2[6];
  4889. +};
  4890. +static_assert(sizeof(struct touch_sensor_feedback_ready_rsp_data) == 28);
  4891. +
  4892. +/*
  4893. + * TOUCH_SENSOR_CLEAR_MEM_WINDOW_RSP code is sent in response to
  4894. + * TOUCH_SENSOR_CLEAR_MEM_WINDOW_CMD. This code will be followed
  4895. + * by TOUCH_SENSOR_CLEAR_MEM_WINDOW_RSP_DATA.
  4896. + *
  4897. + * Possible Status values:
  4898. + * TOUCH_STATUS_SUCCESS:
  4899. + * Command was processed successfully and memory window was set.
  4900. + *
  4901. + * TOUCH_STATUS_CMD_SIZE_ERROR:
  4902. + * Command sent did not match expected size. Other fields will
  4903. + * not contain valid data.
  4904. + *
  4905. + * TOUCH_STATUS_INVALID_PARAMS:
  4906. + * Input parameters are out of range.
  4907. + *
  4908. + * TOUCH_STATUS_QUIESCE_IO_IN_PROGRESS:
  4909. + * Indicates that Quiesce I/O is already in progress and this
  4910. + * command cannot be accepted at this time.
  4911. + */
  4912. +struct touch_sensor_clear_mem_window_rsp_data {
  4913. + // For future expansion
  4914. + u32 reserved[3];
  4915. +};
  4916. +static_assert(sizeof(struct touch_sensor_clear_mem_window_rsp_data) == 12);
  4917. +
  4918. +/*
  4919. + * TOUCH_SENSOR_NOTIFY_DEV_READY_RSP code is sent in response to
  4920. + * TOUCH_SENSOR_NOTIFY_DEV_READY_CMD. This code will be followed
  4921. + * by TOUCH_SENSOR_NOTIFY_DEV_READY_RSP_DATA.
  4922. + *
  4923. + * Possible Status values:
  4924. + * TOUCH_STATUS_SUCCESS:
  4925. + * Command was processed successfully and sensor has
  4926. + * been detected by ME FW.
  4927. + *
  4928. + * TOUCH_STATUS_CMD_SIZE_ERROR:
  4929. + * Command sent did not match expected size.
  4930. + *
  4931. + * TOUCH_STATUS_REQUEST_OUTSTANDING:
  4932. + * Previous request is still outstanding, ME FW cannot handle
  4933. + * another request for the same command.
  4934. + *
  4935. + * TOUCH_STATUS_TIMEOUT:
  4936. + * Sensor did not generate a reset interrupt in the time allotted.
  4937. + * Could indicate sensor is not connected or malfunctioning.
  4938. + *
  4939. + * TOUCH_STATUS_SENSOR_FAIL_FATAL:
  4940. + * Sensor indicated a fatal error, further operation is not
  4941. + * possible. Error details can be found in ErrReg.
  4942. + *
  4943. + * TOUCH_STATUS_SENSOR_FAIL_NONFATAL:
  4944. + * Sensor indicated a non-fatal error. Error should be logged by
  4945. + * caller and init flow can continue. Error details can be found
  4946. + * in ErrReg.
  4947. + */
  4948. +struct touch_sensor_notify_dev_ready_rsp_data {
  4949. + // Value of sensor Error Register, field is only valid for
  4950. + // Status == TOUCH_STATUS_SENSOR_FAIL_FATAL or
  4951. + // TOUCH_STATUS_SENSOR_FAIL_NONFATAL
  4952. + union touch_err_reg err_reg;
  4953. +
  4954. + // For future expansion
  4955. + u32 reserved[2];
  4956. +};
  4957. +static_assert(sizeof(struct touch_sensor_notify_dev_ready_rsp_data) == 12);
  4958. +
  4959. +/*
  4960. + * TOUCH_SENSOR_SET_POLICIES_RSP code is sent in response to
  4961. + * TOUCH_SENSOR_SET_POLICIES_CMD. This code will be followed
  4962. + * by TOUCH_SENSOR_SET_POLICIES_RSP_DATA.
  4963. + *
  4964. + * Possible Status values:
  4965. + * TOUCH_STATUS_SUCCESS:
  4966. + * Command was processed successfully and new policies were set.
  4967. + *
  4968. + * TOUCH_STATUS_CMD_SIZE_ERROR:
  4969. + * Command sent did not match expected size. Other fields will
  4970. + * not contain valid data.
  4971. + *
  4972. + * TOUCH_STATUS_INVALID_PARAMS:
  4973. + * Input parameters are out of range.
  4974. + */
  4975. +struct touch_sensor_set_policies_rsp_data {
  4976. + // For future expansion
  4977. + u32 reserved[3];
  4978. +};
  4979. +static_assert(sizeof(struct touch_sensor_set_policies_rsp_data) == 12);
  4980. +
  4981. +/*
  4982. + * TOUCH_SENSOR_GET_POLICIES_RSP code is sent in response to
  4983. + * TOUCH_SENSOR_GET_POLICIES_CMD. This code will be followed
  4984. + * by TOUCH_SENSOR_GET_POLICIES_RSP_DATA.
  4985. + *
  4986. + * Possible Status values:
  4987. + * TOUCH_STATUS_SUCCESS:
  4988. + * Command was processed successfully and new policies were set.
  4989. + *
  4990. + * TOUCH_STATUS_CMD_SIZE_ERROR:
  4991. + * Command sent did not match expected size. Other fields will
  4992. + * not contain valid data.
  4993. + */
  4994. +struct touch_sensor_get_policies_rsp_data {
  4995. + // Contains the current policy
  4996. + struct touch_policy_data policy_data;
  4997. +};
  4998. +static_assert(sizeof(struct touch_sensor_get_policies_rsp_data) == 16);
  4999. +
  5000. +
  5001. +/*
  5002. + * TOUCH_SENSOR_RESET_RSP code is sent in response to
  5003. + * TOUCH_SENSOR_RESET_CMD. This code will be followed
  5004. + * by TOUCH_SENSOR_RESET_RSP_DATA.
  5005. + *
  5006. + * Possible Status values:
  5007. + * TOUCH_STATUS_SUCCESS:
  5008. + * Command was processed successfully and
  5009. + * sensor reset was completed.
  5010. + *
  5011. + * TOUCH_STATUS_CMD_SIZE_ERROR:
  5012. + * Command sent did not match expected size. Other fields will
  5013. + * not contain valid data.
  5014. + *
  5015. + * TOUCH_STATUS_INVALID_PARAMS:
  5016. + * Input parameters are out of range.
  5017. + *
  5018. + * TOUCH_STATUS_TIMEOUT:
  5019. + * Sensor did not generate a reset interrupt in the time allotted.
  5020. + * Could indicate sensor is not connected or malfunctioning.
  5021. + *
  5022. + * TOUCH_STATUS_RESET_FAILED:
  5023. + * Sensor generated an invalid or unexpected interrupt.
  5024. + *
  5025. + * TOUCH_STATUS_QUIESCE_IO_IN_PROGRESS:
  5026. + * Indicates that Quiesce I/O is already in progress and this
  5027. + * command cannot be accepted at this time.
  5028. + */
  5029. +struct touch_sensor_reset_rsp_data {
  5030. + // For future expansion
  5031. + u32 reserved[3];
  5032. +};
  5033. +static_assert(sizeof(struct touch_sensor_reset_rsp_data) == 12);
  5034. +
  5035. +/*
  5036. + * TOUCH_SENSOR_READ_ALL_REGS_RSP code is sent in response to
  5037. + * TOUCH_SENSOR_READ_ALL_REGS_CMD. This code will be followed
  5038. + * by TOUCH_SENSOR_READ_ALL_REGS_RSP_DATA.
  5039. + *
  5040. + * Possible Status values:
  5041. + * TOUCH_STATUS_SUCCESS:
  5042. + * Command was processed successfully and new policies were set.
  5043. + * TOUCH_STATUS_CMD_SIZE_ERROR:
  5044. + * Command sent did not match expected size. Other fields will
  5045. + * not contain valid data.
  5046. + */
  5047. +struct touch_sensor_read_all_regs_rsp_data {
  5048. + // Returns first 64 bytes of register space used for normal
  5049. + // touch operation. Does not include test mode register.
  5050. + struct touch_reg_block sensor_regs;
  5051. + u32 reserved[4];
  5052. +};
  5053. +static_assert(sizeof(struct touch_sensor_read_all_regs_rsp_data) == 80);
  5054. +
  5055. +/*
  5056. + * ME to Host Message
  5057. + */
  5058. +union touch_sensor_data_m2h {
  5059. + struct touch_sensor_get_device_info_rsp_data device_info_rsp_data;
  5060. + struct touch_sensor_set_mode_rsp_data set_mode_rsp_data;
  5061. + struct touch_sensor_set_mem_window_rsp_data set_mem_window_rsp_data;
  5062. + struct touch_sensor_quiesce_io_rsp_data quiesce_io_rsp_data;
  5063. +
  5064. + struct touch_sensor_hid_ready_for_data_rsp_data
  5065. + hid_ready_for_data_rsp_data;
  5066. +
  5067. + struct touch_sensor_feedback_ready_rsp_data feedback_ready_rsp_data;
  5068. + struct touch_sensor_clear_mem_window_rsp_data clear_mem_window_rsp_data;
  5069. + struct touch_sensor_notify_dev_ready_rsp_data notify_dev_ready_rsp_data;
  5070. + struct touch_sensor_set_policies_rsp_data set_policies_rsp_data;
  5071. + struct touch_sensor_get_policies_rsp_data get_policies_rsp_data;
  5072. + struct touch_sensor_reset_rsp_data reset_rsp_data;
  5073. + struct touch_sensor_read_all_regs_rsp_data read_all_regs_rsp_data;
  5074. +};
  5075. +struct touch_sensor_msg_m2h {
  5076. + u32 command_code;
  5077. + enum touch_status status;
  5078. + union touch_sensor_data_m2h m2h_data;
  5079. +};
  5080. +static_assert(sizeof(struct touch_sensor_msg_m2h) == 88);
  5081. +
  5082. +#pragma pack()
  5083. +
  5084. +#endif // _IPTS_MEI_MSGS_H_
  5085. diff --git a/drivers/misc/ipts/mei.c b/drivers/misc/ipts/mei.c
  5086. new file mode 100644
  5087. index 000000000000..03b5d747a728
  5088. --- /dev/null
  5089. +++ b/drivers/misc/ipts/mei.c
  5090. @@ -0,0 +1,238 @@
  5091. +// SPDX-License-Identifier: GPL-2.0-or-later
  5092. +/*
  5093. + *
  5094. + * Intel Precise Touch & Stylus
  5095. + * Copyright (c) 2016 Intel Corporation
  5096. + *
  5097. + */
  5098. +
  5099. +#include <linux/dma-mapping.h>
  5100. +#include <linux/hid.h>
  5101. +#include <linux/ipts-binary.h>
  5102. +#include <linux/kthread.h>
  5103. +#include <linux/mei_cl_bus.h>
  5104. +#include <linux/module.h>
  5105. +#include <linux/mod_devicetable.h>
  5106. +
  5107. +#include "companion.h"
  5108. +#include "hid.h"
  5109. +#include "ipts.h"
  5110. +#include "params.h"
  5111. +#include "msg-handler.h"
  5112. +#include "mei-msgs.h"
  5113. +#include "state.h"
  5114. +
  5115. +#define IPTS_DRIVER_NAME "ipts"
  5116. +#define IPTS_MEI_UUID UUID_LE(0x3e8d0870, 0x271a, 0x4208, \
  5117. + 0x8e, 0xb5, 0x9a, 0xcb, 0x94, 0x02, 0xae, 0x04)
  5118. +
  5119. +static struct mei_cl_device_id ipts_mei_cl_tbl[] = {
  5120. + { "", IPTS_MEI_UUID, MEI_CL_VERSION_ANY },
  5121. + { }
  5122. +};
  5123. +MODULE_DEVICE_TABLE(mei, ipts_mei_cl_tbl);
  5124. +
  5125. +static ssize_t device_info_show(struct device *dev,
  5126. + struct device_attribute *attr, char *buf)
  5127. +{
  5128. + struct ipts_info *ipts;
  5129. +
  5130. + ipts = dev_get_drvdata(dev);
  5131. + return sprintf(buf, "vendor id = 0x%04hX\ndevice id = 0x%04hX\n"
  5132. + "HW rev = 0x%08X\nfirmware rev = 0x%08X\n",
  5133. + ipts->device_info.vendor_id, ipts->device_info.device_id,
  5134. + ipts->device_info.hw_rev, ipts->device_info.fw_rev);
  5135. +}
  5136. +static DEVICE_ATTR_RO(device_info);
  5137. +
  5138. +static struct attribute *ipts_attrs[] = {
  5139. + &dev_attr_device_info.attr,
  5140. + NULL
  5141. +};
  5142. +
  5143. +static const struct attribute_group ipts_grp = {
  5144. + .attrs = ipts_attrs,
  5145. +};
  5146. +
  5147. +static void raw_data_work_func(struct work_struct *work)
  5148. +{
  5149. + struct ipts_info *ipts = container_of(work,
  5150. + struct ipts_info, raw_data_work);
  5151. +
  5152. + ipts_handle_processed_data(ipts);
  5153. +}
  5154. +
  5155. +static void gfx_status_work_func(struct work_struct *work)
  5156. +{
  5157. + struct ipts_info *ipts = container_of(work, struct ipts_info,
  5158. + gfx_status_work);
  5159. + enum ipts_state state;
  5160. + int status = ipts->gfx_status;
  5161. +
  5162. + ipts_dbg(ipts, "notify gfx status : %d\n", status);
  5163. +
  5164. + state = ipts_get_state(ipts);
  5165. +
  5166. + if (state != IPTS_STA_RAW_DATA_STARTED && state != IPTS_STA_HID_STARTED)
  5167. + return;
  5168. +
  5169. + if (status == IPTS_NOTIFY_STA_BACKLIGHT_ON && !ipts->display_status) {
  5170. + ipts_send_sensor_clear_mem_window_cmd(ipts);
  5171. + ipts->display_status = true;
  5172. + }
  5173. +
  5174. + if (status == IPTS_NOTIFY_STA_BACKLIGHT_OFF && ipts->display_status) {
  5175. + ipts_send_sensor_quiesce_io_cmd(ipts);
  5176. + ipts->display_status = false;
  5177. + }
  5178. +}
  5179. +
  5180. +// event loop
  5181. +static int ipts_mei_cl_event_thread(void *data)
  5182. +{
  5183. + struct ipts_info *ipts = (struct ipts_info *)data;
  5184. + struct mei_cl_device *cldev = ipts->cldev;
  5185. + ssize_t msg_len;
  5186. + struct touch_sensor_msg_m2h m2h_msg;
  5187. +
  5188. + while (!kthread_should_stop()) {
  5189. + msg_len = mei_cldev_recv(cldev,
  5190. + (u8 *)&m2h_msg, sizeof(m2h_msg));
  5191. + if (msg_len <= 0) {
  5192. + ipts_err(ipts, "error in reading m2h msg\n");
  5193. + continue;
  5194. + }
  5195. +
  5196. + if (ipts_handle_resp(ipts, &m2h_msg, msg_len) != 0)
  5197. + ipts_err(ipts, "error in handling resp msg\n");
  5198. + }
  5199. +
  5200. + ipts_dbg(ipts, "!! end event loop !!\n");
  5201. +
  5202. + return 0;
  5203. +}
  5204. +
  5205. +static void init_work_func(struct work_struct *work)
  5206. +{
  5207. + struct ipts_info *ipts = container_of(work,
  5208. + struct ipts_info, init_work);
  5209. +
  5210. + ipts->sensor_mode = TOUCH_SENSOR_MODE_RAW_DATA;
  5211. + ipts->display_status = true;
  5212. +
  5213. + ipts_start(ipts);
  5214. +}
  5215. +
  5216. +static int ipts_mei_cl_probe(struct mei_cl_device *cldev,
  5217. + const struct mei_cl_device_id *id)
  5218. +{
  5219. + int ret = 0;
  5220. + struct ipts_info *ipts = NULL;
  5221. +
  5222. + // Check if a companion driver for firmware loading was registered
  5223. + // If not, defer probing until it was properly registered
  5224. + if (!ipts_companion_available() && !ipts_modparams.ignore_companion)
  5225. + return -EPROBE_DEFER;
  5226. +
  5227. + pr_info("probing Intel Precise Touch & Stylus\n");
  5228. +
  5229. + // setup the DMA BIT mask, the system will choose the best possible
  5230. + if (dma_coerce_mask_and_coherent(&cldev->dev, DMA_BIT_MASK(64)) == 0) {
  5231. + pr_info("IPTS using DMA_BIT_MASK(64)\n");
  5232. + } else if (dma_coerce_mask_and_coherent(&cldev->dev,
  5233. + DMA_BIT_MASK(32)) == 0) {
  5234. + pr_info("IPTS using DMA_BIT_MASK(32)\n");
  5235. + } else {
  5236. + pr_err("IPTS: No suitable DMA available\n");
  5237. + return -EFAULT;
  5238. + }
  5239. +
  5240. + ret = mei_cldev_enable(cldev);
  5241. + if (ret < 0) {
  5242. + pr_err("cannot enable IPTS\n");
  5243. + return ret;
  5244. + }
  5245. +
  5246. + ipts = devm_kzalloc(&cldev->dev, sizeof(struct ipts_info), GFP_KERNEL);
  5247. + if (ipts == NULL) {
  5248. + ret = -ENOMEM;
  5249. + goto disable_mei;
  5250. + }
  5251. +
  5252. + ipts->cldev = cldev;
  5253. + mei_cldev_set_drvdata(cldev, ipts);
  5254. + ipts->event_loop = kthread_run(ipts_mei_cl_event_thread, (void *)ipts,
  5255. + "ipts_event_thread");
  5256. +
  5257. + if (ipts_dbgfs_register(ipts, "ipts"))
  5258. + pr_debug("cannot register debugfs for IPTS\n");
  5259. +
  5260. + INIT_WORK(&ipts->init_work, init_work_func);
  5261. + INIT_WORK(&ipts->raw_data_work, raw_data_work_func);
  5262. + INIT_WORK(&ipts->gfx_status_work, gfx_status_work_func);
  5263. +
  5264. + ret = sysfs_create_group(&cldev->dev.kobj, &ipts_grp);
  5265. + if (ret != 0)
  5266. + pr_debug("cannot create sysfs for IPTS\n");
  5267. +
  5268. + schedule_work(&ipts->init_work);
  5269. +
  5270. + return 0;
  5271. +
  5272. +disable_mei:
  5273. + mei_cldev_disable(cldev);
  5274. +
  5275. + return ret;
  5276. +}
  5277. +
  5278. +static int ipts_mei_cl_remove(struct mei_cl_device *cldev)
  5279. +{
  5280. + struct ipts_info *ipts = mei_cldev_get_drvdata(cldev);
  5281. +
  5282. + ipts_stop(ipts);
  5283. +
  5284. + sysfs_remove_group(&cldev->dev.kobj, &ipts_grp);
  5285. + ipts_hid_release(ipts);
  5286. + ipts_dbgfs_deregister(ipts);
  5287. + mei_cldev_disable(cldev);
  5288. +
  5289. + kthread_stop(ipts->event_loop);
  5290. +
  5291. + pr_info("IPTS removed\n");
  5292. +
  5293. + return 0;
  5294. +}
  5295. +
  5296. +static struct mei_cl_driver ipts_mei_cl_driver = {
  5297. + .id_table = ipts_mei_cl_tbl,
  5298. + .name = IPTS_DRIVER_NAME,
  5299. + .probe = ipts_mei_cl_probe,
  5300. + .remove = ipts_mei_cl_remove,
  5301. +};
  5302. +
  5303. +static int ipts_mei_cl_init(void)
  5304. +{
  5305. + int ret;
  5306. +
  5307. + pr_info("IPTS %s() is called\n", __func__);
  5308. +
  5309. + ret = mei_cldev_driver_register(&ipts_mei_cl_driver);
  5310. + if (ret) {
  5311. + pr_err("unable to register IPTS mei client driver\n");
  5312. + return ret;
  5313. + }
  5314. +
  5315. + return 0;
  5316. +}
  5317. +
  5318. +static void __exit ipts_mei_cl_exit(void)
  5319. +{
  5320. + pr_info("IPTS %s() is called\n", __func__);
  5321. + mei_cldev_driver_unregister(&ipts_mei_cl_driver);
  5322. +}
  5323. +
  5324. +module_init(ipts_mei_cl_init);
  5325. +module_exit(ipts_mei_cl_exit);
  5326. +
  5327. +MODULE_DESCRIPTION("Intel(R) ME Interface Client Driver for IPTS");
  5328. +MODULE_LICENSE("GPL");
  5329. diff --git a/drivers/misc/ipts/msg-handler.c b/drivers/misc/ipts/msg-handler.c
  5330. new file mode 100644
  5331. index 000000000000..b2b382ea4675
  5332. --- /dev/null
  5333. +++ b/drivers/misc/ipts/msg-handler.c
  5334. @@ -0,0 +1,396 @@
  5335. +// SPDX-License-Identifier: GPL-2.0-or-later
  5336. +/*
  5337. + *
  5338. + * Intel Precise Touch & Stylus
  5339. + * Copyright (c) 2016 Intel Corporation
  5340. + *
  5341. + */
  5342. +
  5343. +#include <linux/mei_cl_bus.h>
  5344. +
  5345. +#include "hid.h"
  5346. +#include "ipts.h"
  5347. +#include "mei-msgs.h"
  5348. +#include "resource.h"
  5349. +
  5350. +#define rsp_failed(ipts, cmd, status) \
  5351. + ipts_err(ipts, "0x%08x failed status = %d\n", cmd, status)
  5352. +
  5353. +int ipts_handle_cmd(struct ipts_info *ipts, u32 cmd, void *data, int data_size)
  5354. +{
  5355. + int ret = 0;
  5356. + int len = 0;
  5357. + struct touch_sensor_msg_h2m h2m_msg;
  5358. +
  5359. + memset(&h2m_msg, 0, sizeof(h2m_msg));
  5360. +
  5361. + h2m_msg.command_code = cmd;
  5362. + len = sizeof(h2m_msg.command_code) + data_size;
  5363. +
  5364. + if (data != NULL && data_size != 0)
  5365. + memcpy(&h2m_msg.h2m_data, data, data_size); // copy payload
  5366. +
  5367. + ret = mei_cldev_send(ipts->cldev, (u8 *)&h2m_msg, len);
  5368. + if (ret < 0) {
  5369. + ipts_err(ipts, "mei_cldev_send() error 0x%X:%d\n", cmd, ret);
  5370. + return ret;
  5371. + }
  5372. +
  5373. + return 0;
  5374. +}
  5375. +
  5376. +int ipts_send_feedback(struct ipts_info *ipts, int buffer_idx,
  5377. + u32 transaction_id)
  5378. +{
  5379. + int cmd_len = sizeof(struct touch_sensor_feedback_ready_cmd_data);
  5380. + struct touch_sensor_feedback_ready_cmd_data fb_ready_cmd;
  5381. +
  5382. + memset(&fb_ready_cmd, 0, cmd_len);
  5383. +
  5384. + fb_ready_cmd.feedback_index = buffer_idx;
  5385. + fb_ready_cmd.transaction_id = transaction_id;
  5386. +
  5387. + return ipts_handle_cmd(ipts, TOUCH_SENSOR_FEEDBACK_READY_CMD,
  5388. + &fb_ready_cmd, cmd_len);
  5389. +}
  5390. +
  5391. +int ipts_send_sensor_quiesce_io_cmd(struct ipts_info *ipts)
  5392. +{
  5393. + int cmd_len = sizeof(struct touch_sensor_quiesce_io_cmd_data);
  5394. + struct touch_sensor_quiesce_io_cmd_data quiesce_io_cmd;
  5395. +
  5396. + memset(&quiesce_io_cmd, 0, cmd_len);
  5397. +
  5398. + return ipts_handle_cmd(ipts, TOUCH_SENSOR_QUIESCE_IO_CMD,
  5399. + &quiesce_io_cmd, cmd_len);
  5400. +}
  5401. +
  5402. +int ipts_send_sensor_hid_ready_for_data_cmd(struct ipts_info *ipts)
  5403. +{
  5404. + return ipts_handle_cmd(ipts,
  5405. + TOUCH_SENSOR_HID_READY_FOR_DATA_CMD, NULL, 0);
  5406. +}
  5407. +
  5408. +int ipts_send_sensor_clear_mem_window_cmd(struct ipts_info *ipts)
  5409. +{
  5410. + return ipts_handle_cmd(ipts,
  5411. + TOUCH_SENSOR_CLEAR_MEM_WINDOW_CMD, NULL, 0);
  5412. +}
  5413. +
  5414. +static int check_validity(struct touch_sensor_msg_m2h *m2h_msg, u32 msg_len)
  5415. +{
  5416. + int ret = 0;
  5417. + int valid_msg_len = sizeof(m2h_msg->command_code);
  5418. + u32 cmd_code = m2h_msg->command_code;
  5419. +
  5420. + switch (cmd_code) {
  5421. + case TOUCH_SENSOR_SET_MODE_RSP:
  5422. + valid_msg_len +=
  5423. + sizeof(struct touch_sensor_set_mode_rsp_data);
  5424. + break;
  5425. + case TOUCH_SENSOR_SET_MEM_WINDOW_RSP:
  5426. + valid_msg_len +=
  5427. + sizeof(struct touch_sensor_set_mem_window_rsp_data);
  5428. + break;
  5429. + case TOUCH_SENSOR_QUIESCE_IO_RSP:
  5430. + valid_msg_len +=
  5431. + sizeof(struct touch_sensor_quiesce_io_rsp_data);
  5432. + break;
  5433. + case TOUCH_SENSOR_HID_READY_FOR_DATA_RSP:
  5434. + valid_msg_len +=
  5435. + sizeof(struct touch_sensor_hid_ready_for_data_rsp_data);
  5436. + break;
  5437. + case TOUCH_SENSOR_FEEDBACK_READY_RSP:
  5438. + valid_msg_len +=
  5439. + sizeof(struct touch_sensor_feedback_ready_rsp_data);
  5440. + break;
  5441. + case TOUCH_SENSOR_CLEAR_MEM_WINDOW_RSP:
  5442. + valid_msg_len +=
  5443. + sizeof(struct touch_sensor_clear_mem_window_rsp_data);
  5444. + break;
  5445. + case TOUCH_SENSOR_NOTIFY_DEV_READY_RSP:
  5446. + valid_msg_len +=
  5447. + sizeof(struct touch_sensor_notify_dev_ready_rsp_data);
  5448. + break;
  5449. + case TOUCH_SENSOR_SET_POLICIES_RSP:
  5450. + valid_msg_len +=
  5451. + sizeof(struct touch_sensor_set_policies_rsp_data);
  5452. + break;
  5453. + case TOUCH_SENSOR_GET_POLICIES_RSP:
  5454. + valid_msg_len +=
  5455. + sizeof(struct touch_sensor_get_policies_rsp_data);
  5456. + break;
  5457. + case TOUCH_SENSOR_RESET_RSP:
  5458. + valid_msg_len +=
  5459. + sizeof(struct touch_sensor_reset_rsp_data);
  5460. + break;
  5461. + }
  5462. +
  5463. + if (valid_msg_len != msg_len)
  5464. + return -EINVAL;
  5465. + return ret;
  5466. +}
  5467. +
  5468. +int ipts_start(struct ipts_info *ipts)
  5469. +{
  5470. + /*
  5471. + * TODO: check if we need to do SET_POLICIES_CMD we need to do this
  5472. + * when protocol version doesn't match with reported one how we keep
  5473. + * vendor specific data is the first thing to solve.
  5474. + */
  5475. + ipts_set_state(ipts, IPTS_STA_INIT);
  5476. + ipts->num_of_parallel_data_buffers = TOUCH_SENSOR_MAX_DATA_BUFFERS;
  5477. +
  5478. + // start with RAW_DATA
  5479. + ipts->sensor_mode = TOUCH_SENSOR_MODE_RAW_DATA;
  5480. +
  5481. + return ipts_handle_cmd(ipts,
  5482. + TOUCH_SENSOR_NOTIFY_DEV_READY_CMD, NULL, 0);
  5483. +}
  5484. +
  5485. +void ipts_stop(struct ipts_info *ipts)
  5486. +{
  5487. + enum ipts_state old_state = ipts_get_state(ipts);
  5488. +
  5489. + ipts_set_state(ipts, IPTS_STA_STOPPING);
  5490. +
  5491. + ipts_send_sensor_quiesce_io_cmd(ipts);
  5492. + ipts_send_sensor_clear_mem_window_cmd(ipts);
  5493. +
  5494. + if (old_state < IPTS_STA_RESOURCE_READY)
  5495. + return;
  5496. +
  5497. + if (old_state == IPTS_STA_RAW_DATA_STARTED ||
  5498. + old_state == IPTS_STA_HID_STARTED) {
  5499. + ipts_free_default_resource(ipts);
  5500. + ipts_free_raw_data_resource(ipts);
  5501. + }
  5502. +}
  5503. +
  5504. +int ipts_restart(struct ipts_info *ipts)
  5505. +{
  5506. + ipts_dbg(ipts, "ipts restart\n");
  5507. + ipts_stop(ipts);
  5508. +
  5509. + ipts_send_sensor_quiesce_io_cmd(ipts);
  5510. + ipts->restart = true;
  5511. +
  5512. + return 0;
  5513. +}
  5514. +
  5515. +int ipts_handle_resp(struct ipts_info *ipts,
  5516. + struct touch_sensor_msg_m2h *m2h_msg, u32 msg_len)
  5517. +{
  5518. + int ret = 0;
  5519. + int rsp_status = 0;
  5520. + int cmd_status = 0;
  5521. + int cmd_len = 0;
  5522. + u32 cmd;
  5523. +
  5524. + if (!check_validity(m2h_msg, msg_len)) {
  5525. + ipts_err(ipts, "wrong rsp\n");
  5526. + return -EINVAL;
  5527. + }
  5528. +
  5529. + rsp_status = m2h_msg->status;
  5530. + cmd = m2h_msg->command_code;
  5531. +
  5532. + switch (cmd) {
  5533. + case TOUCH_SENSOR_NOTIFY_DEV_READY_RSP: {
  5534. + if (rsp_status != TOUCH_STATUS_SENSOR_FAIL_NONFATAL &&
  5535. + rsp_status != 0) {
  5536. + rsp_failed(ipts, cmd, rsp_status);
  5537. + break;
  5538. + }
  5539. +
  5540. + cmd_status = ipts_handle_cmd(ipts,
  5541. + TOUCH_SENSOR_GET_DEVICE_INFO_CMD, NULL, 0);
  5542. +
  5543. + break;
  5544. + }
  5545. + case TOUCH_SENSOR_GET_DEVICE_INFO_RSP: {
  5546. + if (rsp_status != TOUCH_STATUS_COMPAT_CHECK_FAIL &&
  5547. + rsp_status != 0) {
  5548. + rsp_failed(ipts, cmd, rsp_status);
  5549. + break;
  5550. + }
  5551. +
  5552. + memcpy(&ipts->device_info,
  5553. + &m2h_msg->m2h_data.device_info_rsp_data,
  5554. + sizeof(struct touch_sensor_get_device_info_rsp_data));
  5555. +
  5556. + /*
  5557. + * TODO: support raw_request during HID init. Although HID
  5558. + * init happens here, technically most of reports
  5559. + * (for both direction) can be issued only after
  5560. + * SET_MEM_WINDOWS_CMD since they may require ME or touch IC.
  5561. + * If ipts vendor requires raw_request during HID init, we
  5562. + * need to consider to move HID init.
  5563. + */
  5564. + if (ipts->hid_desc_ready == false) {
  5565. + ret = ipts_hid_init(ipts);
  5566. + if (ret)
  5567. + break;
  5568. + }
  5569. +
  5570. + cmd_status = ipts_send_sensor_clear_mem_window_cmd(ipts);
  5571. +
  5572. + break;
  5573. + }
  5574. + case TOUCH_SENSOR_CLEAR_MEM_WINDOW_RSP: {
  5575. + struct touch_sensor_set_mode_cmd_data sensor_mode_cmd;
  5576. +
  5577. + if (rsp_status != TOUCH_STATUS_TIMEOUT && rsp_status != 0) {
  5578. + rsp_failed(ipts, cmd, rsp_status);
  5579. + break;
  5580. + }
  5581. +
  5582. + if (ipts_get_state(ipts) == IPTS_STA_STOPPING)
  5583. + break;
  5584. +
  5585. + // allocate default resource: common & hid only
  5586. + if (!ipts_is_default_resource_ready(ipts)) {
  5587. + ret = ipts_allocate_default_resource(ipts);
  5588. + if (ret)
  5589. + break;
  5590. + }
  5591. +
  5592. + if (ipts->sensor_mode == TOUCH_SENSOR_MODE_RAW_DATA &&
  5593. + !ipts_is_raw_data_resource_ready(ipts)) {
  5594. + ret = ipts_allocate_raw_data_resource(ipts);
  5595. + if (ret) {
  5596. + ipts_free_default_resource(ipts);
  5597. + break;
  5598. + }
  5599. + }
  5600. +
  5601. + ipts_set_state(ipts, IPTS_STA_RESOURCE_READY);
  5602. +
  5603. + cmd_len = sizeof(struct touch_sensor_set_mode_cmd_data);
  5604. + memset(&sensor_mode_cmd, 0, cmd_len);
  5605. +
  5606. + sensor_mode_cmd.sensor_mode = ipts->sensor_mode;
  5607. + cmd_status = ipts_handle_cmd(ipts, TOUCH_SENSOR_SET_MODE_CMD,
  5608. + &sensor_mode_cmd, cmd_len);
  5609. +
  5610. + break;
  5611. + }
  5612. + case TOUCH_SENSOR_SET_MODE_RSP: {
  5613. + struct touch_sensor_set_mem_window_cmd_data smw_cmd;
  5614. +
  5615. + if (rsp_status != 0) {
  5616. + rsp_failed(ipts, cmd, rsp_status);
  5617. + break;
  5618. + }
  5619. +
  5620. + cmd_len = sizeof(struct touch_sensor_set_mem_window_cmd_data);
  5621. + memset(&smw_cmd, 0, cmd_len);
  5622. +
  5623. + ipts_get_set_mem_window_cmd_data(ipts, &smw_cmd);
  5624. + cmd_status = ipts_handle_cmd(ipts,
  5625. + TOUCH_SENSOR_SET_MEM_WINDOW_CMD, &smw_cmd, cmd_len);
  5626. +
  5627. + break;
  5628. + }
  5629. + case TOUCH_SENSOR_SET_MEM_WINDOW_RSP: {
  5630. + if (rsp_status != 0) {
  5631. + rsp_failed(ipts, cmd, rsp_status);
  5632. + break;
  5633. + }
  5634. +
  5635. + cmd_status = ipts_send_sensor_hid_ready_for_data_cmd(ipts);
  5636. + if (cmd_status)
  5637. + break;
  5638. +
  5639. + if (ipts->sensor_mode == TOUCH_SENSOR_MODE_HID)
  5640. + ipts_set_state(ipts, IPTS_STA_HID_STARTED);
  5641. + else if (ipts->sensor_mode == TOUCH_SENSOR_MODE_RAW_DATA)
  5642. + ipts_set_state(ipts, IPTS_STA_RAW_DATA_STARTED);
  5643. +
  5644. + ipts_dbg(ipts, "touch enabled %d\n", ipts_get_state(ipts));
  5645. +
  5646. + break;
  5647. + }
  5648. + case TOUCH_SENSOR_HID_READY_FOR_DATA_RSP: {
  5649. + struct touch_sensor_hid_ready_for_data_rsp_data *hid_data;
  5650. + enum ipts_state state;
  5651. +
  5652. + if (rsp_status != TOUCH_STATUS_SENSOR_DISABLED &&
  5653. + rsp_status != 0) {
  5654. + rsp_failed(ipts, cmd, rsp_status);
  5655. + break;
  5656. + }
  5657. +
  5658. + state = ipts_get_state(ipts);
  5659. + if (ipts->sensor_mode == TOUCH_SENSOR_MODE_HID &&
  5660. + state == IPTS_STA_HID_STARTED) {
  5661. + hid_data =
  5662. + &m2h_msg->m2h_data.hid_ready_for_data_rsp_data;
  5663. +
  5664. + // HID mode only uses buffer 0
  5665. + if (hid_data->touch_data_buffer_index != 0)
  5666. + break;
  5667. +
  5668. + // handle hid data
  5669. + ipts_handle_hid_data(ipts, hid_data);
  5670. + }
  5671. +
  5672. + break;
  5673. + }
  5674. + case TOUCH_SENSOR_FEEDBACK_READY_RSP: {
  5675. + if (rsp_status != TOUCH_STATUS_COMPAT_CHECK_FAIL &&
  5676. + rsp_status != 0) {
  5677. + rsp_failed(ipts, cmd, rsp_status);
  5678. + break;
  5679. + }
  5680. +
  5681. + if (m2h_msg->m2h_data.feedback_ready_rsp_data.feedback_index
  5682. + == TOUCH_HID_2_ME_BUFFER_ID)
  5683. + break;
  5684. +
  5685. + if (ipts->sensor_mode == TOUCH_SENSOR_MODE_HID)
  5686. + cmd_status = ipts_handle_cmd(ipts,
  5687. + TOUCH_SENSOR_HID_READY_FOR_DATA_CMD, NULL, 0);
  5688. +
  5689. + break;
  5690. + }
  5691. + case TOUCH_SENSOR_QUIESCE_IO_RSP: {
  5692. + enum ipts_state state;
  5693. +
  5694. + if (rsp_status != 0) {
  5695. + rsp_failed(ipts, cmd, rsp_status);
  5696. + break;
  5697. + }
  5698. +
  5699. + state = ipts_get_state(ipts);
  5700. + if (state == IPTS_STA_STOPPING && ipts->restart) {
  5701. + ipts_dbg(ipts, "restart\n");
  5702. + ipts_start(ipts);
  5703. + ipts->restart = 0;
  5704. + break;
  5705. + }
  5706. +
  5707. + break;
  5708. + }
  5709. + }
  5710. +
  5711. + // handle error in rsp_status
  5712. + if (rsp_status != 0) {
  5713. + switch (rsp_status) {
  5714. + case TOUCH_STATUS_SENSOR_EXPECTED_RESET:
  5715. + case TOUCH_STATUS_SENSOR_UNEXPECTED_RESET:
  5716. + ipts_dbg(ipts, "sensor reset %d\n", rsp_status);
  5717. + ipts_restart(ipts);
  5718. + break;
  5719. + default:
  5720. + ipts_dbg(ipts, "cmd : 0x%08x, status %d\n",
  5721. + cmd, rsp_status);
  5722. + break;
  5723. + }
  5724. + }
  5725. +
  5726. + if (cmd_status)
  5727. + ipts_restart(ipts);
  5728. +
  5729. + return ret;
  5730. +}
  5731. diff --git a/drivers/misc/ipts/msg-handler.h b/drivers/misc/ipts/msg-handler.h
  5732. new file mode 100644
  5733. index 000000000000..eca4238adf4b
  5734. --- /dev/null
  5735. +++ b/drivers/misc/ipts/msg-handler.h
  5736. @@ -0,0 +1,28 @@
  5737. +/* SPDX-License-Identifier: GPL-2.0-or-later */
  5738. +/*
  5739. + *
  5740. + * Intel Precise Touch & Stylus
  5741. + * Copyright (c) 2016 Intel Corporation
  5742. + *
  5743. + */
  5744. +
  5745. +#ifndef _IPTS_MSG_HANDLER_H_
  5746. +#define _IPTS_MSG_HANDLER_H_
  5747. +
  5748. +int ipts_start(struct ipts_info *ipts);
  5749. +void ipts_stop(struct ipts_info *ipts);
  5750. +int ipts_handle_cmd(struct ipts_info *ipts, u32 cmd, void *data, int data_size);
  5751. +
  5752. +int ipts_handle_resp(struct ipts_info *ipts,
  5753. + struct touch_sensor_msg_m2h *m2h_msg, u32 msg_len);
  5754. +
  5755. +int ipts_send_feedback(struct ipts_info *ipts,
  5756. + int buffer_idx, u32 transaction_id);
  5757. +
  5758. +int ipts_handle_processed_data(struct ipts_info *ipts);
  5759. +int ipts_send_sensor_quiesce_io_cmd(struct ipts_info *ipts);
  5760. +int ipts_send_sensor_hid_ready_for_data_cmd(struct ipts_info *ipts);
  5761. +int ipts_send_sensor_clear_mem_window_cmd(struct ipts_info *ipts);
  5762. +int ipts_restart(struct ipts_info *ipts);
  5763. +
  5764. +#endif /* _IPTS_MSG_HANDLER_H */
  5765. diff --git a/drivers/misc/ipts/params.c b/drivers/misc/ipts/params.c
  5766. new file mode 100644
  5767. index 000000000000..93b19cbf4786
  5768. --- /dev/null
  5769. +++ b/drivers/misc/ipts/params.c
  5770. @@ -0,0 +1,46 @@
  5771. +// SPDX-License-Identifier: GPL-2.0-or-later
  5772. +/*
  5773. + *
  5774. + * Intel Precise Touch & Stylus
  5775. + * Copyright (c) 2016 Intel Corporation
  5776. + *
  5777. + */
  5778. +
  5779. +#include <linux/moduleparam.h>
  5780. +
  5781. +#include "params.h"
  5782. +
  5783. +#define IPTS_PARAM(NAME, TYPE, PERM, DESC) \
  5784. + module_param_named(NAME, ipts_modparams.NAME, TYPE, PERM); \
  5785. + MODULE_PARM_DESC(NAME, DESC)
  5786. +
  5787. +struct ipts_params ipts_modparams = {
  5788. + .ignore_fw_fallback = false,
  5789. + .ignore_config_fallback = false,
  5790. + .ignore_companion = false,
  5791. + .no_feedback = -1,
  5792. +
  5793. + .debug = false,
  5794. + .debug_thread = false,
  5795. +};
  5796. +
  5797. +IPTS_PARAM(ignore_fw_fallback, bool, 0400,
  5798. + "Don't use the IPTS firmware fallback path. (default: false)"
  5799. +);
  5800. +IPTS_PARAM(ignore_config_fallback, bool, 0400,
  5801. + "Don't try to load the IPTS firmware config from a file. (default: false)"
  5802. +);
  5803. +IPTS_PARAM(ignore_companion, bool, 0400,
  5804. + "Don't use a companion driver to load firmware. (default: false)"
  5805. +);
  5806. +IPTS_PARAM(no_feedback, int, 0644,
  5807. + "Disable sending feedback to ME (can prevent crashes on Skylake). (-1=auto [default], 0=false, 1=true)"
  5808. +);
  5809. +
  5810. +IPTS_PARAM(debug, bool, 0400,
  5811. + "Enable IPTS debugging output. (default: false)"
  5812. +);
  5813. +IPTS_PARAM(debug_thread, bool, 0400,
  5814. + "Periodically print the ME status into the kernel log. (default: false)"
  5815. +);
  5816. +
  5817. diff --git a/drivers/misc/ipts/params.h b/drivers/misc/ipts/params.h
  5818. new file mode 100644
  5819. index 000000000000..4d9d2bca5ede
  5820. --- /dev/null
  5821. +++ b/drivers/misc/ipts/params.h
  5822. @@ -0,0 +1,26 @@
  5823. +/* SPDX-License-Identifier: GPL-2.0-or-later */
  5824. +/*
  5825. + *
  5826. + * Intel Precise Touch & Stylus
  5827. + * Copyright (c) 2016 Intel Corporation
  5828. + *
  5829. + */
  5830. +
  5831. +#ifndef _IPTS_PARAMS_H_
  5832. +#define _IPTS_PARAMS_H_
  5833. +
  5834. +#include <linux/types.h>
  5835. +
  5836. +struct ipts_params {
  5837. + bool ignore_fw_fallback;
  5838. + bool ignore_config_fallback;
  5839. + bool ignore_companion;
  5840. + int no_feedback;
  5841. +
  5842. + bool debug;
  5843. + bool debug_thread;
  5844. +};
  5845. +
  5846. +extern struct ipts_params ipts_modparams;
  5847. +
  5848. +#endif // _IPTS_PARAMS_H_
  5849. diff --git a/drivers/misc/ipts/resource.c b/drivers/misc/ipts/resource.c
  5850. new file mode 100644
  5851. index 000000000000..cfd212f2cac0
  5852. --- /dev/null
  5853. +++ b/drivers/misc/ipts/resource.c
  5854. @@ -0,0 +1,291 @@
  5855. +// SPDX-License-Identifier: GPL-2.0-or-later
  5856. +/*
  5857. + *
  5858. + * Intel Precise Touch & Stylus
  5859. + * Copyright (c) 2016 Intel Corporation
  5860. + *
  5861. + */
  5862. +
  5863. +#include <linux/dma-mapping.h>
  5864. +
  5865. +#include "ipts.h"
  5866. +#include "kernel.h"
  5867. +#include "mei-msgs.h"
  5868. +
  5869. +static void free_common_resource(struct ipts_info *ipts)
  5870. +{
  5871. + char *addr;
  5872. + struct ipts_buffer_info *feedback_buffer;
  5873. + dma_addr_t dma_addr;
  5874. + u32 buffer_size;
  5875. + int i, num_of_parallels;
  5876. +
  5877. + if (ipts->resource.me2hid_buffer) {
  5878. + devm_kfree(&ipts->cldev->dev, ipts->resource.me2hid_buffer);
  5879. + ipts->resource.me2hid_buffer = 0;
  5880. + }
  5881. +
  5882. + addr = ipts->resource.hid2me_buffer.addr;
  5883. + dma_addr = ipts->resource.hid2me_buffer.dma_addr;
  5884. + buffer_size = ipts->resource.hid2me_buffer_size;
  5885. +
  5886. + if (ipts->resource.hid2me_buffer.addr) {
  5887. + dmam_free_coherent(&ipts->cldev->dev, buffer_size,
  5888. + addr, dma_addr);
  5889. +
  5890. + ipts->resource.hid2me_buffer.addr = 0;
  5891. + ipts->resource.hid2me_buffer.dma_addr = 0;
  5892. + ipts->resource.hid2me_buffer_size = 0;
  5893. + }
  5894. +
  5895. + feedback_buffer = ipts->resource.feedback_buffer;
  5896. + num_of_parallels = ipts_get_num_of_parallel_buffers(ipts);
  5897. + for (i = 0; i < num_of_parallels; i++) {
  5898. +
  5899. + if (!feedback_buffer[i].addr)
  5900. + continue;
  5901. +
  5902. + dmam_free_coherent(&ipts->cldev->dev,
  5903. + ipts->device_info.feedback_size,
  5904. + feedback_buffer[i].addr, feedback_buffer[i].dma_addr);
  5905. +
  5906. + feedback_buffer[i].addr = 0;
  5907. + feedback_buffer[i].dma_addr = 0;
  5908. + }
  5909. +}
  5910. +
  5911. +static int allocate_common_resource(struct ipts_info *ipts)
  5912. +{
  5913. + char *addr, *me2hid_addr;
  5914. + struct ipts_buffer_info *feedback_buffer;
  5915. + dma_addr_t dma_addr;
  5916. + int i, ret = 0, num_of_parallels;
  5917. + u32 buffer_size;
  5918. +
  5919. + buffer_size = ipts->device_info.feedback_size;
  5920. +
  5921. + addr = dmam_alloc_coherent(&ipts->cldev->dev, buffer_size, &dma_addr,
  5922. + GFP_ATOMIC | __GFP_ZERO);
  5923. + if (addr == NULL)
  5924. + return -ENOMEM;
  5925. +
  5926. + me2hid_addr = devm_kzalloc(&ipts->cldev->dev, buffer_size, GFP_KERNEL);
  5927. + if (me2hid_addr == NULL) {
  5928. + ret = -ENOMEM;
  5929. + goto release_resource;
  5930. + }
  5931. +
  5932. + ipts->resource.hid2me_buffer.addr = addr;
  5933. + ipts->resource.hid2me_buffer.dma_addr = dma_addr;
  5934. + ipts->resource.hid2me_buffer_size = buffer_size;
  5935. + ipts->resource.me2hid_buffer = me2hid_addr;
  5936. +
  5937. + feedback_buffer = ipts->resource.feedback_buffer;
  5938. + num_of_parallels = ipts_get_num_of_parallel_buffers(ipts);
  5939. +
  5940. + for (i = 0; i < num_of_parallels; i++) {
  5941. + feedback_buffer[i].addr = dmam_alloc_coherent(&ipts->cldev->dev,
  5942. + ipts->device_info.feedback_size,
  5943. + &feedback_buffer[i].dma_addr, GFP_ATOMIC|__GFP_ZERO);
  5944. +
  5945. + if (feedback_buffer[i].addr == NULL) {
  5946. + ret = -ENOMEM;
  5947. + goto release_resource;
  5948. + }
  5949. + }
  5950. +
  5951. + return 0;
  5952. +
  5953. +release_resource:
  5954. + free_common_resource(ipts);
  5955. +
  5956. + return ret;
  5957. +}
  5958. +
  5959. +void ipts_free_raw_data_resource(struct ipts_info *ipts)
  5960. +{
  5961. + if (ipts_is_raw_data_resource_ready(ipts)) {
  5962. + ipts->resource.raw_data_resource_ready = false;
  5963. + ipts_release_kernels(ipts);
  5964. + }
  5965. +}
  5966. +
  5967. +static int allocate_hid_resource(struct ipts_info *ipts)
  5968. +{
  5969. + struct ipts_buffer_info *buffer_hid;
  5970. +
  5971. + // hid mode uses only one touch data buffer
  5972. + buffer_hid = &ipts->resource.touch_data_buffer_hid;
  5973. + buffer_hid->addr = dmam_alloc_coherent(&ipts->cldev->dev,
  5974. + ipts->device_info.frame_size, &buffer_hid->dma_addr,
  5975. + GFP_ATOMIC|__GFP_ZERO);
  5976. +
  5977. + if (buffer_hid->addr == NULL)
  5978. + return -ENOMEM;
  5979. +
  5980. + return 0;
  5981. +}
  5982. +
  5983. +static void free_hid_resource(struct ipts_info *ipts)
  5984. +{
  5985. + struct ipts_buffer_info *buffer_hid;
  5986. +
  5987. + buffer_hid = &ipts->resource.touch_data_buffer_hid;
  5988. + if (buffer_hid->addr) {
  5989. + dmam_free_coherent(&ipts->cldev->dev,
  5990. + ipts->device_info.frame_size,
  5991. + buffer_hid->addr, buffer_hid->dma_addr);
  5992. +
  5993. + buffer_hid->addr = 0;
  5994. + buffer_hid->dma_addr = 0;
  5995. + }
  5996. +}
  5997. +
  5998. +int ipts_allocate_default_resource(struct ipts_info *ipts)
  5999. +{
  6000. + int ret;
  6001. +
  6002. + ret = allocate_common_resource(ipts);
  6003. + if (ret) {
  6004. + ipts_dbg(ipts, "cannot allocate common resource\n");
  6005. + return ret;
  6006. + }
  6007. +
  6008. + ret = allocate_hid_resource(ipts);
  6009. + if (ret) {
  6010. + ipts_dbg(ipts, "cannot allocate hid resource\n");
  6011. + free_common_resource(ipts);
  6012. + return ret;
  6013. + }
  6014. +
  6015. + ipts->resource.default_resource_ready = true;
  6016. +
  6017. + return 0;
  6018. +}
  6019. +
  6020. +void ipts_free_default_resource(struct ipts_info *ipts)
  6021. +{
  6022. + if (ipts_is_default_resource_ready(ipts)) {
  6023. + ipts->resource.default_resource_ready = false;
  6024. + free_hid_resource(ipts);
  6025. + free_common_resource(ipts);
  6026. + }
  6027. +}
  6028. +
  6029. +int ipts_allocate_raw_data_resource(struct ipts_info *ipts)
  6030. +{
  6031. + int ret = 0;
  6032. +
  6033. + ret = ipts_init_kernels(ipts);
  6034. + if (ret)
  6035. + return ret;
  6036. +
  6037. + ipts->resource.raw_data_resource_ready = true;
  6038. + return 0;
  6039. +}
  6040. +
  6041. +static void get_hid_only_smw_cmd_data(struct ipts_info *ipts,
  6042. + struct touch_sensor_set_mem_window_cmd_data *data,
  6043. + struct ipts_resource *resrc)
  6044. +{
  6045. + struct ipts_buffer_info *touch_buf;
  6046. + struct ipts_buffer_info *feedback_buf;
  6047. +
  6048. + touch_buf = &resrc->touch_data_buffer_hid;
  6049. + feedback_buf = &resrc->feedback_buffer[0];
  6050. +
  6051. + data->touch_data_buffer_addr_lower[0] =
  6052. + lower_32_bits(touch_buf->dma_addr);
  6053. +
  6054. + data->touch_data_buffer_addr_upper[0] =
  6055. + upper_32_bits(touch_buf->dma_addr);
  6056. +
  6057. + data->feedback_buffer_addr_lower[0] =
  6058. + lower_32_bits(feedback_buf->dma_addr);
  6059. +
  6060. + data->feedback_buffer_addr_upper[0] =
  6061. + upper_32_bits(feedback_buf->dma_addr);
  6062. +}
  6063. +
  6064. +static void get_raw_data_only_smw_cmd_data(struct ipts_info *ipts,
  6065. + struct touch_sensor_set_mem_window_cmd_data *data,
  6066. + struct ipts_resource *resrc)
  6067. +{
  6068. + u64 wq_tail_phy_addr;
  6069. + u64 cookie_phy_addr;
  6070. + struct ipts_buffer_info *touch_buf;
  6071. + struct ipts_buffer_info *feedback_buf;
  6072. + int i, num_of_parallels;
  6073. +
  6074. + touch_buf = resrc->touch_data_buffer_raw;
  6075. + feedback_buf = resrc->feedback_buffer;
  6076. +
  6077. + num_of_parallels = ipts_get_num_of_parallel_buffers(ipts);
  6078. + for (i = 0; i < num_of_parallels; i++) {
  6079. + data->touch_data_buffer_addr_lower[i] =
  6080. + lower_32_bits(touch_buf[i].dma_addr);
  6081. +
  6082. + data->touch_data_buffer_addr_upper[i] =
  6083. + upper_32_bits(touch_buf[i].dma_addr);
  6084. +
  6085. + data->feedback_buffer_addr_lower[i] =
  6086. + lower_32_bits(feedback_buf[i].dma_addr);
  6087. +
  6088. + data->feedback_buffer_addr_upper[i] =
  6089. + upper_32_bits(feedback_buf[i].dma_addr);
  6090. + }
  6091. +
  6092. + wq_tail_phy_addr = resrc->wq_info.wq_tail_phy_addr;
  6093. + data->tail_offset_addr_lower = lower_32_bits(wq_tail_phy_addr);
  6094. + data->tail_offset_addr_upper = upper_32_bits(wq_tail_phy_addr);
  6095. +
  6096. + cookie_phy_addr = resrc->wq_info.db_phy_addr +
  6097. + resrc->wq_info.db_cookie_offset;
  6098. +
  6099. + data->doorbell_cookie_addr_lower = lower_32_bits(cookie_phy_addr);
  6100. + data->doorbell_cookie_addr_upper = upper_32_bits(cookie_phy_addr);
  6101. + data->work_queue_size = resrc->wq_info.wq_size;
  6102. + data->work_queue_item_size = resrc->wq_item_size;
  6103. +}
  6104. +
  6105. +void ipts_get_set_mem_window_cmd_data(struct ipts_info *ipts,
  6106. + struct touch_sensor_set_mem_window_cmd_data *data)
  6107. +{
  6108. + struct ipts_resource *resrc = &ipts->resource;
  6109. +
  6110. + if (ipts->sensor_mode == TOUCH_SENSOR_MODE_RAW_DATA)
  6111. + get_raw_data_only_smw_cmd_data(ipts, data, resrc);
  6112. + else if (ipts->sensor_mode == TOUCH_SENSOR_MODE_HID)
  6113. + get_hid_only_smw_cmd_data(ipts, data, resrc);
  6114. +
  6115. + // hid2me is common for "raw data" and "hid"
  6116. + data->hid2me_buffer_addr_lower =
  6117. + lower_32_bits(resrc->hid2me_buffer.dma_addr);
  6118. +
  6119. + data->hid2me_buffer_addr_upper =
  6120. + upper_32_bits(resrc->hid2me_buffer.dma_addr);
  6121. +
  6122. + data->hid2me_buffer_size = resrc->hid2me_buffer_size;
  6123. +}
  6124. +
  6125. +void ipts_set_input_buffer(struct ipts_info *ipts, int parallel_idx,
  6126. + u8 *cpu_addr, u64 dma_addr)
  6127. +{
  6128. + struct ipts_buffer_info *touch_buf;
  6129. +
  6130. + touch_buf = ipts->resource.touch_data_buffer_raw;
  6131. + touch_buf[parallel_idx].dma_addr = dma_addr;
  6132. + touch_buf[parallel_idx].addr = cpu_addr;
  6133. +}
  6134. +
  6135. +void ipts_set_output_buffer(struct ipts_info *ipts, int parallel_idx,
  6136. + int output_idx, u8 *cpu_addr, u64 dma_addr)
  6137. +{
  6138. + struct ipts_buffer_info *output_buf;
  6139. +
  6140. + output_buf = &ipts->resource.raw_data_mode_output_buffer
  6141. + [parallel_idx][output_idx];
  6142. +
  6143. + output_buf->dma_addr = dma_addr;
  6144. + output_buf->addr = cpu_addr;
  6145. +}
  6146. diff --git a/drivers/misc/ipts/resource.h b/drivers/misc/ipts/resource.h
  6147. new file mode 100644
  6148. index 000000000000..27b9c17fcb89
  6149. --- /dev/null
  6150. +++ b/drivers/misc/ipts/resource.h
  6151. @@ -0,0 +1,26 @@
  6152. +/* SPDX-License-Identifier: GPL-2.0-or-later */
  6153. +/*
  6154. + *
  6155. + * Intel Precise Touch & Stylus
  6156. + * Copyright (c) 2016 Intel Corporation
  6157. + *
  6158. + */
  6159. +
  6160. +#ifndef _IPTS_RESOURCE_H_
  6161. +#define _IPTS_RESOURCE_H_
  6162. +
  6163. +int ipts_allocate_default_resource(struct ipts_info *ipts);
  6164. +void ipts_free_default_resource(struct ipts_info *ipts);
  6165. +int ipts_allocate_raw_data_resource(struct ipts_info *ipts);
  6166. +void ipts_free_raw_data_resource(struct ipts_info *ipts);
  6167. +
  6168. +void ipts_get_set_mem_window_cmd_data(struct ipts_info *ipts,
  6169. + struct touch_sensor_set_mem_window_cmd_data *data);
  6170. +
  6171. +void ipts_set_input_buffer(struct ipts_info *ipts, int parallel_idx,
  6172. + u8 *cpu_addr, u64 dma_addr);
  6173. +
  6174. +void ipts_set_output_buffer(struct ipts_info *ipts, int parallel_idx,
  6175. + int output_idx, u8 *cpu_addr, u64 dma_addr);
  6176. +
  6177. +#endif // _IPTS_RESOURCE_H_
  6178. diff --git a/drivers/misc/ipts/sensor-regs.h b/drivers/misc/ipts/sensor-regs.h
  6179. new file mode 100644
  6180. index 000000000000..490de6fd9bc1
  6181. --- /dev/null
  6182. +++ b/drivers/misc/ipts/sensor-regs.h
  6183. @@ -0,0 +1,827 @@
  6184. +/* SPDX-License-Identifier: GPL-2.0-or-later */
  6185. +/*
  6186. + *
  6187. + * Intel Precise Touch & Stylus
  6188. + * Copyright (c) 2013-2016 Intel Corporation
  6189. + *
  6190. + */
  6191. +
  6192. +#ifndef _IPTS_SENSOR_REGS_H_
  6193. +#define _IPTS_SENSOR_REGS_H_
  6194. +
  6195. +#include <linux/build_bug.h>
  6196. +
  6197. +#pragma pack(1)
  6198. +
  6199. +/*
  6200. + * Compatibility versions for this header file
  6201. + */
  6202. +#define TOUCH_EDS_REV_MINOR 0
  6203. +#define TOUCH_EDS_REV_MAJOR 1
  6204. +#define TOUCH_EDS_INTF_REV 1
  6205. +#define TOUCH_PROTOCOL_VER 0
  6206. +
  6207. +/*
  6208. + * Offset 00h: TOUCH_STS: Status Register
  6209. + * This register is read by the SPI Controller immediately following
  6210. + * an interrupt.
  6211. + */
  6212. +#define TOUCH_STS_REG_OFFSET 0x00
  6213. +
  6214. +#define TOUCH_SYNC_BYTE_VALUE 0x5A
  6215. +
  6216. +/*
  6217. + * Offset 04h: TOUCH_FRAME_CHAR: Frame Characteristics Register
  6218. + * This registers describes the characteristics of each data frame read by the
  6219. + * SPI Controller in response to a touch interrupt.
  6220. + */
  6221. +#define TOUCH_FRAME_CHAR_REG_OFFSET 0x04
  6222. +
  6223. +/*
  6224. + * Offset 08h: Touch Error Register
  6225. + */
  6226. +#define TOUCH_ERR_REG_OFFSET 0x08
  6227. +
  6228. +/*
  6229. + * Offset 10h: Touch Identification Register
  6230. + */
  6231. +#define TOUCH_ID_REG_OFFSET 0x10
  6232. +#define TOUCH_ID_REG_VALUE 0x43495424
  6233. +
  6234. +/*
  6235. + * Offset 14h: TOUCH_DATA_SZ: Touch Data Size Register
  6236. + * This register describes the maximum size of frames and feedback data
  6237. + */
  6238. +#define TOUCH_DATA_SZ_REG_OFFSET 0x14
  6239. +
  6240. +#define TOUCH_MAX_FRAME_SIZE_INCREMENT 64
  6241. +#define TOUCH_MAX_FEEDBACK_SIZE_INCREMENT 64
  6242. +
  6243. +/*
  6244. + * Max allowed frame size 32KB
  6245. + * Max allowed feedback size 16KB
  6246. + */
  6247. +#define TOUCH_SENSOR_MAX_FRAME_SIZE (32 * 1024)
  6248. +#define TOUCH_SENSOR_MAX_FEEDBACK_SIZE (16 * 1024)
  6249. +
  6250. +/*
  6251. + * Offset 18h: TOUCH_CAPABILITIES: Touch Capabilities Register
  6252. + * This register informs the host as to the capabilities of the touch IC.
  6253. + */
  6254. +#define TOUCH_CAPS_REG_OFFSET 0x18
  6255. +
  6256. +#define TOUCH_BULK_DATA_MAX_WRITE_INCREMENT 64
  6257. +
  6258. +/*
  6259. + * Offset 1Ch: TOUCH_CFG: Touch Configuration Register
  6260. + * This register allows the SPI Controller to configure the touch sensor as
  6261. + * needed during touch operations.
  6262. + */
  6263. +#define TOUCH_CFG_REG_OFFSET 0x1C
  6264. +
  6265. +/*
  6266. + * Offset 20h: TOUCH_CMD: Touch Command Register
  6267. + * This register is used for sending commands to the Touch IC.
  6268. + */
  6269. +#define TOUCH_CMD_REG_OFFSET 0x20
  6270. +
  6271. +/*
  6272. + * Offset 24h: Power Management Control
  6273. + * This register is used for active power management. The Touch IC is allowed
  6274. + * to mover from Doze or Armed to Sensing after a touch has occurred. All other
  6275. + * transitions will be made at the request of the SPI Controller.
  6276. + */
  6277. +#define TOUCH_PWR_MGMT_CTRL_REG_OFFSET 0x24
  6278. +
  6279. +/*
  6280. + * Offset 28h: Vendor HW Information Register
  6281. + * This register is used to relay Intel-assigned vendor ID information to the
  6282. + * SPI Controller, which may be forwarded to SW running on the host CPU.
  6283. + */
  6284. +#define TOUCH_VEN_HW_INFO_REG_OFFSET 0x28
  6285. +
  6286. +/*
  6287. + * Offset 2Ch: HW Revision ID Register
  6288. + * This register is used to relay vendor HW revision information to the SPI
  6289. + * Controller which may be forwarded to SW running on the host CPU.
  6290. + */
  6291. +#define TOUCH_HW_REV_REG_OFFSET 0x2C
  6292. +
  6293. +/*
  6294. + * Offset 30h: FW Revision ID Register
  6295. + * This register is used to relay vendor FW revision information to the SPI
  6296. + * Controller which may be forwarded to SW running on the host CPU.
  6297. + */
  6298. +#define TOUCH_FW_REV_REG_OFFSET 0x30
  6299. +
  6300. +/*
  6301. + * Offset 34h: Compatibility Revision ID Register
  6302. + * This register is used to relay vendor compatibility information to the SPI
  6303. + * Controller which may be forwarded to SW running on the host CPU.
  6304. + * Compatibility Information is a numeric value given by Intel to the Touch IC
  6305. + * vendor based on the major and minor revision of the EDS supported. From a
  6306. + * nomenclature point of view in an x.y revision number of the EDS, the major
  6307. + * version is the value of x and the minor version is the value of y. For
  6308. + * example, a Touch IC supporting an EDS version of 0.61 would contain a major
  6309. + * version of 0 and a minor version of 61 in the register.
  6310. + */
  6311. +#define TOUCH_COMPAT_REV_REG_OFFSET 0x34
  6312. +
  6313. +/*
  6314. + * Touch Register Block is the full set of registers from offset 0x00h to 0x3F
  6315. + * This is the entire set of registers needed for normal touch operation. It
  6316. + * does not include test registers such as TOUCH_TEST_CTRL_REG
  6317. + */
  6318. +#define TOUCH_REG_BLOCK_OFFSET TOUCH_STS_REG_OFFSET
  6319. +
  6320. +/*
  6321. + * Offset 40h: Test Control Register
  6322. + * This register
  6323. + */
  6324. +#define TOUCH_TEST_CTRL_REG_OFFSET 0x40
  6325. +
  6326. +/*
  6327. + * Offsets 0x000 to 0xFFF are reserved for Intel-defined Registers
  6328. + */
  6329. +#define TOUCH_REGISTER_LIMIT 0xFFF
  6330. +
  6331. +/*
  6332. + * Data Window: Address 0x1000-0x1FFFF
  6333. + * The data window is reserved for writing and reading large quantities of
  6334. + * data to and from the sensor.
  6335. + */
  6336. +#define TOUCH_DATA_WINDOW_OFFSET 0x1000
  6337. +#define TOUCH_DATA_WINDOW_LIMIT 0x1FFFF
  6338. +
  6339. +#define TOUCH_SENSOR_MAX_OFFSET TOUCH_DATA_WINDOW_LIMIT
  6340. +
  6341. +enum touch_sts_reg_int_type {
  6342. + // Touch Data Available
  6343. + TOUCH_STS_REG_INT_TYPE_DATA_AVAIL = 0,
  6344. +
  6345. + // Reset Occurred
  6346. + TOUCH_STS_REG_INT_TYPE_RESET_OCCURRED,
  6347. +
  6348. + // Error Occurred
  6349. + TOUCH_STS_REG_INT_TYPE_ERROR_OCCURRED,
  6350. +
  6351. + // Vendor specific data, treated same as raw frame
  6352. + TOUCH_STS_REG_INT_TYPE_VENDOR_DATA,
  6353. +
  6354. + // Get Features response data available
  6355. + TOUCH_STS_REG_INT_TYPE_GET_FEATURES,
  6356. +
  6357. + TOUCH_STS_REG_INT_TYPE_MAX
  6358. +};
  6359. +static_assert(sizeof(enum touch_sts_reg_int_type) == 4);
  6360. +
  6361. +enum touch_sts_reg_pwr_state {
  6362. + // Sleep
  6363. + TOUCH_STS_REG_PWR_STATE_SLEEP = 0,
  6364. +
  6365. + // Doze
  6366. + TOUCH_STS_REG_PWR_STATE_DOZE,
  6367. +
  6368. + // Armed
  6369. + TOUCH_STS_REG_PWR_STATE_ARMED,
  6370. +
  6371. + // Sensing
  6372. + TOUCH_STS_REG_PWR_STATE_SENSING,
  6373. +
  6374. + TOUCH_STS_REG_PWR_STATE_MAX
  6375. +};
  6376. +static_assert(sizeof(enum touch_sts_reg_pwr_state) == 4);
  6377. +
  6378. +enum touch_sts_reg_init_state {
  6379. + // Ready for normal operation
  6380. + TOUCH_STS_REG_INIT_STATE_READY_FOR_OP = 0,
  6381. +
  6382. + // Touch IC needs its Firmware loaded
  6383. + TOUCH_STS_REG_INIT_STATE_FW_NEEDED,
  6384. +
  6385. + // Touch IC needs its Data loaded
  6386. + TOUCH_STS_REG_INIT_STATE_DATA_NEEDED,
  6387. +
  6388. + // Error info in TOUCH_ERR_REG
  6389. + TOUCH_STS_REG_INIT_STATE_INIT_ERROR,
  6390. +
  6391. + TOUCH_STS_REG_INIT_STATE_MAX
  6392. +};
  6393. +static_assert(sizeof(enum touch_sts_reg_init_state) == 4);
  6394. +
  6395. +union touch_sts_reg {
  6396. + u32 reg_value;
  6397. + struct {
  6398. + // When set, this indicates the hardware has data
  6399. + // that needs to be read.
  6400. + u32 int_status:1;
  6401. +
  6402. + // see TOUCH_STS_REG_INT_TYPE
  6403. + u32 int_type:4;
  6404. +
  6405. + // see TOUCH_STS_REG_PWR_STATE
  6406. + u32 pwr_state:2;
  6407. +
  6408. + // see TOUCH_STS_REG_INIT_STATE
  6409. + u32 init_state:2;
  6410. +
  6411. + // Busy bit indicates that sensor cannot
  6412. + // accept writes at this time
  6413. + u32 busy:1;
  6414. +
  6415. + // Reserved
  6416. + u32 reserved:14;
  6417. +
  6418. + // Synchronization bit, should always be TOUCH_SYNC_BYTE_VALUE
  6419. + u32 sync_byte:8;
  6420. + } fields;
  6421. +};
  6422. +static_assert(sizeof(union touch_sts_reg) == 4);
  6423. +
  6424. +union touch_frame_char_reg {
  6425. + u32 reg_value;
  6426. + struct {
  6427. + // Micro-Frame Size (MFS): Indicates the size of a touch
  6428. + // micro-frame in byte increments. When a micro-frame is to be
  6429. + // read for processing (in data mode), this is the total number
  6430. + // of bytes that must be read per interrupt, split into
  6431. + // multiple read commands no longer than RPS.
  6432. + // Maximum micro-frame size is 256KB.
  6433. + u32 microframe_size:18;
  6434. +
  6435. + // Micro-Frames per Frame (MFPF): Indicates the number of
  6436. + // micro-frames per frame. If a sensor's frame does not contain
  6437. + // micro-frames this value will be 1. Valid values are 1-31.
  6438. + u32 microframes_per_frame:5;
  6439. +
  6440. + // Micro-Frame Index (MFI): Indicates the index of the
  6441. + // micro-frame within a frame. This allows the SPI Controller
  6442. + // to maintain synchronization with the sensor and determine
  6443. + // when the final micro-frame has arrived.
  6444. + // Valid values are 1-31.
  6445. + u32 microframe_index:5;
  6446. +
  6447. + // HID/Raw Data: This bit describes whether the data from the
  6448. + // sensor is Raw data or a HID report. When set, the data
  6449. + // is a HID report.
  6450. + u32 hid_report:1;
  6451. +
  6452. + // Reserved
  6453. + u32 reserved:3;
  6454. + } fields;
  6455. +};
  6456. +static_assert(sizeof(union touch_frame_char_reg) == 4);
  6457. +
  6458. +// bit definition is vendor specific
  6459. +union touch_err_reg {
  6460. + u32 reg_value;
  6461. + struct {
  6462. + u32 invalid_fw:1;
  6463. + u32 invalid_data:1;
  6464. + u32 self_test_failed:1;
  6465. + u32 reserved:12;
  6466. + u32 fatal_error:1;
  6467. + u32 vendor_errors:16;
  6468. + } fields;
  6469. +};
  6470. +static_assert(sizeof(union touch_err_reg) == 4);
  6471. +
  6472. +union touch_data_sz_reg {
  6473. + u32 reg_value;
  6474. + struct {
  6475. + // This value describes the maximum frame size in
  6476. + // 64byte increments.
  6477. + u32 max_frame_size:12;
  6478. +
  6479. + // This value describes the maximum feedback size in
  6480. + // 64byte increments.
  6481. + u32 max_feedback_size:8;
  6482. +
  6483. + // Reserved
  6484. + u32 reserved:12;
  6485. + } fields;
  6486. +};
  6487. +static_assert(sizeof(union touch_data_sz_reg) == 4);
  6488. +
  6489. +enum touch_caps_reg_read_delay_time {
  6490. + TOUCH_CAPS_REG_READ_DELAY_TIME_0,
  6491. + TOUCH_CAPS_REG_READ_DELAY_TIME_10uS,
  6492. + TOUCH_CAPS_REG_READ_DELAY_TIME_50uS,
  6493. + TOUCH_CAPS_REG_READ_DELAY_TIME_100uS,
  6494. + TOUCH_CAPS_REG_READ_DELAY_TIME_150uS,
  6495. + TOUCH_CAPS_REG_READ_DELAY_TIME_250uS,
  6496. + TOUCH_CAPS_REG_READ_DELAY_TIME_500uS,
  6497. + TOUCH_CAPS_REG_READ_DELAY_TIME_1mS,
  6498. +};
  6499. +static_assert(sizeof(enum touch_caps_reg_read_delay_time) == 4);
  6500. +
  6501. +union touch_caps_reg {
  6502. + u32 reg_value;
  6503. + struct {
  6504. + // Reserved for future frequency
  6505. + u32 reserved0:1;
  6506. +
  6507. + // 17 MHz (14 MHz on Atom) Supported
  6508. + // 0b - Not supported, 1b - Supported
  6509. + u32 supported_17Mhz:1;
  6510. +
  6511. + // 30 MHz (25MHz on Atom) Supported
  6512. + // 0b - Not supported, 1b - Supported
  6513. + u32 supported_30Mhz:1;
  6514. +
  6515. + // 50 MHz Supported
  6516. + // 0b - Not supported, 1b - Supported
  6517. + u32 supported_50Mhz:1;
  6518. +
  6519. + // Reserved
  6520. + u32 reserved1:4;
  6521. +
  6522. + // Single I/O Supported
  6523. + // 0b - Not supported, 1b - Supported
  6524. + u32 supported_single_io:1;
  6525. +
  6526. + // Dual I/O Supported
  6527. + // 0b - Not supported, 1b - Supported
  6528. + u32 supported_dual_io:1;
  6529. +
  6530. + // Quad I/O Supported
  6531. + // 0b - Not supported, 1b - Supported
  6532. + u32 supported_quad_io:1;
  6533. +
  6534. + // Bulk Data Area Max Write Size: The amount of data the SPI
  6535. + // Controller can write to the bulk data area before it has to
  6536. + // poll the busy bit. This field is in multiples of 64 bytes.
  6537. + // The SPI Controller will write the amount of data specified
  6538. + // in this field, then check and wait for the Status.Busy bit
  6539. + // to be zero before writing the next data chunk. This field is
  6540. + // 6 bits long, allowing for 4KB of contiguous writes w/o a
  6541. + // poll of the busy bit. If this field is 0x00 the Touch IC has
  6542. + // no limit in the amount of data the SPI Controller can write
  6543. + // to the bulk data area.
  6544. + u32 bulk_data_max_write:6;
  6545. +
  6546. + // Read Delay Timer Value: This field describes the delay the
  6547. + // SPI Controller will initiate when a read interrupt follows
  6548. + // a write data command. Uses values from
  6549. + // TOUCH_CAPS_REG_READ_DELAY_TIME
  6550. + u32 read_delay_timer_value:3;
  6551. +
  6552. + // Reserved
  6553. + u32 reserved2:4;
  6554. +
  6555. + // Maximum Touch Points: A byte value based on the
  6556. + // HID descriptor definition.
  6557. + u32 max_touch_points:8;
  6558. + } fields;
  6559. +};
  6560. +static_assert(sizeof(union touch_caps_reg) == 4);
  6561. +
  6562. +enum touch_cfg_reg_bulk_xfer_size {
  6563. + // Bulk Data Transfer Size is 4 bytes
  6564. + TOUCH_CFG_REG_BULK_XFER_SIZE_4B = 0,
  6565. +
  6566. + // Bulk Data Transfer Size is 8 bytes
  6567. + TOUCH_CFG_REG_BULK_XFER_SIZE_8B,
  6568. +
  6569. + // Bulk Data Transfer Size is 16 bytes
  6570. + TOUCH_CFG_REG_BULK_XFER_SIZE_16B,
  6571. +
  6572. + // Bulk Data Transfer Size is 32 bytes
  6573. + TOUCH_CFG_REG_BULK_XFER_SIZE_32B,
  6574. +
  6575. + // Bulk Data Transfer Size is 64 bytes
  6576. + TOUCH_CFG_REG_BULK_XFER_SIZE_64B,
  6577. +
  6578. + TOUCH_CFG_REG_BULK_XFER_SIZE_MAX
  6579. +};
  6580. +static_assert(sizeof(enum touch_cfg_reg_bulk_xfer_size) == 4);
  6581. +
  6582. +/*
  6583. + * Frequency values used by TOUCH_CFG_REG
  6584. + * and TOUCH_SENSOR_GET_DEVICE_INFO_RSP_DATA.
  6585. + */
  6586. +enum touch_freq {
  6587. + // Reserved value
  6588. + TOUCH_FREQ_RSVD = 0,
  6589. +
  6590. + // Sensor set for 17MHz operation (14MHz on Atom)
  6591. + TOUCH_FREQ_17MHZ,
  6592. +
  6593. + // Sensor set for 30MHz operation (25MHz on Atom)
  6594. + TOUCH_FREQ_30MHZ,
  6595. +
  6596. + // Invalid value
  6597. + TOUCH_FREQ_MAX
  6598. +};
  6599. +static_assert(sizeof(enum touch_freq) == 4);
  6600. +
  6601. +union touch_cfg_reg {
  6602. + u32 reg_value;
  6603. + struct {
  6604. + // Touch Enable (TE): This bit is used as a HW semaphore for
  6605. + // the Touch IC to guarantee to the SPI Controller to that
  6606. + // (when 0) no sensing operations will occur and only the Reset
  6607. + // interrupt will be generated.
  6608. + //
  6609. + // When TE is cleared by the SPI
  6610. + // Controller:
  6611. + // - TICs must flush all output buffers
  6612. + // - TICs must De-assert any pending interrupt
  6613. + // - ME must throw away any partial frame and pending
  6614. + // interrupt must be cleared/not serviced.
  6615. + //
  6616. + // The SPI Controller will only modify the configuration of the
  6617. + // TIC when TE is cleared.
  6618. + // TE is defaulted to 0h on a power-on reset.
  6619. + u32 touch_enable:1;
  6620. +
  6621. + // Data/HID Packet Mode (DHPM)
  6622. + // Raw Data Mode: 0h, HID Packet Mode: 1h
  6623. + u32 dhpm:1;
  6624. +
  6625. + // Bulk Data Transfer Size: This field represents the amount
  6626. + // of data written to the Bulk Data Area
  6627. + // (SPI Offset 0x1000-0x2FFF) in a single SPI write protocol
  6628. + u32 bulk_xfer_size:4;
  6629. +
  6630. + // Frequency Select: Frequency for the TouchIC to run at.
  6631. + // Use values from TOUCH_FREQ
  6632. + u32 freq_select:3;
  6633. +
  6634. + // Reserved
  6635. + u32 reserved:23;
  6636. + } fields;
  6637. +};
  6638. +static_assert(sizeof(union touch_cfg_reg) == 4);
  6639. +
  6640. +enum touch_cmd_reg_code {
  6641. + // No Operation
  6642. + TOUCH_CMD_REG_CODE_NOP = 0,
  6643. +
  6644. + // Soft Reset
  6645. + TOUCH_CMD_REG_CODE_SOFT_RESET,
  6646. +
  6647. + // Prepare All Registers for Read
  6648. + TOUCH_CMD_REG_CODE_PREP_4_READ,
  6649. +
  6650. + // Generate Test Packets according to value in TOUCH_TEST_CTRL_REG
  6651. + TOUCH_CMD_REG_CODE_GEN_TEST_PACKETS,
  6652. +
  6653. + TOUCH_CMD_REG_CODE_MAX
  6654. +};
  6655. +static_assert(sizeof(enum touch_cmd_reg_code) == 4);
  6656. +
  6657. +union touch_cmd_reg {
  6658. + u32 reg_value;
  6659. + struct {
  6660. + // Command Code: See TOUCH_CMD_REG_CODE
  6661. + u32 command_code:8;
  6662. +
  6663. + // Reserved
  6664. + u32 reserved:24;
  6665. + } fields;
  6666. +};
  6667. +static_assert(sizeof(union touch_cmd_reg) == 4);
  6668. +
  6669. +enum touch_pwr_mgmt_ctrl_reg_cmd {
  6670. + // No change to power state
  6671. + TOUCH_PWR_MGMT_CTRL_REG_CMD_NOP = 0,
  6672. +
  6673. + // Sleep - set when the system goes into connected standby
  6674. + TOUCH_PWR_MGMT_CTRL_REG_CMD_SLEEP,
  6675. +
  6676. + // Doze - set after 300 seconds of inactivity
  6677. + TOUCH_PWR_MGMT_CTRL_REG_CMD_DOZE,
  6678. +
  6679. + // Armed - Set by FW when a "finger off" message is
  6680. + // received from the EUs
  6681. + TOUCH_PWR_MGMT_CTRL_REG_CMD_ARMED,
  6682. +
  6683. + // Sensing - not typically set by FW
  6684. + TOUCH_PWR_MGMT_CTRL_REG_CMD_SENSING,
  6685. +
  6686. + // Values will result in no change to the power state of the Touch IC
  6687. + TOUCH_PWR_MGMT_CTRL_REG_CMD_MAX
  6688. +};
  6689. +static_assert(sizeof(enum touch_pwr_mgmt_ctrl_reg_cmd) == 4);
  6690. +
  6691. +union touch_pwr_mgmt_ctrl_reg {
  6692. + u32 reg_value;
  6693. + struct {
  6694. + // Power State Command: See TOUCH_PWR_MGMT_CTRL_REG_CMD
  6695. + u32 pwr_state_cmd:3;
  6696. +
  6697. + // Reserved
  6698. + u32 reserved:29;
  6699. + } fields;
  6700. +};
  6701. +static_assert(sizeof(union touch_pwr_mgmt_ctrl_reg) == 4);
  6702. +
  6703. +union touch_ven_hw_info_reg {
  6704. + u32 reg_value;
  6705. + struct {
  6706. + // Touch Sensor Vendor ID
  6707. + u32 vendor_id:16;
  6708. +
  6709. + // Touch Sensor Device ID
  6710. + u32 device_id:16;
  6711. + } fields;
  6712. +};
  6713. +static_assert(sizeof(union touch_ven_hw_info_reg) == 4);
  6714. +
  6715. +union touch_compat_rev_reg {
  6716. + u32 reg_value;
  6717. +
  6718. + struct {
  6719. + // EDS Minor Revision
  6720. + u8 minor;
  6721. +
  6722. + // EDS Major Revision
  6723. + u8 major;
  6724. +
  6725. + // Interface Revision Number (from EDS)
  6726. + u8 intf_rev;
  6727. +
  6728. + // EU Kernel Compatibility Version - vendor specific value
  6729. + u8 kernel_compat_ver;
  6730. + } fields;
  6731. +};
  6732. +static_assert(sizeof(union touch_compat_rev_reg) == 4);
  6733. +
  6734. +struct touch_reg_block {
  6735. + // 0x00
  6736. + union touch_sts_reg sts_reg;
  6737. +
  6738. + // 0x04
  6739. + union touch_frame_char_reg frame_char_reg;
  6740. +
  6741. + // 0x08
  6742. + union touch_err_reg error_reg;
  6743. +
  6744. + // 0x0C
  6745. + u32 reserved0;
  6746. +
  6747. + // 0x10 - expected value is "$TIC" or 0x43495424
  6748. + u32 id_reg;
  6749. +
  6750. + // 0x14
  6751. + union touch_data_sz_reg data_size_reg;
  6752. +
  6753. + // 0x18
  6754. + union touch_caps_reg caps_reg;
  6755. +
  6756. + // 0x1C
  6757. + union touch_cfg_reg cfg_reg;
  6758. +
  6759. + // 0x20
  6760. + union touch_cmd_reg cmd_reg;
  6761. +
  6762. + // 0x24
  6763. + union touch_pwr_mgmt_ctrl_reg pwm_mgme_ctrl_reg;
  6764. +
  6765. + // 0x28
  6766. + union touch_ven_hw_info_reg ven_hw_info_reg;
  6767. +
  6768. + // 0x2C
  6769. + u32 hw_rev_reg;
  6770. +
  6771. + // 0x30
  6772. + u32 fw_rev_reg;
  6773. +
  6774. + // 0x34
  6775. + union touch_compat_rev_reg compat_rev_reg;
  6776. +
  6777. + // 0x38
  6778. + u32 reserved1;
  6779. +
  6780. + // 0x3C
  6781. + u32 reserved2;
  6782. +};
  6783. +static_assert(sizeof(struct touch_reg_block) == 64);
  6784. +
  6785. +union touch_test_ctrl_reg {
  6786. + u32 reg_value;
  6787. + struct {
  6788. + // Size of Test Frame in Raw Data Mode: This field specifies
  6789. + // the test frame size in raw data mode in multiple of 64 bytes.
  6790. + // For example, if this field value is 16, the test frame size
  6791. + // will be 16x64 = 1K.
  6792. + u32 raw_test_frame_size:16;
  6793. +
  6794. + // Number of Raw Data Frames or HID Report Packets Generation.
  6795. + // This field represents the number of test frames or HID
  6796. + // reports to be generated when test mode is enabled. When
  6797. + // multiple packets/frames are generated, they need be
  6798. + // generated at 100 Hz frequency, i.e. 10ms per packet/frame.
  6799. + u32 num_test_frames:16;
  6800. + } fields;
  6801. +};
  6802. +static_assert(sizeof(union touch_test_ctrl_reg) == 4);
  6803. +
  6804. +/*
  6805. + * The following data structures represent the headers defined in the Data
  6806. + * Structures chapter of the Intel Integrated Touch EDS
  6807. + */
  6808. +
  6809. +// Enumeration used in TOUCH_RAW_DATA_HDR
  6810. +enum touch_raw_data_types {
  6811. + TOUCH_RAW_DATA_TYPE_FRAME = 0,
  6812. +
  6813. + // RawData will be the TOUCH_ERROR struct below
  6814. + TOUCH_RAW_DATA_TYPE_ERROR,
  6815. +
  6816. + // Set when InterruptType is Vendor Data
  6817. + TOUCH_RAW_DATA_TYPE_VENDOR_DATA,
  6818. +
  6819. + TOUCH_RAW_DATA_TYPE_HID_REPORT,
  6820. + TOUCH_RAW_DATA_TYPE_GET_FEATURES,
  6821. + TOUCH_RAW_DATA_TYPE_MAX
  6822. +};
  6823. +static_assert(sizeof(enum touch_raw_data_types) == 4);
  6824. +
  6825. +// Private data structure. Kernels must copy to HID driver buffer
  6826. +struct touch_hid_private_data {
  6827. + u32 transaction_id;
  6828. + u8 reserved[28];
  6829. +};
  6830. +static_assert(sizeof(struct touch_hid_private_data) == 32);
  6831. +
  6832. +// This is the data structure sent from the PCH FW to the EU kernel
  6833. +struct touch_raw_data_hdr {
  6834. + // use values from TOUCH_RAW_DATA_TYPES
  6835. + u32 data_type;
  6836. +
  6837. + // The size in bytes of the raw data read from the sensor, does not
  6838. + // include TOUCH_RAW_DATA_HDR. Will be the sum of all uFrames, or size
  6839. + // of TOUCH_ERROR for if DataType is TOUCH_RAW_DATA_TYPE_ERROR
  6840. + u32 raw_data_size_bytes;
  6841. +
  6842. + // An ID to qualify with the feedback data to track buffer usage
  6843. + u32 buffer_id;
  6844. +
  6845. + // Must match protocol version of the EDS
  6846. + u32 protocol_ver;
  6847. +
  6848. + // Copied from the Compatibility Revision ID Reg
  6849. + u8 kernel_compat_id;
  6850. +
  6851. + // Padding to extend header to full 64 bytes and allow for growth
  6852. + u8 reserved[15];
  6853. +
  6854. + // Private data structure. Kernels must copy to HID driver buffer
  6855. + struct touch_hid_private_data hid_private_data;
  6856. +};
  6857. +static_assert(sizeof(struct touch_raw_data_hdr) == 64);
  6858. +
  6859. +struct touch_raw_data {
  6860. + struct touch_raw_data_hdr header;
  6861. +
  6862. + // used to access the raw data as an array and keep the compilers
  6863. + // happy. Actual size of this array is Header.RawDataSizeBytes
  6864. + u8 raw_data[1];
  6865. +};
  6866. +
  6867. +/*
  6868. + * The following section describes the data passed in TOUCH_RAW_DATA.RawData
  6869. + * when DataType equals TOUCH_RAW_DATA_TYPE_ERROR
  6870. + * Note: This data structure is also applied to HID mode
  6871. + */
  6872. +enum touch_err_types {
  6873. + TOUCH_RAW_DATA_ERROR = 0,
  6874. + TOUCH_RAW_ERROR_MAX
  6875. +};
  6876. +static_assert(sizeof(enum touch_err_types) == 4);
  6877. +
  6878. +union touch_me_fw_error {
  6879. + u32 value;
  6880. + struct {
  6881. + u32 invalid_frame_characteristics:1;
  6882. + u32 microframe_index_invalid:1;
  6883. + u32 reserved:30;
  6884. + } fields;
  6885. +};
  6886. +static_assert(sizeof(union touch_me_fw_error) == 4);
  6887. +
  6888. +struct touch_error {
  6889. + // This must be a value from TOUCH_ERROR_TYPES
  6890. + u8 touch_error_type;
  6891. + u8 reserved[3];
  6892. + union touch_me_fw_error touch_me_fw_error;
  6893. +
  6894. + // Contains the value copied from the Touch Error Reg
  6895. + union touch_err_reg touch_error_register;
  6896. +};
  6897. +static_assert(sizeof(struct touch_error) == 12);
  6898. +
  6899. +// Enumeration used in TOUCH_FEEDBACK_BUFFER
  6900. +enum touch_feedback_cmd_types {
  6901. + TOUCH_FEEDBACK_CMD_TYPE_NONE = 0,
  6902. + TOUCH_FEEDBACK_CMD_TYPE_SOFT_RESET,
  6903. + TOUCH_FEEDBACK_CMD_TYPE_GOTO_ARMED,
  6904. + TOUCH_FEEDBACK_CMD_TYPE_GOTO_SENSING,
  6905. + TOUCH_FEEDBACK_CMD_TYPE_GOTO_SLEEP,
  6906. + TOUCH_FEEDBACK_CMD_TYPE_GOTO_DOZE,
  6907. + TOUCH_FEEDBACK_CMD_TYPE_HARD_RESET,
  6908. + TOUCH_FEEDBACK_CMD_TYPE_MAX
  6909. +};
  6910. +static_assert(sizeof(enum touch_feedback_cmd_types) == 4);
  6911. +
  6912. +// Enumeration used in TOUCH_FEEDBACK_HDR
  6913. +enum touch_feedback_data_types {
  6914. + // This is vendor specific feedback to be written to the sensor
  6915. + TOUCH_FEEDBACK_DATA_TYPE_FEEDBACK = 0,
  6916. +
  6917. + // This is a set features command to be written to the sensor
  6918. + TOUCH_FEEDBACK_DATA_TYPE_SET_FEATURES,
  6919. +
  6920. + // This is a get features command to be written to the sensor
  6921. + TOUCH_FEEDBACK_DATA_TYPE_GET_FEATURES,
  6922. +
  6923. + // This is a HID output report to be written to the sensor
  6924. + TOUCH_FEEDBACK_DATA_TYPE_OUTPUT_REPORT,
  6925. +
  6926. + // This is calibration data to be written to system flash
  6927. + TOUCH_FEEDBACK_DATA_TYPE_STORE_DATA,
  6928. +
  6929. + TOUCH_FEEDBACK_DATA_TYPE_MAX
  6930. +};
  6931. +static_assert(sizeof(enum touch_feedback_data_types) == 4);
  6932. +
  6933. +/*
  6934. + * This is the data structure sent from the EU kernels back to the ME FW.
  6935. + * In addition to "feedback" data, the FW can execute a "command" described by
  6936. + * the command type parameter. Any payload data will always be sent to the TIC
  6937. + * first, then any command will be issued.
  6938. + */
  6939. +struct touch_feedback_hdr {
  6940. + // use values from TOUCH_FEEDBACK_CMD_TYPES
  6941. + u32 feedback_cmd_type;
  6942. +
  6943. + // The amount of data to be written to the sensor,
  6944. + // not including the header
  6945. + u32 payload_size_bytes;
  6946. +
  6947. + // The ID of the raw data buffer that generated this feedback data
  6948. + u32 buffer_id;
  6949. +
  6950. + // Must match protocol version of the EDS
  6951. + u32 protocol_ver;
  6952. +
  6953. + // use values from TOUCH_FEEDBACK_DATA_TYPES. This is not relevant
  6954. + // if PayloadSizeBytes is 0
  6955. + u32 feedback_data_type;
  6956. +
  6957. + // The offset from TOUCH_DATA_WINDOW_OFFSET at which to write the
  6958. + // Payload data. Maximum offset is 0x1EFFF.
  6959. + u32 spi_offest;
  6960. +
  6961. + // Padding to extend header to full 64 bytes and allow for growth
  6962. + u8 reserved[40];
  6963. +};
  6964. +static_assert(sizeof(struct touch_feedback_hdr) == 64);
  6965. +
  6966. +struct touch_feedback_buffer {
  6967. + struct touch_feedback_hdr Header;
  6968. +
  6969. + // used to access the feedback data as an array and keep the compilers
  6970. + // happy. Actual size of this array is Header.PayloadSizeBytes
  6971. + u8 feedback_data[1];
  6972. +};
  6973. +
  6974. +/*
  6975. + * This data structure describes the header prepended to all data
  6976. + * written to the touch IC at the bulk data write
  6977. + * (TOUCH_DATA_WINDOW_OFFSET + TOUCH_FEEDBACK_HDR.SpiOffest) address.
  6978. + */
  6979. +enum touch_write_data_type {
  6980. + TOUCH_WRITE_DATA_TYPE_FW_LOAD = 0,
  6981. + TOUCH_WRITE_DATA_TYPE_DATA_LOAD,
  6982. + TOUCH_WRITE_DATA_TYPE_FEEDBACK,
  6983. + TOUCH_WRITE_DATA_TYPE_SET_FEATURES,
  6984. + TOUCH_WRITE_DATA_TYPE_GET_FEATURES,
  6985. + TOUCH_WRITE_DATA_TYPE_OUTPUT_REPORT,
  6986. + TOUCH_WRITE_DATA_TYPE_NO_DATA_USE_DEFAULTS,
  6987. + TOUCH_WRITE_DATA_TYPE_MAX
  6988. +};
  6989. +static_assert(sizeof(enum touch_write_data_type) == 4);
  6990. +
  6991. +struct touch_write_hdr {
  6992. + // Use values from TOUCH_WRITE_DATA_TYPE
  6993. + u32 write_data_type;
  6994. +
  6995. + // This field designates the amount of data to follow
  6996. + u32 write_data_len;
  6997. +};
  6998. +static_assert(sizeof(struct touch_write_hdr) == 8);
  6999. +
  7000. +struct touch_write_data {
  7001. + struct touch_write_hdr header;
  7002. +
  7003. + // used to access the write data as an array and keep the compilers
  7004. + // happy. Actual size of this array is Header.WriteDataLen
  7005. + u8 write_data[1];
  7006. +};
  7007. +
  7008. +#pragma pack()
  7009. +
  7010. +#endif // _IPTS_SENSOR_REGS_H_
  7011. diff --git a/drivers/misc/ipts/state.h b/drivers/misc/ipts/state.h
  7012. new file mode 100644
  7013. index 000000000000..ef73d28db47c
  7014. --- /dev/null
  7015. +++ b/drivers/misc/ipts/state.h
  7016. @@ -0,0 +1,22 @@
  7017. +/* SPDX-License-Identifier: GPL-2.0-or-later */
  7018. +/*
  7019. + *
  7020. + * Intel Precise Touch & Stylus
  7021. + * Copyright (c) 2016 Intel Corporation
  7022. + *
  7023. + */
  7024. +
  7025. +#ifndef _IPTS_STATE_H_
  7026. +#define _IPTS_STATE_H_
  7027. +
  7028. +// IPTS driver states
  7029. +enum ipts_state {
  7030. + IPTS_STA_NONE,
  7031. + IPTS_STA_INIT,
  7032. + IPTS_STA_RESOURCE_READY,
  7033. + IPTS_STA_HID_STARTED,
  7034. + IPTS_STA_RAW_DATA_STARTED,
  7035. + IPTS_STA_STOPPING
  7036. +};
  7037. +
  7038. +#endif // _IPTS_STATE_H_
  7039. diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h
  7040. index b359f06f05e7..4ddfc8771611 100644
  7041. --- a/drivers/misc/mei/hw-me-regs.h
  7042. +++ b/drivers/misc/mei/hw-me-regs.h
  7043. @@ -59,6 +59,7 @@
  7044. #define MEI_DEV_ID_SPT 0x9D3A /* Sunrise Point */
  7045. #define MEI_DEV_ID_SPT_2 0x9D3B /* Sunrise Point 2 */
  7046. +#define MEI_DEV_ID_SPT_4 0x9D3E /* Sunrise Point 4 */
  7047. #define MEI_DEV_ID_SPT_H 0xA13A /* Sunrise Point H */
  7048. #define MEI_DEV_ID_SPT_H_2 0xA13B /* Sunrise Point H 2 */
  7049. diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c
  7050. index b1c518abc10e..30506fbf187c 100644
  7051. --- a/drivers/misc/mei/pci-me.c
  7052. +++ b/drivers/misc/mei/pci-me.c
  7053. @@ -77,6 +77,7 @@ static const struct pci_device_id mei_me_pci_tbl[] = {
  7054. {MEI_PCI_DEVICE(MEI_DEV_ID_SPT, MEI_ME_PCH8_CFG)},
  7055. {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_2, MEI_ME_PCH8_CFG)},
  7056. + {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_4, MEI_ME_PCH8_CFG)},
  7057. {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H, MEI_ME_PCH8_SPS_CFG)},
  7058. {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H_2, MEI_ME_PCH8_SPS_CFG)},
  7059. {MEI_PCI_DEVICE(MEI_DEV_ID_LBG, MEI_ME_PCH12_CFG)},
  7060. diff --git a/include/linux/ipts-binary.h b/include/linux/ipts-binary.h
  7061. new file mode 100644
  7062. index 000000000000..98b54d74ff88
  7063. --- /dev/null
  7064. +++ b/include/linux/ipts-binary.h
  7065. @@ -0,0 +1,140 @@
  7066. +/* SPDX-License-Identifier: GPL-2.0-or-later */
  7067. +/*
  7068. + *
  7069. + * Intel Precise Touch & Stylus
  7070. + * Copyright (c) 2016 Intel Corporation
  7071. + *
  7072. + */
  7073. +
  7074. +#ifndef IPTS_BINARY_H
  7075. +#define IPTS_BINARY_H
  7076. +
  7077. +#include <linux/ipts.h>
  7078. +#include <linux/types.h>
  7079. +
  7080. +#define IPTS_BIN_HEADER_VERSION 2
  7081. +
  7082. +#pragma pack(1)
  7083. +
  7084. +// we support 16 output buffers (1:feedback, 15:HID)
  7085. +#define MAX_NUM_OUTPUT_BUFFERS 16
  7086. +
  7087. +enum ipts_bin_res_type {
  7088. + IPTS_BIN_KERNEL,
  7089. + IPTS_BIN_RO_DATA,
  7090. + IPTS_BIN_RW_DATA,
  7091. + IPTS_BIN_SENSOR_FRAME,
  7092. + IPTS_BIN_OUTPUT,
  7093. + IPTS_BIN_DYNAMIC_STATE_HEAP,
  7094. + IPTS_BIN_PATCH_LOCATION_LIST,
  7095. + IPTS_BIN_ALLOCATION_LIST,
  7096. + IPTS_BIN_COMMAND_BUFFER_PACKET,
  7097. + IPTS_BIN_TAG,
  7098. +};
  7099. +
  7100. +struct ipts_bin_header {
  7101. + char str[4];
  7102. + u32 version;
  7103. +
  7104. +#if IPTS_BIN_HEADER_VERSION > 1
  7105. + u32 gfxcore;
  7106. + u32 revid;
  7107. +#endif
  7108. +};
  7109. +
  7110. +struct ipts_bin_alloc {
  7111. + u32 handle;
  7112. + u32 reserved;
  7113. +};
  7114. +
  7115. +struct ipts_bin_alloc_list {
  7116. + u32 num;
  7117. + struct ipts_bin_alloc alloc[];
  7118. +};
  7119. +
  7120. +struct ipts_bin_cmdbuf {
  7121. + u32 size;
  7122. + char data[];
  7123. +};
  7124. +
  7125. +struct ipts_bin_res {
  7126. + u32 handle;
  7127. + enum ipts_bin_res_type type;
  7128. + u32 initialize;
  7129. + u32 aligned_size;
  7130. + u32 size;
  7131. + char data[];
  7132. +};
  7133. +
  7134. +enum ipts_bin_io_buffer_type {
  7135. + IPTS_INPUT,
  7136. + IPTS_OUTPUT,
  7137. + IPTS_CONFIGURATION,
  7138. + IPTS_CALIBRATION,
  7139. + IPTS_FEATURE,
  7140. +};
  7141. +
  7142. +struct ipts_bin_io_header {
  7143. + char str[10];
  7144. + u16 type;
  7145. +};
  7146. +
  7147. +struct ipts_bin_res_list {
  7148. + u32 num;
  7149. + struct ipts_bin_res res[];
  7150. +};
  7151. +
  7152. +struct ipts_bin_patch {
  7153. + u32 index;
  7154. + u32 reserved1[2];
  7155. + u32 alloc_offset;
  7156. + u32 patch_offset;
  7157. + u32 reserved2;
  7158. +};
  7159. +
  7160. +struct ipts_bin_patch_list {
  7161. + u32 num;
  7162. + struct ipts_bin_patch patch[];
  7163. +};
  7164. +
  7165. +struct ipts_bin_guc_wq_info {
  7166. + u32 batch_offset;
  7167. + u32 size;
  7168. + char data[];
  7169. +};
  7170. +
  7171. +struct ipts_bin_bufid_patch {
  7172. + u32 imm_offset;
  7173. + u32 mem_offset;
  7174. +};
  7175. +
  7176. +enum ipts_bin_data_file_flags {
  7177. + IPTS_DATA_FILE_FLAG_NONE = 0,
  7178. + IPTS_DATA_FILE_FLAG_SHARE = 1,
  7179. + IPTS_DATA_FILE_FLAG_ALLOC_CONTIGUOUS = 2,
  7180. +};
  7181. +
  7182. +struct ipts_bin_data_file_info {
  7183. + u32 io_buffer_type;
  7184. + u32 flags;
  7185. + char file_name[MAX_IOCL_FILE_NAME_LEN];
  7186. +};
  7187. +
  7188. +struct ipts_bin_fw_info {
  7189. + char fw_name[MAX_IOCL_FILE_NAME_LEN];
  7190. +
  7191. + // output index. -1 for no use
  7192. + s32 vendor_output;
  7193. +
  7194. + u32 num_of_data_files;
  7195. + struct ipts_bin_data_file_info data_file[];
  7196. +};
  7197. +
  7198. +struct ipts_bin_fw_list {
  7199. + u32 num_of_fws;
  7200. + struct ipts_bin_fw_info fw_info[];
  7201. +};
  7202. +
  7203. +#pragma pack()
  7204. +
  7205. +#endif // IPTS_BINARY_H
  7206. diff --git a/include/linux/ipts-companion.h b/include/linux/ipts-companion.h
  7207. new file mode 100644
  7208. index 000000000000..1f606a5fb5f2
  7209. --- /dev/null
  7210. +++ b/include/linux/ipts-companion.h
  7211. @@ -0,0 +1,30 @@
  7212. +/* SPDX-License-Identifier: GPL-2.0-or-later */
  7213. +/*
  7214. + *
  7215. + * Intel Precise Touch & Stylus
  7216. + * Copyright (c) 2016 Intel Corporation
  7217. + * Copyright (c) 2019 Dorian Stoll
  7218. + *
  7219. + */
  7220. +
  7221. +#ifndef IPTS_COMPANION_H
  7222. +#define IPTS_COMPANION_H
  7223. +
  7224. +#include <linux/firmware.h>
  7225. +#include <linux/ipts-binary.h>
  7226. +
  7227. +struct ipts_companion {
  7228. + unsigned int (*get_quirks)(struct ipts_companion *companion);
  7229. + int (*firmware_request)(struct ipts_companion *companion,
  7230. + const struct firmware **fw,
  7231. + const char *name, struct device *device);
  7232. +
  7233. + struct ipts_bin_fw_info **firmware_config;
  7234. + void *data;
  7235. + const char *name;
  7236. +};
  7237. +
  7238. +int ipts_add_companion(struct ipts_companion *companion);
  7239. +int ipts_remove_companion(struct ipts_companion *companion);
  7240. +
  7241. +#endif // IPTS_COMPANION_H
  7242. diff --git a/include/linux/ipts-gfx.h b/include/linux/ipts-gfx.h
  7243. new file mode 100644
  7244. index 000000000000..cb9d98fe96e4
  7245. --- /dev/null
  7246. +++ b/include/linux/ipts-gfx.h
  7247. @@ -0,0 +1,86 @@
  7248. +/* SPDX-License-Identifier: GPL-2.0-or-later */
  7249. +/*
  7250. + *
  7251. + * Intel Precise Touch & Stylus
  7252. + * Copyright (c) 2016 Intel Corporation
  7253. + *
  7254. + */
  7255. +
  7256. +#ifndef IPTS_GFX_H
  7257. +#define IPTS_GFX_H
  7258. +
  7259. +enum {
  7260. + IPTS_INTERFACE_V1 = 1,
  7261. +};
  7262. +
  7263. +#define IPTS_BUF_FLAG_CONTIGUOUS 0x01
  7264. +
  7265. +#define IPTS_NOTIFY_STA_BACKLIGHT_OFF 0x00
  7266. +#define IPTS_NOTIFY_STA_BACKLIGHT_ON 0x01
  7267. +
  7268. +struct ipts_mapbuffer {
  7269. + u32 size;
  7270. + u32 flags;
  7271. + void *gfx_addr;
  7272. + void *cpu_addr;
  7273. + u64 buf_handle;
  7274. + u64 phy_addr;
  7275. +};
  7276. +
  7277. +struct ipts_wq_info {
  7278. + u64 db_addr;
  7279. + u64 db_phy_addr;
  7280. + u32 db_cookie_offset;
  7281. + u32 wq_size;
  7282. + u64 wq_addr;
  7283. + u64 wq_phy_addr;
  7284. +
  7285. + // head of wq is managed by GPU
  7286. + u64 wq_head_addr;
  7287. + u64 wq_head_phy_addr;
  7288. +
  7289. + // tail of wq is managed by CSME
  7290. + u64 wq_tail_addr;
  7291. + u64 wq_tail_phy_addr;
  7292. +};
  7293. +
  7294. +struct ipts_ops {
  7295. + int (*get_wq_info)(uint64_t gfx_handle,
  7296. + struct ipts_wq_info *wq_info);
  7297. + int (*map_buffer)(uint64_t gfx_handle,
  7298. + struct ipts_mapbuffer *mapbuffer);
  7299. + int (*unmap_buffer)(uint64_t gfx_handle, uint64_t buf_handle);
  7300. +};
  7301. +
  7302. +struct ipts_callback {
  7303. + void (*workload_complete)(void *data);
  7304. + void (*notify_gfx_status)(u32 status, void *data);
  7305. +};
  7306. +
  7307. +struct ipts_connect {
  7308. + // input: Client device for PM setup
  7309. + struct device *client;
  7310. +
  7311. + // input: Callback addresses
  7312. + struct ipts_callback ipts_cb;
  7313. +
  7314. + // input: Callback data
  7315. + void *data;
  7316. +
  7317. + // input: interface version
  7318. + u32 if_version;
  7319. +
  7320. + // output: GFX version
  7321. + u32 gfx_version;
  7322. +
  7323. + // output: GFX handle
  7324. + u64 gfx_handle;
  7325. +
  7326. + // output: GFX ops for IPTS
  7327. + struct ipts_ops ipts_ops;
  7328. +};
  7329. +
  7330. +int ipts_connect(struct ipts_connect *ipts_connect);
  7331. +void ipts_disconnect(uint64_t gfx_handle);
  7332. +
  7333. +#endif // IPTS_GFX_H
  7334. diff --git a/include/linux/ipts.h b/include/linux/ipts.h
  7335. new file mode 100644
  7336. index 000000000000..bfa8e1375926
  7337. --- /dev/null
  7338. +++ b/include/linux/ipts.h
  7339. @@ -0,0 +1,20 @@
  7340. +/* SPDX-License-Identifier: GPL-2.0-or-later */
  7341. +/*
  7342. + *
  7343. + * Intel Precise Touch & Stylus
  7344. + * Copyright (c) 2016 Intel Corporation
  7345. + *
  7346. + */
  7347. +
  7348. +#ifndef IPTS_H
  7349. +#define IPTS_H
  7350. +
  7351. +#include <linux/bits.h>
  7352. +
  7353. +#define MAX_IOCL_FILE_NAME_LEN 80
  7354. +#define MAX_IOCL_FILE_PATH_LEN 256
  7355. +
  7356. +#define IPTS_QUIRK_NONE 0
  7357. +#define IPTS_QUIRK_NO_FEEDBACK BIT(0)
  7358. +
  7359. +#endif // IPTS_H
  7360. --
  7361. 2.24.1