ipts.patch 188 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058
  1. diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
  2. index 4c6adae23e18..1171fbd3a823 100644
  3. --- a/drivers/gpu/drm/i915/Makefile
  4. +++ b/drivers/gpu/drm/i915/Makefile
  5. @@ -154,6 +154,9 @@ i915-y += dvo_ch7017.o \
  6. intel_sdvo.o \
  7. intel_tv.o
  8. +# intel precise touch & stylus
  9. +i915-y += intel_ipts.o
  10. +
  11. # Post-mortem debug and GPU hang state capture
  12. i915-$(CONFIG_DRM_I915_CAPTURE_ERROR) += i915_gpu_error.o
  13. i915-$(CONFIG_DRM_I915_SELFTEST) += \
  14. diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
  15. index 9c449b8d8eab..d5d91d196627 100644
  16. --- a/drivers/gpu/drm/i915/i915_drv.c
  17. +++ b/drivers/gpu/drm/i915/i915_drv.c
  18. @@ -53,6 +53,7 @@
  19. #include "i915_vgpu.h"
  20. #include "intel_drv.h"
  21. #include "intel_uc.h"
  22. +#include "intel_ipts.h"
  23. static struct drm_driver driver;
  24. @@ -717,6 +718,9 @@ static int i915_load_modeset_init(struct drm_device *dev)
  25. /* Only enable hotplug handling once the fbdev is fully set up. */
  26. intel_hpd_init(dev_priv);
  27. + if (INTEL_GEN(dev_priv) >= 9 && i915_modparams.enable_guc && i915_modparams.enable_ipts)
  28. + intel_ipts_init(dev);
  29. +
  30. return 0;
  31. cleanup_gem:
  32. @@ -1441,6 +1445,9 @@ void i915_driver_unload(struct drm_device *dev)
  33. struct drm_i915_private *dev_priv = to_i915(dev);
  34. struct pci_dev *pdev = dev_priv->drm.pdev;
  35. + if (INTEL_GEN(dev_priv) >= 9 && i915_modparams.enable_guc && i915_modparams.enable_ipts)
  36. + intel_ipts_cleanup(dev);
  37. +
  38. i915_driver_unregister(dev_priv);
  39. if (i915_gem_suspend(dev_priv))
  40. diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
  41. index 71e1aa54f774..62686739ff57 100644
  42. --- a/drivers/gpu/drm/i915/i915_drv.h
  43. +++ b/drivers/gpu/drm/i915/i915_drv.h
  44. @@ -3230,6 +3230,9 @@ void i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj,
  45. void i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj,
  46. struct sg_table *pages);
  47. +struct i915_gem_context *
  48. +i915_gem_context_create_ipts(struct drm_device *dev);
  49. +
  50. static inline struct i915_gem_context *
  51. __i915_gem_context_lookup_rcu(struct drm_i915_file_private *file_priv, u32 id)
  52. {
  53. diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
  54. index 060335d3d9e0..525eb397c862 100644
  55. --- a/drivers/gpu/drm/i915/i915_gem_context.c
  56. +++ b/drivers/gpu/drm/i915/i915_gem_context.c
  57. @@ -457,6 +457,18 @@ static bool needs_preempt_context(struct drm_i915_private *i915)
  58. return HAS_LOGICAL_RING_PREEMPTION(i915);
  59. }
  60. +struct i915_gem_context *i915_gem_context_create_ipts(struct drm_device *dev)
  61. +{
  62. + struct drm_i915_private *dev_priv = dev->dev_private;
  63. + struct i915_gem_context *ctx;
  64. +
  65. + BUG_ON(!mutex_is_locked(&dev->struct_mutex));
  66. +
  67. + ctx = i915_gem_create_context(dev_priv, NULL);
  68. +
  69. + return ctx;
  70. +}
  71. +
  72. int i915_gem_contexts_init(struct drm_i915_private *dev_priv)
  73. {
  74. struct i915_gem_context *ctx;
  75. diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
  76. index c16cb025755e..8fb9160d013b 100644
  77. --- a/drivers/gpu/drm/i915/i915_irq.c
  78. +++ b/drivers/gpu/drm/i915/i915_irq.c
  79. @@ -36,6 +36,7 @@
  80. #include "i915_drv.h"
  81. #include "i915_trace.h"
  82. #include "intel_drv.h"
  83. +#include "intel_ipts.h"
  84. /**
  85. * DOC: interrupt handling
  86. @@ -1476,6 +1477,9 @@ gen8_cs_irq_handler(struct intel_engine_cs *engine, u32 iir)
  87. tasklet |= USES_GUC_SUBMISSION(engine->i915);
  88. }
  89. + if (iir & GT_RENDER_PIPECTL_NOTIFY_INTERRUPT)
  90. + intel_ipts_notify_complete();
  91. +
  92. if (tasklet)
  93. tasklet_hi_schedule(&execlists->tasklet);
  94. }
  95. @@ -3909,7 +3913,8 @@ static void gen8_gt_irq_postinstall(struct drm_i915_private *dev_priv)
  96. {
  97. /* These are interrupts we'll toggle with the ring mask register */
  98. uint32_t gt_interrupts[] = {
  99. - GT_RENDER_USER_INTERRUPT << GEN8_RCS_IRQ_SHIFT |
  100. + GT_RENDER_PIPECTL_NOTIFY_INTERRUPT << GEN8_RCS_IRQ_SHIFT |
  101. + GT_RENDER_USER_INTERRUPT << GEN8_RCS_IRQ_SHIFT |
  102. GT_CONTEXT_SWITCH_INTERRUPT << GEN8_RCS_IRQ_SHIFT |
  103. GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT |
  104. GT_CONTEXT_SWITCH_INTERRUPT << GEN8_BCS_IRQ_SHIFT,
  105. diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
  106. index 66ea3552c63e..4f54d74febc8 100644
  107. --- a/drivers/gpu/drm/i915/i915_params.c
  108. +++ b/drivers/gpu/drm/i915/i915_params.c
  109. @@ -152,7 +152,10 @@ i915_param_named_unsafe(edp_vswing, int, 0400,
  110. i915_param_named_unsafe(enable_guc, int, 0400,
  111. "Enable GuC load for GuC submission and/or HuC load. "
  112. "Required functionality can be selected using bitmask values. "
  113. - "(-1=auto, 0=disable [default], 1=GuC submission, 2=HuC load)");
  114. + "(-1=auto, 0=disable, 1=GuC submission [default], 2=HuC load)");
  115. +
  116. +i915_param_named_unsafe(enable_ipts, int, 0400,
  117. + "Enable IPTS Touchscreen and Pen support (default: 1)");
  118. i915_param_named(guc_log_level, int, 0400,
  119. "GuC firmware logging level. Requires GuC to be loaded. "
  120. diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h
  121. index 6684025b7af8..f7f0a63a87e5 100644
  122. --- a/drivers/gpu/drm/i915/i915_params.h
  123. +++ b/drivers/gpu/drm/i915/i915_params.h
  124. @@ -47,7 +47,7 @@ struct drm_printer;
  125. param(int, disable_power_well, -1) \
  126. param(int, enable_ips, 1) \
  127. param(int, invert_brightness, 0) \
  128. - param(int, enable_guc, 0) \
  129. + param(int, enable_guc, 1) \
  130. param(int, guc_log_level, -1) \
  131. param(char *, guc_firmware_path, NULL) \
  132. param(char *, huc_firmware_path, NULL) \
  133. @@ -70,7 +70,8 @@ struct drm_printer;
  134. param(bool, nuclear_pageflip, false) \
  135. param(bool, enable_dp_mst, true) \
  136. param(bool, enable_dpcd_backlight, false) \
  137. - param(bool, enable_gvt, false)
  138. + param(bool, enable_gvt, false) \
  139. + param(int, enable_ipts, 1)
  140. #define MEMBER(T, member, ...) T member;
  141. struct i915_params {
  142. diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
  143. index 16faea30114a..e5c1e24a6072 100644
  144. --- a/drivers/gpu/drm/i915/intel_dp.c
  145. +++ b/drivers/gpu/drm/i915/intel_dp.c
  146. @@ -2601,8 +2601,8 @@ void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode)
  147. return;
  148. if (mode != DRM_MODE_DPMS_ON) {
  149. - if (downstream_hpd_needs_d0(intel_dp))
  150. - return;
  151. + //if (downstream_hpd_needs_d0(intel_dp))
  152. + // return;
  153. ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER,
  154. DP_SET_POWER_D3);
  155. diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
  156. index f1265e122d30..1303090a4bd8 100644
  157. --- a/drivers/gpu/drm/i915/intel_guc.h
  158. +++ b/drivers/gpu/drm/i915/intel_guc.h
  159. @@ -69,6 +69,7 @@ struct intel_guc {
  160. struct intel_guc_client *execbuf_client;
  161. struct intel_guc_client *preempt_client;
  162. + struct intel_guc_client *ipts_client;
  163. struct guc_preempt_work preempt_work[I915_NUM_ENGINES];
  164. struct workqueue_struct *preempt_wq;
  165. diff --git a/drivers/gpu/drm/i915/intel_guc_submission.c b/drivers/gpu/drm/i915/intel_guc_submission.c
  166. index 2feb65096966..1b7b8dc27a28 100644
  167. --- a/drivers/gpu/drm/i915/intel_guc_submission.c
  168. +++ b/drivers/gpu/drm/i915/intel_guc_submission.c
  169. @@ -94,6 +94,7 @@ static inline bool is_high_priority(struct intel_guc_client *client)
  170. static int reserve_doorbell(struct intel_guc_client *client)
  171. {
  172. + struct drm_i915_private *dev_priv = guc_to_i915(client->guc);
  173. unsigned long offset;
  174. unsigned long end;
  175. u16 id;
  176. @@ -106,11 +107,16 @@ static int reserve_doorbell(struct intel_guc_client *client)
  177. * priority contexts, the second half for high-priority ones.
  178. */
  179. offset = 0;
  180. - end = GUC_NUM_DOORBELLS / 2;
  181. - if (is_high_priority(client)) {
  182. - offset = end;
  183. - end += offset;
  184. + if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
  185. + end = GUC_NUM_DOORBELLS;
  186. }
  187. + else {
  188. + end = GUC_NUM_DOORBELLS/2;
  189. + if (is_high_priority(client)) {
  190. + offset = end;
  191. + end += offset;
  192. + }
  193. + }
  194. id = find_next_zero_bit(client->guc->doorbell_bitmap, end, offset);
  195. if (id == end)
  196. @@ -355,8 +361,14 @@ static void guc_stage_desc_init(struct intel_guc *guc,
  197. desc = __get_stage_desc(client);
  198. memset(desc, 0, sizeof(*desc));
  199. - desc->attribute = GUC_STAGE_DESC_ATTR_ACTIVE |
  200. - GUC_STAGE_DESC_ATTR_KERNEL;
  201. + desc->attribute = GUC_STAGE_DESC_ATTR_ACTIVE;
  202. + if ((client->priority == GUC_CLIENT_PRIORITY_KMD_NORMAL) ||
  203. + (client->priority == GUC_CLIENT_PRIORITY_KMD_HIGH)) {
  204. + desc->attribute |= GUC_STAGE_DESC_ATTR_KERNEL;
  205. + } else {
  206. + desc->attribute |= GUC_STAGE_DESC_ATTR_PCH;
  207. + }
  208. +
  209. if (is_high_priority(client))
  210. desc->attribute |= GUC_STAGE_DESC_ATTR_PREEMPT;
  211. desc->stage_id = client->stage_id;
  212. @@ -1160,7 +1172,8 @@ static void guc_interrupts_capture(struct drm_i915_private *dev_priv)
  213. I915_WRITE(RING_MODE_GEN7(engine), irqs);
  214. /* route USER_INTERRUPT to Host, all others are sent to GuC. */
  215. - irqs = GT_RENDER_USER_INTERRUPT << GEN8_RCS_IRQ_SHIFT |
  216. + irqs = (GT_RENDER_USER_INTERRUPT | GT_RENDER_PIPECTL_NOTIFY_INTERRUPT)
  217. + << GEN8_RCS_IRQ_SHIFT |
  218. GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT;
  219. /* These three registers have the same bit definitions */
  220. I915_WRITE(GUC_BCS_RCS_IER, ~irqs);
  221. @@ -1289,6 +1302,58 @@ void intel_guc_submission_disable(struct intel_guc *guc)
  222. intel_engines_reset_default_submission(dev_priv);
  223. }
  224. +int i915_guc_ipts_submission_enable(struct drm_i915_private *dev_priv,
  225. + struct i915_gem_context *ctx)
  226. +{
  227. + struct intel_guc *guc = &dev_priv->guc;
  228. + struct intel_guc_client *client;
  229. + int err;
  230. + int ret;
  231. +
  232. + /* client for execbuf submission */
  233. + client = guc_client_alloc(dev_priv,
  234. + INTEL_INFO(dev_priv)->ring_mask,
  235. + GUC_CLIENT_PRIORITY_NORMAL,
  236. + ctx);
  237. + if (IS_ERR(client)) {
  238. + DRM_ERROR("Failed to create normal GuC client!\n");
  239. + return -ENOMEM;
  240. + }
  241. +
  242. + guc->ipts_client = client;
  243. +
  244. + err = intel_guc_sample_forcewake(guc);
  245. + if (err)
  246. + return err;
  247. +
  248. + ret = create_doorbell(guc->ipts_client);
  249. + if (ret)
  250. + return ret;
  251. +
  252. + return 0;
  253. +}
  254. +
  255. +void i915_guc_ipts_submission_disable(struct drm_i915_private *dev_priv)
  256. +{
  257. + struct intel_guc *guc = &dev_priv->guc;
  258. +
  259. + if (!guc->ipts_client)
  260. + return;
  261. +
  262. + guc_client_free(guc->ipts_client);
  263. + guc->ipts_client = NULL;
  264. +}
  265. +
  266. +void i915_guc_ipts_reacquire_doorbell(struct drm_i915_private *dev_priv)
  267. +{
  268. + struct intel_guc *guc = &dev_priv->guc;
  269. +
  270. + int err = __guc_allocate_doorbell(guc, guc->ipts_client->stage_id);
  271. +
  272. + if (err)
  273. + DRM_ERROR("Not able to reacquire IPTS doorbell\n");
  274. +}
  275. +
  276. #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
  277. #include "selftests/intel_guc.c"
  278. #endif
  279. diff --git a/drivers/gpu/drm/i915/intel_guc_submission.h b/drivers/gpu/drm/i915/intel_guc_submission.h
  280. index fb081cefef93..71fc7986585a 100644
  281. --- a/drivers/gpu/drm/i915/intel_guc_submission.h
  282. +++ b/drivers/gpu/drm/i915/intel_guc_submission.h
  283. @@ -79,5 +79,9 @@ void intel_guc_submission_disable(struct intel_guc *guc);
  284. void intel_guc_submission_fini(struct intel_guc *guc);
  285. int intel_guc_preempt_work_create(struct intel_guc *guc);
  286. void intel_guc_preempt_work_destroy(struct intel_guc *guc);
  287. +int i915_guc_ipts_submission_enable(struct drm_i915_private *dev_priv,
  288. + struct i915_gem_context *ctx);
  289. +void i915_guc_ipts_submission_disable(struct drm_i915_private *dev_priv);
  290. +void i915_guc_ipts_reacquire_doorbell(struct drm_i915_private *dev_priv);
  291. #endif
  292. diff --git a/drivers/gpu/drm/i915/intel_ipts.c b/drivers/gpu/drm/i915/intel_ipts.c
  293. new file mode 100644
  294. index 000000000000..f8cc5eaf033d
  295. --- /dev/null
  296. +++ b/drivers/gpu/drm/i915/intel_ipts.c
  297. @@ -0,0 +1,627 @@
  298. +/*
  299. + * Copyright 2016 Intel Corporation
  300. + *
  301. + * Permission is hereby granted, free of charge, to any person obtaining a
  302. + * copy of this software and associated documentation files (the "Software"),
  303. + * to deal in the Software without restriction, including without limitation
  304. + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  305. + * and/or sell copies of the Software, and to permit persons to whom the
  306. + * Software is furnished to do so, subject to the following conditions:
  307. + *
  308. + * The above copyright notice and this permission notice (including the next
  309. + * paragraph) shall be included in all copies or substantial portions of the
  310. + * Software.
  311. + *
  312. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  313. + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  314. + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  315. + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  316. + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  317. + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  318. + * IN THE SOFTWARE.
  319. + *
  320. + */
  321. +#include <linux/kernel.h>
  322. +#include <linux/types.h>
  323. +#include <linux/module.h>
  324. +#include <linux/intel_ipts_if.h>
  325. +#include <drm/drmP.h>
  326. +
  327. +#include "intel_guc_submission.h"
  328. +#include "i915_drv.h"
  329. +
  330. +#define SUPPORTED_IPTS_INTERFACE_VERSION 1
  331. +
  332. +#define REACQUIRE_DB_THRESHOLD 8
  333. +#define DB_LOST_CHECK_STEP1_INTERVAL 2000 /* ms */
  334. +#define DB_LOST_CHECK_STEP2_INTERVAL 500 /* ms */
  335. +
  336. +/* intel IPTS ctx for ipts support */
  337. +typedef struct intel_ipts {
  338. + struct drm_device *dev;
  339. + struct i915_gem_context *ipts_context;
  340. + intel_ipts_callback_t ipts_clbks;
  341. +
  342. + /* buffers' list */
  343. + struct {
  344. + spinlock_t lock;
  345. + struct list_head list;
  346. + } buffers;
  347. +
  348. + void *data;
  349. +
  350. + struct delayed_work reacquire_db_work;
  351. + intel_ipts_wq_info_t wq_info;
  352. + u32 old_tail;
  353. + u32 old_head;
  354. + bool need_reacquire_db;
  355. +
  356. + bool connected;
  357. + bool initialized;
  358. +} intel_ipts_t;
  359. +
  360. +intel_ipts_t intel_ipts;
  361. +
  362. +typedef struct intel_ipts_object {
  363. + struct list_head list;
  364. + struct drm_i915_gem_object *gem_obj;
  365. + void *cpu_addr;
  366. +} intel_ipts_object_t;
  367. +
  368. +static intel_ipts_object_t *ipts_object_create(size_t size, u32 flags)
  369. +{
  370. + struct drm_i915_private *dev_priv = to_i915(intel_ipts.dev);
  371. + intel_ipts_object_t *obj = NULL;
  372. + struct drm_i915_gem_object *gem_obj = NULL;
  373. + int ret = 0;
  374. +
  375. + obj = kzalloc(sizeof(*obj), GFP_KERNEL);
  376. + if (!obj)
  377. + return NULL;
  378. +
  379. + size = roundup(size, PAGE_SIZE);
  380. + if (size == 0) {
  381. + ret = -EINVAL;
  382. + goto err_out;
  383. + }
  384. +
  385. + /* Allocate the new object */
  386. + gem_obj = i915_gem_object_create(dev_priv, size);
  387. + if (gem_obj == NULL) {
  388. + ret = -ENOMEM;
  389. + goto err_out;
  390. + }
  391. +
  392. + if (flags & IPTS_BUF_FLAG_CONTIGUOUS) {
  393. + ret = i915_gem_object_attach_phys(gem_obj, PAGE_SIZE);
  394. + if (ret) {
  395. + pr_info(">> ipts no contiguous : %d\n", ret);
  396. + goto err_out;
  397. + }
  398. + }
  399. +
  400. + obj->gem_obj = gem_obj;
  401. +
  402. + spin_lock(&intel_ipts.buffers.lock);
  403. + list_add_tail(&obj->list, &intel_ipts.buffers.list);
  404. + spin_unlock(&intel_ipts.buffers.lock);
  405. +
  406. + return obj;
  407. +
  408. +err_out:
  409. + if (gem_obj)
  410. + i915_gem_free_object(&gem_obj->base);
  411. +
  412. + if (obj)
  413. + kfree(obj);
  414. +
  415. + return NULL;
  416. +}
  417. +
  418. +static void ipts_object_free(intel_ipts_object_t* obj)
  419. +{
  420. + spin_lock(&intel_ipts.buffers.lock);
  421. + list_del(&obj->list);
  422. + spin_unlock(&intel_ipts.buffers.lock);
  423. +
  424. + i915_gem_free_object(&obj->gem_obj->base);
  425. + kfree(obj);
  426. +}
  427. +
  428. +static int ipts_object_pin(intel_ipts_object_t* obj,
  429. + struct i915_gem_context *ipts_ctx)
  430. +{
  431. + struct i915_address_space *vm = NULL;
  432. + struct i915_vma *vma = NULL;
  433. + struct drm_i915_private *dev_priv = to_i915(intel_ipts.dev);
  434. + int ret = 0;
  435. +
  436. + if (ipts_ctx->ppgtt) {
  437. + vm = &ipts_ctx->ppgtt->base;
  438. + } else {
  439. + vm = &dev_priv->ggtt.base;
  440. + }
  441. +
  442. + vma = i915_vma_instance(obj->gem_obj, vm, NULL);
  443. + if (IS_ERR(vma)) {
  444. + DRM_ERROR("cannot find or create vma\n");
  445. + return -1;
  446. + }
  447. +
  448. + ret = i915_vma_pin(vma, 0, PAGE_SIZE, PIN_USER);
  449. +
  450. + return ret;
  451. +}
  452. +
  453. +static void ipts_object_unpin(intel_ipts_object_t *obj)
  454. +{
  455. + /* TBD: Add support */
  456. +}
  457. +
  458. +static void* ipts_object_map(intel_ipts_object_t *obj)
  459. +{
  460. +
  461. + return i915_gem_object_pin_map(obj->gem_obj, I915_MAP_WB);
  462. +}
  463. +
  464. +static void ipts_object_unmap(intel_ipts_object_t* obj)
  465. +{
  466. + i915_gem_object_unpin_map(obj->gem_obj);
  467. + obj->cpu_addr = NULL;
  468. +}
  469. +
  470. +static int create_ipts_context(void)
  471. +{
  472. + struct i915_gem_context *ipts_ctx = NULL;
  473. + struct drm_i915_private *dev_priv = to_i915(intel_ipts.dev);
  474. + struct intel_ring *pin_ret;
  475. + int ret = 0;
  476. +
  477. + /* Initialize the context right away.*/
  478. + ret = i915_mutex_lock_interruptible(intel_ipts.dev);
  479. + if (ret) {
  480. + DRM_ERROR("i915_mutex_lock_interruptible failed \n");
  481. + return ret;
  482. + }
  483. +
  484. + ipts_ctx = i915_gem_context_create_ipts(intel_ipts.dev);
  485. + if (IS_ERR(ipts_ctx)) {
  486. + DRM_ERROR("Failed to create IPTS context (error %ld)\n",
  487. + PTR_ERR(ipts_ctx));
  488. + ret = PTR_ERR(ipts_ctx);
  489. + goto err_unlock;
  490. + }
  491. +
  492. + ret = execlists_context_deferred_alloc(ipts_ctx, dev_priv->engine[RCS]);
  493. + if (ret) {
  494. + DRM_DEBUG("lr context allocation failed : %d\n", ret);
  495. + goto err_ctx;
  496. + }
  497. +
  498. + pin_ret = execlists_context_pin(dev_priv->engine[RCS], ipts_ctx);
  499. + if (IS_ERR(pin_ret)) {
  500. + DRM_DEBUG("lr context pinning failed : %ld\n", PTR_ERR(pin_ret));
  501. + goto err_ctx;
  502. + }
  503. +
  504. + /* Release the mutex */
  505. + mutex_unlock(&intel_ipts.dev->struct_mutex);
  506. +
  507. + spin_lock_init(&intel_ipts.buffers.lock);
  508. + INIT_LIST_HEAD(&intel_ipts.buffers.list);
  509. +
  510. + intel_ipts.ipts_context = ipts_ctx;
  511. +
  512. + return 0;
  513. +
  514. +err_ctx:
  515. + if (ipts_ctx)
  516. + i915_gem_context_put(ipts_ctx);
  517. +
  518. +err_unlock:
  519. + mutex_unlock(&intel_ipts.dev->struct_mutex);
  520. +
  521. + return ret;
  522. +}
  523. +
  524. +static void destroy_ipts_context(void)
  525. +{
  526. + struct i915_gem_context *ipts_ctx = NULL;
  527. + struct drm_i915_private *dev_priv = to_i915(intel_ipts.dev);
  528. + int ret = 0;
  529. +
  530. + ipts_ctx = intel_ipts.ipts_context;
  531. +
  532. + /* Initialize the context right away.*/
  533. + ret = i915_mutex_lock_interruptible(intel_ipts.dev);
  534. + if (ret) {
  535. + DRM_ERROR("i915_mutex_lock_interruptible failed \n");
  536. + return;
  537. + }
  538. +
  539. + execlists_context_unpin(dev_priv->engine[RCS], ipts_ctx);
  540. + i915_gem_context_put(ipts_ctx);
  541. +
  542. + mutex_unlock(&intel_ipts.dev->struct_mutex);
  543. +}
  544. +
  545. +int intel_ipts_notify_complete(void)
  546. +{
  547. + if (intel_ipts.ipts_clbks.workload_complete)
  548. + intel_ipts.ipts_clbks.workload_complete(intel_ipts.data);
  549. +
  550. + return 0;
  551. +}
  552. +
  553. +int intel_ipts_notify_backlight_status(bool backlight_on)
  554. +{
  555. + if (intel_ipts.ipts_clbks.notify_gfx_status) {
  556. + if (backlight_on) {
  557. + intel_ipts.ipts_clbks.notify_gfx_status(
  558. + IPTS_NOTIFY_STA_BACKLIGHT_ON,
  559. + intel_ipts.data);
  560. + schedule_delayed_work(&intel_ipts.reacquire_db_work,
  561. + msecs_to_jiffies(DB_LOST_CHECK_STEP1_INTERVAL));
  562. + } else {
  563. + intel_ipts.ipts_clbks.notify_gfx_status(
  564. + IPTS_NOTIFY_STA_BACKLIGHT_OFF,
  565. + intel_ipts.data);
  566. + cancel_delayed_work(&intel_ipts.reacquire_db_work);
  567. + }
  568. + }
  569. +
  570. + return 0;
  571. +}
  572. +
  573. +static void intel_ipts_reacquire_db(intel_ipts_t *intel_ipts_p)
  574. +{
  575. + int ret = 0;
  576. +
  577. + ret = i915_mutex_lock_interruptible(intel_ipts_p->dev);
  578. + if (ret) {
  579. + DRM_ERROR("i915_mutex_lock_interruptible failed \n");
  580. + return;
  581. + }
  582. +
  583. + /* Reacquire the doorbell */
  584. + i915_guc_ipts_reacquire_doorbell(intel_ipts_p->dev->dev_private);
  585. +
  586. + mutex_unlock(&intel_ipts_p->dev->struct_mutex);
  587. +
  588. + return;
  589. +}
  590. +
  591. +static int intel_ipts_get_wq_info(uint64_t gfx_handle,
  592. + intel_ipts_wq_info_t *wq_info)
  593. +{
  594. + if (gfx_handle != (uint64_t)&intel_ipts) {
  595. + DRM_ERROR("invalid gfx handle\n");
  596. + return -EINVAL;
  597. + }
  598. +
  599. + *wq_info = intel_ipts.wq_info;
  600. +
  601. + intel_ipts_reacquire_db(&intel_ipts);
  602. + schedule_delayed_work(&intel_ipts.reacquire_db_work,
  603. + msecs_to_jiffies(DB_LOST_CHECK_STEP1_INTERVAL));
  604. +
  605. + return 0;
  606. +}
  607. +
  608. +static int set_wq_info(void)
  609. +{
  610. + struct drm_i915_private *dev_priv = to_i915(intel_ipts.dev);
  611. + struct intel_guc *guc = &dev_priv->guc;
  612. + struct intel_guc_client *client;
  613. + struct guc_process_desc *desc;
  614. + void *base = NULL;
  615. + intel_ipts_wq_info_t *wq_info;
  616. + u64 phy_base = 0;
  617. +
  618. + wq_info = &intel_ipts.wq_info;
  619. +
  620. + client = guc->ipts_client;
  621. + if (!client) {
  622. + DRM_ERROR("IPTS GuC client is NOT available\n");
  623. + return -EINVAL;
  624. + }
  625. +
  626. + base = client->vaddr;
  627. + desc = (struct guc_process_desc *)((u64)base + client->proc_desc_offset);
  628. +
  629. + desc->wq_base_addr = (u64)base + GUC_DB_SIZE;
  630. + desc->db_base_addr = (u64)base + client->doorbell_offset;
  631. +
  632. + /* IPTS expects physical addresses to pass it to ME */
  633. + phy_base = sg_dma_address(client->vma->pages->sgl);
  634. +
  635. + wq_info->db_addr = desc->db_base_addr;
  636. + wq_info->db_phy_addr = phy_base + client->doorbell_offset;
  637. + wq_info->db_cookie_offset = offsetof(struct guc_doorbell_info, cookie);
  638. + wq_info->wq_addr = desc->wq_base_addr;
  639. + wq_info->wq_phy_addr = phy_base + GUC_DB_SIZE;
  640. + wq_info->wq_head_addr = (u64)&desc->head;
  641. + wq_info->wq_head_phy_addr = phy_base + client->proc_desc_offset +
  642. + offsetof(struct guc_process_desc, head);
  643. + wq_info->wq_tail_addr = (u64)&desc->tail;
  644. + wq_info->wq_tail_phy_addr = phy_base + client->proc_desc_offset +
  645. + offsetof(struct guc_process_desc, tail);
  646. + wq_info->wq_size = desc->wq_size_bytes;
  647. +
  648. + return 0;
  649. +}
  650. +
  651. +static int intel_ipts_init_wq(void)
  652. +{
  653. + int ret = 0;
  654. +
  655. + ret = i915_mutex_lock_interruptible(intel_ipts.dev);
  656. + if (ret) {
  657. + DRM_ERROR("i915_mutex_lock_interruptible failed\n");
  658. + return ret;
  659. + }
  660. +
  661. + /* disable IPTS submission */
  662. + i915_guc_ipts_submission_disable(intel_ipts.dev->dev_private);
  663. +
  664. + /* enable IPTS submission */
  665. + ret = i915_guc_ipts_submission_enable(intel_ipts.dev->dev_private,
  666. + intel_ipts.ipts_context);
  667. + if (ret) {
  668. + DRM_ERROR("i915_guc_ipts_submission_enable failed : %d\n", ret);
  669. + goto out;
  670. + }
  671. +
  672. + ret = set_wq_info();
  673. + if (ret) {
  674. + DRM_ERROR("set_wq_info failed\n");
  675. + goto out;
  676. + }
  677. +
  678. +out:
  679. + mutex_unlock(&intel_ipts.dev->struct_mutex);
  680. +
  681. + return ret;
  682. +}
  683. +
  684. +static void intel_ipts_release_wq(void)
  685. +{
  686. + int ret = 0;
  687. +
  688. + ret = i915_mutex_lock_interruptible(intel_ipts.dev);
  689. + if (ret) {
  690. + DRM_ERROR("i915_mutex_lock_interruptible failed\n");
  691. + return;
  692. + }
  693. +
  694. + /* disable IPTS submission */
  695. + i915_guc_ipts_submission_disable(intel_ipts.dev->dev_private);
  696. +
  697. + mutex_unlock(&intel_ipts.dev->struct_mutex);
  698. +}
  699. +
  700. +static int intel_ipts_map_buffer(u64 gfx_handle, intel_ipts_mapbuffer_t *mapbuf)
  701. +{
  702. + intel_ipts_object_t* obj;
  703. + struct i915_gem_context *ipts_ctx = NULL;
  704. + struct drm_i915_private *dev_priv = to_i915(intel_ipts.dev);
  705. + struct i915_address_space *vm = NULL;
  706. + struct i915_vma *vma = NULL;
  707. + int ret = 0;
  708. +
  709. + if (gfx_handle != (uint64_t)&intel_ipts) {
  710. + DRM_ERROR("invalid gfx handle\n");
  711. + return -EINVAL;
  712. + }
  713. +
  714. + /* Acquire mutex first */
  715. + ret = i915_mutex_lock_interruptible(intel_ipts.dev);
  716. + if (ret) {
  717. + DRM_ERROR("i915_mutex_lock_interruptible failed \n");
  718. + return -EINVAL;
  719. + }
  720. +
  721. + obj = ipts_object_create(mapbuf->size, mapbuf->flags);
  722. + if (!obj)
  723. + return -ENOMEM;
  724. +
  725. + ipts_ctx = intel_ipts.ipts_context;
  726. + ret = ipts_object_pin(obj, ipts_ctx);
  727. + if (ret) {
  728. + DRM_ERROR("Not able to pin iTouch obj\n");
  729. + ipts_object_free(obj);
  730. + mutex_unlock(&intel_ipts.dev->struct_mutex);
  731. + return -ENOMEM;
  732. + }
  733. +
  734. + if (mapbuf->flags & IPTS_BUF_FLAG_CONTIGUOUS) {
  735. + obj->cpu_addr = obj->gem_obj->phys_handle->vaddr;
  736. + } else {
  737. + obj->cpu_addr = ipts_object_map(obj);
  738. + }
  739. +
  740. + if (ipts_ctx->ppgtt) {
  741. + vm = &ipts_ctx->ppgtt->base;
  742. + } else {
  743. + vm = &dev_priv->ggtt.base;
  744. + }
  745. +
  746. + vma = i915_vma_instance(obj->gem_obj, vm, NULL);
  747. + if (IS_ERR(vma)) {
  748. + DRM_ERROR("cannot find or create vma\n");
  749. + return -EINVAL;
  750. + }
  751. +
  752. + mapbuf->gfx_addr = (void*)vma->node.start;
  753. + mapbuf->cpu_addr = (void*)obj->cpu_addr;
  754. + mapbuf->buf_handle = (u64)obj;
  755. + if (mapbuf->flags & IPTS_BUF_FLAG_CONTIGUOUS) {
  756. + mapbuf->phy_addr = (u64)obj->gem_obj->phys_handle->busaddr;
  757. + }
  758. +
  759. + /* Release the mutex */
  760. + mutex_unlock(&intel_ipts.dev->struct_mutex);
  761. +
  762. + return 0;
  763. +}
  764. +
  765. +static int intel_ipts_unmap_buffer(uint64_t gfx_handle, uint64_t buf_handle)
  766. +{
  767. + intel_ipts_object_t* obj = (intel_ipts_object_t*)buf_handle;
  768. +
  769. + if (gfx_handle != (uint64_t)&intel_ipts) {
  770. + DRM_ERROR("invalid gfx handle\n");
  771. + return -EINVAL;
  772. + }
  773. +
  774. + if (!obj->gem_obj->phys_handle)
  775. + ipts_object_unmap(obj);
  776. + ipts_object_unpin(obj);
  777. + ipts_object_free(obj);
  778. +
  779. + return 0;
  780. +}
  781. +
  782. +int intel_ipts_connect(intel_ipts_connect_t *ipts_connect)
  783. +{
  784. + struct drm_i915_private *dev_priv = to_i915(intel_ipts.dev);
  785. + int ret = 0;
  786. +
  787. + if (!intel_ipts.initialized)
  788. + return -EIO;
  789. +
  790. + if (ipts_connect && ipts_connect->if_version <=
  791. + SUPPORTED_IPTS_INTERFACE_VERSION) {
  792. +
  793. + /* return gpu operations for ipts */
  794. + ipts_connect->ipts_ops.get_wq_info = intel_ipts_get_wq_info;
  795. + ipts_connect->ipts_ops.map_buffer = intel_ipts_map_buffer;
  796. + ipts_connect->ipts_ops.unmap_buffer = intel_ipts_unmap_buffer;
  797. + ipts_connect->gfx_version = INTEL_INFO(dev_priv)->gen;
  798. + ipts_connect->gfx_handle = (uint64_t)&intel_ipts;
  799. +
  800. + /* save callback and data */
  801. + intel_ipts.data = ipts_connect->data;
  802. + intel_ipts.ipts_clbks = ipts_connect->ipts_cb;
  803. +
  804. + intel_ipts.connected = true;
  805. + } else {
  806. + ret = -EINVAL;
  807. + }
  808. +
  809. + return ret;
  810. +}
  811. +EXPORT_SYMBOL_GPL(intel_ipts_connect);
  812. +
  813. +void intel_ipts_disconnect(uint64_t gfx_handle)
  814. +{
  815. + if (!intel_ipts.initialized)
  816. + return;
  817. +
  818. + if (gfx_handle != (uint64_t)&intel_ipts ||
  819. + intel_ipts.connected == false) {
  820. + DRM_ERROR("invalid gfx handle\n");
  821. + return;
  822. + }
  823. +
  824. + intel_ipts.data = 0;
  825. + memset(&intel_ipts.ipts_clbks, 0, sizeof(intel_ipts_callback_t));
  826. +
  827. + intel_ipts.connected = false;
  828. +}
  829. +EXPORT_SYMBOL_GPL(intel_ipts_disconnect);
  830. +
  831. +static void reacquire_db_work_func(struct work_struct *work)
  832. +{
  833. + struct delayed_work *d_work = container_of(work, struct delayed_work,
  834. + work);
  835. + intel_ipts_t *intel_ipts_p = container_of(d_work, intel_ipts_t,
  836. + reacquire_db_work);
  837. + u32 head;
  838. + u32 tail;
  839. + u32 size;
  840. + u32 load;
  841. +
  842. + head = *(u32*)intel_ipts_p->wq_info.wq_head_addr;
  843. + tail = *(u32*)intel_ipts_p->wq_info.wq_tail_addr;
  844. + size = intel_ipts_p->wq_info.wq_size;
  845. +
  846. + if (head >= tail)
  847. + load = head - tail;
  848. + else
  849. + load = head + size - tail;
  850. +
  851. + if (load < REACQUIRE_DB_THRESHOLD) {
  852. + intel_ipts_p->need_reacquire_db = false;
  853. + goto reschedule_work;
  854. + }
  855. +
  856. + if (intel_ipts_p->need_reacquire_db) {
  857. + if (intel_ipts_p->old_head == head && intel_ipts_p->old_tail == tail)
  858. + intel_ipts_reacquire_db(intel_ipts_p);
  859. + intel_ipts_p->need_reacquire_db = false;
  860. + } else {
  861. + intel_ipts_p->old_head = head;
  862. + intel_ipts_p->old_tail = tail;
  863. + intel_ipts_p->need_reacquire_db = true;
  864. +
  865. + /* recheck */
  866. + schedule_delayed_work(&intel_ipts_p->reacquire_db_work,
  867. + msecs_to_jiffies(DB_LOST_CHECK_STEP2_INTERVAL));
  868. + return;
  869. + }
  870. +
  871. +reschedule_work:
  872. + schedule_delayed_work(&intel_ipts_p->reacquire_db_work,
  873. + msecs_to_jiffies(DB_LOST_CHECK_STEP1_INTERVAL));
  874. +}
  875. +
  876. +/**
  877. + * intel_ipts_init - Initialize ipts support
  878. + * @dev: drm device
  879. + *
  880. + * Setup the required structures for ipts.
  881. + */
  882. +int intel_ipts_init(struct drm_device *dev)
  883. +{
  884. + int ret = 0;
  885. +
  886. + pr_info("ipts: initializing ipts\n");
  887. +
  888. + intel_ipts.dev = dev;
  889. + INIT_DELAYED_WORK(&intel_ipts.reacquire_db_work, reacquire_db_work_func);
  890. +
  891. + ret = create_ipts_context();
  892. + if (ret)
  893. + return -ENOMEM;
  894. +
  895. + ret = intel_ipts_init_wq();
  896. + if (ret)
  897. + return ret;
  898. +
  899. + intel_ipts.initialized = true;
  900. + DRM_DEBUG_DRIVER("Intel iTouch framework initialized\n");
  901. +
  902. + return ret;
  903. +}
  904. +
  905. +void intel_ipts_cleanup(struct drm_device *dev)
  906. +{
  907. + intel_ipts_object_t *obj, *n;
  908. +
  909. + if (intel_ipts.dev == dev) {
  910. + list_for_each_entry_safe(obj, n, &intel_ipts.buffers.list, list) {
  911. + list_del(&obj->list);
  912. +
  913. + if (!obj->gem_obj->phys_handle)
  914. + ipts_object_unmap(obj);
  915. + ipts_object_unpin(obj);
  916. + i915_gem_free_object(&obj->gem_obj->base);
  917. + kfree(obj);
  918. + }
  919. +
  920. + intel_ipts_release_wq();
  921. + destroy_ipts_context();
  922. + cancel_delayed_work(&intel_ipts.reacquire_db_work);
  923. + }
  924. +}
  925. diff --git a/drivers/gpu/drm/i915/intel_ipts.h b/drivers/gpu/drm/i915/intel_ipts.h
  926. new file mode 100644
  927. index 000000000000..a6965d102417
  928. --- /dev/null
  929. +++ b/drivers/gpu/drm/i915/intel_ipts.h
  930. @@ -0,0 +1,34 @@
  931. +/*
  932. + * Copyright © 2016 Intel Corporation
  933. + *
  934. + * Permission is hereby granted, free of charge, to any person obtaining a
  935. + * copy of this software and associated documentation files (the "Software"),
  936. + * to deal in the Software without restriction, including without limitation
  937. + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  938. + * and/or sell copies of the Software, and to permit persons to whom the
  939. + * Software is furnished to do so, subject to the following conditions:
  940. + *
  941. + * The above copyright notice and this permission notice (including the next
  942. + * paragraph) shall be included in all copies or substantial portions of the
  943. + * Software.
  944. + *
  945. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  946. + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  947. + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  948. + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  949. + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  950. + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  951. + * IN THE SOFTWARE.
  952. + *
  953. + */
  954. +#ifndef _INTEL_IPTS_H_
  955. +#define _INTEL_IPTS_H_
  956. +
  957. +struct drm_device;
  958. +
  959. +int intel_ipts_init(struct drm_device *dev);
  960. +void intel_ipts_cleanup(struct drm_device *dev);
  961. +int intel_ipts_notify_backlight_status(bool backlight_on);
  962. +int intel_ipts_notify_complete(void);
  963. +
  964. +#endif //_INTEL_IPTS_H_
  965. diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
  966. index 7c4c8fb1dae4..88cab775a4d2 100644
  967. --- a/drivers/gpu/drm/i915/intel_lrc.c
  968. +++ b/drivers/gpu/drm/i915/intel_lrc.c
  969. @@ -163,8 +163,6 @@
  970. #define WA_TAIL_DWORDS 2
  971. #define WA_TAIL_BYTES (sizeof(u32) * WA_TAIL_DWORDS)
  972. -static int execlists_context_deferred_alloc(struct i915_gem_context *ctx,
  973. - struct intel_engine_cs *engine);
  974. static void execlists_init_reg_state(u32 *reg_state,
  975. struct i915_gem_context *ctx,
  976. struct intel_engine_cs *engine,
  977. @@ -1345,7 +1343,7 @@ static int __context_pin(struct i915_gem_context *ctx, struct i915_vma *vma)
  978. return i915_vma_pin(vma, 0, GEN8_LR_CONTEXT_ALIGN, flags);
  979. }
  980. -static struct intel_ring *
  981. +struct intel_ring *
  982. execlists_context_pin(struct intel_engine_cs *engine,
  983. struct i915_gem_context *ctx)
  984. {
  985. @@ -1399,7 +1397,7 @@ execlists_context_pin(struct intel_engine_cs *engine,
  986. return ERR_PTR(ret);
  987. }
  988. -static void execlists_context_unpin(struct intel_engine_cs *engine,
  989. +void execlists_context_unpin(struct intel_engine_cs *engine,
  990. struct i915_gem_context *ctx)
  991. {
  992. struct intel_context *ce = to_intel_context(ctx, engine);
  993. @@ -2364,6 +2362,9 @@ int logical_render_ring_init(struct intel_engine_cs *engine)
  994. logical_ring_setup(engine);
  995. + engine->irq_keep_mask |= GT_RENDER_PIPECTL_NOTIFY_INTERRUPT
  996. + << GEN8_RCS_IRQ_SHIFT;
  997. +
  998. if (HAS_L3_DPF(dev_priv))
  999. engine->irq_keep_mask |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT;
  1000. @@ -2628,7 +2629,7 @@ populate_lr_context(struct i915_gem_context *ctx,
  1001. return ret;
  1002. }
  1003. -static int execlists_context_deferred_alloc(struct i915_gem_context *ctx,
  1004. +int execlists_context_deferred_alloc(struct i915_gem_context *ctx,
  1005. struct intel_engine_cs *engine)
  1006. {
  1007. struct drm_i915_gem_object *ctx_obj;
  1008. diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h
  1009. index 4ec7d8dd13c8..7b63b5b6d6bc 100644
  1010. --- a/drivers/gpu/drm/i915/intel_lrc.h
  1011. +++ b/drivers/gpu/drm/i915/intel_lrc.h
  1012. @@ -111,4 +111,12 @@ intel_lr_context_descriptor(struct i915_gem_context *ctx,
  1013. return to_intel_context(ctx, engine)->lrc_desc;
  1014. }
  1015. +struct intel_ring *
  1016. +execlists_context_pin(struct intel_engine_cs *engine,
  1017. + struct i915_gem_context *ctx);
  1018. +void execlists_context_unpin(struct intel_engine_cs *engine,
  1019. + struct i915_gem_context *ctx);
  1020. +int execlists_context_deferred_alloc(struct i915_gem_context *ctx,
  1021. + struct intel_engine_cs *engine);
  1022. +
  1023. #endif /* _INTEL_LRC_H_ */
  1024. diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
  1025. index b443278e569c..4e44ae7c3387 100644
  1026. --- a/drivers/gpu/drm/i915/intel_panel.c
  1027. +++ b/drivers/gpu/drm/i915/intel_panel.c
  1028. @@ -34,6 +34,7 @@
  1029. #include <linux/moduleparam.h>
  1030. #include <linux/pwm.h>
  1031. #include "intel_drv.h"
  1032. +#include "intel_ipts.h"
  1033. #define CRC_PMIC_PWM_PERIOD_NS 21333
  1034. @@ -679,6 +680,9 @@ static void lpt_disable_backlight(const struct drm_connector_state *old_conn_sta
  1035. struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
  1036. u32 tmp;
  1037. + if (INTEL_GEN(dev_priv) >= 9 && i915_modparams.enable_guc && i915_modparams.enable_ipts)
  1038. + intel_ipts_notify_backlight_status(false);
  1039. +
  1040. intel_panel_actually_set_backlight(old_conn_state, 0);
  1041. /*
  1042. @@ -866,6 +870,9 @@ static void lpt_enable_backlight(const struct intel_crtc_state *crtc_state,
  1043. /* This won't stick until the above enable. */
  1044. intel_panel_actually_set_backlight(conn_state, panel->backlight.level);
  1045. +
  1046. + if (INTEL_GEN(dev_priv) >= 9 && i915_modparams.enable_guc && i915_modparams.enable_ipts)
  1047. + intel_ipts_notify_backlight_status(true);
  1048. }
  1049. static void pch_enable_backlight(const struct intel_crtc_state *crtc_state,
  1050. diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
  1051. index 45968f7970f8..a0e053c4dc1c 100644
  1052. --- a/drivers/hid/hid-multitouch.c
  1053. +++ b/drivers/hid/hid-multitouch.c
  1054. @@ -151,6 +151,7 @@ struct mt_device {
  1055. static void mt_post_parse_default_settings(struct mt_device *td);
  1056. static void mt_post_parse(struct mt_device *td);
  1057. +static int cc_seen = 0;
  1058. /* classes of device behavior */
  1059. #define MT_CLS_DEFAULT 0x0001
  1060. @@ -614,8 +615,12 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
  1061. if (field->index >= field->report->maxfield ||
  1062. usage->usage_index >= field->report_count)
  1063. return 1;
  1064. - td->cc_index = field->index;
  1065. - td->cc_value_index = usage->usage_index;
  1066. +
  1067. + if(cc_seen != 1) {
  1068. + td->cc_index = field->index;
  1069. + td->cc_value_index = usage->usage_index;
  1070. + cc_seen++;
  1071. + }
  1072. return 1;
  1073. case HID_DG_AZIMUTH:
  1074. hid_map_usage(hi, usage, bit, max,
  1075. @@ -666,6 +671,16 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
  1076. return 0;
  1077. }
  1078. +static int mt_touch_input_mapped(struct hid_device *hdev, struct hid_input *hi,
  1079. + struct hid_field *field, struct hid_usage *usage,
  1080. + unsigned long **bit, int *max)
  1081. +{
  1082. + if (usage->type == EV_KEY || usage->type == EV_ABS)
  1083. + set_bit(usage->type, hi->input->evbit);
  1084. +
  1085. + return -1;
  1086. +}
  1087. +
  1088. static int mt_compute_slot(struct mt_device *td, struct input_dev *input)
  1089. {
  1090. __s32 quirks = td->mtclass.quirks;
  1091. @@ -1062,9 +1077,11 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
  1092. field->application != HID_DG_TOUCHSCREEN &&
  1093. field->application != HID_DG_PEN &&
  1094. field->application != HID_DG_TOUCHPAD &&
  1095. + field->application != HID_GD_MOUSE &&
  1096. field->application != HID_GD_KEYBOARD &&
  1097. field->application != HID_GD_SYSTEM_CONTROL &&
  1098. field->application != HID_CP_CONSUMER_CONTROL &&
  1099. + field->logical != HID_DG_TOUCHSCREEN &&
  1100. field->application != HID_GD_WIRELESS_RADIO_CTLS &&
  1101. !(field->application == HID_VD_ASUS_CUSTOM_MEDIA_KEYS &&
  1102. td->mtclass.quirks & MT_QUIRK_ASUS_CUSTOM_UP))
  1103. @@ -1127,10 +1144,8 @@ static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi,
  1104. return 0;
  1105. if (field->application == HID_DG_TOUCHSCREEN ||
  1106. - field->application == HID_DG_TOUCHPAD) {
  1107. - /* We own these mappings, tell hid-input to ignore them */
  1108. - return -1;
  1109. - }
  1110. + field->application == HID_DG_TOUCHPAD)
  1111. + return mt_touch_input_mapped(hdev, hi, field, usage, bit, max);
  1112. /* let hid-core decide for the others */
  1113. return 0;
  1114. @@ -1315,6 +1330,7 @@ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
  1115. suffix = "Pen";
  1116. /* force BTN_STYLUS to allow tablet matching in udev */
  1117. __set_bit(BTN_STYLUS, hi->input->keybit);
  1118. + __set_bit(INPUT_PROP_DIRECT, hi->input->propbit);
  1119. }
  1120. }
  1121. @@ -1330,12 +1346,13 @@ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
  1122. /* already handled by hid core */
  1123. break;
  1124. case HID_DG_TOUCHSCREEN:
  1125. - /* we do not set suffix = "Touchscreen" */
  1126. + suffix = "Touchscreen";
  1127. hi->input->name = hdev->name;
  1128. break;
  1129. case HID_DG_STYLUS:
  1130. /* force BTN_STYLUS to allow tablet matching in udev */
  1131. __set_bit(BTN_STYLUS, hi->input->keybit);
  1132. + __set_bit(INPUT_PROP_DIRECT, hi->input->propbit);
  1133. break;
  1134. case HID_VD_ASUS_CUSTOM_MEDIA_KEYS:
  1135. suffix = "Custom Media Keys";
  1136. @@ -1452,6 +1469,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
  1137. td->cc_index = -1;
  1138. td->scantime_index = -1;
  1139. td->mt_report_id = -1;
  1140. + cc_seen = 0;
  1141. hid_set_drvdata(hdev, td);
  1142. td->fields = devm_kzalloc(&hdev->dev, sizeof(struct mt_fields),
  1143. diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
  1144. index 3726eacdf65d..77263b5f5915 100644
  1145. --- a/drivers/misc/Kconfig
  1146. +++ b/drivers/misc/Kconfig
  1147. @@ -520,6 +520,7 @@ source "drivers/misc/ti-st/Kconfig"
  1148. source "drivers/misc/lis3lv02d/Kconfig"
  1149. source "drivers/misc/altera-stapl/Kconfig"
  1150. source "drivers/misc/mei/Kconfig"
  1151. +source "drivers/misc/ipts/Kconfig"
  1152. source "drivers/misc/vmw_vmci/Kconfig"
  1153. source "drivers/misc/mic/Kconfig"
  1154. source "drivers/misc/genwqe/Kconfig"
  1155. diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
  1156. index af22bbc3d00c..eb1eb0d58c32 100644
  1157. --- a/drivers/misc/Makefile
  1158. +++ b/drivers/misc/Makefile
  1159. @@ -44,6 +44,7 @@ obj-y += lis3lv02d/
  1160. obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
  1161. obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/
  1162. obj-$(CONFIG_INTEL_MEI) += mei/
  1163. +obj-$(CONFIG_INTEL_IPTS) += ipts/
  1164. obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/
  1165. obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o
  1166. obj-$(CONFIG_SRAM) += sram.o
  1167. diff --git a/drivers/misc/ipts/Kconfig b/drivers/misc/ipts/Kconfig
  1168. new file mode 100644
  1169. index 000000000000..360ed3861b82
  1170. --- /dev/null
  1171. +++ b/drivers/misc/ipts/Kconfig
  1172. @@ -0,0 +1,9 @@
  1173. +config INTEL_IPTS
  1174. + tristate "Intel Precise Touch & Stylus"
  1175. + select INTEL_MEI
  1176. + depends on X86 && PCI && HID
  1177. + help
  1178. + Intel Precise Touch & Stylus support
  1179. + Supported SoCs:
  1180. + Intel Skylake
  1181. + Intel Kabylake
  1182. diff --git a/drivers/misc/ipts/Makefile b/drivers/misc/ipts/Makefile
  1183. new file mode 100644
  1184. index 000000000000..1783e9cf13c9
  1185. --- /dev/null
  1186. +++ b/drivers/misc/ipts/Makefile
  1187. @@ -0,0 +1,13 @@
  1188. +#
  1189. +# Makefile - Intel Precise Touch & Stylus device driver
  1190. +# Copyright (c) 2016, Intel Corporation.
  1191. +#
  1192. +
  1193. +obj-$(CONFIG_INTEL_IPTS)+= intel-ipts.o
  1194. +intel-ipts-objs += ipts-mei.o
  1195. +intel-ipts-objs += ipts-hid.o
  1196. +intel-ipts-objs += ipts-msg-handler.o
  1197. +intel-ipts-objs += ipts-kernel.o
  1198. +intel-ipts-objs += ipts-resource.o
  1199. +intel-ipts-objs += ipts-gfx.o
  1200. +intel-ipts-$(CONFIG_DEBUG_FS) += ipts-dbgfs.o
  1201. diff --git a/drivers/misc/ipts/ipts-binary-spec.h b/drivers/misc/ipts/ipts-binary-spec.h
  1202. new file mode 100644
  1203. index 000000000000..87d4bc4133c4
  1204. --- /dev/null
  1205. +++ b/drivers/misc/ipts/ipts-binary-spec.h
  1206. @@ -0,0 +1,118 @@
  1207. +/*
  1208. + *
  1209. + * Intel Precise Touch & Stylus binary spec
  1210. + * Copyright (c) 2016 Intel Corporation.
  1211. + *
  1212. + * This program is free software; you can redistribute it and/or modify it
  1213. + * under the terms and conditions of the GNU General Public License,
  1214. + * version 2, as published by the Free Software Foundation.
  1215. + *
  1216. + * This program is distributed in the hope it will be useful, but WITHOUT
  1217. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  1218. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  1219. + * more details.
  1220. + *
  1221. + */
  1222. +
  1223. +#ifndef _IPTS_BINARY_SPEC_H
  1224. +#define _IPTS_BINARY_SPEC_H
  1225. +
  1226. +#define IPTS_BIN_HEADER_VERSION 2
  1227. +
  1228. +#pragma pack(1)
  1229. +
  1230. +/* we support 16 output buffers(1:feedback, 15:HID) */
  1231. +#define MAX_NUM_OUTPUT_BUFFERS 16
  1232. +
  1233. +typedef enum {
  1234. + IPTS_BIN_KERNEL,
  1235. + IPTS_BIN_RO_DATA,
  1236. + IPTS_BIN_RW_DATA,
  1237. + IPTS_BIN_SENSOR_FRAME,
  1238. + IPTS_BIN_OUTPUT,
  1239. + IPTS_BIN_DYNAMIC_STATE_HEAP,
  1240. + IPTS_BIN_PATCH_LOCATION_LIST,
  1241. + IPTS_BIN_ALLOCATION_LIST,
  1242. + IPTS_BIN_COMMAND_BUFFER_PACKET,
  1243. + IPTS_BIN_TAG,
  1244. +} ipts_bin_res_type_t;
  1245. +
  1246. +typedef struct ipts_bin_header {
  1247. + char str[4];
  1248. + unsigned int version;
  1249. +
  1250. +#if IPTS_BIN_HEADER_VERSION > 1
  1251. + unsigned int gfxcore;
  1252. + unsigned int revid;
  1253. +#endif
  1254. +} ipts_bin_header_t;
  1255. +
  1256. +typedef struct ipts_bin_alloc {
  1257. + unsigned int handle;
  1258. + unsigned int reserved;
  1259. +} ipts_bin_alloc_t;
  1260. +
  1261. +typedef struct ipts_bin_alloc_list {
  1262. + unsigned int num;
  1263. + ipts_bin_alloc_t alloc[];
  1264. +} ipts_bin_alloc_list_t;
  1265. +
  1266. +typedef struct ipts_bin_cmdbuf {
  1267. + unsigned int size;
  1268. + char data[];
  1269. +} ipts_bin_cmdbuf_t;
  1270. +
  1271. +typedef struct ipts_bin_res {
  1272. + unsigned int handle;
  1273. + ipts_bin_res_type_t type;
  1274. + unsigned int initialize;
  1275. + unsigned int aligned_size;
  1276. + unsigned int size;
  1277. + char data[];
  1278. +} ipts_bin_res_t;
  1279. +
  1280. +typedef enum {
  1281. + IPTS_INPUT,
  1282. + IPTS_OUTPUT,
  1283. + IPTS_CONFIGURATION,
  1284. + IPTS_CALIBRATION,
  1285. + IPTS_FEATURE,
  1286. +} ipts_bin_io_buffer_type_t;
  1287. +
  1288. +typedef struct ipts_bin_io_header {
  1289. + char str[10];
  1290. + unsigned short type;
  1291. +} ipts_bin_io_header_t;
  1292. +
  1293. +typedef struct ipts_bin_res_list {
  1294. + unsigned int num;
  1295. + ipts_bin_res_t res[];
  1296. +} ipts_bin_res_list_t;
  1297. +
  1298. +typedef struct ipts_bin_patch {
  1299. + unsigned int index;
  1300. + unsigned int reserved1[2];
  1301. + unsigned int alloc_offset;
  1302. + unsigned int patch_offset;
  1303. + unsigned int reserved2;
  1304. +} ipts_bin_patch_t;
  1305. +
  1306. +typedef struct ipts_bin_patch_list {
  1307. + unsigned int num;
  1308. + ipts_bin_patch_t patch[];
  1309. +} ipts_bin_patch_list_t;
  1310. +
  1311. +typedef struct ipts_bin_guc_wq_info {
  1312. + unsigned int batch_offset;
  1313. + unsigned int size;
  1314. + char data[];
  1315. +} ipts_bin_guc_wq_info_t;
  1316. +
  1317. +typedef struct ipts_bin_bufid_patch {
  1318. + unsigned int imm_offset;
  1319. + unsigned int mem_offset;
  1320. +} ipts_bin_bufid_patch_t;
  1321. +
  1322. +#pragma pack()
  1323. +
  1324. +#endif /* _IPTS_BINARY_SPEC_H */
  1325. diff --git a/drivers/misc/ipts/ipts-dbgfs.c b/drivers/misc/ipts/ipts-dbgfs.c
  1326. new file mode 100644
  1327. index 000000000000..1c5c92f7d4ba
  1328. --- /dev/null
  1329. +++ b/drivers/misc/ipts/ipts-dbgfs.c
  1330. @@ -0,0 +1,152 @@
  1331. +/*
  1332. + * Intel Precise Touch & Stylus device driver
  1333. + * Copyright (c) 2016, Intel Corporation.
  1334. + *
  1335. + * This program is free software; you can redistribute it and/or modify it
  1336. + * under the terms and conditions of the GNU General Public License,
  1337. + * version 2, as published by the Free Software Foundation.
  1338. + *
  1339. + * This program is distributed in the hope it will be useful, but WITHOUT
  1340. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  1341. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  1342. + * more details.
  1343. + *
  1344. + */
  1345. +#include <linux/debugfs.h>
  1346. +#include <linux/ctype.h>
  1347. +#include <linux/uaccess.h>
  1348. +
  1349. +#include "ipts.h"
  1350. +#include "ipts-sensor-regs.h"
  1351. +#include "ipts-msg-handler.h"
  1352. +#include "ipts-state.h"
  1353. +
  1354. +const char sensor_mode_fmt[] = "sensor mode : %01d\n";
  1355. +const char ipts_status_fmt[] = "sensor mode : %01d\nipts state : %01d\n";
  1356. +
  1357. +static ssize_t ipts_dbgfs_mode_read(struct file *fp, char __user *ubuf,
  1358. + size_t cnt, loff_t *ppos)
  1359. +{
  1360. + ipts_info_t *ipts = fp->private_data;
  1361. + char mode[80];
  1362. + int len = 0;
  1363. +
  1364. + if (cnt < sizeof(sensor_mode_fmt) - 3)
  1365. + return -EINVAL;
  1366. +
  1367. + len = scnprintf(mode, 80, sensor_mode_fmt, ipts->sensor_mode);
  1368. + if (len < 0)
  1369. + return -EIO;
  1370. +
  1371. + return simple_read_from_buffer(ubuf, cnt, ppos, mode, len);
  1372. +}
  1373. +
  1374. +static ssize_t ipts_dbgfs_mode_write(struct file *fp, const char __user *ubuf,
  1375. + size_t cnt, loff_t *ppos)
  1376. +{
  1377. + ipts_info_t *ipts = fp->private_data;
  1378. + ipts_state_t state;
  1379. + int sensor_mode, len;
  1380. + char mode[3];
  1381. +
  1382. + if (cnt == 0 || cnt > 3)
  1383. + return -EINVAL;
  1384. +
  1385. + state = ipts_get_state(ipts);
  1386. + if (state != IPTS_STA_RAW_DATA_STARTED && state != IPTS_STA_HID_STARTED) {
  1387. + return -EIO;
  1388. + }
  1389. +
  1390. + len = cnt;
  1391. + if (copy_from_user(mode, ubuf, len))
  1392. + return -EFAULT;
  1393. +
  1394. + while(len > 0 && (isspace(mode[len-1]) || mode[len-1] == '\n'))
  1395. + len--;
  1396. + mode[len] = '\0';
  1397. +
  1398. + if (sscanf(mode, "%d", &sensor_mode) != 1)
  1399. + return -EINVAL;
  1400. +
  1401. + if (sensor_mode != TOUCH_SENSOR_MODE_RAW_DATA &&
  1402. + sensor_mode != TOUCH_SENSOR_MODE_HID) {
  1403. + return -EINVAL;
  1404. + }
  1405. +
  1406. + if (sensor_mode == ipts->sensor_mode)
  1407. + return 0;
  1408. +
  1409. + ipts_switch_sensor_mode(ipts, sensor_mode);
  1410. +
  1411. + return cnt;
  1412. +}
  1413. +
  1414. +static const struct file_operations ipts_mode_dbgfs_fops = {
  1415. + .open = simple_open,
  1416. + .read = ipts_dbgfs_mode_read,
  1417. + .write = ipts_dbgfs_mode_write,
  1418. + .llseek = generic_file_llseek,
  1419. +};
  1420. +
  1421. +static ssize_t ipts_dbgfs_status_read(struct file *fp, char __user *ubuf,
  1422. + size_t cnt, loff_t *ppos)
  1423. +{
  1424. + ipts_info_t *ipts = fp->private_data;
  1425. + char status[256];
  1426. + int len = 0;
  1427. +
  1428. + if (cnt < sizeof(ipts_status_fmt) - 3)
  1429. + return -EINVAL;
  1430. +
  1431. + len = scnprintf(status, 256, ipts_status_fmt, ipts->sensor_mode,
  1432. + ipts->state);
  1433. + if (len < 0)
  1434. + return -EIO;
  1435. +
  1436. + return simple_read_from_buffer(ubuf, cnt, ppos, status, len);
  1437. +}
  1438. +
  1439. +static const struct file_operations ipts_status_dbgfs_fops = {
  1440. + .open = simple_open,
  1441. + .read = ipts_dbgfs_status_read,
  1442. + .llseek = generic_file_llseek,
  1443. +};
  1444. +
  1445. +void ipts_dbgfs_deregister(ipts_info_t* ipts)
  1446. +{
  1447. + if (!ipts->dbgfs_dir)
  1448. + return;
  1449. +
  1450. + debugfs_remove_recursive(ipts->dbgfs_dir);
  1451. + ipts->dbgfs_dir = NULL;
  1452. +}
  1453. +
  1454. +int ipts_dbgfs_register(ipts_info_t* ipts, const char *name)
  1455. +{
  1456. + struct dentry *dir, *f;
  1457. +
  1458. + dir = debugfs_create_dir(name, NULL);
  1459. + if (!dir)
  1460. + return -ENOMEM;
  1461. +
  1462. + f = debugfs_create_file("mode", S_IRUSR | S_IWUSR, dir,
  1463. + ipts, &ipts_mode_dbgfs_fops);
  1464. + if (!f) {
  1465. + ipts_err(ipts, "debugfs mode creation failed\n");
  1466. + goto err;
  1467. + }
  1468. +
  1469. + f = debugfs_create_file("status", S_IRUSR, dir,
  1470. + ipts, &ipts_status_dbgfs_fops);
  1471. + if (!f) {
  1472. + ipts_err(ipts, "debugfs status creation failed\n");
  1473. + goto err;
  1474. + }
  1475. +
  1476. + ipts->dbgfs_dir = dir;
  1477. +
  1478. + return 0;
  1479. +err:
  1480. + ipts_dbgfs_deregister(ipts);
  1481. + return -ENODEV;
  1482. +}
  1483. diff --git a/drivers/misc/ipts/ipts-gfx.c b/drivers/misc/ipts/ipts-gfx.c
  1484. new file mode 100644
  1485. index 000000000000..51727770e75d
  1486. --- /dev/null
  1487. +++ b/drivers/misc/ipts/ipts-gfx.c
  1488. @@ -0,0 +1,184 @@
  1489. +/*
  1490. + *
  1491. + * Intel Integrated Touch Gfx Interface Layer
  1492. + * Copyright (c) 2016 Intel Corporation.
  1493. + *
  1494. + * This program is free software; you can redistribute it and/or modify it
  1495. + * under the terms and conditions of the GNU General Public License,
  1496. + * version 2, as published by the Free Software Foundation.
  1497. + *
  1498. + * This program is distributed in the hope it will be useful, but WITHOUT
  1499. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  1500. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  1501. + * more details.
  1502. + *
  1503. + */
  1504. +#include <linux/kthread.h>
  1505. +#include <linux/delay.h>
  1506. +#include <linux/intel_ipts_if.h>
  1507. +
  1508. +#include "ipts.h"
  1509. +#include "ipts-msg-handler.h"
  1510. +#include "ipts-state.h"
  1511. +
  1512. +static void gfx_processing_complete(void *data)
  1513. +{
  1514. + ipts_info_t *ipts = data;
  1515. +
  1516. + if (ipts_get_state(ipts) == IPTS_STA_RAW_DATA_STARTED) {
  1517. + schedule_work(&ipts->raw_data_work);
  1518. + return;
  1519. + }
  1520. +
  1521. + ipts_dbg(ipts, "not ready to handle gfx event\n");
  1522. +}
  1523. +
  1524. +static void notify_gfx_status(u32 status, void *data)
  1525. +{
  1526. + ipts_info_t *ipts = data;
  1527. +
  1528. + ipts->gfx_status = status;
  1529. + schedule_work(&ipts->gfx_status_work);
  1530. +}
  1531. +
  1532. +static int connect_gfx(ipts_info_t *ipts)
  1533. +{
  1534. + int ret = 0;
  1535. + intel_ipts_connect_t ipts_connect;
  1536. +
  1537. + ipts_connect.if_version = IPTS_INTERFACE_V1;
  1538. + ipts_connect.ipts_cb.workload_complete = gfx_processing_complete;
  1539. + ipts_connect.ipts_cb.notify_gfx_status = notify_gfx_status;
  1540. + ipts_connect.data = (void*)ipts;
  1541. +
  1542. + ret = intel_ipts_connect(&ipts_connect);
  1543. + if (ret)
  1544. + return ret;
  1545. +
  1546. + /* TODO: gfx version check */
  1547. + ipts->gfx_info.gfx_handle = ipts_connect.gfx_handle;
  1548. + ipts->gfx_info.ipts_ops = ipts_connect.ipts_ops;
  1549. +
  1550. + return ret;
  1551. +}
  1552. +
  1553. +static void disconnect_gfx(ipts_info_t *ipts)
  1554. +{
  1555. + intel_ipts_disconnect(ipts->gfx_info.gfx_handle);
  1556. +}
  1557. +
  1558. +#ifdef RUN_DBG_THREAD
  1559. +#include "../mei/mei_dev.h"
  1560. +
  1561. +static struct task_struct *dbg_thread;
  1562. +
  1563. +static void ipts_print_dbg_info(ipts_info_t* ipts)
  1564. +{
  1565. + char fw_sts_str[MEI_FW_STATUS_STR_SZ];
  1566. + u32 *db, *head, *tail;
  1567. + intel_ipts_wq_info_t* wq_info;
  1568. +
  1569. + wq_info = &ipts->resource.wq_info;
  1570. +
  1571. + mei_fw_status_str(ipts->cldev->bus, fw_sts_str, MEI_FW_STATUS_STR_SZ);
  1572. + pr_info(">> tdt : fw status : %s\n", fw_sts_str);
  1573. +
  1574. + db = (u32*)wq_info->db_addr;
  1575. + head = (u32*)wq_info->wq_head_addr;
  1576. + tail = (u32*)wq_info->wq_tail_addr;
  1577. + pr_info(">> == DB s:%x, c:%x ==\n", *db, *(db+1));
  1578. + pr_info(">> == WQ h:%u, t:%u ==\n", *head, *tail);
  1579. +}
  1580. +
  1581. +static int ipts_dbg_thread(void *data)
  1582. +{
  1583. + ipts_info_t *ipts = (ipts_info_t *)data;
  1584. +
  1585. + pr_info(">> start debug thread\n");
  1586. +
  1587. + while (!kthread_should_stop()) {
  1588. + if (ipts_get_state(ipts) != IPTS_STA_RAW_DATA_STARTED) {
  1589. + pr_info("state is not IPTS_STA_RAW_DATA_STARTED : %d\n",
  1590. + ipts_get_state(ipts));
  1591. + msleep(5000);
  1592. + continue;
  1593. + }
  1594. +
  1595. + ipts_print_dbg_info(ipts);
  1596. +
  1597. + msleep(3000);
  1598. + }
  1599. +
  1600. + return 0;
  1601. +}
  1602. +#endif
  1603. +
  1604. +int ipts_open_gpu(ipts_info_t *ipts)
  1605. +{
  1606. + int ret = 0;
  1607. +
  1608. + ret = connect_gfx(ipts);
  1609. + if (ret) {
  1610. + ipts_dbg(ipts, "cannot connect GPU\n");
  1611. + return ret;
  1612. + }
  1613. +
  1614. + ret = ipts->gfx_info.ipts_ops.get_wq_info(ipts->gfx_info.gfx_handle,
  1615. + &ipts->resource.wq_info);
  1616. + if (ret) {
  1617. + ipts_dbg(ipts, "error in get_wq_info\n");
  1618. + return ret;
  1619. + }
  1620. +
  1621. +#ifdef RUN_DBG_THREAD
  1622. + dbg_thread = kthread_run(ipts_dbg_thread, (void *)ipts, "ipts_debug");
  1623. +#endif
  1624. +
  1625. + return 0;
  1626. +}
  1627. +
  1628. +void ipts_close_gpu(ipts_info_t *ipts)
  1629. +{
  1630. + disconnect_gfx(ipts);
  1631. +
  1632. +#ifdef RUN_DBG_THREAD
  1633. + kthread_stop(dbg_thread);
  1634. +#endif
  1635. +}
  1636. +
  1637. +intel_ipts_mapbuffer_t *ipts_map_buffer(ipts_info_t *ipts, u32 size, u32 flags)
  1638. +{
  1639. + intel_ipts_mapbuffer_t *buf;
  1640. + u64 handle;
  1641. + int ret;
  1642. +
  1643. + buf = devm_kzalloc(&ipts->cldev->dev, sizeof(*buf), GFP_KERNEL);
  1644. + if (!buf)
  1645. + return NULL;
  1646. +
  1647. + buf->size = size;
  1648. + buf->flags = flags;
  1649. +
  1650. + handle = ipts->gfx_info.gfx_handle;
  1651. + ret = ipts->gfx_info.ipts_ops.map_buffer(handle, buf);
  1652. + if (ret) {
  1653. + devm_kfree(&ipts->cldev->dev, buf);
  1654. + return NULL;
  1655. + }
  1656. +
  1657. + return buf;
  1658. +}
  1659. +
  1660. +void ipts_unmap_buffer(ipts_info_t *ipts, intel_ipts_mapbuffer_t *buf)
  1661. +{
  1662. + u64 handle;
  1663. + int ret;
  1664. +
  1665. + if (!buf)
  1666. + return;
  1667. +
  1668. + handle = ipts->gfx_info.gfx_handle;
  1669. + ret = ipts->gfx_info.ipts_ops.unmap_buffer(handle, buf->buf_handle);
  1670. +
  1671. + devm_kfree(&ipts->cldev->dev, buf);
  1672. +}
  1673. diff --git a/drivers/misc/ipts/ipts-gfx.h b/drivers/misc/ipts/ipts-gfx.h
  1674. new file mode 100644
  1675. index 000000000000..03a5f3551ddf
  1676. --- /dev/null
  1677. +++ b/drivers/misc/ipts/ipts-gfx.h
  1678. @@ -0,0 +1,24 @@
  1679. +/*
  1680. + * Intel Precise Touch & Stylus gpu wrapper
  1681. + * Copyright (c) 2016, Intel Corporation.
  1682. + *
  1683. + * This program is free software; you can redistribute it and/or modify it
  1684. + * under the terms and conditions of the GNU General Public License,
  1685. + * version 2, as published by the Free Software Foundation.
  1686. + *
  1687. + * This program is distributed in the hope it will be useful, but WITHOUT
  1688. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  1689. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  1690. + * more details.
  1691. + */
  1692. +
  1693. +
  1694. +#ifndef _IPTS_GFX_H_
  1695. +#define _IPTS_GFX_H_
  1696. +
  1697. +int ipts_open_gpu(ipts_info_t *ipts);
  1698. +void ipts_close_gpu(ipts_info_t *ipts);
  1699. +intel_ipts_mapbuffer_t *ipts_map_buffer(ipts_info_t *ipts, u32 size, u32 flags);
  1700. +void ipts_unmap_buffer(ipts_info_t *ipts, intel_ipts_mapbuffer_t *buf);
  1701. +
  1702. +#endif // _IPTS_GFX_H_
  1703. diff --git a/drivers/misc/ipts/ipts-hid.c b/drivers/misc/ipts/ipts-hid.c
  1704. new file mode 100644
  1705. index 000000000000..3b3be6177648
  1706. --- /dev/null
  1707. +++ b/drivers/misc/ipts/ipts-hid.c
  1708. @@ -0,0 +1,456 @@
  1709. +/*
  1710. + * Intel Precise Touch & Stylus HID driver
  1711. + *
  1712. + * Copyright (c) 2016, Intel Corporation.
  1713. + *
  1714. + * This program is free software; you can redistribute it and/or modify it
  1715. + * under the terms and conditions of the GNU General Public License,
  1716. + * version 2, as published by the Free Software Foundation.
  1717. + *
  1718. + * This program is distributed in the hope it will be useful, but WITHOUT
  1719. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  1720. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  1721. + * more details.
  1722. + */
  1723. +
  1724. +#include <linux/module.h>
  1725. +#include <linux/firmware.h>
  1726. +#include <linux/hid.h>
  1727. +#include <linux/vmalloc.h>
  1728. +
  1729. +#include "ipts.h"
  1730. +#include "ipts-resource.h"
  1731. +#include "ipts-sensor-regs.h"
  1732. +#include "ipts-msg-handler.h"
  1733. +
  1734. +#define BUS_MEI 0x44
  1735. +
  1736. +#define HID_DESC_INTEL "intel/ipts/intel_desc.bin"
  1737. +#define HID_DESC_VENDOR "intel/ipts/vendor_desc.bin"
  1738. +MODULE_FIRMWARE(HID_DESC_INTEL);
  1739. +MODULE_FIRMWARE(HID_DESC_VENDOR);
  1740. +
  1741. +typedef enum output_buffer_payload_type {
  1742. + OUTPUT_BUFFER_PAYLOAD_ERROR = 0,
  1743. + OUTPUT_BUFFER_PAYLOAD_HID_INPUT_REPORT,
  1744. + OUTPUT_BUFFER_PAYLOAD_HID_FEATURE_REPORT,
  1745. + OUTPUT_BUFFER_PAYLOAD_KERNEL_LOAD,
  1746. + OUTPUT_BUFFER_PAYLOAD_FEEDBACK_BUFFER
  1747. +} output_buffer_payload_type_t;
  1748. +
  1749. +typedef struct kernel_output_buffer_header {
  1750. + u16 length;
  1751. + u8 payload_type;
  1752. + u8 reserved1;
  1753. + touch_hid_private_data_t hid_private_data;
  1754. + u8 reserved2[28];
  1755. + u8 data[0];
  1756. +} kernel_output_buffer_header_t;
  1757. +
  1758. +typedef struct kernel_output_payload_error {
  1759. + u16 severity;
  1760. + u16 source;
  1761. + u8 code[4];
  1762. + char string[128];
  1763. +} kernel_output_payload_error_t;
  1764. +
  1765. +static int ipts_hid_get_hid_descriptor(ipts_info_t *ipts, u8 **desc, int *size)
  1766. +{
  1767. + u8 *buf;
  1768. + int hid_size = 0, ret = 0;
  1769. + const struct firmware *intel_desc = NULL;
  1770. + const struct firmware *vendor_desc = NULL;
  1771. + const char *intel_desc_path = HID_DESC_INTEL;
  1772. + const char *vendor_desc_path = HID_DESC_VENDOR;
  1773. +
  1774. + ret = request_firmware(&intel_desc, intel_desc_path, &ipts->cldev->dev);
  1775. + if (ret) {
  1776. + goto no_hid;
  1777. + }
  1778. + hid_size = intel_desc->size;
  1779. +
  1780. + ret = request_firmware(&vendor_desc, vendor_desc_path, &ipts->cldev->dev);
  1781. + if (ret) {
  1782. + ipts_dbg(ipts, "error in reading HID Vendor Descriptor\n");
  1783. + } else {
  1784. + hid_size += vendor_desc->size;
  1785. + }
  1786. +
  1787. + ipts_dbg(ipts, "hid size = %d\n", hid_size);
  1788. + buf = vmalloc(hid_size);
  1789. + if (buf == NULL) {
  1790. + ret = -ENOMEM;
  1791. + goto no_mem;
  1792. + }
  1793. +
  1794. + memcpy(buf, intel_desc->data, intel_desc->size);
  1795. + if (vendor_desc) {
  1796. + memcpy(&buf[intel_desc->size], vendor_desc->data,
  1797. + vendor_desc->size);
  1798. + release_firmware(vendor_desc);
  1799. + }
  1800. +
  1801. + release_firmware(intel_desc);
  1802. +
  1803. + *desc = buf;
  1804. + *size = hid_size;
  1805. +
  1806. + return 0;
  1807. +no_mem :
  1808. + if (vendor_desc)
  1809. + release_firmware(vendor_desc);
  1810. + release_firmware(intel_desc);
  1811. +
  1812. +no_hid :
  1813. + return ret;
  1814. +}
  1815. +
  1816. +static int ipts_hid_parse(struct hid_device *hid)
  1817. +{
  1818. + ipts_info_t *ipts = hid->driver_data;
  1819. + int ret = 0, size;
  1820. + u8 *buf;
  1821. +
  1822. + ipts_dbg(ipts, "ipts_hid_parse() start\n");
  1823. + ret = ipts_hid_get_hid_descriptor(ipts, &buf, &size);
  1824. + if (ret != 0) {
  1825. + ipts_dbg(ipts, "ipts_hid_ipts_get_hid_descriptor ret %d\n", ret);
  1826. + return -EIO;
  1827. + }
  1828. +
  1829. + ret = hid_parse_report(hid, buf, size);
  1830. + vfree(buf);
  1831. + if (ret) {
  1832. + ipts_err(ipts, "hid_parse_report error : %d\n", ret);
  1833. + goto out;
  1834. + }
  1835. +
  1836. + ipts->hid_desc_ready = true;
  1837. +out:
  1838. + return ret;
  1839. +}
  1840. +
  1841. +static int ipts_hid_start(struct hid_device *hid)
  1842. +{
  1843. + return 0;
  1844. +}
  1845. +
  1846. +static void ipts_hid_stop(struct hid_device *hid)
  1847. +{
  1848. + return;
  1849. +}
  1850. +
  1851. +static int ipts_hid_open(struct hid_device *hid)
  1852. +{
  1853. + return 0;
  1854. +}
  1855. +
  1856. +static void ipts_hid_close(struct hid_device *hid)
  1857. +{
  1858. + ipts_info_t *ipts = hid->driver_data;
  1859. +
  1860. + ipts->hid_desc_ready = false;
  1861. +
  1862. + return;
  1863. +}
  1864. +
  1865. +static int ipts_hid_send_hid2me_feedback(ipts_info_t *ipts, u32 fb_data_type,
  1866. + __u8 *buf, size_t count)
  1867. +{
  1868. + ipts_buffer_info_t *fb_buf;
  1869. + touch_feedback_hdr_t *feedback;
  1870. + u8 *payload;
  1871. + int header_size;
  1872. + ipts_state_t state;
  1873. +
  1874. + header_size = sizeof(touch_feedback_hdr_t);
  1875. +
  1876. + if (count > ipts->resource.hid2me_buffer_size - header_size)
  1877. + return -EINVAL;
  1878. +
  1879. + state = ipts_get_state(ipts);
  1880. + if (state != IPTS_STA_RAW_DATA_STARTED && state != IPTS_STA_HID_STARTED)
  1881. + return 0;
  1882. +
  1883. + fb_buf = ipts_get_hid2me_buffer(ipts);
  1884. + feedback = (touch_feedback_hdr_t *)fb_buf->addr;
  1885. + payload = fb_buf->addr + header_size;
  1886. + memset(feedback, 0, header_size);
  1887. +
  1888. + feedback->feedback_data_type = fb_data_type;
  1889. + feedback->feedback_cmd_type = TOUCH_FEEDBACK_CMD_TYPE_NONE;
  1890. + feedback->payload_size_bytes = count;
  1891. + feedback->buffer_id = TOUCH_HID_2_ME_BUFFER_ID;
  1892. + feedback->protocol_ver = 0;
  1893. + feedback->reserved[0] = 0xAC;
  1894. +
  1895. + /* copy payload */
  1896. + memcpy(payload, buf, count);
  1897. +
  1898. + ipts_send_feedback(ipts, TOUCH_HID_2_ME_BUFFER_ID, 0);
  1899. +
  1900. + return 0;
  1901. +}
  1902. +
  1903. +static int ipts_hid_raw_request(struct hid_device *hid,
  1904. + unsigned char report_number, __u8 *buf,
  1905. + size_t count, unsigned char report_type,
  1906. + int reqtype)
  1907. +{
  1908. + ipts_info_t *ipts = hid->driver_data;
  1909. + u32 fb_data_type;
  1910. +
  1911. + ipts_dbg(ipts, "hid raw request => report %d, request %d\n",
  1912. + (int)report_type, reqtype);
  1913. +
  1914. + if (report_type != HID_FEATURE_REPORT)
  1915. + return 0;
  1916. +
  1917. + switch (reqtype) {
  1918. + case HID_REQ_GET_REPORT:
  1919. + fb_data_type = TOUCH_FEEDBACK_DATA_TYPE_GET_FEATURES;
  1920. + break;
  1921. + case HID_REQ_SET_REPORT:
  1922. + fb_data_type = TOUCH_FEEDBACK_DATA_TYPE_SET_FEATURES;
  1923. + break;
  1924. + default:
  1925. + ipts_err(ipts, "raw request not supprted: %d\n", reqtype);
  1926. + return -EIO;
  1927. + }
  1928. +
  1929. + return ipts_hid_send_hid2me_feedback(ipts, fb_data_type, buf, count);
  1930. +}
  1931. +
  1932. +static int ipts_hid_output_report(struct hid_device *hid,
  1933. + __u8 *buf, size_t count)
  1934. +{
  1935. + ipts_info_t *ipts = hid->driver_data;
  1936. + u32 fb_data_type;
  1937. +
  1938. + ipts_dbg(ipts, "hid output report\n");
  1939. +
  1940. + fb_data_type = TOUCH_FEEDBACK_DATA_TYPE_OUTPUT_REPORT;
  1941. +
  1942. + return ipts_hid_send_hid2me_feedback(ipts, fb_data_type, buf, count);
  1943. +}
  1944. +
  1945. +static struct hid_ll_driver ipts_hid_ll_driver = {
  1946. + .parse = ipts_hid_parse,
  1947. + .start = ipts_hid_start,
  1948. + .stop = ipts_hid_stop,
  1949. + .open = ipts_hid_open,
  1950. + .close = ipts_hid_close,
  1951. + .raw_request = ipts_hid_raw_request,
  1952. + .output_report = ipts_hid_output_report,
  1953. +};
  1954. +
  1955. +int ipts_hid_init(ipts_info_t *ipts)
  1956. +{
  1957. + int ret = 0;
  1958. + struct hid_device *hid;
  1959. +
  1960. + hid = hid_allocate_device();
  1961. + if (IS_ERR(hid)) {
  1962. + ret = PTR_ERR(hid);
  1963. + goto err_dev;
  1964. + }
  1965. +
  1966. + hid->driver_data = ipts;
  1967. + hid->ll_driver = &ipts_hid_ll_driver;
  1968. + hid->dev.parent = &ipts->cldev->dev;
  1969. + hid->bus = BUS_MEI;
  1970. + hid->version = ipts->device_info.fw_rev;
  1971. + hid->vendor = ipts->device_info.vendor_id;
  1972. + hid->product = ipts->device_info.device_id;
  1973. +
  1974. + snprintf(hid->phys, sizeof(hid->phys), "heci3");
  1975. + snprintf(hid->name, sizeof(hid->name),
  1976. + "%s %04hX:%04hX", "ipts", hid->vendor, hid->product);
  1977. +
  1978. + ret = hid_add_device(hid);
  1979. + if (ret) {
  1980. + if (ret != -ENODEV)
  1981. + ipts_err(ipts, "can't add hid device: %d\n", ret);
  1982. + goto err_mem_free;
  1983. + }
  1984. +
  1985. + ipts->hid = hid;
  1986. +
  1987. + return 0;
  1988. +
  1989. +err_mem_free:
  1990. + hid_destroy_device(hid);
  1991. +err_dev:
  1992. + return ret;
  1993. +}
  1994. +
  1995. +void ipts_hid_release(ipts_info_t *ipts)
  1996. +{
  1997. + if (!ipts->hid)
  1998. + return;
  1999. + hid_destroy_device(ipts->hid);
  2000. +}
  2001. +
  2002. +int ipts_handle_hid_data(ipts_info_t *ipts,
  2003. + touch_sensor_hid_ready_for_data_rsp_data_t *hid_rsp)
  2004. +{
  2005. + touch_raw_data_hdr_t *raw_header;
  2006. + ipts_buffer_info_t *buffer_info;
  2007. + touch_feedback_hdr_t *feedback;
  2008. + u8 *raw_data;
  2009. + int touch_data_buffer_index;
  2010. + int transaction_id;
  2011. + int ret = 0;
  2012. +
  2013. + touch_data_buffer_index = (int)hid_rsp->touch_data_buffer_index;
  2014. + buffer_info = ipts_get_touch_data_buffer_hid(ipts);
  2015. + raw_header = (touch_raw_data_hdr_t *)buffer_info->addr;
  2016. + transaction_id = raw_header->hid_private_data.transaction_id;
  2017. +
  2018. + raw_data = (u8*)raw_header + sizeof(touch_raw_data_hdr_t);
  2019. + if (raw_header->data_type == TOUCH_RAW_DATA_TYPE_HID_REPORT) {
  2020. + memcpy(ipts->hid_input_report, raw_data,
  2021. + raw_header->raw_data_size_bytes);
  2022. +
  2023. + ret = hid_input_report(ipts->hid, HID_INPUT_REPORT,
  2024. + (u8*)ipts->hid_input_report,
  2025. + raw_header->raw_data_size_bytes, 1);
  2026. + if (ret) {
  2027. + ipts_err(ipts, "error in hid_input_report : %d\n", ret);
  2028. + }
  2029. + } else if (raw_header->data_type == TOUCH_RAW_DATA_TYPE_GET_FEATURES) {
  2030. + /* TODO: implement together with "get feature ioctl" */
  2031. + } else if (raw_header->data_type == TOUCH_RAW_DATA_TYPE_ERROR) {
  2032. + touch_error_t *touch_err = (touch_error_t *)raw_data;
  2033. +
  2034. + ipts_err(ipts, "error type : %d, me fw error : %x, err reg : %x\n",
  2035. + touch_err->touch_error_type,
  2036. + touch_err->touch_me_fw_error.value,
  2037. + touch_err->touch_error_register.reg_value);
  2038. + }
  2039. +
  2040. + /* send feedback data for HID mode */
  2041. + buffer_info = ipts_get_feedback_buffer(ipts, touch_data_buffer_index);
  2042. + feedback = (touch_feedback_hdr_t *)buffer_info->addr;
  2043. + memset(feedback, 0, sizeof(touch_feedback_hdr_t));
  2044. + feedback->feedback_cmd_type = TOUCH_FEEDBACK_CMD_TYPE_NONE;
  2045. + feedback->payload_size_bytes = 0;
  2046. + feedback->buffer_id = touch_data_buffer_index;
  2047. + feedback->protocol_ver = 0;
  2048. + feedback->reserved[0] = 0xAC;
  2049. +
  2050. + ret = ipts_send_feedback(ipts, touch_data_buffer_index, transaction_id);
  2051. +
  2052. + return ret;
  2053. +}
  2054. +
  2055. +static int handle_outputs(ipts_info_t *ipts, int parallel_idx)
  2056. +{
  2057. + kernel_output_buffer_header_t *out_buf_hdr;
  2058. + ipts_buffer_info_t *output_buf, *fb_buf = NULL;
  2059. + u8 *input_report, *payload;
  2060. + u32 transaction_id;
  2061. + int i, payload_size, ret = 0, header_size;
  2062. +
  2063. + header_size = sizeof(kernel_output_buffer_header_t);
  2064. + output_buf = ipts_get_output_buffers_by_parallel_id(ipts, parallel_idx);
  2065. + for (i = 0; i < ipts->resource.num_of_outputs; i++) {
  2066. + out_buf_hdr = (kernel_output_buffer_header_t*)output_buf[i].addr;
  2067. + if (out_buf_hdr->length < header_size)
  2068. + continue;
  2069. +
  2070. + payload_size = out_buf_hdr->length - header_size;
  2071. + payload = out_buf_hdr->data;
  2072. +
  2073. + switch(out_buf_hdr->payload_type) {
  2074. + case OUTPUT_BUFFER_PAYLOAD_HID_INPUT_REPORT:
  2075. + input_report = ipts->hid_input_report;
  2076. + memcpy(input_report, payload, payload_size);
  2077. + hid_input_report(ipts->hid, HID_INPUT_REPORT,
  2078. + input_report, payload_size, 1);
  2079. + break;
  2080. + case OUTPUT_BUFFER_PAYLOAD_HID_FEATURE_REPORT:
  2081. + ipts_dbg(ipts, "output hid feature report\n");
  2082. + break;
  2083. + case OUTPUT_BUFFER_PAYLOAD_KERNEL_LOAD:
  2084. + ipts_dbg(ipts, "output kernel load\n");
  2085. + break;
  2086. + case OUTPUT_BUFFER_PAYLOAD_FEEDBACK_BUFFER:
  2087. + {
  2088. + /* send feedback data for raw data mode */
  2089. + fb_buf = ipts_get_feedback_buffer(ipts,
  2090. + parallel_idx);
  2091. + transaction_id = out_buf_hdr->
  2092. + hid_private_data.transaction_id;
  2093. + memcpy(fb_buf->addr, payload, payload_size);
  2094. + break;
  2095. + }
  2096. + case OUTPUT_BUFFER_PAYLOAD_ERROR:
  2097. + {
  2098. + kernel_output_payload_error_t *err_payload;
  2099. +
  2100. + if (payload_size == 0)
  2101. + break;
  2102. +
  2103. + err_payload =
  2104. + (kernel_output_payload_error_t*)payload;
  2105. +
  2106. + ipts_err(ipts, "error : severity : %d,"
  2107. + " source : %d,"
  2108. + " code : %d:%d:%d:%d\n"
  2109. + "string %s\n",
  2110. + err_payload->severity,
  2111. + err_payload->source,
  2112. + err_payload->code[0],
  2113. + err_payload->code[1],
  2114. + err_payload->code[2],
  2115. + err_payload->code[3],
  2116. + err_payload->string);
  2117. +
  2118. + break;
  2119. + }
  2120. + default:
  2121. + ipts_err(ipts, "invalid output buffer payload\n");
  2122. + break;
  2123. + }
  2124. + }
  2125. +
  2126. + if (fb_buf) {
  2127. + ret = ipts_send_feedback(ipts, parallel_idx, transaction_id);
  2128. + if (ret)
  2129. + return ret;
  2130. + }
  2131. +
  2132. + return 0;
  2133. +}
  2134. +
  2135. +static int handle_output_buffers(ipts_info_t *ipts, int cur_idx, int end_idx)
  2136. +{
  2137. + int max_num_of_buffers = ipts_get_num_of_parallel_buffers(ipts);
  2138. +
  2139. + do {
  2140. + cur_idx++; /* cur_idx has last completed so starts with +1 */
  2141. + cur_idx %= max_num_of_buffers;
  2142. + handle_outputs(ipts, cur_idx);
  2143. + } while (cur_idx != end_idx);
  2144. +
  2145. + return 0;
  2146. +}
  2147. +
  2148. +int ipts_handle_processed_data(ipts_info_t *ipts)
  2149. +{
  2150. + int ret = 0;
  2151. + int current_buffer_idx;
  2152. + int last_buffer_idx;
  2153. +
  2154. + current_buffer_idx = *ipts->last_submitted_id;
  2155. + last_buffer_idx = ipts->last_buffer_completed;
  2156. +
  2157. + if (current_buffer_idx == last_buffer_idx)
  2158. + return 0;
  2159. +
  2160. + ipts->last_buffer_completed = current_buffer_idx;
  2161. + handle_output_buffers(ipts, last_buffer_idx, current_buffer_idx);
  2162. +
  2163. + return ret;
  2164. +}
  2165. diff --git a/drivers/misc/ipts/ipts-hid.h b/drivers/misc/ipts/ipts-hid.h
  2166. new file mode 100644
  2167. index 000000000000..f1b22c912df7
  2168. --- /dev/null
  2169. +++ b/drivers/misc/ipts/ipts-hid.h
  2170. @@ -0,0 +1,34 @@
  2171. +/*
  2172. + * Intel Precise Touch & Stylus HID definition
  2173. + *
  2174. + * Copyright (c) 2016, Intel Corporation.
  2175. + *
  2176. + * This program is free software; you can redistribute it and/or modify it
  2177. + * under the terms and conditions of the GNU General Public License,
  2178. + * version 2, as published by the Free Software Foundation.
  2179. + *
  2180. + * This program is distributed in the hope it will be useful, but WITHOUT
  2181. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  2182. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  2183. + * more details.
  2184. + */
  2185. +
  2186. +#ifndef _IPTS_HID_H_
  2187. +#define _IPTS_HID_H_
  2188. +
  2189. +#define BUS_MEI 0x44
  2190. +
  2191. +#if 0 /* TODO : we have special report ID. will implement them */
  2192. +#define WRITE_CHANNEL_REPORT_ID 0xa
  2193. +#define READ_CHANNEL_REPORT_ID 0xb
  2194. +#define CONFIG_CHANNEL_REPORT_ID 0xd
  2195. +#define VENDOR_INFO_REPORT_ID 0xF
  2196. +#define SINGLE_TOUCH_REPORT_ID 0x40
  2197. +#endif
  2198. +
  2199. +int ipts_hid_init(ipts_info_t *ipts);
  2200. +void ipts_hid_release(ipts_info_t *ipts);
  2201. +int ipts_handle_hid_data(ipts_info_t *ipts,
  2202. + touch_sensor_hid_ready_for_data_rsp_data_t *hid_rsp);
  2203. +
  2204. +#endif /* _IPTS_HID_H_ */
  2205. diff --git a/drivers/misc/ipts/ipts-kernel.c b/drivers/misc/ipts/ipts-kernel.c
  2206. new file mode 100644
  2207. index 000000000000..ca5e24ce579e
  2208. --- /dev/null
  2209. +++ b/drivers/misc/ipts/ipts-kernel.c
  2210. @@ -0,0 +1,1050 @@
  2211. +#include <linux/module.h>
  2212. +#include <linux/firmware.h>
  2213. +#include <linux/vmalloc.h>
  2214. +#include <linux/intel_ipts_if.h>
  2215. +
  2216. +#include "ipts.h"
  2217. +#include "ipts-resource.h"
  2218. +#include "ipts-binary-spec.h"
  2219. +#include "ipts-state.h"
  2220. +#include "ipts-msg-handler.h"
  2221. +#include "ipts-gfx.h"
  2222. +
  2223. +#define MAX_IOCL_FILE_NAME_LEN 80
  2224. +#define MAX_IOCL_FILE_PATH_LEN 256
  2225. +
  2226. +#pragma pack(1)
  2227. +typedef struct bin_data_file_info {
  2228. + u32 io_buffer_type;
  2229. + u32 flags;
  2230. + char file_name[MAX_IOCL_FILE_NAME_LEN];
  2231. +} bin_data_file_info_t;
  2232. +
  2233. +typedef struct bin_fw_info {
  2234. + char fw_name[MAX_IOCL_FILE_NAME_LEN];
  2235. +
  2236. + /* list of parameters to load a kernel */
  2237. + s32 vendor_output; /* output index. -1 for no use */
  2238. + u32 num_of_data_files;
  2239. + bin_data_file_info_t data_file[];
  2240. +} bin_fw_info_t;
  2241. +
  2242. +typedef struct bin_fw_list {
  2243. + u32 num_of_fws;
  2244. + bin_fw_info_t fw_info[];
  2245. +} bin_fw_list_t;
  2246. +#pragma pack()
  2247. +
  2248. +/* OpenCL kernel */
  2249. +typedef struct bin_workload {
  2250. + int cmdbuf_index;
  2251. + int iobuf_input;
  2252. + int iobuf_output[MAX_NUM_OUTPUT_BUFFERS];
  2253. +} bin_workload_t;
  2254. +
  2255. +typedef struct bin_buffer {
  2256. + unsigned int handle;
  2257. + intel_ipts_mapbuffer_t *buf;
  2258. + bool no_unmap; /* only releasing vendor kernel unmaps output buffers */
  2259. +} bin_buffer_t;
  2260. +
  2261. +typedef struct bin_alloc_info {
  2262. + bin_buffer_t *buffs;
  2263. + int num_of_allocations;
  2264. + int num_of_outputs;
  2265. +
  2266. + int num_of_buffers;
  2267. +} bin_alloc_info_t;
  2268. +
  2269. +typedef struct bin_guc_wq_item {
  2270. + unsigned int batch_offset;
  2271. + unsigned int size;
  2272. + char data[];
  2273. +} bin_guc_wq_item_t;
  2274. +
  2275. +typedef struct bin_kernel_info {
  2276. + bin_workload_t *wl;
  2277. + bin_alloc_info_t *alloc_info;
  2278. + bin_guc_wq_item_t *guc_wq_item;
  2279. + ipts_bin_bufid_patch_t bufid_patch;
  2280. +
  2281. + bool is_vendor; /* 1: vendor, 0: postprocessing */
  2282. +} bin_kernel_info_t;
  2283. +
  2284. +typedef struct bin_kernel_list {
  2285. + intel_ipts_mapbuffer_t *bufid_buf;
  2286. + int num_of_kernels;
  2287. + bin_kernel_info_t kernels[];
  2288. +} bin_kernel_list_t;
  2289. +
  2290. +typedef struct bin_parse_info {
  2291. + u8 *data;
  2292. + int size;
  2293. + int parsed;
  2294. +
  2295. + bin_fw_info_t *fw_info;
  2296. +
  2297. + /* only used by postprocessing */
  2298. + bin_kernel_info_t *vendor_kernel;
  2299. + u32 interested_vendor_output; /* interested vendor output index */
  2300. +} bin_parse_info_t;
  2301. +
  2302. +#define BDW_SURFACE_BASE_ADDRESS 0x6101000e
  2303. +#define SURFACE_STATE_OFFSET_WORD 4
  2304. +#define SBA_OFFSET_BYTES 16384
  2305. +#define LASTSUBMITID_DEFAULT_VALUE -1
  2306. +
  2307. +#define IPTS_FW_PATH_FMT "intel/ipts/%s"
  2308. +#define IPTS_FW_CONFIG_FILE "intel/ipts/ipts_fw_config.bin"
  2309. +
  2310. +MODULE_FIRMWARE(IPTS_FW_CONFIG_FILE);
  2311. +
  2312. +#define IPTS_INPUT_ON ((u32)1 << IPTS_INPUT)
  2313. +#define IPTS_OUTPUT_ON ((u32)1 << IPTS_OUTPUT)
  2314. +#define IPTS_CONFIGURATION_ON ((u32)1 << IPTS_CONFIGURATION)
  2315. +#define IPTS_CALIBRATION_ON ((u32)1 << IPTS_CALIBRATION)
  2316. +#define IPTS_FEATURE_ON ((u32)1 << IPTS_FEATURE)
  2317. +
  2318. +#define DATA_FILE_FLAG_SHARE 0x00000001
  2319. +#define DATA_FILE_FLAG_ALLOC_CONTIGUOUS 0x00000002
  2320. +
  2321. +static int bin_read_fw(ipts_info_t *ipts, const char *fw_name,
  2322. + u8* data, int size)
  2323. +{
  2324. + const struct firmware *fw = NULL;
  2325. + char fw_path[MAX_IOCL_FILE_PATH_LEN];
  2326. + int ret = 0;
  2327. +
  2328. + snprintf(fw_path, MAX_IOCL_FILE_PATH_LEN, IPTS_FW_PATH_FMT, fw_name);
  2329. + ret = request_firmware(&fw, fw_path, &ipts->cldev->dev);
  2330. + if (ret) {
  2331. + ipts_err(ipts, "cannot read fw %s\n", fw_path);
  2332. + return ret;
  2333. + }
  2334. +
  2335. + if (fw->size > size) {
  2336. + ipts_dbg(ipts, "too small buffer to contain fw data\n");
  2337. + ret = -EINVAL;
  2338. + goto rel_return;
  2339. + }
  2340. +
  2341. + memcpy(data, fw->data, fw->size);
  2342. +
  2343. +rel_return:
  2344. + release_firmware(fw);
  2345. +
  2346. + return ret;
  2347. +}
  2348. +
  2349. +
  2350. +static bin_data_file_info_t* bin_get_data_file_info(bin_fw_info_t* fw_info,
  2351. + u32 io_buffer_type)
  2352. +{
  2353. + int i;
  2354. +
  2355. + for (i = 0; i < fw_info->num_of_data_files; i++) {
  2356. + if (fw_info->data_file[i].io_buffer_type == io_buffer_type)
  2357. + break;
  2358. + }
  2359. +
  2360. + if (i == fw_info->num_of_data_files)
  2361. + return NULL;
  2362. +
  2363. + return &fw_info->data_file[i];
  2364. +}
  2365. +
  2366. +static inline bool is_shared_data(const bin_data_file_info_t *data_file)
  2367. +{
  2368. + if (data_file)
  2369. + return (!!(data_file->flags & DATA_FILE_FLAG_SHARE));
  2370. +
  2371. + return false;
  2372. +}
  2373. +
  2374. +static inline bool is_alloc_cont_data(const bin_data_file_info_t *data_file)
  2375. +{
  2376. + if (data_file)
  2377. + return (!!(data_file->flags & DATA_FILE_FLAG_ALLOC_CONTIGUOUS));
  2378. +
  2379. + return false;
  2380. +}
  2381. +
  2382. +static inline bool is_parsing_vendor_kernel(const bin_parse_info_t *parse_info)
  2383. +{
  2384. + /* vendor_kernel == null while loading itself(vendor kernel) */
  2385. + return parse_info->vendor_kernel == NULL;
  2386. +}
  2387. +
  2388. +static int bin_read_allocation_list(ipts_info_t *ipts,
  2389. + bin_parse_info_t *parse_info,
  2390. + bin_alloc_info_t *alloc_info)
  2391. +{
  2392. + ipts_bin_alloc_list_t *alloc_list;
  2393. + int alloc_idx, parallel_idx, num_of_parallels, buf_idx, num_of_buffers;
  2394. + int parsed, size;
  2395. +
  2396. + parsed = parse_info->parsed;
  2397. + size = parse_info->size;
  2398. +
  2399. + alloc_list = (ipts_bin_alloc_list_t *)&parse_info->data[parsed];
  2400. +
  2401. + /* validation check */
  2402. + if (sizeof(alloc_list->num) > size - parsed)
  2403. + return -EINVAL;
  2404. +
  2405. + /* read the number of aloocations */
  2406. + parsed += sizeof(alloc_list->num);
  2407. +
  2408. + /* validation check */
  2409. + if (sizeof(alloc_list->alloc[0]) * alloc_list->num > size - parsed)
  2410. + return -EINVAL;
  2411. +
  2412. + num_of_parallels = ipts_get_num_of_parallel_buffers(ipts);
  2413. + num_of_buffers = num_of_parallels * alloc_list->num + num_of_parallels;
  2414. +
  2415. + alloc_info->buffs = vmalloc(sizeof(bin_buffer_t) * num_of_buffers);
  2416. + if (alloc_info->buffs == NULL)
  2417. + return -ENOMEM;
  2418. +
  2419. + memset(alloc_info->buffs, 0, sizeof(bin_buffer_t) * num_of_buffers);
  2420. + for (alloc_idx = 0; alloc_idx < alloc_list->num; alloc_idx++) {
  2421. + for (parallel_idx = 0; parallel_idx < num_of_parallels;
  2422. + parallel_idx++) {
  2423. + buf_idx = alloc_idx + (parallel_idx * alloc_list->num);
  2424. + alloc_info->buffs[buf_idx].handle =
  2425. + alloc_list->alloc[alloc_idx].handle;
  2426. +
  2427. + }
  2428. +
  2429. + parsed += sizeof(alloc_list->alloc[0]);
  2430. + }
  2431. +
  2432. + parse_info->parsed = parsed;
  2433. + alloc_info->num_of_allocations = alloc_list->num;
  2434. + alloc_info->num_of_buffers = num_of_buffers;
  2435. +
  2436. + ipts_dbg(ipts, "number of allocations = %d, buffers = %d\n",
  2437. + alloc_info->num_of_allocations,
  2438. + alloc_info->num_of_buffers);
  2439. +
  2440. + return 0;
  2441. +}
  2442. +
  2443. +static void patch_SBA(u32 *buf_addr, u64 gpu_addr, int size)
  2444. +{
  2445. + u64 *stateBase;
  2446. + u64 SBA;
  2447. + u32 inst;
  2448. + int i;
  2449. +
  2450. + SBA = gpu_addr + SBA_OFFSET_BYTES;
  2451. +
  2452. + for (i = 0; i < size/4; i++) {
  2453. + inst = buf_addr[i];
  2454. + if (inst == BDW_SURFACE_BASE_ADDRESS) {
  2455. + stateBase = (u64*)&buf_addr[i + SURFACE_STATE_OFFSET_WORD];
  2456. + *stateBase |= SBA;
  2457. + *stateBase |= 0x01; // enable
  2458. + break;
  2459. + }
  2460. + }
  2461. +}
  2462. +
  2463. +static int bin_read_cmd_buffer(ipts_info_t *ipts,
  2464. + bin_parse_info_t *parse_info,
  2465. + bin_alloc_info_t *alloc_info,
  2466. + bin_workload_t *wl)
  2467. +{
  2468. + ipts_bin_cmdbuf_t *cmd;
  2469. + intel_ipts_mapbuffer_t *buf;
  2470. + int cmdbuf_idx, size, parsed, parallel_idx, num_of_parallels;
  2471. +
  2472. + size = parse_info->size;
  2473. + parsed = parse_info->parsed;
  2474. +
  2475. + cmd = (ipts_bin_cmdbuf_t *)&parse_info->data[parsed];
  2476. +
  2477. + if (sizeof(cmd->size) > size - parsed)
  2478. + return -EINVAL;
  2479. +
  2480. + parsed += sizeof(cmd->size);
  2481. + if (cmd->size > size - parsed)
  2482. + return -EINVAL;
  2483. +
  2484. + ipts_dbg(ipts, "cmd buf size = %d\n", cmd->size);
  2485. +
  2486. + num_of_parallels = ipts_get_num_of_parallel_buffers(ipts);
  2487. + /* command buffers are located after the other allocations */
  2488. + cmdbuf_idx = num_of_parallels * alloc_info->num_of_allocations;
  2489. + for (parallel_idx = 0; parallel_idx < num_of_parallels; parallel_idx++) {
  2490. + buf = ipts_map_buffer(ipts, cmd->size, 0);
  2491. + if (buf == NULL)
  2492. + return -ENOMEM;
  2493. +
  2494. + ipts_dbg(ipts, "cmd_idx[%d] = %d, g:0x%p, c:0x%p\n", parallel_idx,
  2495. + cmdbuf_idx, buf->gfx_addr, buf->cpu_addr);
  2496. +
  2497. + memcpy((void *)buf->cpu_addr, &(cmd->data[0]), cmd->size);
  2498. + patch_SBA(buf->cpu_addr, (u64)buf->gfx_addr, cmd->size);
  2499. + alloc_info->buffs[cmdbuf_idx].buf = buf;
  2500. + wl[parallel_idx].cmdbuf_index = cmdbuf_idx;
  2501. +
  2502. + cmdbuf_idx++;
  2503. + }
  2504. +
  2505. + parsed += cmd->size;
  2506. + parse_info->parsed = parsed;
  2507. +
  2508. + return 0;
  2509. +}
  2510. +
  2511. +static int bin_find_alloc(ipts_info_t *ipts,
  2512. + bin_alloc_info_t *alloc_info,
  2513. + u32 handle)
  2514. +{
  2515. + int i;
  2516. +
  2517. + for (i = 0; i < alloc_info->num_of_allocations; i++) {
  2518. + if (alloc_info->buffs[i].handle == handle)
  2519. + return i;
  2520. + }
  2521. +
  2522. + return -1;
  2523. +}
  2524. +
  2525. +static intel_ipts_mapbuffer_t* bin_get_vendor_kernel_output(
  2526. + bin_parse_info_t *parse_info,
  2527. + int parallel_idx)
  2528. +{
  2529. + bin_kernel_info_t *vendor = parse_info->vendor_kernel;
  2530. + bin_alloc_info_t *alloc_info;
  2531. + int buf_idx, vendor_output_idx;
  2532. +
  2533. + alloc_info = vendor->alloc_info;
  2534. + vendor_output_idx = parse_info->interested_vendor_output;
  2535. +
  2536. + if (vendor_output_idx >= alloc_info->num_of_outputs)
  2537. + return NULL;
  2538. +
  2539. + buf_idx = vendor->wl[parallel_idx].iobuf_output[vendor_output_idx];
  2540. + return alloc_info->buffs[buf_idx].buf;
  2541. +}
  2542. +
  2543. +static int bin_read_res_list(ipts_info_t *ipts,
  2544. + bin_parse_info_t *parse_info,
  2545. + bin_alloc_info_t *alloc_info,
  2546. + bin_workload_t *wl)
  2547. +{
  2548. + ipts_bin_res_list_t *res_list;
  2549. + ipts_bin_res_t *res;
  2550. + intel_ipts_mapbuffer_t *buf;
  2551. + bin_data_file_info_t *data_file;
  2552. + u8 *bin_data;
  2553. + int i, size, parsed, parallel_idx, num_of_parallels, output_idx = -1;
  2554. + int buf_idx, num_of_alloc;
  2555. + u32 buf_size, flags, io_buf_type;
  2556. + bool initialize;
  2557. +
  2558. + parsed = parse_info->parsed;
  2559. + size = parse_info->size;
  2560. + bin_data = parse_info->data;
  2561. +
  2562. + res_list = (ipts_bin_res_list_t *)&parse_info->data[parsed];
  2563. + if (sizeof(res_list->num) > (size - parsed))
  2564. + return -EINVAL;
  2565. + parsed += sizeof(res_list->num);
  2566. + num_of_parallels = ipts_get_num_of_parallel_buffers(ipts);
  2567. +
  2568. + ipts_dbg(ipts, "number of resources %u\n", res_list->num);
  2569. + for (i = 0; i < res_list->num; i++) {
  2570. + initialize = false;
  2571. + io_buf_type = 0;
  2572. + flags = 0;
  2573. +
  2574. + /* initial data */
  2575. + data_file = NULL;
  2576. +
  2577. + res = (ipts_bin_res_t *)(&(bin_data[parsed]));
  2578. + if (sizeof(res[0]) > (size - parsed)) {
  2579. + return -EINVAL;
  2580. + }
  2581. +
  2582. + ipts_dbg(ipts, "Resource(%d):handle 0x%08x type %u init %u"
  2583. + " size %u alsigned %u\n",
  2584. + i, res->handle, res->type, res->initialize,
  2585. + res->size, res->aligned_size);
  2586. + parsed += sizeof(res[0]);
  2587. +
  2588. + if (res->initialize) {
  2589. + if (res->size > (size - parsed)) {
  2590. + return -EINVAL;
  2591. + }
  2592. + parsed += res->size;
  2593. + }
  2594. +
  2595. + initialize = res->initialize;
  2596. + if (initialize && res->size > sizeof(ipts_bin_io_header_t)) {
  2597. + ipts_bin_io_header_t *io_hdr;
  2598. + io_hdr = (ipts_bin_io_header_t *)(&res->data[0]);
  2599. + if (strncmp(io_hdr->str, "INTELTOUCH", 10) == 0) {
  2600. + data_file = bin_get_data_file_info(
  2601. + parse_info->fw_info,
  2602. + (u32)io_hdr->type);
  2603. + switch (io_hdr->type) {
  2604. + case IPTS_INPUT:
  2605. + ipts_dbg(ipts, "input detected\n");
  2606. + io_buf_type = IPTS_INPUT_ON;
  2607. + flags = IPTS_BUF_FLAG_CONTIGUOUS;
  2608. + break;
  2609. + case IPTS_OUTPUT:
  2610. + ipts_dbg(ipts, "output detected\n");
  2611. + io_buf_type = IPTS_OUTPUT_ON;
  2612. + output_idx++;
  2613. + break;
  2614. + default:
  2615. + if ((u32)io_hdr->type > 31) {
  2616. + ipts_err(ipts,
  2617. + "invalid io buffer : %u\n",
  2618. + (u32)io_hdr->type);
  2619. + continue;
  2620. + }
  2621. +
  2622. + if (is_alloc_cont_data(data_file))
  2623. + flags = IPTS_BUF_FLAG_CONTIGUOUS;
  2624. +
  2625. + io_buf_type = ((u32)1 << (u32)io_hdr->type);
  2626. + ipts_dbg(ipts, "special io buffer %u\n",
  2627. + io_hdr->type);
  2628. + break;
  2629. + }
  2630. +
  2631. + initialize = false;
  2632. + }
  2633. + }
  2634. +
  2635. + num_of_alloc = alloc_info->num_of_allocations;
  2636. + buf_idx = bin_find_alloc(ipts, alloc_info, res->handle);
  2637. + if (buf_idx == -1) {
  2638. + ipts_dbg(ipts, "cannot find alloc info\n");
  2639. + return -EINVAL;
  2640. + }
  2641. + for (parallel_idx = 0; parallel_idx < num_of_parallels;
  2642. + parallel_idx++, buf_idx += num_of_alloc) {
  2643. + if (!res->aligned_size)
  2644. + continue;
  2645. +
  2646. + if (!(parallel_idx == 0 ||
  2647. + (io_buf_type && !is_shared_data(data_file))))
  2648. + continue;
  2649. +
  2650. + buf_size = res->aligned_size;
  2651. + if (io_buf_type & IPTS_INPUT_ON) {
  2652. + buf_size = max_t(u32,
  2653. + ipts->device_info.frame_size,
  2654. + buf_size);
  2655. + wl[parallel_idx].iobuf_input = buf_idx;
  2656. + } else if (io_buf_type & IPTS_OUTPUT_ON) {
  2657. + wl[parallel_idx].iobuf_output[output_idx] = buf_idx;
  2658. +
  2659. + if (!is_parsing_vendor_kernel(parse_info) &&
  2660. + output_idx > 0) {
  2661. + ipts_err(ipts,
  2662. + "postproc with more than one inout"
  2663. + " is not supported : %d\n", output_idx);
  2664. + return -EINVAL;
  2665. + }
  2666. + }
  2667. +
  2668. + if (!is_parsing_vendor_kernel(parse_info) &&
  2669. + io_buf_type & IPTS_OUTPUT_ON) {
  2670. + buf = bin_get_vendor_kernel_output(
  2671. + parse_info,
  2672. + parallel_idx);
  2673. + alloc_info->buffs[buf_idx].no_unmap = true;
  2674. + } else
  2675. + buf = ipts_map_buffer(ipts, buf_size, flags);
  2676. +
  2677. + if (buf == NULL) {
  2678. + ipts_dbg(ipts, "ipts_map_buffer failed\n");
  2679. + return -ENOMEM;
  2680. + }
  2681. +
  2682. + if (initialize) {
  2683. + memcpy((void *)buf->cpu_addr, &(res->data[0]),
  2684. + res->size);
  2685. + } else {
  2686. + if (data_file && strlen(data_file->file_name)) {
  2687. + bin_read_fw(ipts, data_file->file_name,
  2688. + buf->cpu_addr, buf_size);
  2689. + } else if (is_parsing_vendor_kernel(parse_info) ||
  2690. + !(io_buf_type & IPTS_OUTPUT_ON)) {
  2691. + memset((void *)buf->cpu_addr, 0, res->size);
  2692. + }
  2693. + }
  2694. +
  2695. + alloc_info->buffs[buf_idx].buf = buf;
  2696. + }
  2697. + }
  2698. +
  2699. + alloc_info->num_of_outputs = output_idx + 1;
  2700. + parse_info->parsed = parsed;
  2701. +
  2702. + return 0;
  2703. +}
  2704. +
  2705. +static int bin_read_patch_list(ipts_info_t *ipts,
  2706. + bin_parse_info_t *parse_info,
  2707. + bin_alloc_info_t *alloc_info,
  2708. + bin_workload_t *wl)
  2709. +{
  2710. + ipts_bin_patch_list_t *patch_list;
  2711. + ipts_bin_patch_t *patch;
  2712. + intel_ipts_mapbuffer_t *cmd = NULL;
  2713. + u8 *batch;
  2714. + int parsed, size, i, parallel_idx, num_of_parallels, cmd_idx, buf_idx;
  2715. + unsigned int gtt_offset;
  2716. +
  2717. + parsed = parse_info->parsed;
  2718. + size = parse_info->size;
  2719. + patch_list = (ipts_bin_patch_list_t *)&parse_info->data[parsed];
  2720. +
  2721. + if (sizeof(patch_list->num) > (size - parsed)) {
  2722. + return -EFAULT;
  2723. + }
  2724. + parsed += sizeof(patch_list->num);
  2725. +
  2726. + num_of_parallels = ipts_get_num_of_parallel_buffers(ipts);
  2727. + patch = (ipts_bin_patch_t *)(&patch_list->patch[0]);
  2728. + for (i = 0; i < patch_list->num; i++) {
  2729. + if (sizeof(patch_list->patch[0]) > (size - parsed)) {
  2730. + return -EFAULT;
  2731. + }
  2732. +
  2733. + for (parallel_idx = 0; parallel_idx < num_of_parallels;
  2734. + parallel_idx++) {
  2735. + cmd_idx = wl[parallel_idx].cmdbuf_index;
  2736. + buf_idx = patch[i].index + parallel_idx *
  2737. + alloc_info->num_of_allocations;
  2738. +
  2739. + if (alloc_info->buffs[buf_idx].buf == NULL) {
  2740. + /* buffer shared */
  2741. + buf_idx = patch[i].index;
  2742. + }
  2743. +
  2744. + cmd = alloc_info->buffs[cmd_idx].buf;
  2745. + batch = (char *)(u64)cmd->cpu_addr;
  2746. +
  2747. + gtt_offset = 0;
  2748. + if(alloc_info->buffs[buf_idx].buf != NULL) {
  2749. + gtt_offset = (u32)(u64)
  2750. + alloc_info->buffs[buf_idx].buf->gfx_addr;
  2751. + }
  2752. + gtt_offset += patch[i].alloc_offset;
  2753. +
  2754. + batch += patch[i].patch_offset;
  2755. + *(u32*)batch = gtt_offset;
  2756. + }
  2757. +
  2758. + parsed += sizeof(patch_list->patch[0]);
  2759. + }
  2760. +
  2761. + parse_info->parsed = parsed;
  2762. +
  2763. + return 0;
  2764. +}
  2765. +
  2766. +static int bin_read_guc_wq_item(ipts_info_t *ipts,
  2767. + bin_parse_info_t *parse_info,
  2768. + bin_guc_wq_item_t **guc_wq_item)
  2769. +{
  2770. + ipts_bin_guc_wq_info_t *bin_guc_wq;
  2771. + bin_guc_wq_item_t *item;
  2772. + u8 *wi_data;
  2773. + int size, parsed, hdr_size, wi_size;
  2774. + int i, batch_offset;
  2775. +
  2776. + parsed = parse_info->parsed;
  2777. + size = parse_info->size;
  2778. + bin_guc_wq = (ipts_bin_guc_wq_info_t *)&parse_info->data[parsed];
  2779. +
  2780. + wi_size = bin_guc_wq->size;
  2781. + wi_data = bin_guc_wq->data;
  2782. + batch_offset = bin_guc_wq->batch_offset;
  2783. + ipts_dbg(ipts, "wi size = %d, bt offset = %d\n", wi_size, batch_offset);
  2784. + for (i = 0; i < wi_size / sizeof(u32); i++) {
  2785. + ipts_dbg(ipts, "wi[%d] = 0x%08x\n", i, *((u32*)wi_data + i));
  2786. + }
  2787. + hdr_size = sizeof(bin_guc_wq->size) + sizeof(bin_guc_wq->batch_offset);
  2788. +
  2789. + if (hdr_size > (size - parsed)) {
  2790. + return -EINVAL;
  2791. + }
  2792. + parsed += hdr_size;
  2793. +
  2794. + item = vmalloc(sizeof(bin_guc_wq_item_t) + wi_size);
  2795. + if (item == NULL)
  2796. + return -ENOMEM;
  2797. +
  2798. + item->size = wi_size;
  2799. + item->batch_offset = batch_offset;
  2800. + memcpy(item->data, wi_data, wi_size);
  2801. +
  2802. + *guc_wq_item = item;
  2803. +
  2804. + parsed += wi_size;
  2805. + parse_info->parsed = parsed;
  2806. +
  2807. + return 0;
  2808. +}
  2809. +
  2810. +static int bin_setup_guc_workqueue(ipts_info_t *ipts,
  2811. + bin_kernel_list_t *kernel_list)
  2812. +{
  2813. + bin_alloc_info_t *alloc_info;
  2814. + bin_workload_t *wl;
  2815. + bin_kernel_info_t *kernel;
  2816. + u8 *wq_start, *wq_addr, *wi_data;
  2817. + bin_buffer_t *bin_buf;
  2818. + int wq_size, wi_size, parallel_idx, cmd_idx, k_idx, iter_size;
  2819. + int i, num_of_parallels, batch_offset, k_num, total_workload;
  2820. +
  2821. + wq_addr = (u8*)ipts->resource.wq_info.wq_addr;
  2822. + wq_size = ipts->resource.wq_info.wq_size;
  2823. + num_of_parallels = ipts_get_num_of_parallel_buffers(ipts);
  2824. + total_workload = ipts_get_wq_item_size(ipts);
  2825. + k_num = kernel_list->num_of_kernels;
  2826. +
  2827. + iter_size = total_workload * num_of_parallels;
  2828. + if (wq_size % iter_size) {
  2829. + ipts_err(ipts, "wq item cannot fit into wq\n");
  2830. + return -EINVAL;
  2831. + }
  2832. +
  2833. + wq_start = wq_addr;
  2834. + for (parallel_idx = 0; parallel_idx < num_of_parallels;
  2835. + parallel_idx++) {
  2836. + kernel = &kernel_list->kernels[0];
  2837. + for (k_idx = 0; k_idx < k_num; k_idx++, kernel++) {
  2838. + wl = kernel->wl;
  2839. + alloc_info = kernel->alloc_info;
  2840. +
  2841. + batch_offset = kernel->guc_wq_item->batch_offset;
  2842. + wi_size = kernel->guc_wq_item->size;
  2843. + wi_data = &kernel->guc_wq_item->data[0];
  2844. +
  2845. + cmd_idx = wl[parallel_idx].cmdbuf_index;
  2846. + bin_buf = &alloc_info->buffs[cmd_idx];
  2847. +
  2848. + /* Patch the WQ Data with proper batch buffer offset */
  2849. + *(u32*)(wi_data + batch_offset) =
  2850. + (u32)(unsigned long)(bin_buf->buf->gfx_addr);
  2851. +
  2852. + memcpy(wq_addr, wi_data, wi_size);
  2853. +
  2854. + wq_addr += wi_size;
  2855. + }
  2856. + }
  2857. +
  2858. + for (i = 0; i < (wq_size / iter_size) - 1; i++) {
  2859. + memcpy(wq_addr, wq_start, iter_size);
  2860. + wq_addr += iter_size;
  2861. + }
  2862. +
  2863. + return 0;
  2864. +}
  2865. +
  2866. +static int bin_read_bufid_patch(ipts_info_t *ipts,
  2867. + bin_parse_info_t *parse_info,
  2868. + ipts_bin_bufid_patch_t *bufid_patch)
  2869. +{
  2870. + ipts_bin_bufid_patch_t *patch;
  2871. + int size, parsed;
  2872. +
  2873. + parsed = parse_info->parsed;
  2874. + size = parse_info->size;
  2875. + patch = (ipts_bin_bufid_patch_t *)&parse_info->data[parsed];
  2876. +
  2877. + if (sizeof(ipts_bin_bufid_patch_t) > (size - parsed)) {
  2878. + ipts_dbg(ipts, "invalid bufid info\n");
  2879. + return -EINVAL;
  2880. + }
  2881. + parsed += sizeof(ipts_bin_bufid_patch_t);
  2882. +
  2883. + memcpy(bufid_patch, patch, sizeof(ipts_bin_bufid_patch_t));
  2884. +
  2885. + parse_info->parsed = parsed;
  2886. +
  2887. + return 0;
  2888. +}
  2889. +
  2890. +static int bin_setup_bufid_buffer(ipts_info_t *ipts, bin_kernel_list_t *kernel_list)
  2891. +{
  2892. + intel_ipts_mapbuffer_t *buf, *cmd_buf;
  2893. + bin_kernel_info_t *last_kernel;
  2894. + bin_alloc_info_t *alloc_info;
  2895. + bin_workload_t *wl;
  2896. + u8 *batch;
  2897. + int parallel_idx, num_of_parallels, cmd_idx;
  2898. + u32 mem_offset, imm_offset;
  2899. +
  2900. + buf = ipts_map_buffer(ipts, PAGE_SIZE, 0);
  2901. + if (!buf) {
  2902. + return -ENOMEM;
  2903. + }
  2904. +
  2905. + last_kernel = &kernel_list->kernels[kernel_list->num_of_kernels - 1];
  2906. +
  2907. + mem_offset = last_kernel->bufid_patch.mem_offset;
  2908. + imm_offset = last_kernel->bufid_patch.imm_offset;
  2909. + wl = last_kernel->wl;
  2910. + alloc_info = last_kernel->alloc_info;
  2911. +
  2912. + /* Initialize the buffer with default value */
  2913. + *((u32*)buf->cpu_addr) = LASTSUBMITID_DEFAULT_VALUE;
  2914. + ipts->current_buffer_index = LASTSUBMITID_DEFAULT_VALUE;
  2915. + ipts->last_buffer_completed = LASTSUBMITID_DEFAULT_VALUE;
  2916. + ipts->last_submitted_id = (int*)buf->cpu_addr;
  2917. +
  2918. + num_of_parallels = ipts_get_num_of_parallel_buffers(ipts);
  2919. + for (parallel_idx = 0; parallel_idx < num_of_parallels; parallel_idx++) {
  2920. + cmd_idx = wl[parallel_idx].cmdbuf_index;
  2921. + cmd_buf = alloc_info->buffs[cmd_idx].buf;
  2922. + batch = (u8*)(u64)cmd_buf->cpu_addr;
  2923. +
  2924. + *((u32*)(batch + mem_offset)) = (u32)(u64)(buf->gfx_addr);
  2925. + *((u32*)(batch + imm_offset)) = parallel_idx;
  2926. + }
  2927. +
  2928. + kernel_list->bufid_buf = buf;
  2929. +
  2930. + return 0;
  2931. +}
  2932. +
  2933. +static void unmap_buffers(ipts_info_t *ipts, bin_alloc_info_t *alloc_info)
  2934. +{
  2935. + bin_buffer_t *buffs;
  2936. + int i, num_of_buffers;
  2937. +
  2938. + num_of_buffers = alloc_info->num_of_buffers;
  2939. + buffs = &alloc_info->buffs[0];
  2940. +
  2941. + for (i = 0; i < num_of_buffers; i++) {
  2942. + if (buffs[i].no_unmap != true && buffs[i].buf != NULL)
  2943. + ipts_unmap_buffer(ipts, buffs[i].buf);
  2944. + }
  2945. +}
  2946. +
  2947. +static int load_kernel(ipts_info_t *ipts, bin_parse_info_t *parse_info,
  2948. + bin_kernel_info_t *kernel)
  2949. +{
  2950. + ipts_bin_header_t *hdr;
  2951. + bin_workload_t *wl;
  2952. + bin_alloc_info_t *alloc_info;
  2953. + bin_guc_wq_item_t *guc_wq_item = NULL;
  2954. + ipts_bin_bufid_patch_t bufid_patch;
  2955. + int num_of_parallels, ret;
  2956. +
  2957. + num_of_parallels = ipts_get_num_of_parallel_buffers(ipts);
  2958. +
  2959. + /* check header version and magic numbers */
  2960. + hdr = (ipts_bin_header_t *)parse_info->data;
  2961. + if (hdr->version != IPTS_BIN_HEADER_VERSION ||
  2962. + strncmp(hdr->str, "IOCL", 4) != 0) {
  2963. + ipts_err(ipts, "binary header is not correct version = %d, "
  2964. + "string = %c%c%c%c\n", hdr->version,
  2965. + hdr->str[0], hdr->str[1],
  2966. + hdr->str[2], hdr->str[3] );
  2967. + return -EINVAL;
  2968. + }
  2969. +
  2970. + parse_info->parsed = sizeof(ipts_bin_header_t);
  2971. + wl = vmalloc(sizeof(bin_workload_t) * num_of_parallels);
  2972. + if (wl == NULL)
  2973. + return -ENOMEM;
  2974. + memset(wl, 0, sizeof(bin_workload_t) * num_of_parallels);
  2975. +
  2976. + alloc_info = vmalloc(sizeof(bin_alloc_info_t));
  2977. + if (alloc_info == NULL) {
  2978. + vfree(wl);
  2979. + return -ENOMEM;
  2980. + }
  2981. + memset(alloc_info, 0, sizeof(bin_alloc_info_t));
  2982. +
  2983. + ipts_dbg(ipts, "kernel setup(size : %d)\n", parse_info->size);
  2984. +
  2985. + ret = bin_read_allocation_list(ipts, parse_info, alloc_info);
  2986. + if (ret) {
  2987. + ipts_dbg(ipts, "error read_allocation_list\n");
  2988. + goto setup_error;
  2989. + }
  2990. +
  2991. + ret = bin_read_cmd_buffer(ipts, parse_info, alloc_info, wl);
  2992. + if (ret) {
  2993. + ipts_dbg(ipts, "error read_cmd_buffer\n");
  2994. + goto setup_error;
  2995. + }
  2996. +
  2997. + ret = bin_read_res_list(ipts, parse_info, alloc_info, wl);
  2998. + if (ret) {
  2999. + ipts_dbg(ipts, "error read_res_list\n");
  3000. + goto setup_error;
  3001. + }
  3002. +
  3003. + ret = bin_read_patch_list(ipts, parse_info, alloc_info, wl);
  3004. + if (ret) {
  3005. + ipts_dbg(ipts, "error read_patch_list\n");
  3006. + goto setup_error;
  3007. + }
  3008. +
  3009. + ret = bin_read_guc_wq_item(ipts, parse_info, &guc_wq_item);
  3010. + if (ret) {
  3011. + ipts_dbg(ipts, "error read_guc_workqueue\n");
  3012. + goto setup_error;
  3013. + }
  3014. +
  3015. + memset(&bufid_patch, 0, sizeof(bufid_patch));
  3016. + ret = bin_read_bufid_patch(ipts, parse_info, &bufid_patch);
  3017. + if (ret) {
  3018. + ipts_dbg(ipts, "error read_bufid_patch\n");
  3019. + goto setup_error;
  3020. + }
  3021. +
  3022. + kernel->wl = wl;
  3023. + kernel->alloc_info = alloc_info;
  3024. + kernel->is_vendor = is_parsing_vendor_kernel(parse_info);
  3025. + kernel->guc_wq_item = guc_wq_item;
  3026. + memcpy(&kernel->bufid_patch, &bufid_patch, sizeof(bufid_patch));
  3027. +
  3028. + return 0;
  3029. +
  3030. +setup_error:
  3031. + vfree(guc_wq_item);
  3032. +
  3033. + unmap_buffers(ipts, alloc_info);
  3034. +
  3035. + vfree(alloc_info->buffs);
  3036. + vfree(alloc_info);
  3037. + vfree(wl);
  3038. +
  3039. + return ret;
  3040. +}
  3041. +
  3042. +void bin_setup_input_output(ipts_info_t *ipts, bin_kernel_list_t *kernel_list)
  3043. +{
  3044. + bin_kernel_info_t *vendor_kernel;
  3045. + bin_workload_t *wl;
  3046. + intel_ipts_mapbuffer_t *buf;
  3047. + bin_alloc_info_t *alloc_info;
  3048. + int parallel_idx, num_of_parallels, i, buf_idx;
  3049. +
  3050. + vendor_kernel = &kernel_list->kernels[0];
  3051. +
  3052. + wl = vendor_kernel->wl;
  3053. + alloc_info = vendor_kernel->alloc_info;
  3054. + ipts->resource.num_of_outputs = alloc_info->num_of_outputs;
  3055. + num_of_parallels = ipts_get_num_of_parallel_buffers(ipts);
  3056. +
  3057. + for (parallel_idx = 0; parallel_idx < num_of_parallels; parallel_idx++) {
  3058. + buf_idx = wl[parallel_idx].iobuf_input;
  3059. + buf = alloc_info->buffs[buf_idx].buf;
  3060. +
  3061. + ipts_dbg(ipts, "in_buf[%d](%d) c:%p, p:%p, g:%p\n",
  3062. + parallel_idx, buf_idx, (void*)buf->cpu_addr,
  3063. + (void*)buf->phy_addr, (void*)buf->gfx_addr);
  3064. +
  3065. + ipts_set_input_buffer(ipts, parallel_idx, buf->cpu_addr,
  3066. + buf->phy_addr);
  3067. +
  3068. + for (i = 0; i < alloc_info->num_of_outputs; i++) {
  3069. + buf_idx = wl[parallel_idx].iobuf_output[i];
  3070. + buf = alloc_info->buffs[buf_idx].buf;
  3071. +
  3072. + ipts_dbg(ipts, "out_buf[%d][%d] c:%p, p:%p, g:%p\n",
  3073. + parallel_idx, i, (void*)buf->cpu_addr,
  3074. + (void*)buf->phy_addr, (void*)buf->gfx_addr);
  3075. +
  3076. + ipts_set_output_buffer(ipts, parallel_idx, i,
  3077. + buf->cpu_addr, buf->phy_addr);
  3078. + }
  3079. + }
  3080. +}
  3081. +
  3082. +static void unload_kernel(ipts_info_t *ipts, bin_kernel_info_t *kernel)
  3083. +{
  3084. + bin_alloc_info_t *alloc_info = kernel->alloc_info;
  3085. + bin_guc_wq_item_t *guc_wq_item = kernel->guc_wq_item;
  3086. +
  3087. + if (guc_wq_item) {
  3088. + vfree(guc_wq_item);
  3089. + }
  3090. +
  3091. + if (alloc_info) {
  3092. + unmap_buffers(ipts, alloc_info);
  3093. +
  3094. + vfree(alloc_info->buffs);
  3095. + vfree(alloc_info);
  3096. + }
  3097. +}
  3098. +
  3099. +static int setup_kernel(ipts_info_t *ipts, bin_fw_list_t *fw_list)
  3100. +{
  3101. + bin_kernel_list_t *kernel_list = NULL;
  3102. + bin_kernel_info_t *kernel = NULL;
  3103. + const struct firmware *fw = NULL;
  3104. + bin_workload_t *wl;
  3105. + bin_fw_info_t *fw_info;
  3106. + char *fw_name, *fw_data;
  3107. + bin_parse_info_t parse_info;
  3108. + int ret = 0, kernel_idx = 0, num_of_kernels = 0;
  3109. + int vendor_output_idx, total_workload = 0;
  3110. + char fw_path[MAX_IOCL_FILE_PATH_LEN];
  3111. +
  3112. + num_of_kernels = fw_list->num_of_fws;
  3113. + kernel_list = vmalloc(sizeof(*kernel) * num_of_kernels + sizeof(*kernel_list));
  3114. + if (kernel_list == NULL)
  3115. + return -ENOMEM;
  3116. +
  3117. + memset(kernel_list, 0, sizeof(*kernel) * num_of_kernels + sizeof(*kernel_list));
  3118. + kernel_list->num_of_kernels = num_of_kernels;
  3119. + kernel = &kernel_list->kernels[0];
  3120. +
  3121. + fw_data = (char *)&fw_list->fw_info[0];
  3122. + for (kernel_idx = 0; kernel_idx < num_of_kernels; kernel_idx++) {
  3123. + fw_info = (bin_fw_info_t *)fw_data;
  3124. + fw_name = &fw_info->fw_name[0];
  3125. + vendor_output_idx = fw_info->vendor_output;
  3126. + snprintf(fw_path, MAX_IOCL_FILE_PATH_LEN, IPTS_FW_PATH_FMT, fw_name);
  3127. + ret = request_firmware(&fw, (const char *)fw_path, &ipts->cldev->dev);
  3128. + if (ret) {
  3129. + ipts_err(ipts, "cannot read fw %s\n", fw_path);
  3130. + goto error_exit;
  3131. + }
  3132. +
  3133. + parse_info.data = (u8*)fw->data;
  3134. + parse_info.size = fw->size;
  3135. + parse_info.parsed = 0;
  3136. + parse_info.fw_info = fw_info;
  3137. + parse_info.vendor_kernel = (kernel_idx == 0) ? NULL : &kernel[0];
  3138. + parse_info.interested_vendor_output = vendor_output_idx;
  3139. +
  3140. + ret = load_kernel(ipts, &parse_info, &kernel[kernel_idx]);
  3141. + if (ret) {
  3142. + ipts_err(ipts, "do_setup_kernel error : %d\n", ret);
  3143. + release_firmware(fw);
  3144. + goto error_exit;
  3145. + }
  3146. +
  3147. + release_firmware(fw);
  3148. +
  3149. + total_workload += kernel[kernel_idx].guc_wq_item->size;
  3150. +
  3151. + /* advance to the next kernel */
  3152. + fw_data += sizeof(bin_fw_info_t);
  3153. + fw_data += sizeof(bin_data_file_info_t) * fw_info->num_of_data_files;
  3154. + }
  3155. +
  3156. + ipts_set_wq_item_size(ipts, total_workload);
  3157. +
  3158. + ret = bin_setup_guc_workqueue(ipts, kernel_list);
  3159. + if (ret) {
  3160. + ipts_dbg(ipts, "error setup_guc_workqueue\n");
  3161. + goto error_exit;
  3162. + }
  3163. +
  3164. + ret = bin_setup_bufid_buffer(ipts, kernel_list);
  3165. + if (ret) {
  3166. + ipts_dbg(ipts, "error setup_lastbubmit_buffer\n");
  3167. + goto error_exit;
  3168. + }
  3169. +
  3170. + bin_setup_input_output(ipts, kernel_list);
  3171. +
  3172. + /* workload is not needed during run-time so free them */
  3173. + for (kernel_idx = 0; kernel_idx < num_of_kernels; kernel_idx++) {
  3174. + wl = kernel[kernel_idx].wl;
  3175. + vfree(wl);
  3176. + }
  3177. +
  3178. + ipts->kernel_handle = (u64)kernel_list;
  3179. +
  3180. + return 0;
  3181. +
  3182. +error_exit:
  3183. +
  3184. + for (kernel_idx = 0; kernel_idx < num_of_kernels; kernel_idx++) {
  3185. + wl = kernel[kernel_idx].wl;
  3186. + vfree(wl);
  3187. + unload_kernel(ipts, &kernel[kernel_idx]);
  3188. + }
  3189. +
  3190. + vfree(kernel_list);
  3191. +
  3192. + return ret;
  3193. +}
  3194. +
  3195. +
  3196. +static void release_kernel(ipts_info_t *ipts)
  3197. +{
  3198. + bin_kernel_list_t *kernel_list;
  3199. + bin_kernel_info_t *kernel;
  3200. + int k_idx, k_num;
  3201. +
  3202. + kernel_list = (bin_kernel_list_t *)ipts->kernel_handle;
  3203. + k_num = kernel_list->num_of_kernels;
  3204. + kernel = &kernel_list->kernels[0];
  3205. +
  3206. + for (k_idx = 0; k_idx < k_num; k_idx++) {
  3207. + unload_kernel(ipts, kernel);
  3208. + kernel++;
  3209. + }
  3210. +
  3211. + ipts_unmap_buffer(ipts, kernel_list->bufid_buf);
  3212. +
  3213. + vfree(kernel_list);
  3214. + ipts->kernel_handle = 0;
  3215. +}
  3216. +
  3217. +int ipts_init_kernels(ipts_info_t *ipts)
  3218. +{
  3219. + const struct firmware *config_fw = NULL;
  3220. + const char *config_fw_path = IPTS_FW_CONFIG_FILE;
  3221. + bin_fw_list_t *fw_list;
  3222. + int ret;
  3223. +
  3224. + ret = ipts_open_gpu(ipts);
  3225. + if (ret) {
  3226. + ipts_err(ipts, "open gpu error : %d\n", ret);
  3227. + return ret;
  3228. + }
  3229. +
  3230. + ret = request_firmware(&config_fw, config_fw_path, &ipts->cldev->dev);
  3231. + if (ret) {
  3232. + ipts_err(ipts, "request firmware error : %d\n", ret);
  3233. + goto close_gpu;
  3234. + }
  3235. +
  3236. + fw_list = (bin_fw_list_t *)config_fw->data;
  3237. + ret = setup_kernel(ipts, fw_list);
  3238. + if (ret) {
  3239. + ipts_err(ipts, "setup kernel error : %d\n", ret);
  3240. + goto close_firmware;
  3241. + }
  3242. +
  3243. + release_firmware(config_fw);
  3244. +
  3245. + return ret;
  3246. +
  3247. +close_firmware:
  3248. + release_firmware(config_fw);
  3249. +
  3250. +close_gpu:
  3251. + ipts_close_gpu(ipts);
  3252. +
  3253. + return ret;
  3254. +}
  3255. +
  3256. +void ipts_release_kernels(ipts_info_t *ipts)
  3257. +{
  3258. + release_kernel(ipts);
  3259. + ipts_close_gpu(ipts);
  3260. +}
  3261. diff --git a/drivers/misc/ipts/ipts-kernel.h b/drivers/misc/ipts/ipts-kernel.h
  3262. new file mode 100644
  3263. index 000000000000..0e7f1393b807
  3264. --- /dev/null
  3265. +++ b/drivers/misc/ipts/ipts-kernel.h
  3266. @@ -0,0 +1,23 @@
  3267. +/*
  3268. + *
  3269. + * Intel Precise Touch & Stylus Linux driver
  3270. + * Copyright (c) 2016, Intel Corporation.
  3271. + *
  3272. + * This program is free software; you can redistribute it and/or modify it
  3273. + * under the terms and conditions of the GNU General Public License,
  3274. + * version 2, as published by the Free Software Foundation.
  3275. + *
  3276. + * This program is distributed in the hope it will be useful, but WITHOUT
  3277. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  3278. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  3279. + * more details.
  3280. + *
  3281. + */
  3282. +
  3283. +#ifndef _ITPS_GFX_H
  3284. +#define _ITPS_GFX_H
  3285. +
  3286. +int ipts_init_kernels(ipts_info_t *ipts);
  3287. +void ipts_release_kernels(ipts_info_t *ipts);
  3288. +
  3289. +#endif
  3290. diff --git a/drivers/misc/ipts/ipts-mei-msgs.h b/drivers/misc/ipts/ipts-mei-msgs.h
  3291. new file mode 100644
  3292. index 000000000000..8ca146800a47
  3293. --- /dev/null
  3294. +++ b/drivers/misc/ipts/ipts-mei-msgs.h
  3295. @@ -0,0 +1,585 @@
  3296. +/*
  3297. + * Precise Touch HECI Message
  3298. + *
  3299. + * Copyright (c) 2013-2016, Intel Corporation.
  3300. + *
  3301. + * This program is free software; you can redistribute it and/or modify it
  3302. + * under the terms and conditions of the GNU General Public License,
  3303. + * version 2, as published by the Free Software Foundation.
  3304. + *
  3305. + * This program is distributed in the hope it will be useful, but WITHOUT
  3306. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  3307. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  3308. + * more details.
  3309. + */
  3310. +
  3311. +#ifndef _IPTS_MEI_MSGS_H_
  3312. +#define _IPTS_MEI_MSGS_H_
  3313. +
  3314. +#include "ipts-sensor-regs.h"
  3315. +
  3316. +#pragma pack(1)
  3317. +
  3318. +
  3319. +// Initial protocol version
  3320. +#define TOUCH_HECI_CLIENT_PROTOCOL_VERSION 10
  3321. +
  3322. +// GUID that identifies the Touch HECI client.
  3323. +#define TOUCH_HECI_CLIENT_GUID \
  3324. + {0x3e8d0870, 0x271a, 0x4208, {0x8e, 0xb5, 0x9a, 0xcb, 0x94, 0x02, 0xae, 0x04}}
  3325. +
  3326. +
  3327. +// define C_ASSERT macro to check structure size and fail compile for unexpected mismatch
  3328. +#ifndef C_ASSERT
  3329. +#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
  3330. +#endif
  3331. +
  3332. +
  3333. +// General Type Defines for compatibility with HID driver and BIOS
  3334. +#ifndef BIT0
  3335. +#define BIT0 1
  3336. +#endif
  3337. +#ifndef BIT1
  3338. +#define BIT1 2
  3339. +#endif
  3340. +#ifndef BIT2
  3341. +#define BIT2 4
  3342. +#endif
  3343. +
  3344. +
  3345. +#define TOUCH_SENSOR_GET_DEVICE_INFO_CMD 0x00000001
  3346. +#define TOUCH_SENSOR_GET_DEVICE_INFO_RSP 0x80000001
  3347. +
  3348. +
  3349. +#define TOUCH_SENSOR_SET_MODE_CMD 0x00000002
  3350. +#define TOUCH_SENSOR_SET_MODE_RSP 0x80000002
  3351. +
  3352. +
  3353. +#define TOUCH_SENSOR_SET_MEM_WINDOW_CMD 0x00000003
  3354. +#define TOUCH_SENSOR_SET_MEM_WINDOW_RSP 0x80000003
  3355. +
  3356. +
  3357. +#define TOUCH_SENSOR_QUIESCE_IO_CMD 0x00000004
  3358. +#define TOUCH_SENSOR_QUIESCE_IO_RSP 0x80000004
  3359. +
  3360. +
  3361. +#define TOUCH_SENSOR_HID_READY_FOR_DATA_CMD 0x00000005
  3362. +#define TOUCH_SENSOR_HID_READY_FOR_DATA_RSP 0x80000005
  3363. +
  3364. +
  3365. +#define TOUCH_SENSOR_FEEDBACK_READY_CMD 0x00000006
  3366. +#define TOUCH_SENSOR_FEEDBACK_READY_RSP 0x80000006
  3367. +
  3368. +
  3369. +#define TOUCH_SENSOR_CLEAR_MEM_WINDOW_CMD 0x00000007
  3370. +#define TOUCH_SENSOR_CLEAR_MEM_WINDOW_RSP 0x80000007
  3371. +
  3372. +
  3373. +#define TOUCH_SENSOR_NOTIFY_DEV_READY_CMD 0x00000008
  3374. +#define TOUCH_SENSOR_NOTIFY_DEV_READY_RSP 0x80000008
  3375. +
  3376. +
  3377. +#define TOUCH_SENSOR_SET_POLICIES_CMD 0x00000009
  3378. +#define TOUCH_SENSOR_SET_POLICIES_RSP 0x80000009
  3379. +
  3380. +
  3381. +#define TOUCH_SENSOR_GET_POLICIES_CMD 0x0000000A
  3382. +#define TOUCH_SENSOR_GET_POLICIES_RSP 0x8000000A
  3383. +
  3384. +
  3385. +#define TOUCH_SENSOR_RESET_CMD 0x0000000B
  3386. +#define TOUCH_SENSOR_RESET_RSP 0x8000000B
  3387. +
  3388. +
  3389. +#define TOUCH_SENSOR_READ_ALL_REGS_CMD 0x0000000C
  3390. +#define TOUCH_SENSOR_READ_ALL_REGS_RSP 0x8000000C
  3391. +
  3392. +
  3393. +#define TOUCH_SENSOR_CMD_ERROR_RSP 0x8FFFFFFF // M2H: ME sends this message to indicate previous command was unrecognized/unsupported
  3394. +
  3395. +
  3396. +
  3397. +//*******************************************************************
  3398. +//
  3399. +// Touch Sensor Status Codes
  3400. +//
  3401. +//*******************************************************************
  3402. +typedef enum touch_status
  3403. +{
  3404. + TOUCH_STATUS_SUCCESS = 0, // 0 Requested operation was successful
  3405. + TOUCH_STATUS_INVALID_PARAMS, // 1 Invalid parameter(s) sent
  3406. + TOUCH_STATUS_ACCESS_DENIED, // 2 Unable to validate address range
  3407. + TOUCH_STATUS_CMD_SIZE_ERROR, // 3 HECI message incorrect size for specified command
  3408. + TOUCH_STATUS_NOT_READY, // 4 Memory window not set or device is not armed for operation
  3409. + TOUCH_STATUS_REQUEST_OUTSTANDING, // 5 There is already an outstanding message of the same type, must wait for response before sending another request of that type
  3410. + TOUCH_STATUS_NO_SENSOR_FOUND, // 6 Sensor could not be found. Either no sensor is connected, the sensor has not yet initialized, or the system is improperly configured.
  3411. + TOUCH_STATUS_OUT_OF_MEMORY, // 7 Not enough memory/storage for requested operation
  3412. + TOUCH_STATUS_INTERNAL_ERROR, // 8 Unexpected error occurred
  3413. + TOUCH_STATUS_SENSOR_DISABLED, // 9 Used in TOUCH_SENSOR_HID_READY_FOR_DATA_RSP to indicate sensor has been disabled or reset and must be reinitialized.
  3414. + TOUCH_STATUS_COMPAT_CHECK_FAIL, // 10 Used to indicate compatibility revision check between sensor and ME failed, or protocol ver between ME/HID/Kernels failed.
  3415. + TOUCH_STATUS_SENSOR_EXPECTED_RESET, // 11 Indicates sensor went through a reset initiated by ME
  3416. + TOUCH_STATUS_SENSOR_UNEXPECTED_RESET, // 12 Indicates sensor went through an unexpected reset
  3417. + TOUCH_STATUS_RESET_FAILED, // 13 Requested sensor reset failed to complete
  3418. + TOUCH_STATUS_TIMEOUT, // 14 Operation timed out
  3419. + TOUCH_STATUS_TEST_MODE_FAIL, // 15 Test mode pattern did not match expected values
  3420. + TOUCH_STATUS_SENSOR_FAIL_FATAL, // 16 Indicates sensor reported fatal error during reset sequence. Further progress is not possible.
  3421. + TOUCH_STATUS_SENSOR_FAIL_NONFATAL, // 17 Indicates sensor reported non-fatal error during reset sequence. HID/BIOS logs error and attempts to continue.
  3422. + TOUCH_STATUS_INVALID_DEVICE_CAPS, // 18 Indicates sensor reported invalid capabilities, such as not supporting required minimum frequency or I/O mode.
  3423. + TOUCH_STATUS_QUIESCE_IO_IN_PROGRESS, // 19 Indicates that command cannot be complete until ongoing Quiesce I/O flow has completed.
  3424. + TOUCH_STATUS_MAX // 20 Invalid value, never returned
  3425. +} touch_status_t;
  3426. +C_ASSERT(sizeof(touch_status_t) == 4);
  3427. +
  3428. +
  3429. +
  3430. +//*******************************************************************
  3431. +//
  3432. +// Defines for message structures used for Host to ME communication
  3433. +//
  3434. +//*******************************************************************
  3435. +
  3436. +
  3437. +typedef enum touch_sensor_mode
  3438. +{
  3439. + TOUCH_SENSOR_MODE_HID = 0, // Set mode to HID mode
  3440. + TOUCH_SENSOR_MODE_RAW_DATA, // Set mode to Raw Data mode
  3441. + TOUCH_SENSOR_MODE_SENSOR_DEBUG = 4, // Used like TOUCH_SENSOR_MODE_HID but data coming from sensor is not necessarily a HID packet.
  3442. + TOUCH_SENSOR_MODE_MAX // Invalid value
  3443. +} touch_sensor_mode_t;
  3444. +C_ASSERT(sizeof(touch_sensor_mode_t) == 4);
  3445. +
  3446. +typedef struct touch_sensor_set_mode_cmd_data
  3447. +{
  3448. + touch_sensor_mode_t sensor_mode; // Indicate desired sensor mode
  3449. + u32 Reserved[3]; // For future expansion
  3450. +} touch_sensor_set_mode_cmd_data_t;
  3451. +C_ASSERT(sizeof(touch_sensor_set_mode_cmd_data_t) == 16);
  3452. +
  3453. +
  3454. +#define TOUCH_SENSOR_MAX_DATA_BUFFERS 16
  3455. +#define TOUCH_HID_2_ME_BUFFER_ID TOUCH_SENSOR_MAX_DATA_BUFFERS
  3456. +#define TOUCH_HID_2_ME_BUFFER_SIZE_MAX 1024
  3457. +#define TOUCH_INVALID_BUFFER_ID 0xFF
  3458. +
  3459. +typedef struct touch_sensor_set_mem_window_cmd_data
  3460. +{
  3461. + u32 touch_data_buffer_addr_lower[TOUCH_SENSOR_MAX_DATA_BUFFERS]; // Lower 32 bits of Touch Data Buffer physical address. Size of each buffer should be TOUCH_SENSOR_GET_DEVICE_INFO_RSP_DATA.FrameSize
  3462. + u32 touch_data_buffer_addr_upper[TOUCH_SENSOR_MAX_DATA_BUFFERS]; // Upper 32 bits of Touch Data Buffer physical address. Size of each buffer should be TOUCH_SENSOR_GET_DEVICE_INFO_RSP_DATA.FrameSize
  3463. + u32 tail_offset_addr_lower; // Lower 32 bits of Tail Offset physical address
  3464. + u32 tail_offset_addr_upper; // Upper 32 bits of Tail Offset physical address, always 32 bit, increment by WorkQueueItemSize
  3465. + u32 doorbell_cookie_addr_lower; // Lower 32 bits of Doorbell register physical address
  3466. + u32 doorbell_cookie_addr_upper; // Upper 32 bits of Doorbell register physical address, always 32 bit, increment as integer, rollover to 1
  3467. + u32 feedback_buffer_addr_lower[TOUCH_SENSOR_MAX_DATA_BUFFERS]; // Lower 32 bits of Feedback Buffer physical address. Size of each buffer should be TOUCH_SENSOR_GET_DEVICE_INFO_RSP_DATA.FeedbackSize
  3468. + u32 feedback_buffer_addr_upper[TOUCH_SENSOR_MAX_DATA_BUFFERS]; // Upper 32 bits of Feedback Buffer physical address. Size of each buffer should be TOUCH_SENSOR_GET_DEVICE_INFO_RSP_DATA.FeedbackSize
  3469. + u32 hid2me_buffer_addr_lower; // Lower 32 bits of dedicated HID to ME communication buffer. Size is Hid2MeBufferSize.
  3470. + u32 hid2me_buffer_addr_upper; // Upper 32 bits of dedicated HID to ME communication buffer. Size is Hid2MeBufferSize.
  3471. + u32 hid2me_buffer_size; // Size in bytes of Hid2MeBuffer, can be no bigger than TOUCH_HID_2_ME_BUFFER_SIZE_MAX
  3472. + u8 reserved1; // For future expansion
  3473. + u8 work_queue_item_size; // Size in bytes of the GuC Work Queue Item pointed to by TailOffset
  3474. + u16 work_queue_size; // Size in bytes of the entire GuC Work Queue
  3475. + u32 reserved[8]; // For future expansion
  3476. +} touch_sensor_set_mem_window_cmd_data_t;
  3477. +C_ASSERT(sizeof(touch_sensor_set_mem_window_cmd_data_t) == 320);
  3478. +
  3479. +
  3480. +#define TOUCH_SENSOR_QUIESCE_FLAG_GUC_RESET BIT0 // indicates GuC got reset and ME must re-read GuC data such as TailOffset and Doorbell Cookie values
  3481. +
  3482. +typedef struct touch_sensor_quiesce_io_cmd_data
  3483. +{
  3484. + u32 quiesce_flags; // Optionally set TOUCH_SENSOR_QUIESCE_FLAG_GUC_RESET
  3485. + u32 reserved[2];
  3486. +} touch_sensor_quiesce_io_cmd_data_t;
  3487. +C_ASSERT(sizeof(touch_sensor_quiesce_io_cmd_data_t) == 12);
  3488. +
  3489. +
  3490. +typedef struct touch_sensor_feedback_ready_cmd_data
  3491. +{
  3492. + u8 feedback_index; // Index value from 0 to TOUCH_HID_2_ME_BUFFER_ID used to indicate which Feedback Buffer to use. Using special value TOUCH_HID_2_ME_BUFFER_ID
  3493. + // is an indication to ME to get feedback data from the Hid2Me buffer instead of one of the standard Feedback buffers.
  3494. + u8 reserved1[3]; // For future expansion
  3495. + u32 transaction_id; // Transaction ID that was originally passed to host in TOUCH_HID_PRIVATE_DATA. Used to track round trip of a given transaction for performance measurements.
  3496. + u32 reserved2[2]; // For future expansion
  3497. +} touch_sensor_feedback_ready_cmd_data_t;
  3498. +C_ASSERT(sizeof(touch_sensor_feedback_ready_cmd_data_t) == 16);
  3499. +
  3500. +
  3501. +#define TOUCH_DEFAULT_DOZE_TIMER_SECONDS 30
  3502. +
  3503. +typedef enum touch_freq_override
  3504. +{
  3505. + TOUCH_FREQ_OVERRIDE_NONE, // Do not apply any override
  3506. + TOUCH_FREQ_OVERRIDE_10MHZ, // Force frequency to 10MHz (not currently supported)
  3507. + TOUCH_FREQ_OVERRIDE_17MHZ, // Force frequency to 17MHz
  3508. + TOUCH_FREQ_OVERRIDE_30MHZ, // Force frequency to 30MHz
  3509. + TOUCH_FREQ_OVERRIDE_50MHZ, // Force frequency to 50MHz (not currently supported)
  3510. + TOUCH_FREQ_OVERRIDE_MAX // Invalid value
  3511. +} touch_freq_override_t;
  3512. +C_ASSERT(sizeof(touch_freq_override_t) == 4);
  3513. +
  3514. +typedef enum touch_spi_io_mode_override
  3515. +{
  3516. + TOUCH_SPI_IO_MODE_OVERRIDE_NONE, // Do not apply any override
  3517. + TOUCH_SPI_IO_MODE_OVERRIDE_SINGLE, // Force Single I/O
  3518. + TOUCH_SPI_IO_MODE_OVERRIDE_DUAL, // Force Dual I/O
  3519. + TOUCH_SPI_IO_MODE_OVERRIDE_QUAD, // Force Quad I/O
  3520. + TOUCH_SPI_IO_MODE_OVERRIDE_MAX // Invalid value
  3521. +} touch_spi_io_mode_override_t;
  3522. +C_ASSERT(sizeof(touch_spi_io_mode_override_t) == 4);
  3523. +
  3524. +// Debug Policy bits used by TOUCH_POLICY_DATA.DebugOverride
  3525. +#define TOUCH_DBG_POLICY_OVERRIDE_STARTUP_TIMER_DIS BIT0 // Disable sensor startup timer
  3526. +#define TOUCH_DBG_POLICY_OVERRIDE_SYNC_BYTE_DIS BIT1 // Disable Sync Byte check
  3527. +#define TOUCH_DBG_POLICY_OVERRIDE_ERR_RESET_DIS BIT2 // Disable error resets
  3528. +
  3529. +typedef struct touch_policy_data
  3530. +{
  3531. + u32 reserved0; // For future expansion.
  3532. + u32 doze_timer :16; // Value in seconds, after which ME will put the sensor into Doze power state if no activity occurs. Set
  3533. + // to 0 to disable Doze mode (not recommended). Value will be set to TOUCH_DEFAULT_DOZE_TIMER_SECONDS by
  3534. + // default.
  3535. + touch_freq_override_t freq_override :3; // Override frequency requested by sensor
  3536. + touch_spi_io_mode_override_t spi_io_override :3; // Override IO mode requested by sensor
  3537. + u32 reserved1 :10; // For future expansion
  3538. + u32 reserved2; // For future expansion
  3539. + u32 debug_override; // Normally all bits will be zero. Bits will be defined as needed for enabling special debug features
  3540. +} touch_policy_data_t;
  3541. +C_ASSERT(sizeof(touch_policy_data_t) == 16);
  3542. +
  3543. +typedef struct touch_sensor_set_policies_cmd_data
  3544. +{
  3545. + touch_policy_data_t policy_data; // Contains the desired policy to be set
  3546. +} touch_sensor_set_policies_cmd_data_t;
  3547. +C_ASSERT(sizeof(touch_sensor_set_policies_cmd_data_t) == 16);
  3548. +
  3549. +
  3550. +typedef enum touch_sensor_reset_type
  3551. +{
  3552. + TOUCH_SENSOR_RESET_TYPE_HARD, // Hardware Reset using dedicated GPIO pin
  3553. + TOUCH_SENSOR_RESET_TYPE_SOFT, // Software Reset using command written over SPI interface
  3554. + TOUCH_SENSOR_RESET_TYPE_MAX // Invalid value
  3555. +} touch_sensor_reset_type_t;
  3556. +C_ASSERT(sizeof(touch_sensor_reset_type_t) == 4);
  3557. +
  3558. +typedef struct touch_sensor_reset_cmd_data
  3559. +{
  3560. + touch_sensor_reset_type_t reset_type; // Indicate desired reset type
  3561. + u32 reserved; // For future expansion
  3562. +} touch_sensor_reset_cmd_data_t;
  3563. +C_ASSERT(sizeof(touch_sensor_reset_cmd_data_t) == 8);
  3564. +
  3565. +
  3566. +//
  3567. +// Host to ME message
  3568. +//
  3569. +typedef struct touch_sensor_msg_h2m
  3570. +{
  3571. + u32 command_code;
  3572. + union
  3573. + {
  3574. + touch_sensor_set_mode_cmd_data_t set_mode_cmd_data;
  3575. + touch_sensor_set_mem_window_cmd_data_t set_window_cmd_data;
  3576. + touch_sensor_quiesce_io_cmd_data_t quiesce_io_cmd_data;
  3577. + touch_sensor_feedback_ready_cmd_data_t feedback_ready_cmd_data;
  3578. + touch_sensor_set_policies_cmd_data_t set_policies_cmd_data;
  3579. + touch_sensor_reset_cmd_data_t reset_cmd_data;
  3580. + } h2m_data;
  3581. +} touch_sensor_msg_h2m_t;
  3582. +C_ASSERT(sizeof(touch_sensor_msg_h2m_t) == 324);
  3583. +
  3584. +
  3585. +//*******************************************************************
  3586. +//
  3587. +// Defines for message structures used for ME to Host communication
  3588. +//
  3589. +//*******************************************************************
  3590. +
  3591. +// I/O mode values used by TOUCH_SENSOR_GET_DEVICE_INFO_RSP_DATA.
  3592. +typedef enum touch_spi_io_mode
  3593. +{
  3594. + TOUCH_SPI_IO_MODE_SINGLE = 0, // Sensor set for Single I/O SPI
  3595. + TOUCH_SPI_IO_MODE_DUAL, // Sensor set for Dual I/O SPI
  3596. + TOUCH_SPI_IO_MODE_QUAD, // Sensor set for Quad I/O SPI
  3597. + TOUCH_SPI_IO_MODE_MAX // Invalid value
  3598. +} touch_spi_io_mode_t;
  3599. +C_ASSERT(sizeof(touch_spi_io_mode_t) == 4);
  3600. +
  3601. +//
  3602. +// TOUCH_SENSOR_GET_DEVICE_INFO_RSP code is sent in response to TOUCH_SENSOR_GET_DEVICE_INFO_CMD. This code will be followed
  3603. +// by TOUCH_SENSOR_GET_DEVICE_INFO_RSP_DATA.
  3604. +//
  3605. +// Possible Status values:
  3606. +// TOUCH_STATUS_SUCCESS: Command was processed successfully and sensor details are reported.
  3607. +// TOUCH_STATUS_CMD_SIZE_ERROR: Command sent did not match expected size. Other fields will not contain valid data.
  3608. +// TOUCH_STATUS_NO_SENSOR_FOUND: Sensor has not yet been detected. Other fields will not contain valid data.
  3609. +// TOUCH_STATUS_INVALID_DEVICE_CAPS: Indicates sensor does not support minimum required Frequency or I/O Mode. ME firmware will choose best possible option for the errant
  3610. +// field. Caller should attempt to continue.
  3611. +// TOUCH_STATUS_COMPAT_CHECK_FAIL: Indicates TouchIC/ME compatibility mismatch. Caller should attempt to continue.
  3612. +//
  3613. +typedef struct touch_sensor_get_device_info_rsp_data
  3614. +{
  3615. + u16 vendor_id; // Touch Sensor vendor ID
  3616. + u16 device_id; // Touch Sensor device ID
  3617. + u32 hw_rev; // Touch Sensor Hardware Revision
  3618. + u32 fw_rev; // Touch Sensor Firmware Revision
  3619. + u32 frame_size; // Max size of one frame returned by Touch IC in bytes. This data will be TOUCH_RAW_DATA_HDR followed
  3620. + // by a payload. The payload can be raw data or a HID structure depending on mode.
  3621. + u32 feedback_size; // Max size of one Feedback structure in bytes
  3622. + touch_sensor_mode_t sensor_mode; // Current operating mode of the sensor
  3623. + u32 max_touch_points :8; // Maximum number of simultaneous touch points that can be reported by sensor
  3624. + touch_freq_t spi_frequency :8; // SPI bus Frequency supported by sensor and ME firmware
  3625. + touch_spi_io_mode_t spi_io_mode :8; // SPI bus I/O Mode supported by sensor and ME firmware
  3626. + u32 reserved0 :8; // For future expansion
  3627. + u8 sensor_minor_eds_rev; // Minor version number of EDS spec supported by sensor (from Compat Rev ID Reg)
  3628. + u8 sensor_major_eds_rev; // Major version number of EDS spec supported by sensor (from Compat Rev ID Reg)
  3629. + u8 me_minor_eds_rev; // Minor version number of EDS spec supported by ME
  3630. + u8 me_major_eds_rev; // Major version number of EDS spec supported by ME
  3631. + u8 sensor_eds_intf_rev; // EDS Interface Revision Number supported by sensor (from Compat Rev ID Reg)
  3632. + u8 me_eds_intf_rev; // EDS Interface Revision Number supported by ME
  3633. + u8 kernel_compat_ver; // EU Kernel Compatibility Version (from Compat Rev ID Reg)
  3634. + u8 reserved1; // For future expansion
  3635. + u32 reserved2[2]; // For future expansion
  3636. +} touch_sensor_get_device_info_rsp_data_t;
  3637. +C_ASSERT(sizeof(touch_sensor_get_device_info_rsp_data_t) == 44);
  3638. +
  3639. +
  3640. +//
  3641. +// TOUCH_SENSOR_SET_MODE_RSP code is sent in response to TOUCH_SENSOR_SET_MODE_CMD. This code will be followed
  3642. +// by TOUCH_SENSOR_SET_MODE_RSP_DATA.
  3643. +//
  3644. +// Possible Status values:
  3645. +// TOUCH_STATUS_SUCCESS: Command was processed successfully and mode was set.
  3646. +// TOUCH_STATUS_CMD_SIZE_ERROR: Command sent did not match expected size. Other fields will not contain valid data.
  3647. +// TOUCH_STATUS_INVALID_PARAMS: Input parameters are out of range.
  3648. +//
  3649. +typedef struct touch_sensor_set_mode_rsp_data
  3650. +{
  3651. + u32 reserved[3]; // For future expansion
  3652. +} touch_sensor_set_mode_rsp_data_t;
  3653. +C_ASSERT(sizeof(touch_sensor_set_mode_rsp_data_t) == 12);
  3654. +
  3655. +
  3656. +//
  3657. +// TOUCH_SENSOR_SET_MEM_WINDOW_RSP code is sent in response to TOUCH_SENSOR_SET_MEM_WINDOW_CMD. This code will be followed
  3658. +// by TOUCH_SENSOR_SET_MEM_WINDOW_RSP_DATA.
  3659. +//
  3660. +// Possible Status values:
  3661. +// TOUCH_STATUS_SUCCESS: Command was processed successfully and memory window was set.
  3662. +// TOUCH_STATUS_CMD_SIZE_ERROR: Command sent did not match expected size. Other fields will not contain valid data.
  3663. +// TOUCH_STATUS_INVALID_PARAMS: Input parameters are out of range.
  3664. +// TOUCH_STATUS_ACCESS_DENIED: Unable to map host address ranges for DMA.
  3665. +// TOUCH_STATUS_OUT_OF_MEMORY: Unable to allocate enough space for needed buffers.
  3666. +//
  3667. +typedef struct touch_sensor_set_mem_window_rsp_data
  3668. +{
  3669. + u32 reserved[3]; // For future expansion
  3670. +} touch_sensor_set_mem_window_rsp_data_t;
  3671. +C_ASSERT(sizeof(touch_sensor_set_mem_window_rsp_data_t) == 12);
  3672. +
  3673. +
  3674. +//
  3675. +// TOUCH_SENSOR_QUIESCE_IO_RSP code is sent in response to TOUCH_SENSOR_QUIESCE_IO_CMD. This code will be followed
  3676. +// by TOUCH_SENSOR_QUIESCE_IO_RSP_DATA.
  3677. +//
  3678. +// Possible Status values:
  3679. +// TOUCH_STATUS_SUCCESS: Command was processed successfully and touch flow has stopped.
  3680. +// TOUCH_STATUS_CMD_SIZE_ERROR: Command sent did not match expected size. Other fields will not contain valid data.
  3681. +// TOUCH_STATUS_QUIESCE_IO_IN_PROGRESS: Indicates that Quiesce I/O is already in progress and this command cannot be accepted at this time.
  3682. +// TOUCH_STATIS_TIMEOUT: Indicates ME timed out waiting for Quiesce I/O flow to complete.
  3683. +//
  3684. +typedef struct touch_sensor_quiesce_io_rsp_data
  3685. +{
  3686. + u32 reserved[3]; // For future expansion
  3687. +} touch_sensor_quiesce_io_rsp_data_t;
  3688. +C_ASSERT(sizeof(touch_sensor_quiesce_io_rsp_data_t) == 12);
  3689. +
  3690. +
  3691. +// Reset Reason values used in TOUCH_SENSOR_HID_READY_FOR_DATA_RSP_DATA
  3692. +typedef enum touch_reset_reason
  3693. +{
  3694. + TOUCH_RESET_REASON_UNKNOWN = 0, // Reason for sensor reset is not known
  3695. + TOUCH_RESET_REASON_FEEDBACK_REQUEST, // Reset was requested as part of TOUCH_SENSOR_FEEDBACK_READY_CMD
  3696. + TOUCH_RESET_REASON_HECI_REQUEST, // Reset was requested via TOUCH_SENSOR_RESET_CMD
  3697. + TOUCH_RESET_REASON_MAX
  3698. +} touch_reset_reason_t;
  3699. +C_ASSERT(sizeof(touch_reset_reason_t) == 4);
  3700. +
  3701. +//
  3702. +// TOUCH_SENSOR_HID_READY_FOR_DATA_RSP code is sent in response to TOUCH_SENSOR_HID_READY_FOR_DATA_CMD. This code will be followed
  3703. +// by TOUCH_SENSOR_HID_READY_FOR_DATA_RSP_DATA.
  3704. +//
  3705. +// Possible Status values:
  3706. +// TOUCH_STATUS_SUCCESS: Command was processed successfully and HID data was sent by DMA. This will only be sent in HID mode.
  3707. +// TOUCH_STATUS_CMD_SIZE_ERROR: Command sent did not match expected size. Other fields will not contain valid data.
  3708. +// TOUCH_STATUS_REQUEST_OUTSTANDING: Previous request is still outstanding, ME FW cannot handle another request for the same command.
  3709. +// TOUCH_STATUS_NOT_READY: Indicates memory window has not yet been set by BIOS/HID.
  3710. +// TOUCH_STATUS_SENSOR_DISABLED: Indicates that ME to HID communication has been stopped either by TOUCH_SENSOR_QUIESCE_IO_CMD or TOUCH_SENSOR_CLEAR_MEM_WINDOW_CMD.
  3711. +// TOUCH_STATUS_SENSOR_UNEXPECTED_RESET: Sensor signaled a Reset Interrupt. ME did not expect this and has no info about why this occurred.
  3712. +// TOUCH_STATUS_SENSOR_EXPECTED_RESET: Sensor signaled a Reset Interrupt. ME either directly requested this reset, or it was expected as part of a defined flow in the EDS.
  3713. +// TOUCH_STATUS_QUIESCE_IO_IN_PROGRESS: Indicates that Quiesce I/O is already in progress and this command cannot be accepted at this time.
  3714. +// TOUCH_STATUS_TIMEOUT: Sensor did not generate a reset interrupt in the time allotted. Could indicate sensor is not connected or malfunctioning.
  3715. +//
  3716. +typedef struct touch_sensor_hid_ready_for_data_rsp_data
  3717. +{
  3718. + u32 data_size; // Size of the data the ME DMA'd into a RawDataBuffer. Valid only when Status == TOUCH_STATUS_SUCCESS
  3719. + u8 touch_data_buffer_index; // Index to indicate which RawDataBuffer was used. Valid only when Status == TOUCH_STATUS_SUCCESS
  3720. + u8 reset_reason; // If Status is TOUCH_STATUS_SENSOR_EXPECTED_RESET, ME will provide the cause. See TOUCH_RESET_REASON.
  3721. + u8 reserved1[2]; // For future expansion
  3722. + u32 reserved2[5]; // For future expansion
  3723. +} touch_sensor_hid_ready_for_data_rsp_data_t;
  3724. +C_ASSERT(sizeof(touch_sensor_hid_ready_for_data_rsp_data_t) == 28);
  3725. +
  3726. +
  3727. +//
  3728. +// TOUCH_SENSOR_FEEDBACK_READY_RSP code is sent in response to TOUCH_SENSOR_FEEDBACK_READY_CMD. This code will be followed
  3729. +// by TOUCH_SENSOR_FEEDBACK_READY_RSP_DATA.
  3730. +//
  3731. +// Possible Status values:
  3732. +// TOUCH_STATUS_SUCCESS: Command was processed successfully and any feedback or commands were sent to sensor.
  3733. +// TOUCH_STATUS_CMD_SIZE_ERROR: Command sent did not match expected size. Other fields will not contain valid data.
  3734. +// TOUCH_STATUS_INVALID_PARAMS: Input parameters are out of range.
  3735. +// TOUCH_STATUS_COMPAT_CHECK_FAIL Indicates ProtocolVer does not match ME supported version. (non-fatal error)
  3736. +// TOUCH_STATUS_INTERNAL_ERROR: Unexpected error occurred. This should not normally be seen.
  3737. +// TOUCH_STATUS_OUT_OF_MEMORY: Insufficient space to store Calibration Data
  3738. +//
  3739. +typedef struct touch_sensor_feedback_ready_rsp_data
  3740. +{
  3741. + u8 feedback_index; // Index value from 0 to TOUCH_SENSOR_MAX_DATA_BUFFERS used to indicate which Feedback Buffer to use
  3742. + u8 reserved1[3]; // For future expansion
  3743. + u32 reserved2[6]; // For future expansion
  3744. +} touch_sensor_feedback_ready_rsp_data_t;
  3745. +C_ASSERT(sizeof(touch_sensor_feedback_ready_rsp_data_t) == 28);
  3746. +
  3747. +
  3748. +//
  3749. +// TOUCH_SENSOR_CLEAR_MEM_WINDOW_RSP code is sent in response to TOUCH_SENSOR_CLEAR_MEM_WINDOW_CMD. This code will be followed
  3750. +// by TOUCH_SENSOR_CLEAR_MEM_WINDOW_RSP_DATA.
  3751. +//
  3752. +// Possible Status values:
  3753. +// TOUCH_STATUS_SUCCESS: Command was processed successfully and memory window was set.
  3754. +// TOUCH_STATUS_CMD_SIZE_ERROR: Command sent did not match expected size. Other fields will not contain valid data.
  3755. +// TOUCH_STATUS_INVALID_PARAMS: Input parameters are out of range.
  3756. +// TOUCH_STATUS_QUIESCE_IO_IN_PROGRESS: Indicates that Quiesce I/O is already in progress and this command cannot be accepted at this time.
  3757. +//
  3758. +typedef struct touch_sensor_clear_mem_window_rsp_data
  3759. +{
  3760. + u32 reserved[3]; // For future expansion
  3761. +} touch_sensor_clear_mem_window_rsp_data_t;
  3762. +C_ASSERT(sizeof(touch_sensor_clear_mem_window_rsp_data_t) == 12);
  3763. +
  3764. +
  3765. +//
  3766. +// TOUCH_SENSOR_NOTIFY_DEV_READY_RSP code is sent in response to TOUCH_SENSOR_NOTIFY_DEV_READY_CMD. This code will be followed
  3767. +// by TOUCH_SENSOR_NOTIFY_DEV_READY_RSP_DATA.
  3768. +//
  3769. +// Possible Status values:
  3770. +// TOUCH_STATUS_SUCCESS: Command was processed successfully and sensor has been detected by ME FW.
  3771. +// TOUCH_STATUS_CMD_SIZE_ERROR: Command sent did not match expected size.
  3772. +// TOUCH_STATUS_REQUEST_OUTSTANDING: Previous request is still outstanding, ME FW cannot handle another request for the same command.
  3773. +// TOUCH_STATUS_TIMEOUT: Sensor did not generate a reset interrupt in the time allotted. Could indicate sensor is not connected or malfunctioning.
  3774. +// TOUCH_STATUS_SENSOR_FAIL_FATAL: Sensor indicated a fatal error, further operation is not possible. Error details can be found in ErrReg.
  3775. +// TOUCH_STATUS_SENSOR_FAIL_NONFATAL: Sensor indicated a non-fatal error. Error should be logged by caller and init flow can continue. Error details can be found in ErrReg.
  3776. +//
  3777. +typedef struct touch_sensor_notify_dev_ready_rsp_data
  3778. +{
  3779. + touch_err_reg_t err_reg; // Value of sensor Error Register, field is only valid for Status == TOUCH_STATUS_SENSOR_FAIL_FATAL or TOUCH_STATUS_SENSOR_FAIL_NONFATAL
  3780. + u32 reserved[2]; // For future expansion
  3781. +} touch_sensor_notify_dev_ready_rsp_data_t;
  3782. +C_ASSERT(sizeof(touch_sensor_notify_dev_ready_rsp_data_t) == 12);
  3783. +
  3784. +
  3785. +//
  3786. +// TOUCH_SENSOR_SET_POLICIES_RSP code is sent in response to TOUCH_SENSOR_SET_POLICIES_CMD. This code will be followed
  3787. +// by TOUCH_SENSOR_SET_POLICIES_RSP_DATA.
  3788. +//
  3789. +// Possible Status values:
  3790. +// TOUCH_STATUS_SUCCESS: Command was processed successfully and new policies were set.
  3791. +// TOUCH_STATUS_CMD_SIZE_ERROR: Command sent did not match expected size. Other fields will not contain valid data.
  3792. +// TOUCH_STATUS_INVALID_PARAMS: Input parameters are out of range.
  3793. +//
  3794. +typedef struct touch_sensor_set_policies_rsp_data
  3795. +{
  3796. + u32 reserved[3]; // For future expansion
  3797. +} touch_sensor_set_policies_rsp_data_t;
  3798. +C_ASSERT(sizeof(touch_sensor_set_policies_rsp_data_t) == 12);
  3799. +
  3800. +
  3801. +//
  3802. +// TOUCH_SENSOR_GET_POLICIES_RSP code is sent in response to TOUCH_SENSOR_GET_POLICIES_CMD. This code will be followed
  3803. +// by TOUCH_SENSOR_GET_POLICIES_RSP_DATA.
  3804. +//
  3805. +// Possible Status values:
  3806. +// TOUCH_STATUS_SUCCESS: Command was processed successfully and new policies were set.
  3807. +// TOUCH_STATUS_CMD_SIZE_ERROR: Command sent did not match expected size. Other fields will not contain valid data.
  3808. +//
  3809. +typedef struct touch_sensor_get_policies_rsp_data
  3810. +{
  3811. + touch_policy_data_t policy_data; // Contains the current policy
  3812. +} touch_sensor_get_policies_rsp_data_t;
  3813. +C_ASSERT(sizeof(touch_sensor_get_policies_rsp_data_t) == 16);
  3814. +
  3815. +
  3816. +//
  3817. +// TOUCH_SENSOR_RESET_RSP code is sent in response to TOUCH_SENSOR_RESET_CMD. This code will be followed
  3818. +// by TOUCH_SENSOR_RESET_RSP_DATA.
  3819. +//
  3820. +// Possible Status values:
  3821. +// TOUCH_STATUS_SUCCESS: Command was processed successfully and sensor reset was completed.
  3822. +// TOUCH_STATUS_CMD_SIZE_ERROR: Command sent did not match expected size. Other fields will not contain valid data.
  3823. +// TOUCH_STATUS_INVALID_PARAMS: Input parameters are out of range.
  3824. +// TOUCH_STATUS_TIMEOUT: Sensor did not generate a reset interrupt in the time allotted. Could indicate sensor is not connected or malfunctioning.
  3825. +// TOUCH_STATUS_RESET_FAILED: Sensor generated an invalid or unexpected interrupt.
  3826. +// TOUCH_STATUS_QUIESCE_IO_IN_PROGRESS: Indicates that Quiesce I/O is already in progress and this command cannot be accepted at this time.
  3827. +//
  3828. +typedef struct touch_sensor_reset_rsp_data
  3829. +{
  3830. + u32 reserved[3]; // For future expansion
  3831. +} touch_sensor_reset_rsp_data_t;
  3832. +C_ASSERT(sizeof(touch_sensor_reset_rsp_data_t) == 12);
  3833. +
  3834. +
  3835. +//
  3836. +// TOUCH_SENSOR_READ_ALL_REGS_RSP code is sent in response to TOUCH_SENSOR_READ_ALL_REGS_CMD. This code will be followed
  3837. +// by TOUCH_SENSOR_READ_ALL_REGS_RSP_DATA.
  3838. +//
  3839. +// Possible Status values:
  3840. +// TOUCH_STATUS_SUCCESS: Command was processed successfully and new policies were set.
  3841. +// TOUCH_STATUS_CMD_SIZE_ERROR: Command sent did not match expected size. Other fields will not contain valid data.
  3842. +//
  3843. +typedef struct touch_sensor_read_all_regs_rsp_data
  3844. +{
  3845. + touch_reg_block_t sensor_regs; // Returns first 64 bytes of register space used for normal touch operation. Does not include test mode register.
  3846. + u32 reserved[4];
  3847. +} touch_sensor_read_all_regs_rsp_data_t;
  3848. +C_ASSERT(sizeof(touch_sensor_read_all_regs_rsp_data_t) == 80);
  3849. +
  3850. +//
  3851. +// ME to Host Message
  3852. +//
  3853. +typedef struct touch_sensor_msg_m2h
  3854. +{
  3855. + u32 command_code;
  3856. + touch_status_t status;
  3857. + union
  3858. + {
  3859. + touch_sensor_get_device_info_rsp_data_t device_info_rsp_data;
  3860. + touch_sensor_set_mode_rsp_data_t set_mode_rsp_data;
  3861. + touch_sensor_set_mem_window_rsp_data_t set_mem_window_rsp_data;
  3862. + touch_sensor_quiesce_io_rsp_data_t quiesce_io_rsp_data;
  3863. + touch_sensor_hid_ready_for_data_rsp_data_t hid_ready_for_data_rsp_data;
  3864. + touch_sensor_feedback_ready_rsp_data_t feedback_ready_rsp_data;
  3865. + touch_sensor_clear_mem_window_rsp_data_t clear_mem_window_rsp_data;
  3866. + touch_sensor_notify_dev_ready_rsp_data_t notify_dev_ready_rsp_data;
  3867. + touch_sensor_set_policies_rsp_data_t set_policies_rsp_data;
  3868. + touch_sensor_get_policies_rsp_data_t get_policies_rsp_data;
  3869. + touch_sensor_reset_rsp_data_t reset_rsp_data;
  3870. + touch_sensor_read_all_regs_rsp_data_t read_all_regs_rsp_data;
  3871. + } m2h_data;
  3872. +} touch_sensor_msg_m2h_t;
  3873. +C_ASSERT(sizeof(touch_sensor_msg_m2h_t) == 88);
  3874. +
  3875. +
  3876. +#define TOUCH_MSG_SIZE_MAX_BYTES (MAX(sizeof(touch_sensor_msg_m2h_t), sizeof(touch_sensor_msg_h2m_t)))
  3877. +
  3878. +#pragma pack()
  3879. +
  3880. +#endif // _IPTS_MEI_MSGS_H_
  3881. diff --git a/drivers/misc/ipts/ipts-mei.c b/drivers/misc/ipts/ipts-mei.c
  3882. new file mode 100644
  3883. index 000000000000..39667e75dafd
  3884. --- /dev/null
  3885. +++ b/drivers/misc/ipts/ipts-mei.c
  3886. @@ -0,0 +1,282 @@
  3887. +/*
  3888. + * MEI client driver for Intel Precise Touch and Stylus
  3889. + *
  3890. + * Copyright (c) 2016, Intel Corporation.
  3891. + *
  3892. + * This program is free software; you can redistribute it and/or modify it
  3893. + * under the terms and conditions of the GNU General Public License,
  3894. + * version 2, as published by the Free Software Foundation.
  3895. + *
  3896. + * This program is distributed in the hope it will be useful, but WITHOUT
  3897. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  3898. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  3899. + * more details.
  3900. + */
  3901. +
  3902. +#include <linux/mei_cl_bus.h>
  3903. +#include <linux/module.h>
  3904. +#include <linux/mod_devicetable.h>
  3905. +#include <linux/hid.h>
  3906. +#include <linux/dma-mapping.h>
  3907. +#include <linux/kthread.h>
  3908. +#include <linux/intel_ipts_if.h>
  3909. +
  3910. +#include "ipts.h"
  3911. +#include "ipts-hid.h"
  3912. +#include "ipts-msg-handler.h"
  3913. +#include "ipts-mei-msgs.h"
  3914. +#include "ipts-binary-spec.h"
  3915. +#include "ipts-state.h"
  3916. +
  3917. +#define IPTS_DRIVER_NAME "ipts"
  3918. +#define IPTS_MEI_UUID UUID_LE(0x3e8d0870, 0x271a, 0x4208, \
  3919. + 0x8e, 0xb5, 0x9a, 0xcb, 0x94, 0x02, 0xae, 0x04)
  3920. +
  3921. +static struct mei_cl_device_id ipts_mei_cl_tbl[] = {
  3922. + { "", IPTS_MEI_UUID, MEI_CL_VERSION_ANY},
  3923. + {}
  3924. +};
  3925. +
  3926. +static ssize_t sensor_mode_show(struct device *dev,
  3927. + struct device_attribute *attr, char *buf)
  3928. +{
  3929. + ipts_info_t *ipts;
  3930. + ipts = dev_get_drvdata(dev);
  3931. +
  3932. + return sprintf(buf, "%d\n", ipts->sensor_mode);
  3933. +}
  3934. +
  3935. +//TODO: Verify the function implementation
  3936. +static ssize_t sensor_mode_store(struct device *dev,
  3937. + struct device_attribute *attr, const char *buf,
  3938. + size_t count)
  3939. +{
  3940. + int ret;
  3941. + long val;
  3942. + ipts_info_t *ipts;
  3943. +
  3944. + ipts = dev_get_drvdata(dev);
  3945. + ret = kstrtol(buf, 10, &val);
  3946. + if (ret)
  3947. + return ret;
  3948. +
  3949. + ipts_dbg(ipts, "try sensor mode = %ld\n", val);
  3950. +
  3951. + switch (val) {
  3952. + case TOUCH_SENSOR_MODE_HID:
  3953. + break;
  3954. + case TOUCH_SENSOR_MODE_RAW_DATA:
  3955. + break;
  3956. + default:
  3957. + ipts_err(ipts, "sensor mode %ld is not supported\n", val);
  3958. + }
  3959. +
  3960. + return count;
  3961. +}
  3962. +
  3963. +static ssize_t device_info_show(struct device *dev,
  3964. + struct device_attribute *attr, char *buf)
  3965. +{
  3966. + ipts_info_t *ipts;
  3967. +
  3968. + ipts = dev_get_drvdata(dev);
  3969. + return sprintf(buf, "vendor id = 0x%04hX\n"
  3970. + "device id = 0x%04hX\n"
  3971. + "HW rev = 0x%08X\n"
  3972. + "firmware rev = 0x%08X\n",
  3973. + ipts->device_info.vendor_id, ipts->device_info.device_id,
  3974. + ipts->device_info.hw_rev, ipts->device_info.fw_rev);
  3975. +}
  3976. +
  3977. +static DEVICE_ATTR_RW(sensor_mode);
  3978. +static DEVICE_ATTR_RO(device_info);
  3979. +
  3980. +static struct attribute *ipts_attrs[] = {
  3981. + &dev_attr_sensor_mode.attr,
  3982. + &dev_attr_device_info.attr,
  3983. + NULL
  3984. +};
  3985. +
  3986. +static const struct attribute_group ipts_grp = {
  3987. + .attrs = ipts_attrs,
  3988. +};
  3989. +
  3990. +MODULE_DEVICE_TABLE(mei, ipts_mei_cl_tbl);
  3991. +
  3992. +static void raw_data_work_func(struct work_struct *work)
  3993. +{
  3994. + ipts_info_t *ipts = container_of(work, ipts_info_t, raw_data_work);
  3995. +
  3996. + ipts_handle_processed_data(ipts);
  3997. +}
  3998. +
  3999. +static void gfx_status_work_func(struct work_struct *work)
  4000. +{
  4001. + ipts_info_t *ipts = container_of(work, ipts_info_t, gfx_status_work);
  4002. + ipts_state_t state;
  4003. + int status = ipts->gfx_status;
  4004. +
  4005. + ipts_dbg(ipts, "notify gfx status : %d\n", status);
  4006. +
  4007. + state = ipts_get_state(ipts);
  4008. +
  4009. + if (state == IPTS_STA_RAW_DATA_STARTED || state == IPTS_STA_HID_STARTED) {
  4010. + if (status == IPTS_NOTIFY_STA_BACKLIGHT_ON &&
  4011. + ipts->display_status == false) {
  4012. + ipts_send_sensor_clear_mem_window_cmd(ipts);
  4013. + ipts->display_status = true;
  4014. + } else if (status == IPTS_NOTIFY_STA_BACKLIGHT_OFF &&
  4015. + ipts->display_status == true) {
  4016. + ipts_send_sensor_quiesce_io_cmd(ipts);
  4017. + ipts->display_status = false;
  4018. + }
  4019. + }
  4020. +}
  4021. +
  4022. +/* event loop */
  4023. +static int ipts_mei_cl_event_thread(void *data)
  4024. +{
  4025. + ipts_info_t *ipts = (ipts_info_t *)data;
  4026. + struct mei_cl_device *cldev = ipts->cldev;
  4027. + ssize_t msg_len;
  4028. + touch_sensor_msg_m2h_t m2h_msg;
  4029. +
  4030. + while (!kthread_should_stop()) {
  4031. + msg_len = mei_cldev_recv(cldev, (u8*)&m2h_msg, sizeof(m2h_msg));
  4032. + if (msg_len <= 0) {
  4033. + ipts_err(ipts, "error in reading m2h msg\n");
  4034. + continue;
  4035. + }
  4036. +
  4037. + if (ipts_handle_resp(ipts, &m2h_msg, msg_len) != 0) {
  4038. + ipts_err(ipts, "error in handling resp msg\n");
  4039. + }
  4040. + }
  4041. +
  4042. + ipts_dbg(ipts, "!! end event loop !!\n");
  4043. +
  4044. + return 0;
  4045. +}
  4046. +
  4047. +static void init_work_func(struct work_struct *work)
  4048. +{
  4049. + ipts_info_t *ipts = container_of(work, ipts_info_t, init_work);
  4050. +
  4051. + ipts->sensor_mode = TOUCH_SENSOR_MODE_RAW_DATA;
  4052. + ipts->display_status = true;
  4053. +
  4054. + ipts_start(ipts);
  4055. +}
  4056. +
  4057. +static int ipts_mei_cl_probe(struct mei_cl_device *cldev,
  4058. + const struct mei_cl_device_id *id)
  4059. +{
  4060. + int ret = 0;
  4061. + ipts_info_t *ipts = NULL;
  4062. +
  4063. + pr_info("probing Intel Precise Touch & Stylus\n");
  4064. +
  4065. + // setup the DMA BIT mask, the system will choose the best possible
  4066. + if (dma_coerce_mask_and_coherent(&cldev->dev, DMA_BIT_MASK(64)) == 0) {
  4067. + pr_info("IPTS using DMA_BIT_MASK(64)\n");
  4068. + } else if (dma_coerce_mask_and_coherent(&cldev->dev,
  4069. + DMA_BIT_MASK(32)) == 0) {
  4070. + pr_info("IPTS using DMA_BIT_MASK(32)\n");
  4071. + } else {
  4072. + pr_err("IPTS: No suitable DMA available\n");
  4073. + return -EFAULT;
  4074. + }
  4075. +
  4076. + ret = mei_cldev_enable(cldev);
  4077. + if (ret < 0) {
  4078. + pr_err("cannot enable IPTS\n");
  4079. + return ret;
  4080. + }
  4081. +
  4082. + ipts = devm_kzalloc(&cldev->dev, sizeof(ipts_info_t), GFP_KERNEL);
  4083. + if (ipts == NULL) {
  4084. + ret = -ENOMEM;
  4085. + goto disable_mei;
  4086. + }
  4087. + ipts->cldev = cldev;
  4088. + mei_cldev_set_drvdata(cldev, ipts);
  4089. +
  4090. + ipts->event_loop = kthread_run(ipts_mei_cl_event_thread, (void*)ipts,
  4091. + "ipts_event_thread");
  4092. +
  4093. + if(ipts_dbgfs_register(ipts, "ipts"))
  4094. + pr_debug("cannot register debugfs for IPTS\n");
  4095. +
  4096. + INIT_WORK(&ipts->init_work, init_work_func);
  4097. + INIT_WORK(&ipts->raw_data_work, raw_data_work_func);
  4098. + INIT_WORK(&ipts->gfx_status_work, gfx_status_work_func);
  4099. +
  4100. + ret = sysfs_create_group(&cldev->dev.kobj, &ipts_grp);
  4101. + if (ret != 0) {
  4102. + pr_debug("cannot create sysfs for IPTS\n");
  4103. + }
  4104. +
  4105. + schedule_work(&ipts->init_work);
  4106. +
  4107. + return 0;
  4108. +
  4109. +disable_mei :
  4110. + mei_cldev_disable(cldev);
  4111. +
  4112. + return ret;
  4113. +}
  4114. +
  4115. +static int ipts_mei_cl_remove(struct mei_cl_device *cldev)
  4116. +{
  4117. + ipts_info_t *ipts = mei_cldev_get_drvdata(cldev);
  4118. +
  4119. + ipts_stop(ipts);
  4120. +
  4121. + sysfs_remove_group(&cldev->dev.kobj, &ipts_grp);
  4122. + ipts_hid_release(ipts);
  4123. + ipts_dbgfs_deregister(ipts);
  4124. + mei_cldev_disable(cldev);
  4125. +
  4126. + kthread_stop(ipts->event_loop);
  4127. +
  4128. + pr_info("IPTS removed\n");
  4129. +
  4130. + return 0;
  4131. +}
  4132. +
  4133. +static struct mei_cl_driver ipts_mei_cl_driver = {
  4134. + .id_table = ipts_mei_cl_tbl,
  4135. + .name = IPTS_DRIVER_NAME,
  4136. + .probe = ipts_mei_cl_probe,
  4137. + .remove = ipts_mei_cl_remove,
  4138. +};
  4139. +
  4140. +static int ipts_mei_cl_init(void)
  4141. +{
  4142. + int ret;
  4143. +
  4144. + pr_info("IPTS %s() is called\n", __func__);
  4145. +
  4146. + ret = mei_cldev_driver_register(&ipts_mei_cl_driver);
  4147. + if (ret) {
  4148. + pr_err("unable to register IPTS mei client driver\n");
  4149. + return ret;
  4150. + }
  4151. +
  4152. + return 0;
  4153. +}
  4154. +
  4155. +static void __exit ipts_mei_cl_exit(void)
  4156. +{
  4157. + pr_info("IPTS %s() is called\n", __func__);
  4158. +
  4159. + mei_cldev_driver_unregister(&ipts_mei_cl_driver);
  4160. +}
  4161. +
  4162. +module_init(ipts_mei_cl_init);
  4163. +module_exit(ipts_mei_cl_exit);
  4164. +
  4165. +MODULE_DESCRIPTION
  4166. + ("Intel(R) Management Engine Interface Client Driver for "\
  4167. + "Intel Precision Touch and Sylus");
  4168. +MODULE_LICENSE("GPL");
  4169. diff --git a/drivers/misc/ipts/ipts-msg-handler.c b/drivers/misc/ipts/ipts-msg-handler.c
  4170. new file mode 100644
  4171. index 000000000000..1396ecc7197f
  4172. --- /dev/null
  4173. +++ b/drivers/misc/ipts/ipts-msg-handler.c
  4174. @@ -0,0 +1,431 @@
  4175. +#include <linux/mei_cl_bus.h>
  4176. +
  4177. +#include "ipts.h"
  4178. +#include "ipts-hid.h"
  4179. +#include "ipts-resource.h"
  4180. +#include "ipts-mei-msgs.h"
  4181. +
  4182. +int ipts_handle_cmd(ipts_info_t *ipts, u32 cmd, void *data, int data_size)
  4183. +{
  4184. + int ret = 0;
  4185. + touch_sensor_msg_h2m_t h2m_msg;
  4186. + int len = 0;
  4187. +
  4188. + memset(&h2m_msg, 0, sizeof(h2m_msg));
  4189. +
  4190. + h2m_msg.command_code = cmd;
  4191. + len = sizeof(h2m_msg.command_code) + data_size;
  4192. + if (data != NULL && data_size != 0)
  4193. + memcpy(&h2m_msg.h2m_data, data, data_size); /* copy payload */
  4194. +
  4195. + ret = mei_cldev_send(ipts->cldev, (u8*)&h2m_msg, len);
  4196. + if (ret < 0) {
  4197. + ipts_err(ipts, "mei_cldev_send() error 0x%X:%d\n",
  4198. + cmd, ret);
  4199. + return ret;
  4200. + }
  4201. +
  4202. + return 0;
  4203. +}
  4204. +
  4205. +int ipts_send_feedback(ipts_info_t *ipts, int buffer_idx, u32 transaction_id)
  4206. +{
  4207. + int ret;
  4208. + int cmd_len;
  4209. + touch_sensor_feedback_ready_cmd_data_t fb_ready_cmd;
  4210. +
  4211. + cmd_len = sizeof(touch_sensor_feedback_ready_cmd_data_t);
  4212. + memset(&fb_ready_cmd, 0, cmd_len);
  4213. +
  4214. + fb_ready_cmd.feedback_index = buffer_idx;
  4215. + fb_ready_cmd.transaction_id = transaction_id;
  4216. +
  4217. + ret = ipts_handle_cmd(ipts, TOUCH_SENSOR_FEEDBACK_READY_CMD,
  4218. + &fb_ready_cmd, cmd_len);
  4219. +
  4220. + return ret;
  4221. +}
  4222. +
  4223. +int ipts_send_sensor_quiesce_io_cmd(ipts_info_t *ipts)
  4224. +{
  4225. + int ret;
  4226. + int cmd_len;
  4227. + touch_sensor_quiesce_io_cmd_data_t quiesce_io_cmd;
  4228. +
  4229. + cmd_len = sizeof(touch_sensor_quiesce_io_cmd_data_t);
  4230. + memset(&quiesce_io_cmd, 0, cmd_len);
  4231. +
  4232. + ret = ipts_handle_cmd(ipts, TOUCH_SENSOR_QUIESCE_IO_CMD,
  4233. + &quiesce_io_cmd, cmd_len);
  4234. +
  4235. + return ret;
  4236. +}
  4237. +
  4238. +int ipts_send_sensor_hid_ready_for_data_cmd(ipts_info_t *ipts)
  4239. +{
  4240. + return ipts_handle_cmd(ipts, TOUCH_SENSOR_HID_READY_FOR_DATA_CMD, NULL, 0);
  4241. +}
  4242. +
  4243. +int ipts_send_sensor_clear_mem_window_cmd(ipts_info_t *ipts)
  4244. +{
  4245. + return ipts_handle_cmd(ipts, TOUCH_SENSOR_CLEAR_MEM_WINDOW_CMD, NULL, 0);
  4246. +}
  4247. +
  4248. +static int check_validity(touch_sensor_msg_m2h_t *m2h_msg, u32 msg_len)
  4249. +{
  4250. + int ret = 0;
  4251. + int valid_msg_len = sizeof(m2h_msg->command_code);
  4252. + u32 cmd_code = m2h_msg->command_code;
  4253. +
  4254. + switch (cmd_code) {
  4255. + case TOUCH_SENSOR_SET_MODE_RSP:
  4256. + valid_msg_len +=
  4257. + sizeof(touch_sensor_set_mode_rsp_data_t);
  4258. + break;
  4259. + case TOUCH_SENSOR_SET_MEM_WINDOW_RSP:
  4260. + valid_msg_len +=
  4261. + sizeof(touch_sensor_set_mem_window_rsp_data_t);
  4262. + break;
  4263. + case TOUCH_SENSOR_QUIESCE_IO_RSP:
  4264. + valid_msg_len +=
  4265. + sizeof(touch_sensor_quiesce_io_rsp_data_t);
  4266. + break;
  4267. + case TOUCH_SENSOR_HID_READY_FOR_DATA_RSP:
  4268. + valid_msg_len +=
  4269. + sizeof(touch_sensor_hid_ready_for_data_rsp_data_t);
  4270. + break;
  4271. + case TOUCH_SENSOR_FEEDBACK_READY_RSP:
  4272. + valid_msg_len +=
  4273. + sizeof(touch_sensor_feedback_ready_rsp_data_t);
  4274. + break;
  4275. + case TOUCH_SENSOR_CLEAR_MEM_WINDOW_RSP:
  4276. + valid_msg_len +=
  4277. + sizeof(touch_sensor_clear_mem_window_rsp_data_t);
  4278. + break;
  4279. + case TOUCH_SENSOR_NOTIFY_DEV_READY_RSP:
  4280. + valid_msg_len +=
  4281. + sizeof(touch_sensor_notify_dev_ready_rsp_data_t);
  4282. + break;
  4283. + case TOUCH_SENSOR_SET_POLICIES_RSP:
  4284. + valid_msg_len +=
  4285. + sizeof(touch_sensor_set_policies_rsp_data_t);
  4286. + break;
  4287. + case TOUCH_SENSOR_GET_POLICIES_RSP:
  4288. + valid_msg_len +=
  4289. + sizeof(touch_sensor_get_policies_rsp_data_t);
  4290. + break;
  4291. + case TOUCH_SENSOR_RESET_RSP:
  4292. + valid_msg_len +=
  4293. + sizeof(touch_sensor_reset_rsp_data_t);
  4294. + break;
  4295. + }
  4296. +
  4297. + if (valid_msg_len != msg_len) {
  4298. + return -EINVAL;
  4299. + }
  4300. +
  4301. + return ret;
  4302. +}
  4303. +
  4304. +int ipts_start(ipts_info_t *ipts)
  4305. +{
  4306. + int ret = 0;
  4307. + /* TODO : check if we need to do SET_POLICIES_CMD
  4308. + we need to do this when protocol version doesn't match with reported one
  4309. + how we keep vendor specific data is the first thing to solve */
  4310. +
  4311. + ipts_set_state(ipts, IPTS_STA_INIT);
  4312. + ipts->num_of_parallel_data_buffers = TOUCH_SENSOR_MAX_DATA_BUFFERS;
  4313. +
  4314. + ipts->sensor_mode = TOUCH_SENSOR_MODE_RAW_DATA; /* start with RAW_DATA */
  4315. +
  4316. + ret = ipts_handle_cmd(ipts, TOUCH_SENSOR_NOTIFY_DEV_READY_CMD, NULL, 0);
  4317. +
  4318. + return ret;
  4319. +}
  4320. +
  4321. +void ipts_stop(ipts_info_t *ipts)
  4322. +{
  4323. + ipts_state_t old_state;
  4324. +
  4325. + old_state = ipts_get_state(ipts);
  4326. + ipts_set_state(ipts, IPTS_STA_STOPPING);
  4327. +
  4328. + if (old_state < IPTS_STA_RESOURCE_READY)
  4329. + return;
  4330. +
  4331. + if (old_state == IPTS_STA_RAW_DATA_STARTED ||
  4332. + old_state == IPTS_STA_HID_STARTED) {
  4333. + ipts_free_default_resource(ipts);
  4334. + ipts_free_raw_data_resource(ipts);
  4335. +
  4336. + return;
  4337. + }
  4338. +}
  4339. +
  4340. +int ipts_restart(ipts_info_t *ipts)
  4341. +{
  4342. + int ret = 0;
  4343. +
  4344. + ipts_dbg(ipts, "ipts restart\n");
  4345. +
  4346. + ipts_stop(ipts);
  4347. +
  4348. + ipts->retry++;
  4349. + if (ipts->retry == IPTS_MAX_RETRY &&
  4350. + ipts->sensor_mode == TOUCH_SENSOR_MODE_RAW_DATA) {
  4351. + /* try with HID mode */
  4352. + ipts->sensor_mode = TOUCH_SENSOR_MODE_HID;
  4353. + } else if (ipts->retry > IPTS_MAX_RETRY) {
  4354. + return -EPERM;
  4355. + }
  4356. +
  4357. + ipts_send_sensor_quiesce_io_cmd(ipts);
  4358. + ipts->restart = true;
  4359. +
  4360. + return ret;
  4361. +}
  4362. +
  4363. +int ipts_switch_sensor_mode(ipts_info_t *ipts, int new_sensor_mode)
  4364. +{
  4365. + int ret = 0;
  4366. +
  4367. + ipts->new_sensor_mode = new_sensor_mode;
  4368. + ipts->switch_sensor_mode = true;
  4369. + ret = ipts_send_sensor_quiesce_io_cmd(ipts);
  4370. +
  4371. + return ret;
  4372. +}
  4373. +
  4374. +#define rsp_failed(ipts, cmd, status) ipts_err(ipts, \
  4375. + "0x%08x failed status = %d\n", cmd, status);
  4376. +
  4377. +int ipts_handle_resp(ipts_info_t *ipts, touch_sensor_msg_m2h_t *m2h_msg,
  4378. + u32 msg_len)
  4379. +{
  4380. + int ret = 0;
  4381. + int rsp_status = 0;
  4382. + int cmd_status = 0;
  4383. + int cmd_len = 0;
  4384. + u32 cmd;
  4385. +
  4386. + if (!check_validity(m2h_msg, msg_len)) {
  4387. + ipts_err(ipts, "wrong rsp\n");
  4388. + return -EINVAL;
  4389. + }
  4390. +
  4391. + rsp_status = m2h_msg->status;
  4392. + cmd = m2h_msg->command_code;
  4393. +
  4394. + switch (cmd) {
  4395. + case TOUCH_SENSOR_NOTIFY_DEV_READY_RSP:
  4396. + if (rsp_status != 0 &&
  4397. + rsp_status != TOUCH_STATUS_SENSOR_FAIL_NONFATAL) {
  4398. + rsp_failed(ipts, cmd, rsp_status);
  4399. + break;
  4400. + }
  4401. +
  4402. + cmd_status = ipts_handle_cmd(ipts,
  4403. + TOUCH_SENSOR_GET_DEVICE_INFO_CMD,
  4404. + NULL, 0);
  4405. + break;
  4406. + case TOUCH_SENSOR_GET_DEVICE_INFO_RSP:
  4407. + if (rsp_status != 0 &&
  4408. + rsp_status != TOUCH_STATUS_COMPAT_CHECK_FAIL) {
  4409. + rsp_failed(ipts, cmd, rsp_status);
  4410. + break;
  4411. + }
  4412. +
  4413. + memcpy(&ipts->device_info,
  4414. + &m2h_msg->m2h_data.device_info_rsp_data,
  4415. + sizeof(touch_sensor_get_device_info_rsp_data_t));
  4416. +
  4417. + /*
  4418. + TODO : support raw_request during HID init.
  4419. + Although HID init happens here, technically most of
  4420. + reports (for both direction) can be issued only
  4421. + after SET_MEM_WINDOWS_CMD since they may require
  4422. + ME or touch IC. If ipts vendor requires raw_request
  4423. + during HID init, we need to consider to move HID init.
  4424. + */
  4425. + if (ipts->hid_desc_ready == false) {
  4426. + ret = ipts_hid_init(ipts);
  4427. + if (ret)
  4428. + break;
  4429. + }
  4430. +
  4431. + cmd_status = ipts_send_sensor_clear_mem_window_cmd(ipts);
  4432. +
  4433. + break;
  4434. + case TOUCH_SENSOR_CLEAR_MEM_WINDOW_RSP:
  4435. + {
  4436. + touch_sensor_set_mode_cmd_data_t sensor_mode_cmd;
  4437. +
  4438. + if (rsp_status != 0 &&
  4439. + rsp_status != TOUCH_STATUS_TIMEOUT) {
  4440. + rsp_failed(ipts, cmd, rsp_status);
  4441. + break;
  4442. + }
  4443. +
  4444. + /* allocate default resource : common & hid only */
  4445. + if (!ipts_is_default_resource_ready(ipts)) {
  4446. + ret = ipts_allocate_default_resource(ipts);
  4447. + if (ret)
  4448. + break;
  4449. + }
  4450. +
  4451. + if (ipts->sensor_mode == TOUCH_SENSOR_MODE_RAW_DATA &&
  4452. + !ipts_is_raw_data_resource_ready(ipts)) {
  4453. + ret = ipts_allocate_raw_data_resource(ipts);
  4454. + if (ret) {
  4455. + ipts_free_default_resource(ipts);
  4456. + break;
  4457. + }
  4458. + }
  4459. +
  4460. + ipts_set_state(ipts, IPTS_STA_RESOURCE_READY);
  4461. +
  4462. + cmd_len = sizeof(touch_sensor_set_mode_cmd_data_t);
  4463. + memset(&sensor_mode_cmd, 0, cmd_len);
  4464. + sensor_mode_cmd.sensor_mode = ipts->sensor_mode;
  4465. + cmd_status = ipts_handle_cmd(ipts,
  4466. + TOUCH_SENSOR_SET_MODE_CMD,
  4467. + &sensor_mode_cmd, cmd_len);
  4468. + break;
  4469. + }
  4470. + case TOUCH_SENSOR_SET_MODE_RSP:
  4471. + {
  4472. + touch_sensor_set_mem_window_cmd_data_t smw_cmd;
  4473. +
  4474. + if (rsp_status != 0) {
  4475. + rsp_failed(ipts, cmd, rsp_status);
  4476. + break;
  4477. + }
  4478. +
  4479. + cmd_len = sizeof(touch_sensor_set_mem_window_cmd_data_t);
  4480. + memset(&smw_cmd, 0, cmd_len);
  4481. + ipts_get_set_mem_window_cmd_data(ipts, &smw_cmd);
  4482. + cmd_status = ipts_handle_cmd(ipts,
  4483. + TOUCH_SENSOR_SET_MEM_WINDOW_CMD,
  4484. + &smw_cmd, cmd_len);
  4485. + break;
  4486. + }
  4487. + case TOUCH_SENSOR_SET_MEM_WINDOW_RSP:
  4488. + if (rsp_status != 0) {
  4489. + rsp_failed(ipts, cmd, rsp_status);
  4490. + break;
  4491. + }
  4492. +
  4493. + cmd_status = ipts_send_sensor_hid_ready_for_data_cmd(ipts);
  4494. + if (cmd_status)
  4495. + break;
  4496. +
  4497. + if (ipts->sensor_mode == TOUCH_SENSOR_MODE_HID) {
  4498. + ipts_set_state(ipts, IPTS_STA_HID_STARTED);
  4499. + } else if (ipts->sensor_mode == TOUCH_SENSOR_MODE_RAW_DATA) {
  4500. + ipts_set_state(ipts, IPTS_STA_RAW_DATA_STARTED);
  4501. + }
  4502. +
  4503. + ipts_err(ipts, "touch enabled %d\n", ipts_get_state(ipts));
  4504. +
  4505. + break;
  4506. + case TOUCH_SENSOR_HID_READY_FOR_DATA_RSP:
  4507. + {
  4508. + touch_sensor_hid_ready_for_data_rsp_data_t *hid_data;
  4509. + ipts_state_t state;
  4510. +
  4511. + if (rsp_status != 0 &&
  4512. + rsp_status != TOUCH_STATUS_SENSOR_DISABLED) {
  4513. + rsp_failed(ipts, cmd, rsp_status);
  4514. + break;
  4515. + }
  4516. +
  4517. + state = ipts_get_state(ipts);
  4518. + if (ipts->sensor_mode == TOUCH_SENSOR_MODE_HID &&
  4519. + state == IPTS_STA_HID_STARTED) {
  4520. +
  4521. + hid_data = &m2h_msg->m2h_data.hid_ready_for_data_rsp_data;
  4522. +
  4523. + /* HID mode only uses buffer 0 */
  4524. + if (hid_data->touch_data_buffer_index != 0)
  4525. + break;
  4526. +
  4527. + /* handle hid data */
  4528. + ipts_handle_hid_data(ipts, hid_data);
  4529. + }
  4530. +
  4531. + break;
  4532. + }
  4533. + case TOUCH_SENSOR_FEEDBACK_READY_RSP:
  4534. + if (rsp_status != 0 &&
  4535. + rsp_status != TOUCH_STATUS_COMPAT_CHECK_FAIL) {
  4536. + rsp_failed(ipts, cmd, rsp_status);
  4537. + break;
  4538. + }
  4539. +
  4540. + if (m2h_msg->m2h_data.feedback_ready_rsp_data.
  4541. + feedback_index == TOUCH_HID_2_ME_BUFFER_ID)
  4542. + break;
  4543. +
  4544. + if (ipts->sensor_mode == TOUCH_SENSOR_MODE_HID) {
  4545. + cmd_status = ipts_handle_cmd(ipts,
  4546. + TOUCH_SENSOR_HID_READY_FOR_DATA_CMD,
  4547. + NULL, 0);
  4548. + }
  4549. +
  4550. + /* reset retry since we are getting touch data */
  4551. + ipts->retry = 0;
  4552. +
  4553. + break;
  4554. + case TOUCH_SENSOR_QUIESCE_IO_RSP:
  4555. + {
  4556. + ipts_state_t state;
  4557. +
  4558. + if (rsp_status != 0) {
  4559. + rsp_failed(ipts, cmd, rsp_status);
  4560. + break;
  4561. + }
  4562. +
  4563. + state = ipts_get_state(ipts);
  4564. + if (state == IPTS_STA_STOPPING && ipts->restart) {
  4565. + ipts_dbg(ipts, "restart\n");
  4566. + ipts_start(ipts);
  4567. + ipts->restart = 0;
  4568. + break;
  4569. + }
  4570. +
  4571. + /* support sysfs debug node for switch sensor mode */
  4572. + if (ipts->switch_sensor_mode) {
  4573. + ipts_set_state(ipts, IPTS_STA_INIT);
  4574. + ipts->sensor_mode = ipts->new_sensor_mode;
  4575. + ipts->switch_sensor_mode = false;
  4576. +
  4577. + ipts_send_sensor_clear_mem_window_cmd(ipts);
  4578. + }
  4579. +
  4580. + break;
  4581. + }
  4582. + }
  4583. +
  4584. + /* handle error in rsp_status */
  4585. + if (rsp_status != 0) {
  4586. + switch (rsp_status) {
  4587. + case TOUCH_STATUS_SENSOR_EXPECTED_RESET:
  4588. + case TOUCH_STATUS_SENSOR_UNEXPECTED_RESET:
  4589. + ipts_dbg(ipts, "sensor reset %d\n", rsp_status);
  4590. + ipts_restart(ipts);
  4591. + break;
  4592. + default:
  4593. + ipts_dbg(ipts, "cmd : 0x%08x, status %d\n",
  4594. + cmd,
  4595. + rsp_status);
  4596. + break;
  4597. + }
  4598. + }
  4599. +
  4600. + if (cmd_status) {
  4601. + ipts_restart(ipts);
  4602. + }
  4603. +
  4604. + return ret;
  4605. +}
  4606. diff --git a/drivers/misc/ipts/ipts-msg-handler.h b/drivers/misc/ipts/ipts-msg-handler.h
  4607. new file mode 100644
  4608. index 000000000000..b8e27d30c63e
  4609. --- /dev/null
  4610. +++ b/drivers/misc/ipts/ipts-msg-handler.h
  4611. @@ -0,0 +1,32 @@
  4612. +/*
  4613. + *
  4614. + * Intel Precise Touch & Stylus ME message handler
  4615. + * Copyright (c) 2016, Intel Corporation.
  4616. + *
  4617. + * This program is free software; you can redistribute it and/or modify it
  4618. + * under the terms and conditions of the GNU General Public License,
  4619. + * version 2, as published by the Free Software Foundation.
  4620. + *
  4621. + * This program is distributed in the hope it will be useful, but WITHOUT
  4622. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  4623. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  4624. + * more details.
  4625. + *
  4626. + */
  4627. +
  4628. +#ifndef _IPTS_MSG_HANDLER_H
  4629. +#define _IPTS_MSG_HANDLER_H
  4630. +
  4631. +int ipts_handle_cmd(ipts_info_t *ipts, u32 cmd, void *data, int data_size);
  4632. +int ipts_start(ipts_info_t *ipts);
  4633. +void ipts_stop(ipts_info_t *ipts);
  4634. +int ipts_switch_sensor_mode(ipts_info_t *ipts, int new_sensor_mode);
  4635. +int ipts_handle_resp(ipts_info_t *ipts, touch_sensor_msg_m2h_t *m2h_msg,
  4636. + u32 msg_len);
  4637. +int ipts_handle_processed_data(ipts_info_t *ipts);
  4638. +int ipts_send_feedback(ipts_info_t *ipts, int buffer_idx, u32 transaction_id);
  4639. +int ipts_send_sensor_quiesce_io_cmd(ipts_info_t *ipts);
  4640. +int ipts_send_sensor_hid_ready_for_data_cmd(ipts_info_t *ipts);
  4641. +int ipts_send_sensor_clear_mem_window_cmd(ipts_info_t *ipts);
  4642. +
  4643. +#endif /* _IPTS_MSG_HANDLER_H */
  4644. diff --git a/drivers/misc/ipts/ipts-resource.c b/drivers/misc/ipts/ipts-resource.c
  4645. new file mode 100644
  4646. index 000000000000..47607ef7c461
  4647. --- /dev/null
  4648. +++ b/drivers/misc/ipts/ipts-resource.c
  4649. @@ -0,0 +1,277 @@
  4650. +#include <linux/dma-mapping.h>
  4651. +
  4652. +#include "ipts.h"
  4653. +#include "ipts-mei-msgs.h"
  4654. +#include "ipts-kernel.h"
  4655. +
  4656. +static void free_common_resource(ipts_info_t *ipts)
  4657. +{
  4658. + char *addr;
  4659. + ipts_buffer_info_t *feedback_buffer;
  4660. + dma_addr_t dma_addr;
  4661. + u32 buffer_size;
  4662. + int i, num_of_parallels;
  4663. +
  4664. + if (ipts->resource.me2hid_buffer) {
  4665. + devm_kfree(&ipts->cldev->dev, ipts->resource.me2hid_buffer);
  4666. + ipts->resource.me2hid_buffer = 0;
  4667. + }
  4668. +
  4669. + addr = ipts->resource.hid2me_buffer.addr;
  4670. + dma_addr = ipts->resource.hid2me_buffer.dma_addr;
  4671. + buffer_size = ipts->resource.hid2me_buffer_size;
  4672. +
  4673. + if (ipts->resource.hid2me_buffer.addr) {
  4674. + dmam_free_coherent(&ipts->cldev->dev, buffer_size, addr, dma_addr);
  4675. + ipts->resource.hid2me_buffer.addr = 0;
  4676. + ipts->resource.hid2me_buffer.dma_addr = 0;
  4677. + ipts->resource.hid2me_buffer_size = 0;
  4678. + }
  4679. +
  4680. + feedback_buffer = ipts->resource.feedback_buffer;
  4681. + num_of_parallels = ipts_get_num_of_parallel_buffers(ipts);
  4682. + for (i = 0; i < num_of_parallels; i++) {
  4683. + if (feedback_buffer[i].addr) {
  4684. + dmam_free_coherent(&ipts->cldev->dev,
  4685. + ipts->device_info.feedback_size,
  4686. + feedback_buffer[i].addr,
  4687. + feedback_buffer[i].dma_addr);
  4688. + feedback_buffer[i].addr = 0;
  4689. + feedback_buffer[i].dma_addr = 0;
  4690. + }
  4691. + }
  4692. +}
  4693. +
  4694. +static int allocate_common_resource(ipts_info_t *ipts)
  4695. +{
  4696. + char *addr, *me2hid_addr;
  4697. + ipts_buffer_info_t *feedback_buffer;
  4698. + dma_addr_t dma_addr;
  4699. + int i, ret = 0, num_of_parallels;
  4700. + u32 buffer_size;
  4701. +
  4702. + buffer_size = ipts->device_info.feedback_size;
  4703. +
  4704. + addr = dmam_alloc_coherent(&ipts->cldev->dev,
  4705. + buffer_size,
  4706. + &dma_addr,
  4707. + GFP_ATOMIC|__GFP_ZERO);
  4708. + if (addr == NULL)
  4709. + return -ENOMEM;
  4710. +
  4711. + me2hid_addr = devm_kzalloc(&ipts->cldev->dev, buffer_size, GFP_KERNEL);
  4712. + if (me2hid_addr == NULL) {
  4713. + ret = -ENOMEM;
  4714. + goto release_resource;
  4715. + }
  4716. +
  4717. + ipts->resource.hid2me_buffer.addr = addr;
  4718. + ipts->resource.hid2me_buffer.dma_addr = dma_addr;
  4719. + ipts->resource.hid2me_buffer_size = buffer_size;
  4720. + ipts->resource.me2hid_buffer = me2hid_addr;
  4721. +
  4722. + feedback_buffer = ipts->resource.feedback_buffer;
  4723. + num_of_parallels = ipts_get_num_of_parallel_buffers(ipts);
  4724. + for (i = 0; i < num_of_parallels; i++) {
  4725. + feedback_buffer[i].addr = dmam_alloc_coherent(&ipts->cldev->dev,
  4726. + ipts->device_info.feedback_size,
  4727. + &feedback_buffer[i].dma_addr,
  4728. + GFP_ATOMIC|__GFP_ZERO);
  4729. +
  4730. + if (feedback_buffer[i].addr == NULL) {
  4731. + ret = -ENOMEM;
  4732. + goto release_resource;
  4733. + }
  4734. + }
  4735. +
  4736. + return 0;
  4737. +
  4738. +release_resource:
  4739. + free_common_resource(ipts);
  4740. +
  4741. + return ret;
  4742. +}
  4743. +
  4744. +void ipts_free_raw_data_resource(ipts_info_t *ipts)
  4745. +{
  4746. + if (ipts_is_raw_data_resource_ready(ipts)) {
  4747. + ipts->resource.raw_data_resource_ready = false;
  4748. +
  4749. + ipts_release_kernels(ipts);
  4750. + }
  4751. +}
  4752. +
  4753. +static int allocate_hid_resource(ipts_info_t *ipts)
  4754. +{
  4755. + ipts_buffer_info_t *buffer_hid;
  4756. +
  4757. + /* hid mode uses only one touch data buffer */
  4758. + buffer_hid = &ipts->resource.touch_data_buffer_hid;
  4759. + buffer_hid->addr = dmam_alloc_coherent(&ipts->cldev->dev,
  4760. + ipts->device_info.frame_size,
  4761. + &buffer_hid->dma_addr,
  4762. + GFP_ATOMIC|__GFP_ZERO);
  4763. + if (buffer_hid->addr == NULL) {
  4764. + return -ENOMEM;
  4765. + }
  4766. +
  4767. + return 0;
  4768. +}
  4769. +
  4770. +static void free_hid_resource(ipts_info_t *ipts)
  4771. +{
  4772. + ipts_buffer_info_t *buffer_hid;
  4773. +
  4774. + buffer_hid = &ipts->resource.touch_data_buffer_hid;
  4775. + if (buffer_hid->addr) {
  4776. + dmam_free_coherent(&ipts->cldev->dev,
  4777. + ipts->device_info.frame_size,
  4778. + buffer_hid->addr,
  4779. + buffer_hid->dma_addr);
  4780. + buffer_hid->addr = 0;
  4781. + buffer_hid->dma_addr = 0;
  4782. + }
  4783. +}
  4784. +
  4785. +int ipts_allocate_default_resource(ipts_info_t *ipts)
  4786. +{
  4787. + int ret;
  4788. +
  4789. + ret = allocate_common_resource(ipts);
  4790. + if (ret) {
  4791. + ipts_dbg(ipts, "cannot allocate common resource\n");
  4792. + return ret;
  4793. + }
  4794. +
  4795. + ret = allocate_hid_resource(ipts);
  4796. + if (ret) {
  4797. + ipts_dbg(ipts, "cannot allocate hid resource\n");
  4798. + free_common_resource(ipts);
  4799. + return ret;
  4800. + }
  4801. +
  4802. + ipts->resource.default_resource_ready = true;
  4803. +
  4804. + return 0;
  4805. +}
  4806. +
  4807. +void ipts_free_default_resource(ipts_info_t *ipts)
  4808. +{
  4809. + if (ipts_is_default_resource_ready(ipts)) {
  4810. + ipts->resource.default_resource_ready = false;
  4811. +
  4812. + free_hid_resource(ipts);
  4813. + free_common_resource(ipts);
  4814. + }
  4815. +}
  4816. +
  4817. +int ipts_allocate_raw_data_resource(ipts_info_t *ipts)
  4818. +{
  4819. + int ret = 0;
  4820. +
  4821. + ret = ipts_init_kernels(ipts);
  4822. + if (ret) {
  4823. + return ret;
  4824. + }
  4825. +
  4826. + ipts->resource.raw_data_resource_ready = true;
  4827. +
  4828. + return 0;
  4829. +}
  4830. +
  4831. +static void get_hid_only_smw_cmd_data(ipts_info_t *ipts,
  4832. + touch_sensor_set_mem_window_cmd_data_t *data,
  4833. + ipts_resource_t *resrc)
  4834. +{
  4835. + ipts_buffer_info_t *touch_buf;
  4836. + ipts_buffer_info_t *feedback_buf;
  4837. +
  4838. + touch_buf = &resrc->touch_data_buffer_hid;
  4839. + feedback_buf = &resrc->feedback_buffer[0];
  4840. +
  4841. + data->touch_data_buffer_addr_lower[0] =
  4842. + lower_32_bits(touch_buf->dma_addr);
  4843. + data->touch_data_buffer_addr_upper[0] =
  4844. + upper_32_bits(touch_buf->dma_addr);
  4845. + data->feedback_buffer_addr_lower[0] =
  4846. + lower_32_bits(feedback_buf->dma_addr);
  4847. + data->feedback_buffer_addr_upper[0] =
  4848. + upper_32_bits(feedback_buf->dma_addr);
  4849. +}
  4850. +
  4851. +static void get_raw_data_only_smw_cmd_data(ipts_info_t *ipts,
  4852. + touch_sensor_set_mem_window_cmd_data_t *data,
  4853. + ipts_resource_t *resrc)
  4854. +{
  4855. + u64 wq_tail_phy_addr;
  4856. + u64 cookie_phy_addr;
  4857. + ipts_buffer_info_t *touch_buf;
  4858. + ipts_buffer_info_t *feedback_buf;
  4859. + int i, num_of_parallels;
  4860. +
  4861. + touch_buf = resrc->touch_data_buffer_raw;
  4862. + feedback_buf = resrc->feedback_buffer;
  4863. +
  4864. + num_of_parallels = ipts_get_num_of_parallel_buffers(ipts);
  4865. + for (i = 0; i < num_of_parallels; i++) {
  4866. + data->touch_data_buffer_addr_lower[i] =
  4867. + lower_32_bits(touch_buf[i].dma_addr);
  4868. + data->touch_data_buffer_addr_upper[i] =
  4869. + upper_32_bits(touch_buf[i].dma_addr);
  4870. + data->feedback_buffer_addr_lower[i] =
  4871. + lower_32_bits(feedback_buf[i].dma_addr);
  4872. + data->feedback_buffer_addr_upper[i] =
  4873. + upper_32_bits(feedback_buf[i].dma_addr);
  4874. + }
  4875. +
  4876. + wq_tail_phy_addr = resrc->wq_info.wq_tail_phy_addr;
  4877. + data->tail_offset_addr_lower = lower_32_bits(wq_tail_phy_addr);
  4878. + data->tail_offset_addr_upper = upper_32_bits(wq_tail_phy_addr);
  4879. +
  4880. + cookie_phy_addr = resrc->wq_info.db_phy_addr +
  4881. + resrc->wq_info.db_cookie_offset;
  4882. + data->doorbell_cookie_addr_lower = lower_32_bits(cookie_phy_addr);
  4883. + data->doorbell_cookie_addr_upper = upper_32_bits(cookie_phy_addr);
  4884. + data->work_queue_size = resrc->wq_info.wq_size;
  4885. +
  4886. + data->work_queue_item_size = resrc->wq_item_size;
  4887. +}
  4888. +
  4889. +void ipts_get_set_mem_window_cmd_data(ipts_info_t *ipts,
  4890. + touch_sensor_set_mem_window_cmd_data_t *data)
  4891. +{
  4892. + ipts_resource_t *resrc = &ipts->resource;
  4893. +
  4894. + if (ipts->sensor_mode == TOUCH_SENSOR_MODE_RAW_DATA)
  4895. + get_raw_data_only_smw_cmd_data(ipts, data, resrc);
  4896. + else if (ipts->sensor_mode == TOUCH_SENSOR_MODE_HID)
  4897. + get_hid_only_smw_cmd_data(ipts, data, resrc);
  4898. +
  4899. + /* hid2me is common for "raw data" and "hid" */
  4900. + data->hid2me_buffer_addr_lower =
  4901. + lower_32_bits(resrc->hid2me_buffer.dma_addr);
  4902. + data->hid2me_buffer_addr_upper =
  4903. + upper_32_bits(resrc->hid2me_buffer.dma_addr);
  4904. + data->hid2me_buffer_size = resrc->hid2me_buffer_size;
  4905. +}
  4906. +
  4907. +void ipts_set_input_buffer(ipts_info_t *ipts, int parallel_idx,
  4908. + u8* cpu_addr, u64 dma_addr)
  4909. +{
  4910. + ipts_buffer_info_t *touch_buf;
  4911. +
  4912. + touch_buf = ipts->resource.touch_data_buffer_raw;
  4913. + touch_buf[parallel_idx].dma_addr = dma_addr;
  4914. + touch_buf[parallel_idx].addr = cpu_addr;
  4915. +}
  4916. +
  4917. +void ipts_set_output_buffer(ipts_info_t *ipts, int parallel_idx, int output_idx,
  4918. + u8* cpu_addr, u64 dma_addr)
  4919. +{
  4920. + ipts_buffer_info_t *output_buf;
  4921. +
  4922. + output_buf = &ipts->resource.raw_data_mode_output_buffer[parallel_idx][output_idx];
  4923. +
  4924. + output_buf->dma_addr = dma_addr;
  4925. + output_buf->addr = cpu_addr;
  4926. +}
  4927. diff --git a/drivers/misc/ipts/ipts-resource.h b/drivers/misc/ipts/ipts-resource.h
  4928. new file mode 100644
  4929. index 000000000000..7d66ac72b475
  4930. --- /dev/null
  4931. +++ b/drivers/misc/ipts/ipts-resource.h
  4932. @@ -0,0 +1,30 @@
  4933. +/*
  4934. + * Intel Precise Touch & Stylus state codes
  4935. + *
  4936. + * Copyright (c) 2016, Intel Corporation.
  4937. + *
  4938. + * This program is free software; you can redistribute it and/or modify it
  4939. + * under the terms and conditions of the GNU General Public License,
  4940. + * version 2, as published by the Free Software Foundation.
  4941. + *
  4942. + * This program is distributed in the hope it will be useful, but WITHOUT
  4943. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  4944. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  4945. + * more details.
  4946. + */
  4947. +
  4948. +#ifndef _IPTS_RESOURCE_H_
  4949. +#define _IPTS_RESOURCE_H_
  4950. +
  4951. +int ipts_allocate_default_resource(ipts_info_t *ipts);
  4952. +void ipts_free_default_resource(ipts_info_t *ipts);
  4953. +int ipts_allocate_raw_data_resource(ipts_info_t *ipts);
  4954. +void ipts_free_raw_data_resource(ipts_info_t *ipts);
  4955. +void ipts_get_set_mem_window_cmd_data(ipts_info_t *ipts,
  4956. + touch_sensor_set_mem_window_cmd_data_t *data);
  4957. +void ipts_set_input_buffer(ipts_info_t *ipts, int parallel_idx,
  4958. + u8* cpu_addr, u64 dma_addr);
  4959. +void ipts_set_output_buffer(ipts_info_t *ipts, int parallel_idx, int output_idx,
  4960. + u8* cpu_addr, u64 dma_addr);
  4961. +
  4962. +#endif // _IPTS_RESOURCE_H_
  4963. diff --git a/drivers/misc/ipts/ipts-sensor-regs.h b/drivers/misc/ipts/ipts-sensor-regs.h
  4964. new file mode 100644
  4965. index 000000000000..96812b0eb980
  4966. --- /dev/null
  4967. +++ b/drivers/misc/ipts/ipts-sensor-regs.h
  4968. @@ -0,0 +1,700 @@
  4969. +/*
  4970. + * Touch Sensor Register definition
  4971. + *
  4972. + * Copyright (c) 2013-2016, Intel Corporation.
  4973. + *
  4974. + * This program is free software; you can redistribute it and/or modify it
  4975. + * under the terms and conditions of the GNU General Public License,
  4976. + * version 2, as published by the Free Software Foundation.
  4977. + *
  4978. + * This program is distributed in the hope it will be useful, but WITHOUT
  4979. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  4980. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  4981. + * more details.
  4982. + */
  4983. +
  4984. +
  4985. +#ifndef _TOUCH_SENSOR_REGS_H
  4986. +#define _TOUCH_SENSOR_REGS_H
  4987. +
  4988. +#pragma pack(1)
  4989. +
  4990. +// define C_ASSERT macro to check structure size and fail compile for unexpected mismatch
  4991. +#ifndef C_ASSERT
  4992. +#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
  4993. +#endif
  4994. +
  4995. +//
  4996. +// Compatibility versions for this header file
  4997. +//
  4998. +#define TOUCH_EDS_REV_MINOR 0
  4999. +#define TOUCH_EDS_REV_MAJOR 1
  5000. +#define TOUCH_EDS_INTF_REV 1
  5001. +#define TOUCH_PROTOCOL_VER 0
  5002. +
  5003. +
  5004. +//
  5005. +// Offset 00h: TOUCH_STS: Status Register
  5006. +// This register is read by the SPI Controller immediately following an interrupt.
  5007. +//
  5008. +#define TOUCH_STS_REG_OFFSET 0x00
  5009. +
  5010. +typedef enum touch_sts_reg_int_type
  5011. +{
  5012. + TOUCH_STS_REG_INT_TYPE_DATA_AVAIL = 0, // Touch Data Available
  5013. + TOUCH_STS_REG_INT_TYPE_RESET_OCCURRED, // Reset Occurred
  5014. + TOUCH_STS_REG_INT_TYPE_ERROR_OCCURRED, // Error Occurred
  5015. + TOUCH_STS_REG_INT_TYPE_VENDOR_DATA, // Vendor specific data, treated same as raw frame
  5016. + TOUCH_STS_REG_INT_TYPE_GET_FEATURES, // Get Features response data available
  5017. + TOUCH_STS_REG_INT_TYPE_MAX
  5018. +} touch_sts_reg_int_type_t;
  5019. +C_ASSERT(sizeof(touch_sts_reg_int_type_t) == 4);
  5020. +
  5021. +typedef enum touch_sts_reg_pwr_state
  5022. +{
  5023. + TOUCH_STS_REG_PWR_STATE_SLEEP = 0, // Sleep
  5024. + TOUCH_STS_REG_PWR_STATE_DOZE, // Doze
  5025. + TOUCH_STS_REG_PWR_STATE_ARMED, // Armed
  5026. + TOUCH_STS_REG_PWR_STATE_SENSING, // Sensing
  5027. + TOUCH_STS_REG_PWR_STATE_MAX
  5028. +} touch_sts_reg_pwr_state_t;
  5029. +C_ASSERT(sizeof(touch_sts_reg_pwr_state_t) == 4);
  5030. +
  5031. +typedef enum touch_sts_reg_init_state
  5032. +{
  5033. + TOUCH_STS_REG_INIT_STATE_READY_FOR_OP = 0, // Ready for normal operation
  5034. + TOUCH_STS_REG_INIT_STATE_FW_NEEDED, // Touch IC needs its Firmware loaded
  5035. + TOUCH_STS_REG_INIT_STATE_DATA_NEEDED, // Touch IC needs its Data loaded
  5036. + TOUCH_STS_REG_INIT_STATE_INIT_ERROR, // Error info in TOUCH_ERR_REG
  5037. + TOUCH_STS_REG_INIT_STATE_MAX
  5038. +} touch_sts_reg_init_state_t;
  5039. +C_ASSERT(sizeof(touch_sts_reg_init_state_t) == 4);
  5040. +
  5041. +#define TOUCH_SYNC_BYTE_VALUE 0x5A
  5042. +
  5043. +typedef union touch_sts_reg
  5044. +{
  5045. + u32 reg_value;
  5046. +
  5047. + struct
  5048. + {
  5049. + // When set, this indicates the hardware has data that needs to be read.
  5050. + u32 int_status :1;
  5051. + // see TOUCH_STS_REG_INT_TYPE
  5052. + u32 int_type :4;
  5053. + // see TOUCH_STS_REG_PWR_STATE
  5054. + u32 pwr_state :2;
  5055. + // see TOUCH_STS_REG_INIT_STATE
  5056. + u32 init_state :2;
  5057. + // Busy bit indicates that sensor cannot accept writes at this time
  5058. + u32 busy :1;
  5059. + // Reserved
  5060. + u32 reserved :14;
  5061. + // Synchronization bit, should always be TOUCH_SYNC_BYTE_VALUE
  5062. + u32 sync_byte :8;
  5063. + } fields;
  5064. +} touch_sts_reg_t;
  5065. +C_ASSERT(sizeof(touch_sts_reg_t) == 4);
  5066. +
  5067. +
  5068. +//
  5069. +// Offset 04h: TOUCH_FRAME_CHAR: Frame Characteristics Register
  5070. +// This registers describes the characteristics of each data frame read by the SPI Controller in
  5071. +// response to a touch interrupt.
  5072. +//
  5073. +#define TOUCH_FRAME_CHAR_REG_OFFSET 0x04
  5074. +
  5075. +typedef union touch_frame_char_reg
  5076. +{
  5077. + u32 reg_value;
  5078. +
  5079. + struct
  5080. + {
  5081. + // Micro-Frame Size (MFS): Indicates the size of a touch micro-frame in byte increments.
  5082. + // When a micro-frame is to be read for processing (in data mode), this is the total number of
  5083. + // bytes that must be read per interrupt, split into multiple read commands no longer than RPS.
  5084. + // Maximum micro-frame size is 256KB.
  5085. + u32 microframe_size :18;
  5086. + // Micro-Frames per Frame (MFPF): Indicates the number of micro-frames per frame. If a
  5087. + // sensor's frame does not contain micro-frames this value will be 1. Valid values are 1-31.
  5088. + u32 microframes_per_frame :5;
  5089. + // Micro-Frame Index (MFI): Indicates the index of the micro-frame within a frame. This allows
  5090. + // the SPI Controller to maintain synchronization with the sensor and determine when the final
  5091. + // micro-frame has arrived. Valid values are 1-31.
  5092. + u32 microframe_index :5;
  5093. + // HID/Raw Data: This bit describes whether the data from the sensor is Raw data or a HID
  5094. + // report. When set, the data is a HID report.
  5095. + u32 hid_report :1;
  5096. + // Reserved
  5097. + u32 reserved :3;
  5098. + } fields;
  5099. +} touch_frame_char_reg_t;
  5100. +C_ASSERT(sizeof(touch_frame_char_reg_t) == 4);
  5101. +
  5102. +
  5103. +//
  5104. +// Offset 08h: Touch Error Register
  5105. +//
  5106. +#define TOUCH_ERR_REG_OFFSET 0x08
  5107. +
  5108. +// bit definition is vendor specific
  5109. +typedef union touch_err_reg
  5110. +{
  5111. + u32 reg_value;
  5112. +
  5113. + struct
  5114. + {
  5115. + u32 invalid_fw :1;
  5116. + u32 invalid_data :1;
  5117. + u32 self_test_failed :1;
  5118. + u32 reserved :12;
  5119. + u32 fatal_error :1;
  5120. + u32 vendor_errors :16;
  5121. + } fields;
  5122. +} touch_err_reg_t;
  5123. +C_ASSERT(sizeof(touch_err_reg_t) == 4);
  5124. +
  5125. +
  5126. +//
  5127. +// Offset 0Ch: RESERVED
  5128. +// This register is reserved for future use.
  5129. +//
  5130. +
  5131. +
  5132. +//
  5133. +// Offset 10h: Touch Identification Register
  5134. +//
  5135. +#define TOUCH_ID_REG_OFFSET 0x10
  5136. +
  5137. +#define TOUCH_ID_REG_VALUE 0x43495424
  5138. +
  5139. +// expected value is "$TIC" or 0x43495424
  5140. +typedef u32 touch_id_reg_t;
  5141. +C_ASSERT(sizeof(touch_id_reg_t) == 4);
  5142. +
  5143. +
  5144. +//
  5145. +// Offset 14h: TOUCH_DATA_SZ: Touch Data Size Register
  5146. +// This register describes the maximum size of frames and feedback data
  5147. +//
  5148. +#define TOUCH_DATA_SZ_REG_OFFSET 0x14
  5149. +
  5150. +#define TOUCH_MAX_FRAME_SIZE_INCREMENT 64
  5151. +#define TOUCH_MAX_FEEDBACK_SIZE_INCREMENT 64
  5152. +
  5153. +#define TOUCH_SENSOR_MAX_FRAME_SIZE (32 * 1024) // Max allowed frame size 32KB
  5154. +#define TOUCH_SENSOR_MAX_FEEDBACK_SIZE (16 * 1024) // Max allowed feedback size 16KB
  5155. +
  5156. +typedef union touch_data_sz_reg
  5157. +{
  5158. + u32 reg_value;
  5159. +
  5160. + struct
  5161. + {
  5162. + // This value describes the maximum frame size in 64byte increments.
  5163. + u32 max_frame_size :12;
  5164. + // This value describes the maximum feedback size in 64byte increments.
  5165. + u32 max_feedback_size :8;
  5166. + // Reserved
  5167. + u32 reserved :12;
  5168. + } fields;
  5169. +} touch_data_sz_reg_t;
  5170. +C_ASSERT(sizeof(touch_data_sz_reg_t) == 4);
  5171. +
  5172. +
  5173. +//
  5174. +// Offset 18h: TOUCH_CAPABILITIES: Touch Capabilities Register
  5175. +// This register informs the host as to the capabilities of the touch IC.
  5176. +//
  5177. +#define TOUCH_CAPS_REG_OFFSET 0x18
  5178. +
  5179. +typedef enum touch_caps_reg_read_delay_time
  5180. +{
  5181. + TOUCH_CAPS_REG_READ_DELAY_TIME_0,
  5182. + TOUCH_CAPS_REG_READ_DELAY_TIME_10uS,
  5183. + TOUCH_CAPS_REG_READ_DELAY_TIME_50uS,
  5184. + TOUCH_CAPS_REG_READ_DELAY_TIME_100uS,
  5185. + TOUCH_CAPS_REG_READ_DELAY_TIME_150uS,
  5186. + TOUCH_CAPS_REG_READ_DELAY_TIME_250uS,
  5187. + TOUCH_CAPS_REG_READ_DELAY_TIME_500uS,
  5188. + TOUCH_CAPS_REG_READ_DELAY_TIME_1mS,
  5189. +} touch_caps_reg_read_delay_time_t;
  5190. +C_ASSERT(sizeof(touch_caps_reg_read_delay_time_t) == 4);
  5191. +
  5192. +#define TOUCH_BULK_DATA_MAX_WRITE_INCREMENT 64
  5193. +
  5194. +typedef union touch_caps_reg
  5195. +{
  5196. + u32 reg_value;
  5197. +
  5198. + struct
  5199. + {
  5200. + // Reserved for future frequency
  5201. + u32 reserved0 :1;
  5202. + // 17 MHz (14 MHz on Atom) Supported: 0b - Not supported, 1b - Supported
  5203. + u32 supported_17Mhz :1;
  5204. + // 30 MHz (25MHz on Atom) Supported: 0b - Not supported, 1b - Supported
  5205. + u32 supported_30Mhz :1;
  5206. + // 50 MHz Supported: 0b - Not supported, 1b - Supported
  5207. + u32 supported_50Mhz :1;
  5208. + // Reserved
  5209. + u32 reserved1 :4;
  5210. + // Single I/O Supported: 0b - Not supported, 1b - Supported
  5211. + u32 supported_single_io :1;
  5212. + // Dual I/O Supported: 0b - Not supported, 1b - Supported
  5213. + u32 supported_dual_io :1;
  5214. + // Quad I/O Supported: 0b - Not supported, 1b - Supported
  5215. + u32 supported_quad_io :1;
  5216. + // Bulk Data Area Max Write Size: The amount of data the SPI Controller can write to the bulk
  5217. + // data area before it has to poll the busy bit. This field is in multiples of 64 bytes. The
  5218. + // SPI Controller will write the amount of data specified in this field, then check and wait
  5219. + // for the Status.Busy bit to be zero before writing the next data chunk. This field is 6 bits
  5220. + // long, allowing for 4KB of contiguous writes w/o a poll of the busy bit. If this field is
  5221. + // 0x00 the Touch IC has no limit in the amount of data the SPI Controller can write to the
  5222. + // bulk data area.
  5223. + u32 bulk_data_max_write :6;
  5224. + // Read Delay Timer Value: This field describes the delay the SPI Controller will initiate when
  5225. + // a read interrupt follows a write data command. Uses values from TOUCH_CAPS_REG_READ_DELAY_TIME
  5226. + u32 read_delay_timer_value :3;
  5227. + // Reserved
  5228. + u32 reserved2 :4;
  5229. + // Maximum Touch Points: A byte value based on the HID descriptor definition.
  5230. + u32 max_touch_points :8;
  5231. + } fields;
  5232. +} touch_caps_reg_t;
  5233. +C_ASSERT(sizeof(touch_caps_reg_t) == 4);
  5234. +
  5235. +
  5236. +//
  5237. +// Offset 1Ch: TOUCH_CFG: Touch Configuration Register
  5238. +// This register allows the SPI Controller to configure the touch sensor as needed during touch
  5239. +// operations.
  5240. +//
  5241. +#define TOUCH_CFG_REG_OFFSET 0x1C
  5242. +
  5243. +typedef enum touch_cfg_reg_bulk_xfer_size
  5244. +{
  5245. + TOUCH_CFG_REG_BULK_XFER_SIZE_4B = 0, // Bulk Data Transfer Size is 4 bytes
  5246. + TOUCH_CFG_REG_BULK_XFER_SIZE_8B, // Bulk Data Transfer Size is 8 bytes
  5247. + TOUCH_CFG_REG_BULK_XFER_SIZE_16B, // Bulk Data Transfer Size is 16 bytes
  5248. + TOUCH_CFG_REG_BULK_XFER_SIZE_32B, // Bulk Data Transfer Size is 32 bytes
  5249. + TOUCH_CFG_REG_BULK_XFER_SIZE_64B, // Bulk Data Transfer Size is 64 bytes
  5250. + TOUCH_CFG_REG_BULK_XFER_SIZE_MAX
  5251. +} touch_cfg_reg_bulk_xfer_size_t;
  5252. +C_ASSERT(sizeof(touch_cfg_reg_bulk_xfer_size_t) == 4);
  5253. +
  5254. +// Frequency values used by TOUCH_CFG_REG and TOUCH_SENSOR_GET_DEVICE_INFO_RSP_DATA.
  5255. +typedef enum touch_freq
  5256. +{
  5257. + TOUCH_FREQ_RSVD = 0, // Reserved value
  5258. + TOUCH_FREQ_17MHZ, // Sensor set for 17MHz operation (14MHz on Atom)
  5259. + TOUCH_FREQ_30MHZ, // Sensor set for 30MHz operation (25MHz on Atom)
  5260. + TOUCH_FREQ_MAX // Invalid value
  5261. +} touch_freq_t;
  5262. +C_ASSERT(sizeof(touch_freq_t) == 4);
  5263. +
  5264. +typedef union touch_cfg_reg
  5265. +{
  5266. + u32 reg_value;
  5267. +
  5268. + struct
  5269. + {
  5270. + // Touch Enable (TE): This bit is used as a HW semaphore for the Touch IC to guarantee to the
  5271. + // SPI Controller to that (when 0) no sensing operations will occur and only the Reset
  5272. + // interrupt will be generated. When TE is cleared by the SPI Controller:
  5273. + // - TICs must flush all output buffers
  5274. + // - TICs must De-assert any pending interrupt
  5275. + // - ME must throw away any partial frame and pending interrupt must be cleared/not serviced.
  5276. + // The SPI Controller will only modify the configuration of the TIC when TE is cleared. TE is
  5277. + // defaulted to 0h on a power-on reset.
  5278. + u32 touch_enable :1;
  5279. + // Data/HID Packet Mode (DHPM): Raw Data Mode: 0h, HID Packet Mode: 1h
  5280. + u32 dhpm :1;
  5281. + // Bulk Data Transfer Size: This field represents the amount of data written to the Bulk Data
  5282. + // Area (SPI Offset 0x1000-0x2FFF) in a single SPI write protocol
  5283. + u32 bulk_xfer_size :4;
  5284. + // Frequency Select: Frequency for the TouchIC to run at. Use values from TOUCH_FREQ
  5285. + u32 freq_select :3;
  5286. + // Reserved
  5287. + u32 reserved :23;
  5288. + } fields;
  5289. +} touch_cfg_reg_t;
  5290. +C_ASSERT(sizeof(touch_cfg_reg_t) == 4);
  5291. +
  5292. +
  5293. +//
  5294. +// Offset 20h: TOUCH_CMD: Touch Command Register
  5295. +// This register is used for sending commands to the Touch IC.
  5296. +//
  5297. +#define TOUCH_CMD_REG_OFFSET 0x20
  5298. +
  5299. +typedef enum touch_cmd_reg_code
  5300. +{
  5301. + TOUCH_CMD_REG_CODE_NOP = 0, // No Operation
  5302. + TOUCH_CMD_REG_CODE_SOFT_RESET, // Soft Reset
  5303. + TOUCH_CMD_REG_CODE_PREP_4_READ, // Prepare All Registers for Read
  5304. + TOUCH_CMD_REG_CODE_GEN_TEST_PACKETS, // Generate Test Packets according to value in TOUCH_TEST_CTRL_REG
  5305. + TOUCH_CMD_REG_CODE_MAX
  5306. +} touch_cmd_reg_code_t;
  5307. +C_ASSERT(sizeof(touch_cmd_reg_code_t) == 4);
  5308. +
  5309. +typedef union touch_cmd_reg
  5310. +{
  5311. + u32 reg_value;
  5312. +
  5313. + struct
  5314. + {
  5315. + // Command Code: See TOUCH_CMD_REG_CODE
  5316. + u32 command_code :8;
  5317. + // Reserved
  5318. + u32 reserved :24;
  5319. + } fields;
  5320. +} touch_cmd_reg_t;
  5321. +C_ASSERT(sizeof(touch_cmd_reg_t) == 4);
  5322. +
  5323. +
  5324. +//
  5325. +// Offset 24h: Power Management Control
  5326. +// This register is used for active power management. The Touch IC is allowed to mover from Doze or
  5327. +// Armed to Sensing after a touch has occurred. All other transitions will be made at the request
  5328. +// of the SPI Controller.
  5329. +//
  5330. +#define TOUCH_PWR_MGMT_CTRL_REG_OFFSET 0x24
  5331. +
  5332. +typedef enum touch_pwr_mgmt_ctrl_reg_cmd
  5333. +{
  5334. + TOUCH_PWR_MGMT_CTRL_REG_CMD_NOP = 0, // No change to power state
  5335. + TOUCH_PWR_MGMT_CTRL_REG_CMD_SLEEP, // Sleep - set when the system goes into connected standby
  5336. + TOUCH_PWR_MGMT_CTRL_REG_CMD_DOZE, // Doze - set after 300 seconds of inactivity
  5337. + TOUCH_PWR_MGMT_CTRL_REG_CMD_ARMED, // Armed - Set by FW when a "finger off" message is received from the EUs
  5338. + TOUCH_PWR_MGMT_CTRL_REG_CMD_SENSING, // Sensing - not typically set by FW
  5339. + TOUCH_PWR_MGMT_CTRL_REG_CMD_MAX // Values will result in no change to the power state of the Touch IC
  5340. +} touch_pwr_mgmt_ctrl_reg_cmd_t;
  5341. +C_ASSERT(sizeof(touch_pwr_mgmt_ctrl_reg_cmd_t) == 4);
  5342. +
  5343. +typedef union touch_pwr_mgmt_ctrl_reg
  5344. +{
  5345. + u32 reg_value;
  5346. +
  5347. + struct
  5348. + {
  5349. + // Power State Command: See TOUCH_PWR_MGMT_CTRL_REG_CMD
  5350. + u32 pwr_state_cmd :3;
  5351. + // Reserved
  5352. + u32 reserved :29;
  5353. + } fields;
  5354. +} touch_pwr_mgmt_ctrl_reg_t;
  5355. +C_ASSERT(sizeof(touch_pwr_mgmt_ctrl_reg_t) == 4);
  5356. +
  5357. +
  5358. +//
  5359. +// Offset 28h: Vendor HW Information Register
  5360. +// This register is used to relay Intel-assigned vendor ID information to the SPI Controller, which
  5361. +// may be forwarded to SW running on the host CPU.
  5362. +//
  5363. +#define TOUCH_VEN_HW_INFO_REG_OFFSET 0x28
  5364. +
  5365. +typedef union touch_ven_hw_info_reg
  5366. +{
  5367. + u32 reg_value;
  5368. +
  5369. + struct
  5370. + {
  5371. + // Touch Sensor Vendor ID
  5372. + u32 vendor_id :16;
  5373. + // Touch Sensor Device ID
  5374. + u32 device_id :16;
  5375. + } fields;
  5376. +} touch_ven_hw_info_reg_t;
  5377. +C_ASSERT(sizeof(touch_ven_hw_info_reg_t) == 4);
  5378. +
  5379. +
  5380. +//
  5381. +// Offset 2Ch: HW Revision ID Register
  5382. +// This register is used to relay vendor HW revision information to the SPI Controller which may be
  5383. +// forwarded to SW running on the host CPU.
  5384. +//
  5385. +#define TOUCH_HW_REV_REG_OFFSET 0x2C
  5386. +
  5387. +typedef u32 touch_hw_rev_reg_t; // bit definition is vendor specific
  5388. +C_ASSERT(sizeof(touch_hw_rev_reg_t) == 4);
  5389. +
  5390. +
  5391. +//
  5392. +// Offset 30h: FW Revision ID Register
  5393. +// This register is used to relay vendor FW revision information to the SPI Controller which may be
  5394. +// forwarded to SW running on the host CPU.
  5395. +//
  5396. +#define TOUCH_FW_REV_REG_OFFSET 0x30
  5397. +
  5398. +typedef u32 touch_fw_rev_reg_t; // bit definition is vendor specific
  5399. +C_ASSERT(sizeof(touch_fw_rev_reg_t) == 4);
  5400. +
  5401. +
  5402. +//
  5403. +// Offset 34h: Compatibility Revision ID Register
  5404. +// This register is used to relay vendor compatibility information to the SPI Controller which may
  5405. +// be forwarded to SW running on the host CPU. Compatibility Information is a numeric value given
  5406. +// by Intel to the Touch IC vendor based on the major and minor revision of the EDS supported. From
  5407. +// a nomenclature point of view in an x.y revision number of the EDS, the major version is the value
  5408. +// of x and the minor version is the value of y. For example, a Touch IC supporting an EDS version
  5409. +// of 0.61 would contain a major version of 0 and a minor version of 61 in the register.
  5410. +//
  5411. +#define TOUCH_COMPAT_REV_REG_OFFSET 0x34
  5412. +
  5413. +typedef union touch_compat_rev_reg
  5414. +{
  5415. + u32 reg_value;
  5416. +
  5417. + struct
  5418. + {
  5419. + // EDS Minor Revision
  5420. + u8 minor;
  5421. + // EDS Major Revision
  5422. + u8 major;
  5423. + // Interface Revision Number (from EDS)
  5424. + u8 intf_rev;
  5425. + // EU Kernel Compatibility Version - vendor specific value
  5426. + u8 kernel_compat_ver;
  5427. + } fields;
  5428. +} touch_compat_rev_reg_t;
  5429. +C_ASSERT(sizeof(touch_compat_rev_reg_t) == 4);
  5430. +
  5431. +
  5432. +//
  5433. +// Touch Register Block is the full set of registers from offset 0x00h to 0x3F
  5434. +// This is the entire set of registers needed for normal touch operation. It does not include test
  5435. +// registers such as TOUCH_TEST_CTRL_REG
  5436. +//
  5437. +#define TOUCH_REG_BLOCK_OFFSET TOUCH_STS_REG_OFFSET
  5438. +
  5439. +typedef struct touch_reg_block
  5440. +{
  5441. + touch_sts_reg_t sts_reg; // 0x00
  5442. + touch_frame_char_reg_t frame_char_reg; // 0x04
  5443. + touch_err_reg_t error_reg; // 0x08
  5444. + u32 reserved0; // 0x0C
  5445. + touch_id_reg_t id_reg; // 0x10
  5446. + touch_data_sz_reg_t data_size_reg; // 0x14
  5447. + touch_caps_reg_t caps_reg; // 0x18
  5448. + touch_cfg_reg_t cfg_reg; // 0x1C
  5449. + touch_cmd_reg_t cmd_reg; // 0x20
  5450. + touch_pwr_mgmt_ctrl_reg_t pwm_mgme_ctrl_reg; // 0x24
  5451. + touch_ven_hw_info_reg_t ven_hw_info_reg; // 0x28
  5452. + touch_hw_rev_reg_t hw_rev_reg; // 0x2C
  5453. + touch_fw_rev_reg_t fw_rev_reg; // 0x30
  5454. + touch_compat_rev_reg_t compat_rev_reg; // 0x34
  5455. + u32 reserved1; // 0x38
  5456. + u32 reserved2; // 0x3C
  5457. +} touch_reg_block_t;
  5458. +C_ASSERT(sizeof(touch_reg_block_t) == 64);
  5459. +
  5460. +
  5461. +//
  5462. +// Offset 40h: Test Control Register
  5463. +// This register
  5464. +//
  5465. +#define TOUCH_TEST_CTRL_REG_OFFSET 0x40
  5466. +
  5467. +typedef union touch_test_ctrl_reg
  5468. +{
  5469. + u32 reg_value;
  5470. +
  5471. + struct
  5472. + {
  5473. + // Size of Test Frame in Raw Data Mode: This field specifies the test frame size in raw data
  5474. + // mode in multiple of 64 bytes. For example, if this field value is 16, the test frame size
  5475. + // will be 16x64 = 1K.
  5476. + u32 raw_test_frame_size :16;
  5477. + // Number of Raw Data Frames or HID Report Packets Generation. This field represents the number
  5478. + // of test frames or HID reports to be generated when test mode is enabled. When multiple
  5479. + // packets/frames are generated, they need be generated at 100 Hz frequency, i.e. 10ms per
  5480. + // packet/frame.
  5481. + u32 num_test_frames :16;
  5482. + } fields;
  5483. +} touch_test_ctrl_reg_t;
  5484. +C_ASSERT(sizeof(touch_test_ctrl_reg_t) == 4);
  5485. +
  5486. +
  5487. +//
  5488. +// Offsets 0x000 to 0xFFF are reserved for Intel-defined Registers
  5489. +//
  5490. +#define TOUCH_REGISTER_LIMIT 0xFFF
  5491. +
  5492. +
  5493. +//
  5494. +// Data Window: Address 0x1000-0x1FFFF
  5495. +// The data window is reserved for writing and reading large quantities of data to and from the
  5496. +// sensor.
  5497. +//
  5498. +#define TOUCH_DATA_WINDOW_OFFSET 0x1000
  5499. +#define TOUCH_DATA_WINDOW_LIMIT 0x1FFFF
  5500. +
  5501. +#define TOUCH_SENSOR_MAX_OFFSET TOUCH_DATA_WINDOW_LIMIT
  5502. +
  5503. +
  5504. +//
  5505. +// The following data structures represent the headers defined in the Data Structures chapter of the
  5506. +// Intel Integrated Touch EDS
  5507. +//
  5508. +
  5509. +// Enumeration used in TOUCH_RAW_DATA_HDR
  5510. +typedef enum touch_raw_data_types
  5511. +{
  5512. + TOUCH_RAW_DATA_TYPE_FRAME = 0,
  5513. + TOUCH_RAW_DATA_TYPE_ERROR, // RawData will be the TOUCH_ERROR struct below
  5514. + TOUCH_RAW_DATA_TYPE_VENDOR_DATA, // Set when InterruptType is Vendor Data
  5515. + TOUCH_RAW_DATA_TYPE_HID_REPORT,
  5516. + TOUCH_RAW_DATA_TYPE_GET_FEATURES,
  5517. + TOUCH_RAW_DATA_TYPE_MAX
  5518. +} touch_raw_data_types_t;
  5519. +C_ASSERT(sizeof(touch_raw_data_types_t) == 4);
  5520. +
  5521. +// Private data structure. Kernels must copy to HID driver buffer
  5522. +typedef struct touch_hid_private_data
  5523. +{
  5524. + u32 transaction_id;
  5525. + u8 reserved[28];
  5526. +} touch_hid_private_data_t;
  5527. +C_ASSERT(sizeof(touch_hid_private_data_t) == 32);
  5528. +
  5529. +// This is the data structure sent from the PCH FW to the EU kernel
  5530. +typedef struct touch_raw_data_hdr
  5531. +{
  5532. + u32 data_type; // use values from TOUCH_RAW_DATA_TYPES
  5533. + u32 raw_data_size_bytes; // The size in bytes of the raw data read from the
  5534. + // sensor, does not include TOUCH_RAW_DATA_HDR. Will
  5535. + // be the sum of all uFrames, or size of TOUCH_ERROR
  5536. + // for if DataType is TOUCH_RAW_DATA_TYPE_ERROR
  5537. + u32 buffer_id; // An ID to qualify with the feedback data to track
  5538. + // buffer usage
  5539. + u32 protocol_ver; // Must match protocol version of the EDS
  5540. + u8 kernel_compat_id; // Copied from the Compatibility Revision ID Reg
  5541. + u8 reserved[15]; // Padding to extend header to full 64 bytes and
  5542. + // allow for growth
  5543. + touch_hid_private_data_t hid_private_data; // Private data structure. Kernels must copy to HID
  5544. + // driver buffer
  5545. +} touch_raw_data_hdr_t;
  5546. +C_ASSERT(sizeof(touch_raw_data_hdr_t) == 64);
  5547. +
  5548. +typedef struct touch_raw_data
  5549. +{
  5550. + touch_raw_data_hdr_t header;
  5551. + u8 raw_data[1]; // used to access the raw data as an array and keep the
  5552. + // compilers happy. Actual size of this array is
  5553. + // Header.RawDataSizeBytes
  5554. +} touch_raw_data_t;
  5555. +
  5556. +
  5557. +// The following section describes the data passed in TOUCH_RAW_DATA.RawData when DataType equals
  5558. +// TOUCH_RAW_DATA_TYPE_ERROR
  5559. +// Note: This data structure is also applied to HID mode
  5560. +typedef enum touch_err_types
  5561. +{
  5562. + TOUCH_RAW_DATA_ERROR = 0,
  5563. + TOUCH_RAW_ERROR_MAX
  5564. +} touch_err_types_t;
  5565. +C_ASSERT(sizeof(touch_err_types_t) == 4);
  5566. +
  5567. +typedef union touch_me_fw_error
  5568. +{
  5569. + u32 value;
  5570. +
  5571. + struct
  5572. + {
  5573. + u32 invalid_frame_characteristics : 1;
  5574. + u32 microframe_index_invalid : 1;
  5575. + u32 reserved : 30;
  5576. + } fields;
  5577. +} touch_me_fw_error_t;
  5578. +C_ASSERT(sizeof(touch_me_fw_error_t) == 4);
  5579. +
  5580. +typedef struct touch_error
  5581. +{
  5582. + u8 touch_error_type; // This must be a value from TOUCH_ERROR_TYPES
  5583. + u8 reserved[3];
  5584. + touch_me_fw_error_t touch_me_fw_error;
  5585. + touch_err_reg_t touch_error_register; // Contains the value copied from the Touch Error Reg
  5586. +} touch_error_t;
  5587. +C_ASSERT(sizeof(touch_error_t) == 12);
  5588. +
  5589. +// Enumeration used in TOUCH_FEEDBACK_BUFFER
  5590. +typedef enum touch_feedback_cmd_types
  5591. +{
  5592. + TOUCH_FEEDBACK_CMD_TYPE_NONE = 0,
  5593. + TOUCH_FEEDBACK_CMD_TYPE_SOFT_RESET,
  5594. + TOUCH_FEEDBACK_CMD_TYPE_GOTO_ARMED,
  5595. + TOUCH_FEEDBACK_CMD_TYPE_GOTO_SENSING,
  5596. + TOUCH_FEEDBACK_CMD_TYPE_GOTO_SLEEP,
  5597. + TOUCH_FEEDBACK_CMD_TYPE_GOTO_DOZE,
  5598. + TOUCH_FEEDBACK_CMD_TYPE_HARD_RESET,
  5599. + TOUCH_FEEDBACK_CMD_TYPE_MAX
  5600. +} touch_feedback_cmd_types_t;
  5601. +C_ASSERT(sizeof(touch_feedback_cmd_types_t) == 4);
  5602. +
  5603. +// Enumeration used in TOUCH_FEEDBACK_HDR
  5604. +typedef enum touch_feedback_data_types
  5605. +{
  5606. + TOUCH_FEEDBACK_DATA_TYPE_FEEDBACK = 0, // This is vendor specific feedback to be written to the sensor
  5607. + TOUCH_FEEDBACK_DATA_TYPE_SET_FEATURES, // This is a set features command to be written to the sensor
  5608. + TOUCH_FEEDBACK_DATA_TYPE_GET_FEATURES, // This is a get features command to be written to the sensor
  5609. + TOUCH_FEEDBACK_DATA_TYPE_OUTPUT_REPORT, // This is a HID output report to be written to the sensor
  5610. + TOUCH_FEEDBACK_DATA_TYPE_STORE_DATA, // This is calibration data to be written to system flash
  5611. + TOUCH_FEEDBACK_DATA_TYPE_MAX
  5612. +} touch_feedback_data_types_t;
  5613. +C_ASSERT(sizeof(touch_feedback_data_types_t) == 4);
  5614. +
  5615. +// This is the data structure sent from the EU kernels back to the ME FW.
  5616. +// In addition to "feedback" data, the FW can execute a "command" described by the command type parameter.
  5617. +// Any payload data will always be sent to the TIC first, then any command will be issued.
  5618. +typedef struct touch_feedback_hdr
  5619. +{
  5620. + u32 feedback_cmd_type; // use values from TOUCH_FEEDBACK_CMD_TYPES
  5621. + u32 payload_size_bytes; // The amount of data to be written to the sensor, not including the header
  5622. + u32 buffer_id; // The ID of the raw data buffer that generated this feedback data
  5623. + u32 protocol_ver; // Must match protocol version of the EDS
  5624. + u32 feedback_data_type; // use values from TOUCH_FEEDBACK_DATA_TYPES. This is not relevant if PayloadSizeBytes is 0
  5625. + u32 spi_offest; // The offset from TOUCH_DATA_WINDOW_OFFSET at which to write the Payload data. Maximum offset is 0x1EFFF.
  5626. + u8 reserved[40]; // Padding to extend header to full 64 bytes and allow for growth
  5627. +} touch_feedback_hdr_t;
  5628. +C_ASSERT(sizeof(touch_feedback_hdr_t) == 64);
  5629. +
  5630. +typedef struct touch_feedback_buffer
  5631. +{
  5632. + touch_feedback_hdr_t Header;
  5633. + u8 feedback_data[1]; // used to access the feedback data as an array and keep the compilers happy. Actual size of this array is Header.PayloadSizeBytes
  5634. +} touch_feedback_buffer_t;
  5635. +
  5636. +
  5637. +//
  5638. +// This data structure describes the header prepended to all data
  5639. +// written to the touch IC at the bulk data write (TOUCH_DATA_WINDOW_OFFSET + TOUCH_FEEDBACK_HDR.SpiOffest) address.
  5640. +typedef enum touch_write_data_type
  5641. +{
  5642. + TOUCH_WRITE_DATA_TYPE_FW_LOAD = 0,
  5643. + TOUCH_WRITE_DATA_TYPE_DATA_LOAD,
  5644. + TOUCH_WRITE_DATA_TYPE_FEEDBACK,
  5645. + TOUCH_WRITE_DATA_TYPE_SET_FEATURES,
  5646. + TOUCH_WRITE_DATA_TYPE_GET_FEATURES,
  5647. + TOUCH_WRITE_DATA_TYPE_OUTPUT_REPORT,
  5648. + TOUCH_WRITE_DATA_TYPE_NO_DATA_USE_DEFAULTS,
  5649. + TOUCH_WRITE_DATA_TYPE_MAX
  5650. +} touch_write_data_type_t;
  5651. +C_ASSERT(sizeof(touch_write_data_type_t) == 4);
  5652. +
  5653. +typedef struct touch_write_hdr
  5654. +{
  5655. + u32 write_data_type; // Use values from TOUCH_WRITE_DATA_TYPE
  5656. + u32 write_data_len; // This field designates the amount of data to follow
  5657. +} touch_write_hdr_t;
  5658. +C_ASSERT(sizeof(touch_write_hdr_t) == 8);
  5659. +
  5660. +typedef struct touch_write_data
  5661. +{
  5662. + touch_write_hdr_t header;
  5663. + u8 write_data[1]; // used to access the write data as an array and keep the compilers happy. Actual size of this array is Header.WriteDataLen
  5664. +} touch_write_data_t;
  5665. +
  5666. +#pragma pack()
  5667. +
  5668. +#endif // _TOUCH_SENSOR_REGS_H
  5669. diff --git a/drivers/misc/ipts/ipts-state.h b/drivers/misc/ipts/ipts-state.h
  5670. new file mode 100644
  5671. index 000000000000..39a2eaf5f004
  5672. --- /dev/null
  5673. +++ b/drivers/misc/ipts/ipts-state.h
  5674. @@ -0,0 +1,29 @@
  5675. +/*
  5676. + * Intel Precise Touch & Stylus state codes
  5677. + *
  5678. + * Copyright (c) 2016, Intel Corporation.
  5679. + *
  5680. + * This program is free software; you can redistribute it and/or modify it
  5681. + * under the terms and conditions of the GNU General Public License,
  5682. + * version 2, as published by the Free Software Foundation.
  5683. + *
  5684. + * This program is distributed in the hope it will be useful, but WITHOUT
  5685. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  5686. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  5687. + * more details.
  5688. + */
  5689. +
  5690. +#ifndef _IPTS_STATE_H_
  5691. +#define _IPTS_STATE_H_
  5692. +
  5693. +/* ipts driver states */
  5694. +typedef enum ipts_state {
  5695. + IPTS_STA_NONE,
  5696. + IPTS_STA_INIT,
  5697. + IPTS_STA_RESOURCE_READY,
  5698. + IPTS_STA_HID_STARTED,
  5699. + IPTS_STA_RAW_DATA_STARTED,
  5700. + IPTS_STA_STOPPING
  5701. +} ipts_state_t;
  5702. +
  5703. +#endif // _IPTS_STATE_H_
  5704. diff --git a/drivers/misc/ipts/ipts.h b/drivers/misc/ipts/ipts.h
  5705. new file mode 100644
  5706. index 000000000000..1fcd02146b50
  5707. --- /dev/null
  5708. +++ b/drivers/misc/ipts/ipts.h
  5709. @@ -0,0 +1,200 @@
  5710. +/*
  5711. + *
  5712. + * Intel Management Engine Interface (Intel MEI) Client Driver for IPTS
  5713. + * Copyright (c) 2016, Intel Corporation.
  5714. + *
  5715. + * This program is free software; you can redistribute it and/or modify it
  5716. + * under the terms and conditions of the GNU General Public License,
  5717. + * version 2, as published by the Free Software Foundation.
  5718. + *
  5719. + * This program is distributed in the hope it will be useful, but WITHOUT
  5720. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  5721. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  5722. + * more details.
  5723. + *
  5724. + */
  5725. +
  5726. +#ifndef _IPTS_H_
  5727. +#define _IPTS_H_
  5728. +
  5729. +#include <linux/types.h>
  5730. +#include <linux/mei_cl_bus.h>
  5731. +#include <linux/hid.h>
  5732. +#include <linux/intel_ipts_if.h>
  5733. +
  5734. +#include "ipts-mei-msgs.h"
  5735. +#include "ipts-state.h"
  5736. +#include "ipts-binary-spec.h"
  5737. +
  5738. +//#define ENABLE_IPTS_DEBUG /* enable IPTS debug */
  5739. +
  5740. +#ifdef ENABLE_IPTS_DEBUG
  5741. +
  5742. +#define ipts_info(ipts, format, arg...) do {\
  5743. + dev_info(&ipts->cldev->dev, format, ##arg);\
  5744. +} while (0)
  5745. +
  5746. +#define ipts_dbg(ipts, format, arg...) do {\
  5747. + dev_info(&ipts->cldev->dev, format, ##arg);\
  5748. +} while (0)
  5749. +
  5750. +//#define RUN_DBG_THREAD
  5751. +
  5752. +#else
  5753. +
  5754. +#define ipts_info(ipts, format, arg...) do {} while(0);
  5755. +#define ipts_dbg(ipts, format, arg...) do {} while(0);
  5756. +
  5757. +#endif
  5758. +
  5759. +#define ipts_err(ipts, format, arg...) do {\
  5760. + dev_err(&ipts->cldev->dev, format, ##arg);\
  5761. +} while (0)
  5762. +
  5763. +#define HID_PARALLEL_DATA_BUFFERS TOUCH_SENSOR_MAX_DATA_BUFFERS
  5764. +
  5765. +#define IPTS_MAX_RETRY 3
  5766. +
  5767. +typedef struct ipts_buffer_info {
  5768. + char *addr;
  5769. + dma_addr_t dma_addr;
  5770. +} ipts_buffer_info_t;
  5771. +
  5772. +typedef struct ipts_gfx_info {
  5773. + u64 gfx_handle;
  5774. + intel_ipts_ops_t ipts_ops;
  5775. +} ipts_gfx_info_t;
  5776. +
  5777. +typedef struct ipts_resource {
  5778. + /* ME & Gfx resource */
  5779. + ipts_buffer_info_t touch_data_buffer_raw[HID_PARALLEL_DATA_BUFFERS];
  5780. + ipts_buffer_info_t touch_data_buffer_hid;
  5781. +
  5782. + ipts_buffer_info_t feedback_buffer[HID_PARALLEL_DATA_BUFFERS];
  5783. +
  5784. + ipts_buffer_info_t hid2me_buffer;
  5785. + u32 hid2me_buffer_size;
  5786. +
  5787. + u8 wq_item_size;
  5788. + intel_ipts_wq_info_t wq_info;
  5789. +
  5790. + /* ME2HID buffer */
  5791. + char *me2hid_buffer;
  5792. +
  5793. + /* Gfx specific resource */
  5794. + ipts_buffer_info_t raw_data_mode_output_buffer
  5795. + [HID_PARALLEL_DATA_BUFFERS][MAX_NUM_OUTPUT_BUFFERS];
  5796. +
  5797. + int num_of_outputs;
  5798. +
  5799. + bool default_resource_ready;
  5800. + bool raw_data_resource_ready;
  5801. +} ipts_resource_t;
  5802. +
  5803. +typedef struct ipts_info {
  5804. + struct mei_cl_device *cldev;
  5805. + struct hid_device *hid;
  5806. +
  5807. + struct work_struct init_work;
  5808. + struct work_struct raw_data_work;
  5809. + struct work_struct gfx_status_work;
  5810. +
  5811. + struct task_struct *event_loop;
  5812. +
  5813. +#if IS_ENABLED(CONFIG_DEBUG_FS)
  5814. + struct dentry *dbgfs_dir;
  5815. +#endif
  5816. +
  5817. + ipts_state_t state;
  5818. +
  5819. + touch_sensor_mode_t sensor_mode;
  5820. + touch_sensor_get_device_info_rsp_data_t device_info;
  5821. + ipts_resource_t resource;
  5822. + u8 hid_input_report[HID_MAX_BUFFER_SIZE];
  5823. + int num_of_parallel_data_buffers;
  5824. + bool hid_desc_ready;
  5825. +
  5826. + int current_buffer_index;
  5827. + int last_buffer_completed;
  5828. + int *last_submitted_id;
  5829. +
  5830. + ipts_gfx_info_t gfx_info;
  5831. + u64 kernel_handle;
  5832. + int gfx_status;
  5833. + bool display_status;
  5834. +
  5835. + bool switch_sensor_mode;
  5836. + touch_sensor_mode_t new_sensor_mode;
  5837. +
  5838. + int retry;
  5839. + bool restart;
  5840. +} ipts_info_t;
  5841. +
  5842. +#if IS_ENABLED(CONFIG_DEBUG_FS)
  5843. +int ipts_dbgfs_register(ipts_info_t *ipts, const char *name);
  5844. +void ipts_dbgfs_deregister(ipts_info_t *ipts);
  5845. +#else
  5846. +static int ipts_dbgfs_register(ipts_info_t *ipts, const char *name);
  5847. +static void ipts_dbgfs_deregister(ipts_info_t *ipts);
  5848. +#endif /* CONFIG_DEBUG_FS */
  5849. +
  5850. +/* inline functions */
  5851. +static inline void ipts_set_state(ipts_info_t *ipts, ipts_state_t state)
  5852. +{
  5853. + ipts->state = state;
  5854. +}
  5855. +
  5856. +static inline ipts_state_t ipts_get_state(const ipts_info_t *ipts)
  5857. +{
  5858. + return ipts->state;
  5859. +}
  5860. +
  5861. +static inline bool ipts_is_default_resource_ready(const ipts_info_t *ipts)
  5862. +{
  5863. + return ipts->resource.default_resource_ready;
  5864. +}
  5865. +
  5866. +static inline bool ipts_is_raw_data_resource_ready(const ipts_info_t *ipts)
  5867. +{
  5868. + return ipts->resource.raw_data_resource_ready;
  5869. +}
  5870. +
  5871. +static inline ipts_buffer_info_t* ipts_get_feedback_buffer(ipts_info_t *ipts,
  5872. + int buffer_idx)
  5873. +{
  5874. + return &ipts->resource.feedback_buffer[buffer_idx];
  5875. +}
  5876. +
  5877. +static inline ipts_buffer_info_t* ipts_get_touch_data_buffer_hid(ipts_info_t *ipts)
  5878. +{
  5879. + return &ipts->resource.touch_data_buffer_hid;
  5880. +}
  5881. +
  5882. +static inline ipts_buffer_info_t* ipts_get_output_buffers_by_parallel_id(
  5883. + ipts_info_t *ipts,
  5884. + int parallel_idx)
  5885. +{
  5886. + return &ipts->resource.raw_data_mode_output_buffer[parallel_idx][0];
  5887. +}
  5888. +
  5889. +static inline ipts_buffer_info_t* ipts_get_hid2me_buffer(ipts_info_t *ipts)
  5890. +{
  5891. + return &ipts->resource.hid2me_buffer;
  5892. +}
  5893. +
  5894. +static inline void ipts_set_wq_item_size(ipts_info_t *ipts, u8 size)
  5895. +{
  5896. + ipts->resource.wq_item_size = size;
  5897. +}
  5898. +
  5899. +static inline u8 ipts_get_wq_item_size(const ipts_info_t *ipts)
  5900. +{
  5901. + return ipts->resource.wq_item_size;
  5902. +}
  5903. +
  5904. +static inline int ipts_get_num_of_parallel_buffers(const ipts_info_t *ipts)
  5905. +{
  5906. + return ipts->num_of_parallel_data_buffers;
  5907. +}
  5908. +
  5909. +#endif // _IPTS_H_
  5910. diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h
  5911. index e4b10b2d1a08..883b185c9dbe 100644
  5912. --- a/drivers/misc/mei/hw-me-regs.h
  5913. +++ b/drivers/misc/mei/hw-me-regs.h
  5914. @@ -119,6 +119,7 @@
  5915. #define MEI_DEV_ID_SPT 0x9D3A /* Sunrise Point */
  5916. #define MEI_DEV_ID_SPT_2 0x9D3B /* Sunrise Point 2 */
  5917. +#define MEI_DEV_ID_SPT_4 0x9D3E /* Sunrise Point 4 */
  5918. #define MEI_DEV_ID_SPT_H 0xA13A /* Sunrise Point H */
  5919. #define MEI_DEV_ID_SPT_H_2 0xA13B /* Sunrise Point H 2 */
  5920. diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c
  5921. index ea4e152270a3..4d301ba3f867 100644
  5922. --- a/drivers/misc/mei/pci-me.c
  5923. +++ b/drivers/misc/mei/pci-me.c
  5924. @@ -86,6 +86,7 @@ static const struct pci_device_id mei_me_pci_tbl[] = {
  5925. {MEI_PCI_DEVICE(MEI_DEV_ID_SPT, MEI_ME_PCH8_CFG)},
  5926. {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_2, MEI_ME_PCH8_CFG)},
  5927. + {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_4, MEI_ME_PCH8_CFG)},
  5928. {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H, MEI_ME_PCH8_SPS_CFG)},
  5929. {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H_2, MEI_ME_PCH8_SPS_CFG)},
  5930. {MEI_PCI_DEVICE(MEI_DEV_ID_LBG, MEI_ME_PCH8_CFG)},
  5931. diff --git a/include/linux/intel_ipts_if.h b/include/linux/intel_ipts_if.h
  5932. new file mode 100644
  5933. index 000000000000..f329bbfb8079
  5934. --- /dev/null
  5935. +++ b/include/linux/intel_ipts_if.h
  5936. @@ -0,0 +1,75 @@
  5937. +/*
  5938. + *
  5939. + * GFX interface to support Intel Precise Touch & Stylus
  5940. + * Copyright (c) 2016 Intel Corporation.
  5941. + *
  5942. + * This program is free software; you can redistribute it and/or modify it
  5943. + * under the terms and conditions of the GNU General Public License,
  5944. + * version 2, as published by the Free Software Foundation.
  5945. + *
  5946. + * This program is distributed in the hope it will be useful, but WITHOUT
  5947. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  5948. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  5949. + * more details.
  5950. + *
  5951. + */
  5952. +
  5953. +#ifndef INTEL_IPTS_IF_H
  5954. +#define INTEL_IPTS_IF_H
  5955. +
  5956. +enum {
  5957. + IPTS_INTERFACE_V1 = 1,
  5958. +};
  5959. +
  5960. +#define IPTS_BUF_FLAG_CONTIGUOUS 0x01
  5961. +
  5962. +#define IPTS_NOTIFY_STA_BACKLIGHT_OFF 0x00
  5963. +#define IPTS_NOTIFY_STA_BACKLIGHT_ON 0x01
  5964. +
  5965. +typedef struct intel_ipts_mapbuffer {
  5966. + u32 size;
  5967. + u32 flags;
  5968. + void *gfx_addr;
  5969. + void *cpu_addr;
  5970. + u64 buf_handle;
  5971. + u64 phy_addr;
  5972. +} intel_ipts_mapbuffer_t;
  5973. +
  5974. +typedef struct intel_ipts_wq_info {
  5975. + u64 db_addr;
  5976. + u64 db_phy_addr;
  5977. + u32 db_cookie_offset;
  5978. + u32 wq_size;
  5979. + u64 wq_addr;
  5980. + u64 wq_phy_addr;
  5981. + u64 wq_head_addr; /* head of wq is managed by GPU */
  5982. + u64 wq_head_phy_addr; /* head of wq is managed by GPU */
  5983. + u64 wq_tail_addr; /* tail of wq is managed by CSME */
  5984. + u64 wq_tail_phy_addr; /* tail of wq is managed by CSME */
  5985. +} intel_ipts_wq_info_t;
  5986. +
  5987. +typedef struct intel_ipts_ops {
  5988. + int (*get_wq_info)(uint64_t gfx_handle, intel_ipts_wq_info_t *wq_info);
  5989. + int (*map_buffer)(uint64_t gfx_handle, intel_ipts_mapbuffer_t *mapbuffer);
  5990. + int (*unmap_buffer)(uint64_t gfx_handle, uint64_t buf_handle);
  5991. +} intel_ipts_ops_t;
  5992. +
  5993. +typedef struct intel_ipts_callback {
  5994. + void (*workload_complete)(void *data);
  5995. + void (*notify_gfx_status)(u32 status, void *data);
  5996. +} intel_ipts_callback_t;
  5997. +
  5998. +typedef struct intel_ipts_connect {
  5999. + intel_ipts_callback_t ipts_cb; /* input : callback addresses */
  6000. + void *data; /* input : callback data */
  6001. + u32 if_version; /* input : interface version */
  6002. +
  6003. + u32 gfx_version; /* output : gfx version */
  6004. + u64 gfx_handle; /* output : gfx handle */
  6005. + intel_ipts_ops_t ipts_ops; /* output : gfx ops for IPTS */
  6006. +} intel_ipts_connect_t;
  6007. +
  6008. +int intel_ipts_connect(intel_ipts_connect_t *ipts_connect);
  6009. +void intel_ipts_disconnect(uint64_t gfx_handle);
  6010. +
  6011. +#endif // INTEL_IPTS_IF_H