| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745 |
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/interrupt.h>
- #include <linux/device.h>
- #include <linux/platform_device.h>
- #include <linux/mm.h>
- #include <linux/uaccess.h>
- #include <linux/slab.h>
- #include <linux/spinlock.h>
- #include <linux/irq.h>
- #include <linux/sched.h>
- #include <linux/list.h>
- #ifdef CONFIG_MTK_AEE_FEATURE
- #include <mt-plat/aee.h>
- #endif
- #include <linux/timer.h>
- #include <linux/workqueue.h>
- #include <mt-plat/mt_device_apc.h>
- #include <mt-plat/sync_write.h>
- #include "mach/irqs.h"
- #include <mt-plat/dma.h>
- #include <linux/of.h>
- #include <linux/of_address.h>
- #include <linux/of_irq.h>
- #include <mt-plat/mt_io.h>
- #include "mach/emi_mpu.h"
- #define ENABLE_EMI_CHKER
- #define ENABLE_EMI_WATCH_POINT
- #define NR_REGION_ABORT 15
- #define MAX_EMI_MPU_STORE_CMD_LEN 128
- #define TIMEOUT 100
- #define AXI_VIO_MONITOR_TIME (1 * HZ)
- static struct work_struct emi_mpu_work;
- static struct workqueue_struct *emi_mpu_workqueue;
- static unsigned int vio_addr;
- static unsigned int emi_physical_offset;
- struct mst_tbl_entry {
- u32 master;
- u32 port;
- u32 id_mask;
- u32 id_val;
- char *note;
- char *name;
- };
- struct emi_mpu_notifier_block {
- struct list_head list;
- emi_mpu_notifier notifier;
- };
- static const struct mst_tbl_entry mst_tbl[] = {
- /* apmcu */
- #if defined(CONFIG_ARCH_MT6753)
- /* --cluster 0 Write */
- {
- .master = MST_ID_APMCU_0,
- .port = 0x0,
- .id_mask = 0x3E7,
- .id_val = 0x004,
- .note = "CA53: Core nn system",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_1,
- .port = 0x0,
- .id_mask = 0x3E7,
- .id_val = 0x024,
- .note = "CA53: Core nn barrier",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_2,
- .port = 0x0,
- .id_mask = 0x3FF,
- .id_val = 0x044,
- .note = "CA53: Unused",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_3,
- .port = 0x0,
- .id_mask = 0x3FF,
- .id_val = 0x04C,
- .note = "CA53: SCU generated barrier",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_4,
- .port = 0x0,
- .id_mask = 0x3F7,
- .id_val = 0x054,
- .note = "CA53: Unused",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_5,
- .port = 0x0,
- .id_mask = 0x3E7,
- .id_val = 0x064,
- .note = "CA53: Core nn non-re-orderable device write",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_6,
- .port = 0x0,
- .id_mask = 0x387,
- .id_val = 0x084,
- .note =
- "CA53: Write to normal memory, or re-orderable device memory",
- .name = "CA53"
- },
- /*--cluster 0 Read */
- {
- .master = MST_ID_APMCU_7,
- .port = 0x0,
- .id_mask = 0x39F,
- .id_val = 0x084,
- .note = "CA53: ACP read",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_8,
- .port = 0x0,
- .id_mask = 0x39F,
- .id_val = 0x08C,
- .note = "CA53: Unused",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_9,
- .port = 0x0,
- .id_mask = 0x397,
- .id_val = 0x094,
- .note = "CA53: Unused",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_10,
- .port = 0x0,
- .id_mask = 0x307,
- .id_val = 0x104,
- .note = "CA53: Core nn read",
- .name = "CA53"
- },
- /*--cluster 1 Write*/
- {
- .master = MST_ID_APMCU_11,
- .port = 0x0,
- .id_mask = 0x3E7,
- .id_val = 0x003,
- .note = "CA53: Core nn system",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_12,
- .port = 0x0,
- .id_mask = 0x3E7,
- .id_val = 0x023,
- .note = "CA53: Core nn barrier",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_13,
- .port = 0x0,
- .id_mask = 0x3FF,
- .id_val = 0x043,
- .note = "CA53: Unused",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_14,
- .port = 0x0,
- .id_mask = 0x3FF,
- .id_val = 0x04B,
- .note = "CA53: SCU generated barrier",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_15,
- .port = 0x0,
- .id_mask = 0x3F7,
- .id_val = 0x053,
- .note = "CA53: Unused",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_16,
- .port = 0x0,
- .id_mask = 0x3E7,
- .id_val = 0x063,
- .note = "CA53: Core nn non-re-orderable device write",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_17,
- .port = 0x0,
- .id_mask = 0x387,
- .id_val = 0x083,
- .note =
- "CA53: Write to normal memory, or re-orderable device memory",
- .name = "CA53"
- },
- /*--cluster 1 Read*/
- {
- .master = MST_ID_APMCU_18,
- .port = 0x0,
- .id_mask = 0x39F,
- .id_val = 0x083,
- .note = "CA53: ACP read",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_19,
- .port = 0x0,
- .id_mask = 0x39F,
- .id_val = 0x08B,
- .note = "CA53: Unused",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_20,
- .port = 0x0,
- .id_mask = 0x397,
- .id_val = 0x093,
- .note = "CA53: Unused",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_21,
- .port = 0x0,
- .id_mask = 0x307,
- .id_val = 0x103,
- .note = "CA53: Core nn read",
- .name = "CA53"
- },
- #else
- {
- .master = MST_ID_APMCU_0,
- .port = 0x0,
- .id_mask = 0x3FC,
- .id_val = 0x000,
- .note = "CA53: Core nn system",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_1,
- .port = 0x0,
- .id_mask = 0x3FC,
- .id_val = 0x004,
- .note = "CA53: Core nn barrier",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_2,
- .port = 0x0,
- .id_mask = 0x3FF,
- .id_val = 0x008,
- .note = "CA53: Unused",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_3,
- .port = 0x0,
- .id_mask = 0x3FF,
- .id_val = 0x009,
- .note = "CA53: SCU generated barrier",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_4,
- .port = 0x0,
- .id_mask = 0x3FE,
- .id_val = 0x006,
- .note = "CA53: Unused",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_5,
- .port = 0x0,
- .id_mask = 0x3FC,
- .id_val = 0x00C,
- .note = "CA53: Core nn non-re-orderable device write",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_6,
- .port = 0x0,
- .id_mask = 0x3F0,
- .id_val = 0x010,
- .note =
- "CA53: Write to normal memory, or re-orderable device memory",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_7,
- .port = 0x0,
- .id_mask = 0x3F3,
- .id_val = 0x010,
- .note = "CA53: ACP read",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_8,
- .port = 0x0,
- .id_mask = 0x3F3,
- .id_val = 0x011,
- .note = "CA53: Unused",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_9,
- .port = 0x0,
- .id_mask = 0x3F2,
- .id_val = 0x012,
- .note = "CA53: Unused",
- .name = "CA53"
- },
- {
- .master = MST_ID_APMCU_10,
- .port = 0x0,
- .id_mask = 0x3E0,
- .id_val = 0x020,
- .note = "CA53: Core nn read",
- .name = "CA53"
- },
- #endif
- /* MM */
- {
- .master = MST_ID_MM_0,
- .port = 0x1,
- .id_mask = 0x380,
- .id_val = 0x000,
- .note = "MM: Larb0",
- .name = "MM_Larb0"
- },
- {
- .master = MST_ID_MM_1,
- .port = 0x1,
- .id_mask = 0x380,
- .id_val = 0x080,
- .note = "MM: Larb1",
- .name = "MM_Larb1"
- },
- {
- .master = MST_ID_MM_2,
- .port = 0x1,
- .id_mask = 0x380,
- .id_val = 0x100,
- .note = "MM: Larb2",
- .name = "MM_Larb2"
- },
- {
- .master = MST_ID_MM_3,
- .port = 0x1,
- .id_mask = 0x380,
- .id_val = 0x180,
- .note = "MM: Larb3",
- .name = "MM_Larb3"
- },
- {
- .master = MST_ID_MM_4,
- .port = 0x1,
- .id_mask = 0x3FE,
- .id_val = 0x3FC,
- .note = "MM IOMMU Internal Used",
- .name = "MM_IOMMU"
- },
- /* Periperal */
- {
- .master = MST_ID_PERI_0,
- .port = 0x2,
- .id_mask = 0x3F7,
- .id_val = 0x000,
- .note = "PERI: DebugTop",
- .name = "DebugTop"
- },
- {
- .master = MST_ID_PERI_1,
- .port = 0x2,
- .id_mask = 0x3FF,
- .id_val = 0x002,
- .note = "PERI: MSDC0",
- .name = "MSDC0"
- },
- {
- .master = MST_ID_PERI_2,
- .port = 0x2,
- .id_mask = 0x3FF,
- .id_val = 0x001,
- .note = "PERI: reserve",
- .name = "reserve"
- },
- {
- .master = MST_ID_PERI_3,
- .port = 0x2,
- .id_mask = 0x3FF,
- .id_val = 0x021,
- .note = "PERI: reserve",
- .name = "reserve"
- },
- {
- .master = MST_ID_PERI_4,
- .port = 0x2,
- .id_mask = 0x3FF,
- .id_val = 0x041,
- .note = "PERI: MSDC3",
- .name = "MSDC3"
- },
- {
- .master = MST_ID_PERI_5,
- .port = 0x2,
- .id_mask = 0x3FF,
- .id_val = 0x061,
- .note = "PERI: USB2.0",
- .name = "USB"
- },
- {
- .master = MST_ID_PERI_6,
- .port = 0x2,
- .id_mask = 0x3FF,
- .id_val = 0x009,
- .note = "PERI: PWM",
- .name = "PWM"
- },
- {
- .master = MST_ID_PERI_7,
- .port = 0x2,
- .id_mask = 0x3FF,
- .id_val = 0x029,
- .note = "PERI: MSDC1",
- .name = "MSDC1"
- },
- {
- .master = MST_ID_PERI_8,
- .port = 0x2,
- .id_mask = 0x3FF,
- .id_val = 0x049,
- .note = "PERI: MSDC2",
- .name = "MSDC2"
- },
- {
- .master = MST_ID_PERI_9,
- .port = 0x2,
- .id_mask = 0x3FF,
- .id_val = 0x069,
- .note = "PERI: SPI0",
- .name = "SPI0"
- },
- {
- .master = MST_ID_PERI_10,
- .port = 0x2,
- .id_mask = 0x3FF,
- .id_val = 0x011,
- .note = "PERI: MD1 + MD2",
- .name = "MD1_MD2"
- },
- {
- .master = MST_ID_PERI_11,
- .port = 0x2,
- .id_mask = 0x3FF,
- .id_val = 0x031,
- .note = "PERI: SPM",
- .name = "SPM"
- },
- {
- .master = MST_ID_PERI_12,
- .port = 0x2,
- .id_mask = 0x3FF,
- .id_val = 0x051,
- .note = "PERI: AUDIO",
- .name = "AUDIO"
- },
- {
- .master = MST_ID_PERI_13,
- .port = 0x2,
- .id_mask = 0x3FF,
- .id_val = 0x071,
- .note = "PERI: THERM",
- .name = "THERM"
- },
- {
- .master = MST_ID_PERI_14,
- .port = 0x2,
- .id_mask = 0x3FF,
- .id_val = 0x019,
- .note = "PERI: DMA",
- .name = "DMA"
- },
- {
- .master = MST_ID_PERI_15,
- .port = 0x2,
- .id_mask = 0x3FF,
- .id_val = 0x003,
- .note = "PERI: CONNSYS",
- .name = "CONNSYS"
- },
- {
- .master = MST_ID_PERI_16,
- .port = 0x2,
- .id_mask = 0x3FF,
- .id_val = 0x004,
- .note = "PERI: GCPU_M",
- .name = "GCPU_M"
- },
- {
- .master = MST_ID_PERI_17,
- .port = 0x2,
- .id_mask = 0x3E7,
- .id_val = 0x005,
- .note = "PERI: GCE_M",
- .name = "GCE_M"
- },
- {
- .master = MST_ID_PERI_18,
- .port = 0x2,
- .id_mask = 0x3FF,
- .id_val = 0x006,
- .note = "PERI: CLDMA_AP",
- .name = "CLDMA_AP"
- },
- {
- .master = MST_ID_PERI_19,
- .port = 0x2,
- .id_mask = 0x3FF,
- .id_val = 0x00E,
- .note = "PERI: CLDMA_MD",
- .name = "CLDMA_MD"
- },
- /* Modem */
- {
- .master = MST_ID_MDMCU_0,
- .port = 0x3,
- .id_mask = 0x30F,
- .id_val = 0x000,
- .note = "MDMCU: ARM7",
- .name = "MDMCU"
- },
- {
- .master = MST_ID_MDMCU_1,
- .port = 0x3,
- .id_mask = 0x3FF,
- .id_val = 0x002,
- .note = "MDMCU",
- .name = "MDMCU"
- },
- {
- .master = MST_ID_MDMCU_2,
- .port = 0x3,
- .id_mask = 0x30F,
- .id_val = 0x004,
- .note = "MDMCU: PREFETCH",
- .name = "MDMCU"
- },
- {
- .master = MST_ID_MDMCU_3,
- .port = 0x3,
- .id_mask = 0x30F,
- .id_val = 0x008,
- .note = "MDMCU: ALC",
- .name = "MDMCU"
- },
- {
- .master = MST_ID_C2KMCU_0,
- .port = 0x3,
- .id_mask = 0x3FF,
- .id_val = 0x003,
- .note = "MDMCU: CK2 MCUP+ HW:ARM D PORT",
- .name = "MDMCU_C2K"
- },
- {
- .master = MST_ID_C2KMCU_1,
- .port = 0x3,
- .id_mask = 0x3FF,
- .id_val = 0x009,
- .note = "MDMCU: CK2 MCUP+ HW:ARM I PORT",
- .name = "MDMCU_C2K"
- },
- {
- .master = MST_ID_C2KMCU_2,
- .port = 0x3,
- .id_mask = 0x3FF,
- .id_val = 0x013,
- .note = "MDMCU: CK2 MCUP+ HW:DMA PORT",
- .name = "MDMCU_C2K"
- },
- /* Modem HW (2G/3G) */
- {
- .master = MST_ID_MDHW_0,
- .port = 0x4,
- .id_mask = 0x3FF,
- .id_val = 0x000,
- .note = "MDHW: MDGDMA",
- .name = "MDHW_MDGDMA"
- },
- {
- .master = MST_ID_MDHW_1,
- .port = 0x4,
- .id_mask = 0x3FB,
- .id_val = 0x001,
- .note = "MDHW: CLDMA_MD",
- .name = "MDHW_CLDMA_MD"
- },
- {
- .master = MST_ID_MDHW_2,
- .port = 0x4,
- .id_mask = 0x3FB,
- .id_val = 0x002,
- .note = "MDHW: ABM",
- .name = "MDHW_ABM"
- },
- {
- .master = MST_ID_MDHW_3,
- .port = 0x4,
- .id_mask = 0x3FB,
- .id_val = 0x003,
- .note = "MDHW: CLDMA_AP",
- .name = "MDHW_CLDMA_AP"
- },
- {
- .master = MST_ID_MDHW_4,
- .port = 0x4,
- .id_mask = 0x3F8,
- .id_val = 0x008,
- .note = "MDHW: MODEMSYS",
- .name = "MDHW_MODEMSYS"
- },
- {
- .master = MST_ID_MDHW_5,
- .port = 0x4,
- .id_mask = 0x3FE,
- .id_val = 0x010,
- .note = "MDHW: LTEL2_DMA",
- .name = "MDHW_LTEL2_DMA"
- },
- {
- .master = MST_ID_MDHW_6,
- .port = 0x4,
- .id_mask = 0x3FF,
- .id_val = 0x018,
- .note = "MDHW: TDDSYS, LTEL1_DMA",
- .name = "MDHW_TDDSYS_LTEL1_DMA"
- },
- {
- .master = MST_ID_MDHW_7,
- .port = 0x4,
- .id_mask = 0x3FE,
- .id_val = 0x020,
- .note = "MDHW: MODEM_HARQ",
- .name = "MDHW_MODEM_HARQ"
- },
- {
- .master = MST_ID_MDHW_8,
- .port = 0x4,
- .id_mask = 0x3FF,
- .id_val = 0x100,
- .note = "MDHW: HARQ ID",
- .name = "MDHW_HARQ_ID"
- },
- {
- .master = MST_ID_MDHW_9,
- .port = 0x4,
- .id_mask = 0x3FF,
- .id_val = 0x102,
- .note = "MDHW: POSITION ID",
- .name = "MDHW_POSITION_ID"
- },
- /* MFG */
- {
- .master = MST_ID_MFG_0,
- .port = 0x5,
- .id_mask = 0x3C0,
- .id_val = 0x000,
- .note = "MFG",
- .name = "MFG"
- },
- };
- static const char *UNKNOWN_MASTER = "unknown";
- static spinlock_t emi_mpu_lock;
- #ifdef ENABLE_EMI_CHKER
- struct timer_list emi_axi_vio_timer;
- #endif
- char *smi_larb0_port[7] = {
- "disp_ovl_0",
- "disp_rdma_0",
- "disp_wdma_0",
- "disp_rdma_1",
- "mdp_rdma",
- "mdp_wdma",
- "mdp_wrot"
- };
- char *smi_larb1_port[7] = {
- "hw_vdec_mc_ext",
- "hw_vdec_pp_ext",
- "hw_vdec_avc_mv_ext" ,
- "hw_vdec_pred_rd_ext",
- "hw_vdec_pred_wr_ext",
- "hw_vdec_vld_ext",
- "hw_vdec_ppwarp_ext"
- };
- char *smi_larb2_port[21] = {
- "cam_imgo",
- "cam_rrzo",
- "cam_aao",
- "cam_isco",
- "cam_esfko",
- "cam_imgo_s",
- "cam_isci",
- "cam_isci_d",
- "cam_bpci",
- "cam_bpci_d",
- "cam_ufdi",
- "cam_imgi",
- "cam_img2o",
- "cam_img3o",
- "cam_vipi",
- "cam_vip2i",
- "cam_vip3i",
- "cam_icei" ,
- "cam_rb" ,
- "cam_rp" ,
- "cam_wr"
- };
- char *smi_larb3_port[13] = {
- "venc_rcpu",
- "venc_rec",
- "venc_bsdma",
- "venc_sv_comv",
- "venc_rd_comv",
- "jpgenc_rdma",
- "jpgenc_bsdma",
- "jpgdec_wdma",
- "jpgdec_bsdma",
- "venc_cur_luma",
- "venc_cur_chroma",
- "venc_ref_luma",
- "vend_ref_chroma"
- };
- static int __match_id(u32 axi_id, int tbl_idx, u32 port_ID)
- {
- u32 mm_larb;
- u32 smi_port;
- if (((axi_id & mst_tbl[tbl_idx].id_mask) == mst_tbl[tbl_idx].id_val) &&
- (port_ID == mst_tbl[tbl_idx].port)) {
- switch (port_ID) {
- case 0: /* ARM */
- case 2: /* Peripheral */
- case 3: /* MDMCU ,C2K MCU */
- case 4: /* MD HW ,LTE */
- case 5: /* MFG */
- case 6:
- case 7:
- pr_err("Violation master name is %s.\n",
- mst_tbl[tbl_idx].name);
- break;
- case 1: /*MM*/
- mm_larb = axi_id>>7;
- smi_port = (axi_id & 0x7F) >> 2;
- if (mm_larb == 0x0) {
- /*smi_larb0 */
- if (smi_port >= ARRAY_SIZE(smi_larb0_port)) {
- pr_err("[EMI MPU ERROR] Invalidatemaster ID! %s",
- "lookup smi table failed!\n");
- return 0;
- }
- pr_err("Violation master name is %s (%s).\n",
- mst_tbl[tbl_idx].name,
- smi_larb0_port[smi_port]);
- } else if (mm_larb == 0x1) {
- /*smi_larb1*/
- if (smi_port >= ARRAY_SIZE(smi_larb1_port)) {
- pr_err("[EMI MPU ERROR] Invalidate master ID! %s",
- "lookup smi table failed!\n");
- return 0;
- }
- pr_err("Violation master name is %s (%s).\n",
- mst_tbl[tbl_idx].name,
- smi_larb1_port[smi_port]);
- } else if (mm_larb == 0x2) {
- /*smi_larb2*/
- if (smi_port >= ARRAY_SIZE(smi_larb2_port)) {
- pr_err("[EMI MPU ERROR] Invalidate master ID! %s",
- "lookup smi table failed!\n");
- return 0;
- }
- pr_err("Violation master name is %s (%s).\n",
- mst_tbl[tbl_idx].name,
- smi_larb2_port[smi_port]);
- } else if (mm_larb == 0x3) {
- /*smi_larb3*/
- if (smi_port >= ARRAY_SIZE(smi_larb3_port)) {
- pr_err("[EMI MPU ERROR] Invalidate master ID! %s",
- "lookup smi table failed!\n");
- return 0;
- }
- pr_err("Violation master name is %s (%s).\n",
- mst_tbl[tbl_idx].name,
- smi_larb3_port[smi_port]);
- } else /*MM IOMMU Internal Used*/ {
- pr_err("Violation master name is %s.\n",
- mst_tbl[tbl_idx].name);
- }
- break;
- default:
- pr_err("[EMI MPU ERROR] Invalidate port ID! lookup bus ID table failed!\n");
- break;
- }
- return 1;
- } else {
- return 0;
- }
- }
- static u32 __id2mst(u32 id)
- {
- int i;
- u32 axi_ID;
- u32 port_ID;
- axi_ID = (id >> 3) & 0x000001FFF;
- port_ID = id & 0x00000007;
- pr_err("[EMI MPU] axi_id = %x, port_id = %x\n", axi_ID, port_ID);
- for (i = 0; i < ARRAY_SIZE(mst_tbl); i++) {
- if (__match_id(axi_ID, i, port_ID))
- return mst_tbl[i].master;
- }
- return MST_INVALID;
- }
- static char *__id2name(u32 id)
- {
- int i;
- u32 axi_ID;
- u32 port_ID;
- axi_ID = (id >> 3) & 0x00001FFF;
- port_ID = id & 0x00000007;
- pr_err("[EMI MPU] axi_id = %x, port_id = %x\n", axi_ID, port_ID);
- for (i = 0; i < ARRAY_SIZE(mst_tbl); i++) {
- if (__match_id(axi_ID, i, port_ID))
- return mst_tbl[i].name;
- }
- return (char *)UNKNOWN_MASTER;
- }
- static void __clear_emi_mpu_vio(void)
- {
- u32 dbg_s, dbg_t;
- /* clear violation status */
- mt_reg_sync_writel(0x00FF03FF, EMI_MPUP);
- mt_reg_sync_writel(0x00FF03FF, EMI_MPUQ);
- mt_reg_sync_writel(0x00FF03FF, EMI_MPUR);
- mt_reg_sync_writel(0x00FF03FF, EMI_MPUY);
- mt_reg_sync_writel(0x00FF03FF, EMI_MPUP2);
- mt_reg_sync_writel(0x00FF03FF, EMI_MPUQ2);
- mt_reg_sync_writel(0x00FF03FF, EMI_MPUR2);
- mt_reg_sync_writel(0x00FF03FF, EMI_MPUY2);
- /* clear debug info */
- mt_reg_sync_writel(0x80000000, EMI_MPUS);
- dbg_s = readl(IOMEM(EMI_MPUS));
- dbg_t = readl(IOMEM(EMI_MPUT));
- /* MT6582 EMI hw bug EMI_MPUS[10:0] and EMI_MPUT can't be cleared */
- if (dbg_s) {
- pr_err("Fail to clear EMI MPU violation\n");
- pr_err("EMI_MPUS = %x, EMI_MPUT = %x", dbg_s, dbg_t);
- }
- }
- /*EMI MPU violation handler*/
- static irqreturn_t mpu_violation_irq(int irq, void *dev_id)
- {
- u32 dbg_s, dbg_t, dbg_pqry;
- u32 master_ID, domain_ID, wr_vio;
- s32 region;
- int res;
- char *master_name;
- /* Need DEVAPC owner porting */
- res = mt_devapc_check_emi_violation();
- if (res)
- return IRQ_NONE;
- pr_debug("It's a MPU violation.\n");
- dbg_s = readl(IOMEM(EMI_MPUS));
- dbg_t = readl(IOMEM(EMI_MPUT));
- pr_debug("Clear status.\n");
- /*in 6735 Master ID valid bit is [13:0] */
- master_ID = (dbg_s & 0x00003FFF);
- domain_ID = (dbg_s >> 21) & 0x00000007;
- wr_vio = (dbg_s >> 28) & 0x00000003;
- region = (dbg_s >> 16) & 0xF;
- switch (domain_ID) {
- case 0:
- dbg_pqry = readl(IOMEM(EMI_MPUP));
- break;
- case 1:
- dbg_pqry = readl(IOMEM(EMI_MPUQ));
- break;
- case 2:
- dbg_pqry = readl(IOMEM(EMI_MPUR));
- break;
- case 3:
- dbg_pqry = readl(IOMEM(EMI_MPUY));
- break;
- #if defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6753)
- case 4:
- dbg_pqry = readl(IOMEM(EMI_MPUP2));
- break;
- case 5:
- dbg_pqry = readl(IOMEM(EMI_MPUQ2));
- break;
- case 6:
- dbg_pqry = readl(IOMEM(EMI_MPUR2));
- break;
- case 7:
- dbg_pqry = readl(IOMEM(EMI_MPUY2));
- break;
- #endif
- default:
- dbg_pqry = 0;
- break;
- }
- /*TBD: print the abort region*/
- pr_err("EMI MPU violation.\n");
- pr_err("[EMI MPU] Debug info start ----------------------------------------\n");
- pr_err("EMI_MPUS = %x, EMI_MPUT = %x.\n", dbg_s, dbg_t);
- pr_err("Current process is \"%s \" (pid: %i).\n",
- current->comm, current->pid);
- pr_err("Violation address is 0x%x.\n", dbg_t + emi_physical_offset);
- pr_err("Violation master ID is 0x%x.\n", master_ID);
- /*print out the murderer name*/
- master_name = __id2name(master_ID);
- pr_err("Violation domain ID is 0x%x.\n", domain_ID);
- pr_err("%s violation.\n", (wr_vio == 1) ? "Write" : "Read");
- pr_err("Corrupted region is %d\n\r", region);
- if (dbg_pqry & OOR_VIO)
- pr_err("Out of range violation.\n");
- pr_err("[EMI MPU] Debug info end------------------------------------------\n");
- #if 0
- /* For MDHW debug usage, 0x6C -> MDHW, Master is 3G */
- if (dbg_s & 0x6C)
- exec_ccci_kern_func_by_md_id(0, ID_FORCE_MD_ASSERT, NULL, 0);
- #endif
- #ifdef CONFIG_MTK_AEE_FEATURE
- /*FIXME: skip ca53 violation to trigger root-cause KE*/
- if ((0 != dbg_s) &&
- (__id2mst(master_ID) != MST_ID_APMCU_0)
- && (__id2mst(master_ID) != MST_ID_APMCU_1)) {
- aee_kernel_exception("EMI MPU",
- "EMI MPU violation.\nEMI_MPUS = 0x%x,EMI_MPUT = 0x%x\nCRDISPATCH_KEY:EMI MPU Violation Issue/%s\n",
- dbg_s, dbg_t+emi_physical_offset, master_name);
- }
- #endif
- __clear_emi_mpu_vio();
- mt_devapc_clear_emi_violation();
- #if 0
- list_for_each(p, &(emi_mpu_notifier_list[__id2mst(master_ID)])) {
- block = list_entry(p, struct emi_mpu_notifier_block, list);
- block->notifier(dbg_t + emi_physical_offset, wr_vio);
- }
- #endif
- vio_addr = dbg_t + emi_physical_offset;
- return IRQ_HANDLED;
- }
- #if defined(CONFIG_ARCH_MT6753)
- /* Acquire DRAM Setting for PASR/DPD */
- void acquire_dram_setting(struct basic_dram_setting *pasrdpd)
- {
- int ch_nr = MAX_CHANNELS;
- unsigned int emi_cona, emi_conh, col_bit, row_bit;
- unsigned int ch0_rank0_size, ch0_rank1_size;
- unsigned int ch1_rank0_size, ch1_rank1_size;
- pasrdpd->channel_nr = ch_nr;
- emi_cona = readl(IOMEM(EMI_CONA));
- emi_conh = readl(IOMEM(EMI_CONH));
- ch0_rank0_size = (emi_conh >> 16) & 0xf;
- ch0_rank1_size = (emi_conh >> 20) & 0xf;
- ch1_rank0_size = (emi_conh >> 24) & 0xf;
- ch1_rank1_size = (emi_conh >> 28) & 0xf;
- /*channel 0*/
- {
- /*rank 0*/
- pasrdpd->channel[0].rank[0].valid_rank = true;
- if (ch0_rank0_size == 0) {
- col_bit = ((emi_cona >> 4) & 0x03) + 9;
- row_bit = ((emi_cona >> 12) & 0x03) + 13;
- /* 32 bits * 8 banks, unit Gb*/
- pasrdpd->channel[0].rank[0].rank_size =
- (1 << (row_bit + col_bit)) >> 22;
- pasrdpd->channel[0].rank[0].segment_nr = 8;
- } else {
- pasrdpd->channel[0].rank[0].rank_size =
- (ch0_rank0_size * 2);
- /*unit Gb*/
- pasrdpd->channel[0].rank[0].segment_nr = 6;
- }
- if (0 != (emi_cona & (1 << 17))) {
- /*rank 1 exist*/
- pasrdpd->channel[0].rank[1].valid_rank = true;
- if (ch0_rank1_size == 0) {
- col_bit = ((emi_cona >> 6) & 0x03) + 9;
- row_bit = ((emi_cona >> 14) & 0x03) + 13;
- pasrdpd->channel[0].rank[1].rank_size =
- (1 << (row_bit + col_bit)) >> 22;
- /*32 bits * 8 banks, unit Gb*/
- pasrdpd->channel[0].rank[1].segment_nr = 8;
- } else {
- pasrdpd->channel[0].rank[1].rank_size =
- (ch0_rank1_size * 2);
- /* unit Gb*/
- pasrdpd->channel[0].rank[1].segment_nr = 6;
- }
- } else {
- pasrdpd->channel[0].rank[1].valid_rank = false;
- pasrdpd->channel[0].rank[1].segment_nr = 0;
- pasrdpd->channel[0].rank[1].rank_size = 0;
- }
- }
- if (0 != (emi_cona & 0x01)) {
- /*channel 1 exist*/
- /*rank0 setting*/
- pasrdpd->channel[1].rank[0].valid_rank = true;
- if (ch1_rank0_size == 0) {
- col_bit = ((emi_cona >> 20) & 0x03) + 9;
- row_bit = ((emi_cona >> 28) & 0x03) + 13;
- pasrdpd->channel[1].rank[0].rank_size =
- (1 << (row_bit + col_bit)) >> 22;
- /* 32 bits * 8 banks, unit Gb*/
- pasrdpd->channel[1].rank[0].segment_nr = 8;
- } else {
- pasrdpd->channel[1].rank[0].rank_size =
- (ch1_rank0_size * 2);
- /* unit Gb*/
- pasrdpd->channel[1].rank[0].segment_nr = 6;
- }
- if (0 != (emi_cona & (1 << 16))) {
- /*rank 1 exist*/
- pasrdpd->channel[1].rank[1].valid_rank = true;
- if (ch1_rank1_size == 0) {
- col_bit = ((emi_cona >> 22) & 0x03) + 9;
- row_bit = ((emi_cona >> 30) & 0x03) + 13;
- pasrdpd->channel[1].rank[1].rank_size =
- (1 << (row_bit + col_bit)) >> 22;
- /* 32 bits * 8 banks, unit Gb*/
- pasrdpd->channel[1].rank[1].segment_nr = 8;
- } else {
- pasrdpd->channel[1].rank[1].rank_size =
- (ch1_rank1_size * 2);
- /* unit Gb*/
- pasrdpd->channel[1].rank[1].segment_nr = 6;
- }
- } else {
- pasrdpd->channel[1].rank[1].valid_rank = false;
- pasrdpd->channel[1].rank[1].segment_nr = 0;
- pasrdpd->channel[1].rank[1].rank_size = 0;
- }
- } else {
- /*channel 2 does not exist*/
- pasrdpd->channel[1].rank[0].valid_rank = false;
- pasrdpd->channel[1].rank[0].segment_nr = 0;
- pasrdpd->channel[1].rank[0].rank_size = 0;
- pasrdpd->channel[1].rank[1].valid_rank = false;
- pasrdpd->channel[1].rank[1].segment_nr = 0;
- pasrdpd->channel[1].rank[1].rank_size = 0;
- }
- }
- #endif
- /*
- * emi_mpu_set_region_protection: protect a region.
- * @start: start address of the region
- * @end: end address of the region
- * @region: EMI MPU region id
- * @access_permission: EMI MPU access permission
- * Return 0 for success, otherwise negative status code.
- */
- int emi_mpu_set_region_protection(unsigned int start,
- unsigned int end, int region, unsigned int access_permission)
- {
- int ret = 0;
- unsigned int tmp, tmp2;
- unsigned int ax_pm, ax_pm2;
- unsigned long flags;
- if ((end != 0) || (start != 0)) {
- /*Address 64KB alignment*/
- start -= emi_physical_offset;
- end -= emi_physical_offset;
- start = start >> 16;
- end = end >> 16;
- if (end < start)
- return -EINVAL;
- }
- ax_pm = (access_permission << 16) >> 16;
- ax_pm2 = (access_permission >> 16);
- spin_lock_irqsave(&emi_mpu_lock, flags);
- switch (region) {
- case 0:
- /* Clear access right before setting MPU address*/
- tmp = readl(IOMEM(EMI_MPUI)) & 0xFFFF0000;
- tmp2 = readl(IOMEM(EMI_MPUI_2ND)) & 0xFFFF0000;
- mt_reg_sync_writel(0, EMI_MPUI);
- mt_reg_sync_writel(0, EMI_MPUI_2ND);
- mt_reg_sync_writel((start << 16) | end, EMI_MPUA);
- mt_reg_sync_writel(tmp | ax_pm, EMI_MPUI);
- mt_reg_sync_writel(tmp2 | ax_pm2, EMI_MPUI_2ND);
- break;
- case 1:
- /* Clear access right before setting MPU address */
- tmp = readl(IOMEM(EMI_MPUI)) & 0x0000FFFF;
- tmp2 = readl(IOMEM(EMI_MPUI_2ND)) & 0x0000FFFF;
- mt_reg_sync_writel(0, EMI_MPUI);
- mt_reg_sync_writel(0, EMI_MPUI_2ND);
- mt_reg_sync_writel((start << 16) | end, EMI_MPUB);
- mt_reg_sync_writel(tmp | (ax_pm << 16), EMI_MPUI);
- mt_reg_sync_writel(tmp2 | (ax_pm2 << 16), EMI_MPUI_2ND);
- break;
- case 2:
- /* Clear access right before setting MPU address */
- tmp = readl(IOMEM(EMI_MPUJ)) & 0xFFFF0000;
- tmp2 = readl(IOMEM(EMI_MPUJ_2ND)) & 0xFFFF0000;
- mt_reg_sync_writel(0, EMI_MPUJ);
- mt_reg_sync_writel(0, EMI_MPUJ_2ND);
- mt_reg_sync_writel((start << 16) | end, EMI_MPUC);
- mt_reg_sync_writel(tmp | ax_pm, EMI_MPUJ);
- mt_reg_sync_writel(tmp2 | ax_pm2, EMI_MPUJ_2ND);
- break;
- case 3:
- /* Clear access right before setting MPU address */
- tmp = readl(IOMEM(EMI_MPUJ)) & 0x0000FFFF;
- tmp2 = readl(IOMEM(EMI_MPUJ_2ND)) & 0x0000FFFF;
- mt_reg_sync_writel(0, EMI_MPUJ);
- mt_reg_sync_writel(0, EMI_MPUJ_2ND);
- mt_reg_sync_writel((start << 16) | end, EMI_MPUD);
- mt_reg_sync_writel(tmp | (ax_pm << 16), EMI_MPUJ);
- mt_reg_sync_writel(tmp2 | (ax_pm2 << 16), EMI_MPUJ_2ND);
- break;
- case 4:
- /* Clear access right before setting MPU address */
- tmp = readl(IOMEM(EMI_MPUK)) & 0xFFFF0000;
- tmp2 = readl(IOMEM(EMI_MPUK_2ND)) & 0xFFFF0000;
- mt_reg_sync_writel(0, EMI_MPUK);
- mt_reg_sync_writel(0, EMI_MPUK_2ND);
- mt_reg_sync_writel((start << 16) | end, EMI_MPUE);
- mt_reg_sync_writel(tmp | ax_pm, EMI_MPUK);
- mt_reg_sync_writel(tmp2 | ax_pm2, EMI_MPUK_2ND);
- break;
- case 5:
- /* Clear access right before setting MPU address */
- tmp = readl(IOMEM(EMI_MPUK)) & 0x0000FFFF;
- tmp2 = readl(IOMEM(EMI_MPUK_2ND)) & 0x0000FFFF;
- mt_reg_sync_writel(0, EMI_MPUK);
- mt_reg_sync_writel(0, EMI_MPUK_2ND);
- mt_reg_sync_writel((start << 16) | end, EMI_MPUF);
- mt_reg_sync_writel(tmp | (ax_pm << 16), EMI_MPUK);
- mt_reg_sync_writel(tmp2 | (ax_pm2 << 16), EMI_MPUK_2ND);
- break;
- case 6:
- /* Clear access right before setting MPU address */
- tmp = readl(IOMEM(EMI_MPUL)) & 0xFFFF0000;
- tmp2 = readl(IOMEM(EMI_MPUL_2ND)) & 0xFFFF0000;
- mt_reg_sync_writel(0, EMI_MPUL);
- mt_reg_sync_writel(0, EMI_MPUL_2ND);
- mt_reg_sync_writel((start << 16) | end, EMI_MPUG);
- mt_reg_sync_writel(tmp | ax_pm, EMI_MPUL);
- mt_reg_sync_writel(tmp2 | ax_pm2, EMI_MPUL_2ND);
- break;
- case 7:
- /* Clear access right before setting MPU address */
- tmp = readl(IOMEM(EMI_MPUL)) & 0x0000FFFF;
- tmp2 = readl(IOMEM(EMI_MPUL_2ND)) & 0x0000FFFF;
- mt_reg_sync_writel(0, EMI_MPUL);
- mt_reg_sync_writel(0, EMI_MPUL_2ND);
- mt_reg_sync_writel((start << 16) | end, EMI_MPUH);
- mt_reg_sync_writel(tmp | (ax_pm << 16), EMI_MPUL);
- mt_reg_sync_writel(tmp2 | (ax_pm2 << 16), EMI_MPUL_2ND);
- break;
- #if defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6753)
- case 8:
- /* Clear access right before setting MPU address */
- tmp = readl(IOMEM(EMI_MPUI2)) & 0xFFFF0000;
- tmp2 = readl(IOMEM(EMI_MPUI2_2ND)) & 0xFFFF0000;
- mt_reg_sync_writel(0, EMI_MPUI2);
- mt_reg_sync_writel(0, EMI_MPUI2_2ND);
- mt_reg_sync_writel((start << 16) | end, EMI_MPUA2);
- mt_reg_sync_writel(tmp | ax_pm, EMI_MPUI2);
- mt_reg_sync_writel(tmp2 | ax_pm2, EMI_MPUI2_2ND);
- break;
- case 9:
- /* Clear access right before setting MPU address */
- tmp = readl(IOMEM(EMI_MPUI2)) & 0x0000FFFF;
- tmp2 = readl(IOMEM(EMI_MPUI2_2ND)) & 0x0000FFFF;
- mt_reg_sync_writel(0, EMI_MPUI2);
- mt_reg_sync_writel(0, EMI_MPUI2_2ND);
- mt_reg_sync_writel((start << 16) | end, EMI_MPUB2);
- mt_reg_sync_writel(tmp | (ax_pm << 16), EMI_MPUI2);
- mt_reg_sync_writel(tmp2 | (ax_pm2 << 16), EMI_MPUI2_2ND);
- break;
- case 10:
- /* Clear access right before setting MPU address */
- tmp = readl(IOMEM(EMI_MPUJ2)) & 0xFFFF0000;
- tmp2 = readl(IOMEM(EMI_MPUJ2_2ND)) & 0xFFFF0000;
- mt_reg_sync_writel(0, EMI_MPUJ2);
- mt_reg_sync_writel(0, EMI_MPUJ2_2ND);
- mt_reg_sync_writel((start << 16) | end, EMI_MPUC2);
- mt_reg_sync_writel(tmp | ax_pm, EMI_MPUJ2);
- mt_reg_sync_writel(tmp2 | ax_pm2, EMI_MPUJ2_2ND);
- break;
- case 11:
- /* Clear access right before setting MPU address */
- tmp = readl(IOMEM(EMI_MPUJ2)) & 0x0000FFFF;
- tmp2 = readl(IOMEM(EMI_MPUJ2_2ND)) & 0x0000FFFF;
- mt_reg_sync_writel(0, EMI_MPUJ2);
- mt_reg_sync_writel(0, EMI_MPUJ2_2ND);
- mt_reg_sync_writel((start << 16) | end, EMI_MPUD2);
- mt_reg_sync_writel(tmp | (ax_pm << 16), EMI_MPUJ2);
- mt_reg_sync_writel(tmp2 | (ax_pm2 << 16), EMI_MPUJ2_2ND);
- break;
- case 12:
- /* Clear access right before setting MPU address */
- tmp = readl(IOMEM(EMI_MPUK2)) & 0xFFFF0000;
- tmp2 = readl(IOMEM(EMI_MPUK2_2ND)) & 0xFFFF0000;
- mt_reg_sync_writel(0, EMI_MPUK2);
- mt_reg_sync_writel(0, EMI_MPUK2_2ND);
- mt_reg_sync_writel((start << 16) | end, EMI_MPUE2);
- mt_reg_sync_writel(tmp | ax_pm, EMI_MPUK2);
- mt_reg_sync_writel(tmp2 | ax_pm2, EMI_MPUK2_2ND);
- break;
- case 13:
- /* Clear access right before setting MPU address */
- tmp = readl(IOMEM(EMI_MPUK2)) & 0x0000FFFF;
- tmp2 = readl(IOMEM(EMI_MPUK2_2ND)) & 0x0000FFFF;
- mt_reg_sync_writel(0, EMI_MPUK2);
- mt_reg_sync_writel(0, EMI_MPUK2_2ND);
- mt_reg_sync_writel((start << 16) | end, EMI_MPUF2);
- mt_reg_sync_writel(tmp | (ax_pm << 16), EMI_MPUK2);
- mt_reg_sync_writel(tmp2 | (ax_pm2 << 16), EMI_MPUK2_2ND);
- break;
- case 14:
- /* Clear access right before setting MPU address */
- tmp = readl(IOMEM(EMI_MPUL2)) & 0xFFFF0000;
- tmp2 = readl(IOMEM(EMI_MPUL2_2ND)) & 0xFFFF0000;
- mt_reg_sync_writel(0, EMI_MPUL2);
- mt_reg_sync_writel(0, EMI_MPUL2_2ND);
- mt_reg_sync_writel((start << 16) | end, EMI_MPUG2);
- mt_reg_sync_writel(tmp | ax_pm, EMI_MPUL2);
- mt_reg_sync_writel(tmp2 | ax_pm2, EMI_MPUL2_2ND);
- break;
- case 15:
- /* Clear access right before setting MPU address */
- tmp = readl(IOMEM(EMI_MPUL2)) & 0x0000FFFF;
- tmp2 = readl(IOMEM(EMI_MPUL2_2ND)) & 0x0000FFFF;
- mt_reg_sync_writel(0, EMI_MPUL2);
- mt_reg_sync_writel(0, EMI_MPUL2_2ND);
- mt_reg_sync_writel((start << 16) | end, EMI_MPUH2);
- mt_reg_sync_writel(tmp | (ax_pm << 16), EMI_MPUL2);
- mt_reg_sync_writel(tmp2 | (ax_pm2 << 16), EMI_MPUL2_2ND);
- break;
- #endif
- default:
- ret = -EINVAL;
- break;
- }
- spin_unlock_irqrestore(&emi_mpu_lock, flags);
- #if 0
- pr_debug("[EMI MPU] emi_physical_offset = 0x%x\n", emi_physical_offset);
- pr_debug("[EMI MPU] EMI_MPUA = 0x%x\n", readl(IOMEM(EMI_MPUA)));
- pr_debug("[EMI MPU] EMI_MPUB = 0x%x\n", readl(IOMEM(EMI_MPUB)));
- pr_debug("[EMI MPU] EMI_MPUC = 0x%x\n", readl(IOMEM(EMI_MPUC)));
- pr_debug("[EMI MPU] EMI_MPUD = 0x%x\n", readl(IOMEM(EMI_MPUD)));
- pr_debug("[EMI MPU] EMI_MPUE = 0x%x\n", readl(IOMEM(EMI_MPUE)));
- pr_debug("[EMI MPU] EMI_MPUF = 0x%x\n", readl(IOMEM(EMI_MPUF)));
- pr_debug("[EMI MPU] EMI_MPUG = 0x%x\n", readl(IOMEM(EMI_MPUG)));
- pr_debug("[EMI MPU] EMI_MPUH = 0x%x\n", readl(IOMEM(EMI_MPUH)));
- pr_debug("[EMI MPU] EMI_MPUA2 = 0x%x\n", readl(IOMEM(EMI_MPUA2)));
- pr_debug("[EMI MPU] EMI_MPUB2 = 0x%x\n", readl(IOMEM(EMI_MPUB2)));
- pr_debug("[EMI MPU] EMI_MPUC2 = 0x%x\n", readl(IOMEM(EMI_MPUC2)));
- pr_debug("[EMI MPU] EMI_MPUD2 = 0x%x\n", readl(IOMEM(EMI_MPUD2)));
- pr_debug("[EMI MPU] EMI_MPUE2 = 0x%x\n", readl(IOMEM(EMI_MPUE2)));
- pr_debug("[EMI MPU] EMI_MPUF2 = 0x%x\n", readl(IOMEM(EMI_MPUF2)));
- pr_debug("[EMI MPU] EMI_MPUG2 = 0x%x\n", readl(IOMEM(EMI_MPUG2)));
- pr_debug("[EMI MPU] EMI_MPUH2 = 0x%x\n", readl(IOMEM(EMI_MPUH2)));
- #endif
- return ret;
- }
- EXPORT_SYMBOL(emi_mpu_set_region_protection);
- /*
- * emi_mpu_notifier_register: register a notifier.
- * master: MST_ID_xxx
- * notifier: the callback function
- * Return 0 for success, otherwise negative error code.
- */
- #if 0
- int emi_mpu_notifier_register(int master, emi_mpu_notifier notifier)
- {
- struct emi_mpu_notifier_block *block;
- static int emi_mpu_notifier_init;
- int i;
- if (master >= MST_INVALID)
- return -EINVAL;
- block = kmalloc(sizeof(struct emi_mpu_notifier_block), GFP_KERNEL);
- if (!block)
- return -ENOMEM;
- if (!emi_mpu_notifier_init) {
- for (i = 0; i < NR_MST; i++)
- INIT_LIST_HEAD(&(emi_mpu_notifier_list[i]));
- emi_mpu_notifier_init = 1;
- }
- block->notifier = notifier;
- list_add(&(block->list), &(emi_mpu_notifier_list[master]));
- return 0;
- }
- #endif
- static ssize_t emi_mpu_show(struct device_driver *driver, char *buf)
- {
- char *ptr = buf;
- unsigned int start, end;
- unsigned int reg_value;
- unsigned int d0, d1, d2, d3;
- #if defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6753)
- unsigned int d4, d5, d6, d7, reg_value2;
- #endif
- static const char *permission[7] = {
- "No protect",
- "Only R/W for secure access",
- "Only R/W for secure access, and non-secure read access",
- "Only R/W for secure access, and non-secure write access",
- "Only R for secure/non-secure",
- "Both R/W are forbidden",
- "Only secure W is forbidden"
- };
- reg_value = readl(IOMEM(EMI_MPUA));
- start = ((reg_value >> 16) << 16) + emi_physical_offset;
- end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
- ptr += sprintf(ptr, "Region 0 --> 0x%x to 0x%x\n", start, end);
- reg_value = readl(IOMEM(EMI_MPUB));
- start = ((reg_value >> 16) << 16) + emi_physical_offset;
- end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
- ptr += sprintf(ptr, "Region 1 --> 0x%x to 0x%x\n", start, end);
- reg_value = readl(IOMEM(EMI_MPUC));
- start = ((reg_value >> 16) << 16) + emi_physical_offset;
- end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
- ptr += sprintf(ptr, "Region 2 --> 0x%x to 0x%x\n", start, end);
- reg_value = readl(IOMEM(EMI_MPUD));
- start = ((reg_value >> 16) << 16) + emi_physical_offset;
- end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
- ptr += sprintf(ptr, "Region 3 --> 0x%x to 0x%x\n", start, end);
- reg_value = readl(IOMEM(EMI_MPUE));
- start = ((reg_value >> 16) << 16) + emi_physical_offset;
- end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
- ptr += sprintf(ptr, "Region 4 --> 0x%x to 0x%x\n", start, end);
- reg_value = readl(IOMEM(EMI_MPUF));
- start = ((reg_value >> 16) << 16) + emi_physical_offset;
- end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
- ptr += sprintf(ptr, "Region 5 --> 0x%x to 0x%x\n", start, end);
- reg_value = readl(IOMEM(EMI_MPUG));
- start = ((reg_value >> 16) << 16) + emi_physical_offset;
- end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
- ptr += sprintf(ptr, "Region 6 --> 0x%x to 0x%x\n", start, end);
- reg_value = readl(IOMEM(EMI_MPUH));
- start = ((reg_value >> 16) << 16) + emi_physical_offset;
- end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
- ptr += sprintf(ptr, "Region 7 --> 0x%x to 0x%x\n", start, end);
- #if defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6753)
- reg_value = readl(IOMEM(EMI_MPUA2));
- start = ((reg_value >> 16) << 16) + emi_physical_offset;
- end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
- ptr += sprintf(ptr, "Region 8 --> 0x%x to 0x%x\n", start, end);
- reg_value = readl(IOMEM(EMI_MPUB2));
- start = ((reg_value >> 16) << 16) + emi_physical_offset;
- end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
- ptr += sprintf(ptr, "Region 9 --> 0x%x to 0x%x\n", start, end);
- reg_value = readl(IOMEM(EMI_MPUC2));
- start = ((reg_value >> 16) << 16) + emi_physical_offset;
- end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
- ptr += sprintf(ptr, "Region 10 --> 0x%x to 0x%x\n", start, end);
- reg_value = readl(IOMEM(EMI_MPUD2));
- start = ((reg_value >> 16) << 16) + emi_physical_offset;
- end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
- ptr += sprintf(ptr, "Region 11 --> 0x%x to 0x%x\n", start, end);
- reg_value = readl(IOMEM(EMI_MPUE2));
- start = ((reg_value >> 16) << 16) + emi_physical_offset;
- end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
- ptr += sprintf(ptr, "Region 12 --> 0x%x to 0x%x\n", start, end);
- reg_value = readl(IOMEM(EMI_MPUF2));
- start = ((reg_value >> 16) << 16) + emi_physical_offset;
- end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
- ptr += sprintf(ptr, "Region 13 --> 0x%x to 0x%x\n", start, end);
- reg_value = readl(IOMEM(EMI_MPUG2));
- start = ((reg_value >> 16) << 16) + emi_physical_offset;
- end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
- ptr += sprintf(ptr, "Region 14 --> 0x%x to 0x%x\n", start, end);
- reg_value = readl(IOMEM(EMI_MPUH2));
- start = ((reg_value >> 16) << 16) + emi_physical_offset;
- end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
- ptr += sprintf(ptr, "Region 15 --> 0x%x to 0x%x\n", start, end);
- #endif
- ptr += sprintf(ptr, "\n");
- #if defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6753)
- reg_value = readl(IOMEM(EMI_MPUI));
- reg_value2 = readl(IOMEM(EMI_MPUI_2ND));
- d0 = (reg_value & 0x7);
- d1 = (reg_value >> 3) & 0x7;
- d2 = (reg_value >> 6) & 0x7;
- d3 = (reg_value >> 9) & 0x7;
- d4 = (reg_value2 & 0x7);
- d5 = (reg_value2 >> 3) & 0x7;
- d6 = (reg_value2 >> 6) & 0x7;
- d7 = (reg_value2 >> 9) & 0x7;
- ptr += sprintf(ptr, "Region 0 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
- permission[d0],
- permission[d1],
- permission[d2],
- permission[d3]);
- ptr += sprintf(ptr, "Region 0 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
- permission[d4],
- permission[d5],
- permission[d6],
- permission[d7]);
- d0 = ((reg_value>>16) & 0x7);
- d1 = ((reg_value>>16) >> 3) & 0x7;
- d2 = ((reg_value>>16) >> 6) & 0x7;
- d3 = ((reg_value>>16) >> 9) & 0x7;
- d4 = ((reg_value2>>16) & 0x7);
- d5 = ((reg_value2>>16) >> 3) & 0x7;
- d6 = ((reg_value2>>16) >> 6) & 0x7;
- d7 = ((reg_value2>>16) >> 9) & 0x7;
- ptr += sprintf(ptr, "Region 1 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
- permission[d0],
- permission[d1],
- permission[d2],
- permission[d3]);
- ptr += sprintf(ptr, "Region 1 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
- permission[d4],
- permission[d5],
- permission[d6],
- permission[d7]);
- reg_value = readl(IOMEM(EMI_MPUJ));
- reg_value2 = readl(IOMEM(EMI_MPUJ_2ND));
- d0 = (reg_value & 0x7);
- d1 = (reg_value >> 3) & 0x7;
- d2 = (reg_value >> 6) & 0x7;
- d3 = (reg_value >> 9) & 0x7;
- d4 = (reg_value2 & 0x7);
- d5 = (reg_value2 >> 3) & 0x7;
- d6 = (reg_value2 >> 6) & 0x7;
- d7 = (reg_value2 >> 9) & 0x7;
- ptr += sprintf(ptr, "Region 2 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
- permission[d0],
- permission[d1],
- permission[d2],
- permission[d3]);
- ptr += sprintf(ptr, "Region 2 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
- permission[d4],
- permission[d5],
- permission[d6],
- permission[d7]);
- d0 = ((reg_value>>16) & 0x7);
- d1 = ((reg_value>>16) >> 3) & 0x7;
- d2 = ((reg_value>>16) >> 6) & 0x7;
- d3 = ((reg_value>>16) >> 9) & 0x7;
- d4 = ((reg_value2>>16) & 0x7);
- d5 = ((reg_value2>>16) >> 3) & 0x7;
- d6 = ((reg_value2>>16) >> 6) & 0x7;
- d7 = ((reg_value2>>16) >> 9) & 0x7;
- ptr += sprintf(ptr, "Region 3 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
- permission[d0],
- permission[d1],
- permission[d2],
- permission[d3]);
- ptr += sprintf(ptr, "Region 3 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
- permission[d4],
- permission[d5],
- permission[d6],
- permission[d7]);
- reg_value = readl(IOMEM(EMI_MPUK));
- reg_value2 = readl(IOMEM(EMI_MPUK_2ND));
- d0 = (reg_value & 0x7);
- d1 = (reg_value >> 3) & 0x7;
- d2 = (reg_value >> 6) & 0x7;
- d3 = (reg_value >> 9) & 0x7;
- d4 = (reg_value2 & 0x7);
- d5 = (reg_value2 >> 3) & 0x7;
- d6 = (reg_value2 >> 6) & 0x7;
- d7 = (reg_value2 >> 9) & 0x7;
- ptr += sprintf(ptr, "Region 4 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
- permission[d0],
- permission[d1],
- permission[d2],
- permission[d3]);
- ptr += sprintf(ptr, "Region 4 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
- permission[d4],
- permission[d5],
- permission[d6],
- permission[d7]);
- d0 = ((reg_value>>16) & 0x7);
- d1 = ((reg_value>>16) >> 3) & 0x7;
- d2 = ((reg_value>>16) >> 6) & 0x7;
- d3 = ((reg_value>>16) >> 9) & 0x7;
- d4 = ((reg_value2>>16) & 0x7);
- d5 = ((reg_value2>>16) >> 3) & 0x7;
- d6 = ((reg_value2>>16) >> 6) & 0x7;
- d7 = ((reg_value2>>16) >> 9) & 0x7;
- ptr += sprintf(ptr, "Region 5 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
- permission[d0],
- permission[d1],
- permission[d2],
- permission[d3]);
- ptr += sprintf(ptr, "Region 5 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
- permission[d4],
- permission[d5],
- permission[d6],
- permission[d7]);
- reg_value = readl(IOMEM(EMI_MPUL));
- reg_value2 = readl(IOMEM(EMI_MPUL_2ND));
- d0 = (reg_value & 0x7);
- d1 = (reg_value >> 3) & 0x7;
- d2 = (reg_value >> 6) & 0x7;
- d3 = (reg_value >> 9) & 0x7;
- d4 = (reg_value2 & 0x7);
- d5 = (reg_value2 >> 3) & 0x7;
- d6 = (reg_value2 >> 6) & 0x7;
- d7 = (reg_value2 >> 9) & 0x7;
- ptr += sprintf(ptr, "Region 6 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
- permission[d0],
- permission[d1],
- permission[d2],
- permission[d3]);
- ptr += sprintf(ptr, "Region 6 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
- permission[d4],
- permission[d5],
- permission[d6],
- permission[d7]);
- d0 = ((reg_value>>16) & 0x7);
- d1 = ((reg_value>>16) >> 3) & 0x7;
- d2 = ((reg_value>>16) >> 6) & 0x7;
- d3 = ((reg_value>>16) >> 9) & 0x7;
- d4 = ((reg_value2>>16) & 0x7);
- d5 = ((reg_value2>>16) >> 3) & 0x7;
- d6 = ((reg_value2>>16) >> 6) & 0x7;
- d7 = ((reg_value2>>16) >> 9) & 0x7;
- ptr += sprintf(ptr, "Region 7 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
- permission[d0],
- permission[d1],
- permission[d2],
- permission[d3]);
- ptr += sprintf(ptr, "Region 7 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
- permission[d4],
- permission[d5],
- permission[d6],
- permission[d7]);
- reg_value = readl(IOMEM(EMI_MPUI2));
- reg_value2 = readl(IOMEM(EMI_MPUI2_2ND));
- d0 = (reg_value & 0x7);
- d1 = (reg_value >> 3) & 0x7;
- d2 = (reg_value >> 6) & 0x7;
- d3 = (reg_value >> 9) & 0x7;
- d4 = (reg_value2 & 0x7);
- d5 = (reg_value2 >> 3) & 0x7;
- d6 = (reg_value2 >> 6) & 0x7;
- d7 = (reg_value2 >> 9) & 0x7;
- ptr += sprintf(ptr, "Region 8 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
- permission[d0],
- permission[d1],
- permission[d2],
- permission[d3]);
- ptr += sprintf(ptr, "Region 8 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
- permission[d4],
- permission[d5],
- permission[d6],
- permission[d7]);
- d0 = ((reg_value>>16) & 0x7);
- d1 = ((reg_value>>16) >> 3) & 0x7;
- d2 = ((reg_value>>16) >> 6) & 0x7;
- d3 = ((reg_value>>16) >> 9) & 0x7;
- d4 = ((reg_value2>>16) & 0x7);
- d5 = ((reg_value2>>16) >> 3) & 0x7;
- d6 = ((reg_value2>>16) >> 6) & 0x7;
- d7 = ((reg_value2>>16) >> 9) & 0x7;
- ptr += sprintf(ptr, "Region 9 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
- permission[d0],
- permission[d1],
- permission[d2],
- permission[d3]);
- ptr += sprintf(ptr, "Region 9 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
- permission[d4],
- permission[d5],
- permission[d6],
- permission[d7]);
- reg_value = readl(IOMEM(EMI_MPUJ2));
- reg_value2 = readl(IOMEM(EMI_MPUJ2_2ND));
- d0 = (reg_value & 0x7);
- d1 = (reg_value >> 3) & 0x7;
- d2 = (reg_value >> 6) & 0x7;
- d3 = (reg_value >> 9) & 0x7;
- d4 = (reg_value2 & 0x7);
- d5 = (reg_value2 >> 3) & 0x7;
- d6 = (reg_value2 >> 6) & 0x7;
- d7 = (reg_value2 >> 9) & 0x7;
- ptr += sprintf(ptr,
- "Region 10 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
- permission[d0],
- permission[d1],
- permission[d2],
- permission[d3]);
- ptr += sprintf(ptr,
- "Region 10 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
- permission[d4],
- permission[d5],
- permission[d6],
- permission[d7]);
- d0 = ((reg_value>>16) & 0x7);
- d1 = ((reg_value>>16) >> 3) & 0x7;
- d2 = ((reg_value>>16) >> 6) & 0x7;
- d3 = ((reg_value>>16) >> 9) & 0x7;
- d4 = ((reg_value2>>16) & 0x7);
- d5 = ((reg_value2>>16) >> 3) & 0x7;
- d6 = ((reg_value2>>16) >> 6) & 0x7;
- d7 = ((reg_value2>>16) >> 9) & 0x7;
- ptr += sprintf(ptr,
- "Region 11 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
- permission[d0],
- permission[d1],
- permission[d2],
- permission[d3]);
- ptr += sprintf(ptr,
- "Region 11 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
- permission[d4],
- permission[d5],
- permission[d6],
- permission[d7]);
- reg_value = readl(IOMEM(EMI_MPUK2));
- reg_value2 = readl(IOMEM(EMI_MPUK2_2ND));
- d0 = (reg_value & 0x7);
- d1 = (reg_value >> 3) & 0x7;
- d2 = (reg_value >> 6) & 0x7;
- d3 = (reg_value >> 9) & 0x7;
- d4 = (reg_value2 & 0x7);
- d5 = (reg_value2 >> 3) & 0x7;
- d6 = (reg_value2 >> 6) & 0x7;
- d7 = (reg_value2 >> 9) & 0x7;
- ptr += sprintf(ptr,
- "Region 12 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
- permission[d0],
- permission[d1],
- permission[d2],
- permission[d3]);
- ptr += sprintf(ptr,
- "Region 12 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
- permission[d4],
- permission[d5],
- permission[d6],
- permission[d7]);
- d0 = ((reg_value>>16) & 0x7);
- d1 = ((reg_value>>16) >> 3) & 0x7;
- d2 = ((reg_value>>16) >> 6) & 0x7;
- d3 = ((reg_value>>16) >> 9) & 0x7;
- d4 = ((reg_value2>>16) & 0x7);
- d5 = ((reg_value2>>16) >> 3) & 0x7;
- d6 = ((reg_value2>>16) >> 6) & 0x7;
- d7 = ((reg_value2>>16) >> 9) & 0x7;
- ptr += sprintf(ptr,
- "Region 13 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
- permission[d0],
- permission[d1],
- permission[d2],
- permission[d3]);
- ptr += sprintf(ptr,
- "Region 13 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
- permission[d4],
- permission[d5],
- permission[d6],
- permission[d7]);
- reg_value = readl(IOMEM(EMI_MPUL2));
- reg_value2 = readl(IOMEM(EMI_MPUL2_2ND));
- d0 = (reg_value & 0x7);
- d1 = (reg_value >> 3) & 0x7;
- d2 = (reg_value >> 6) & 0x7;
- d3 = (reg_value >> 9) & 0x7;
- d4 = (reg_value2 & 0x7);
- d5 = (reg_value2 >> 3) & 0x7;
- d6 = (reg_value2 >> 6) & 0x7;
- d7 = (reg_value2 >> 9) & 0x7;
- ptr += sprintf(ptr,
- "Region 14 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
- permission[d0],
- permission[d1],
- permission[d2],
- permission[d3]);
- ptr += sprintf(ptr,
- "Region 14 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
- permission[d4],
- permission[d5],
- permission[d6],
- permission[d7]);
- d0 = ((reg_value>>16) & 0x7);
- d1 = ((reg_value>>16) >> 3) & 0x7;
- d2 = ((reg_value>>16) >> 6) & 0x7;
- d3 = ((reg_value>>16) >> 9) & 0x7;
- d4 = ((reg_value2>>16) & 0x7);
- d5 = ((reg_value2>>16) >> 3) & 0x7;
- d6 = ((reg_value2>>16) >> 6) & 0x7;
- d7 = ((reg_value2>>16) >> 9) & 0x7;
- ptr += sprintf(ptr,
- "Region 15 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
- permission[d0],
- permission[d1],
- permission[d2],
- permission[d3]);
- ptr += sprintf(ptr,
- "Region 15 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
- permission[d4],
- permission[d5],
- permission[d6],
- permission[d7]);
- #else /*MT6735M*/
- reg_value = readl(IOMEM(EMI_MPUI));
- d0 = (reg_value & 0x7);
- d1 = (reg_value >> 3) & 0x7;
- d2 = (reg_value >> 6) & 0x7;
- d3 = (reg_value >> 9) & 0x7;
- ptr += sprintf(ptr, "Region 0 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
- permission[d0],
- permission[d1],
- permission[d2],
- permission[d3]);
- d0 = ((reg_value>>16) & 0x7);
- d1 = ((reg_value>>16) >> 3) & 0x7;
- d2 = ((reg_value>>16) >> 6) & 0x7;
- d3 = ((reg_value>>16) >> 9) & 0x7;
- ptr += sprintf(ptr, "Region 1 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
- permission[d0],
- permission[d1],
- permission[d2],
- permission[d3]);
- reg_value = readl(IOMEM(EMI_MPUJ));
- d0 = (reg_value & 0x7);
- d1 = (reg_value >> 3) & 0x7;
- d2 = (reg_value >> 6) & 0x7;
- d3 = (reg_value >> 9) & 0x7;
- ptr += sprintf(ptr, "Region 2 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
- permission[d0],
- permission[d1],
- permission[d2],
- permission[d3]);
- d0 = ((reg_value>>16) & 0x7);
- d1 = ((reg_value>>16) >> 3) & 0x7;
- d2 = ((reg_value>>16) >> 6) & 0x7;
- d3 = ((reg_value>>16) >> 9) & 0x7;
- ptr += sprintf(ptr, "Region 3 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
- permission[d0],
- permission[d1],
- permission[d2],
- permission[d3]);
- reg_value = readl(IOMEM(EMI_MPUK));
- d0 = (reg_value & 0x7);
- d1 = (reg_value >> 3) & 0x7;
- d2 = (reg_value >> 6) & 0x7;
- d3 = (reg_value >> 9) & 0x7;
- ptr += sprintf(ptr, "Region 4 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
- permission[d0],
- permission[d1],
- permission[d2],
- permission[d3]);
- d0 = ((reg_value>>16) & 0x7);
- d1 = ((reg_value>>16) >> 3) & 0x7;
- d2 = ((reg_value>>16) >> 6) & 0x7;
- d3 = ((reg_value>>16) >> 9) & 0x7;
- ptr += sprintf(ptr, "Region 5 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
- permission[d0],
- permission[d1],
- permission[d2],
- permission[d3]);
- reg_value = readl(IOMEM(EMI_MPUL));
- d0 = (reg_value & 0x7);
- d1 = (reg_value >> 3) & 0x7;
- d2 = (reg_value >> 6) & 0x7;
- d3 = (reg_value >> 9) & 0x7;
- ptr += sprintf(ptr, "Region 6 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
- permission[d0],
- permission[d1],
- permission[d2],
- permission[d3]);
- d0 = ((reg_value>>16) & 0x7);
- d1 = ((reg_value>>16) >> 3) & 0x7;
- d2 = ((reg_value>>16) >> 6) & 0x7;
- d3 = ((reg_value>>16) >> 9) & 0x7;
- ptr += sprintf(ptr, "Region 7 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
- permission[d0],
- permission[d1],
- permission[d2],
- permission[d3]);
- #endif
- return strlen(buf);
- }
- static ssize_t emi_mpu_store(struct device_driver *driver,
- const char *buf, size_t count)
- {
- int i;
- unsigned int start_addr;
- unsigned int end_addr;
- unsigned int region;
- unsigned int access_permission;
- char *command;
- char *ptr;
- char *token[5];
- int err = 0;
- if ((strlen(buf) + 1) > MAX_EMI_MPU_STORE_CMD_LEN) {
- pr_err("emi_mpu_store command overflow.");
- return count;
- }
- pr_err("emi_mpu_store: %s\n", buf);
- command = kmalloc((size_t)MAX_EMI_MPU_STORE_CMD_LEN, GFP_KERNEL);
- if (!command)
- return count;
- strcpy(command, buf);
- ptr = (char *)buf;
- if (!strncmp(buf, EN_MPU_STR, strlen(EN_MPU_STR))) {
- i = 0;
- while (ptr != NULL) {
- ptr = strsep(&command, " ");
- token[i] = ptr;
- pr_debug("token[%d] = %s\n", i, token[i]);
- i++;
- }
- for (i = 0; i < 5; i++)
- pr_debug("token[%d] = %s\n", i, token[i]);
- err += kstrtoul(token[1], 16, (unsigned long *)&start_addr);
- err += kstrtoul(token[2], 16, (unsigned long *)&end_addr);
- err += kstrtoul(token[3], 16, (unsigned long *)®ion);
- err += kstrtoul(token[4],
- 16, (unsigned long *)&access_permission);
- if (err)
- goto out;
- emi_mpu_set_region_protection(start_addr,
- end_addr,
- region,
- access_permission);
- pr_err("Set EMI_MPU: start: 0x%x, end: 0x%x, region: %d, permission: 0x%x.\n",
- start_addr,
- end_addr,
- region,
- access_permission);
- } else if (!strncmp(buf, DIS_MPU_STR, strlen(DIS_MPU_STR))) {
- i = 0;
- while (ptr != NULL) {
- ptr = strsep(&command, " ");
- token[i] = ptr;
- pr_debug("token[%d] = %s\n", i, token[i]);
- i++;
- }
- for (i = 0; i < 5; i++)
- pr_debug("token[%d] = %s\n", i, token[i]);
- err += kstrtoul(token[1], 16, (unsigned long *)&start_addr);
- err += kstrtoul(token[2], 16, (unsigned long *)&end_addr);
- err += kstrtoul(token[3], 16, (unsigned long *)®ion);
- if (err)
- goto out;
- access_permission = SET_ACCESS_PERMISSON(NO_PROTECTION,
- #if defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6753)
- NO_PROTECTION,
- NO_PROTECTION,
- NO_PROTECTION,
- NO_PROTECTION,
- #endif
- NO_PROTECTION,
- NO_PROTECTION,
- NO_PROTECTION);
- emi_mpu_set_region_protection(0x0,
- 0x0,
- region,
- access_permission);
- pr_err("set EMI MPU: start: 0x%x, end: 0x%x, region: %d, permission: 0x%x\n",
- 0,
- 0,
- region,
- access_permission);
- } else {
- pr_err("Unknown emi_mpu command.\n");
- }
- out:
- kfree(command);
- return count;
- }
- DRIVER_ATTR(mpu_config, 0644, emi_mpu_show, emi_mpu_store);
- void mtk_search_full_pgtab(void)
- {
- pgd_t *pgd;
- pud_t *pud;
- pmd_t *pmd;
- unsigned long addr;
- #ifndef CONFIG_ARM_LPAE
- pte_t *pte;
- unsigned long addr_2nd, addr_2nd_end;
- #endif
- unsigned int v_addr = vio_addr;
- /*FIXME: testing*/
- for (addr = 0xC0000000; addr < 0xFFF00000; addr += 0x100000) {
- pgd = pgd_offset(&init_mm, addr);
- if (pgd_none(*pgd) || !pgd_present(*pgd))
- continue;
- pud = pud_offset(pgd, addr);
- if (pud_none(*pud) || !pud_present(*pud))
- continue;
- pmd = pmd_offset(pud, addr);
- if (pmd_none(*pmd) || !pmd_present(*pmd))
- continue;
- #ifndef CONFIG_ARM_LPAE
- if ((pmd_val(*pmd) & PMD_TYPE_MASK) == PMD_TYPE_TABLE) {
- /* Page table entry*/
- addr_2nd = addr;
- addr_2nd_end = addr_2nd + 0x100000;
- for (; addr_2nd < (addr_2nd_end); addr_2nd += 0x1000) {
- pte = pte_offset_map(pmd, addr_2nd);
- if (((unsigned long)v_addr & PAGE_MASK) ==
- ((unsigned long)pte_val(*(pte))
- & PAGE_MASK)) {
- pr_err("%s %lx. violation address = 0x%x\n",
- "[EMI MPU] Find page entry section at pte:",
- (unsigned long)(pte), v_addr);
- return;
- }
- }
- } else {
- /* Section */
- unsigned long a0;
- unsigned long a1;
- a0 = (unsigned long)pmd_val(*(pmd)) & SECTION_MASK;
- a1 = (unsigned long)v_addr & SECTION_MASK;
- if (a0 == a1) {
- pr_err("[EMI MPU] Find page entry section at pmd: %lx. violation address = 0x%x\n",
- (unsigned long)(pmd),
- v_addr);
- return;
- }
- }
- #else
- /* TBD */
- #endif
- }
- pr_err("[EMI MPU] ****** Can not find page table entry! violation address = 0x%x ******\n",
- v_addr);
- }
- void emi_mpu_work_callback(struct work_struct *work)
- {
- pr_err("[EMI MPU] Enter EMI MPU workqueue!\n");
- mtk_search_full_pgtab();
- pr_err("[EMI MPU] Exit EMI MPU workqueue!\n");
- }
- static ssize_t pgt_scan_show(struct device_driver *driver, char *buf)
- {
- return 0;
- }
- static ssize_t pgt_scan_store(struct device_driver *driver,
- const char *buf, size_t count)
- {
- unsigned int value;
- unsigned int ret;
- if (unlikely(kstrtoint(buf, 0, &value) != 1))
- return -EINVAL;
- if (value == 1) {
- ret = queue_work(emi_mpu_workqueue, &emi_mpu_work);
- if (!ret)
- pr_debug("[EMI MPU] submit workqueue failed, ret = %d\n",
- ret);
- }
- return count;
- }
- DRIVER_ATTR(pgt_scan, 0644, pgt_scan_show, pgt_scan_store);
- #ifdef ENABLE_EMI_CHKER
- static void emi_axi_set_chker(const unsigned int setting)
- {
- int value;
- value = readl(IOMEM(EMI_CHKER));
- value &= ~(0x7 << 16);
- value |= (setting);
- mt_reg_sync_writel(value, EMI_CHKER);
- }
- static void emi_axi_set_master(const unsigned int setting)
- {
- int value;
- value = readl(IOMEM(EMI_CHKER));
- value &= ~(0x0F << AXI_NON_ALIGN_CHK_MST);
- value |= (setting & 0xF) << AXI_NON_ALIGN_CHK_MST;
- mt_reg_sync_writel(value, EMI_CHKER);
- }
- static void emi_axi_dump_info(int aee_ke_en)
- {
- int value, master_ID;
- char *master_name;
- value = readl(IOMEM(EMI_CHKER));
- master_ID = (value & 0x0000FFFF);
- if (value & 0x0000FFFF) {
- pr_err("AXI violation.\n");
- pr_err("[EMI MPU AXI] Debug info start ------\n");
- pr_err("EMI_CHKER = %x.\n", value);
- pr_err("Violation address is 0x%x.\n",
- readl(IOMEM(EMI_CHKER_ADR)));
- pr_err("Violation master ID is 0x%x.\n", master_ID);
- pr_err("Violation type is: AXI_ADR_CHK_EN(%d), AXI_LOCK_CHK_EN(%d), AXI_NON_ALIGN_CHK_EN(%d).\n",
- (value & (1 << AXI_ADR_VIO)) ? 1 : 0,
- (value & (1 << AXI_LOCK_ISSUE)) ? 1 : 0,
- (value & (1 << AXI_NON_ALIGN_ISSUE)) ? 1 : 0);
- pr_err("%s violation.\n",
- (value & (1 << AXI_VIO_WR)) ? "Write" : "Read");
- pr_err("[EMI MPU AXI] Debug info end ---------\n");
- master_name = __id2name(master_ID);
- #ifdef CONFIG_MTK_AEE_FEATURE
- if (aee_ke_en)
- aee_kernel_exception("EMI MPU AXI",
- "AXI violation.\nEMI_CHKER = 0x%x\nCRDISPATCH_KEY:EMI MPU Violation Issue/%s\n",
- value, master_name);
- #endif
- mt_reg_sync_writel((1 << AXI_VIO_CLR) | readl(IOMEM(EMI_CHKER)),
- EMI_CHKER);
- }
- }
- static void emi_axi_vio_timer_func(unsigned long a)
- {
- emi_axi_dump_info(1);
- mod_timer(&emi_axi_vio_timer, jiffies + AXI_VIO_MONITOR_TIME);
- }
- static ssize_t emi_axi_vio_show(struct device_driver *driver, char *buf)
- {
- int value;
- value = readl(IOMEM(EMI_CHKER));
- emi_axi_dump_info(0);
- return snprintf(buf,
- PAGE_SIZE,
- "AXI vio setting is: ADR_CHK_EN %s, LOCK_CHK_EN %s, NON_ALIGN_CHK_EN %s\n",
- (value & (1 << AXI_ADR_CHK_EN)) ? "ON" : "OFF",
- (value & (1 << AXI_LOCK_CHK_EN)) ? "ON" : "OFF",
- (value & (1 << AXI_NON_ALIGN_CHK_EN)) ? "ON" : "OFF");
- }
- ssize_t emi_axi_vio_store(struct device_driver *driver,
- const char *buf, size_t count)
- {
- int value;
- int cpu = 0;
- value = readl(IOMEM(EMI_CHKER));
- if (!strncmp(buf, "ADR_CHK_ON", strlen("ADR_CHK_ON"))) {
- emi_axi_set_chker(1 << AXI_ADR_CHK_EN);
- add_timer_on(&emi_axi_vio_timer, cpu);
- } else if (!strncmp(buf, "LOCK_CHK_ON", strlen("LOCK_CHK_ON"))) {
- emi_axi_set_chker(1 << AXI_LOCK_CHK_EN);
- add_timer_on(&emi_axi_vio_timer, cpu);
- } else if (!strncmp(buf, "NON_ALIGN_CHK_ON",
- strlen("NON_ALIGN_CHK_ON"))) {
- emi_axi_set_chker(1 << AXI_NON_ALIGN_CHK_EN);
- add_timer_on(&emi_axi_vio_timer, cpu);
- } else if (!strncmp(buf, "OFF", strlen("OFF"))) {
- emi_axi_set_chker(0);
- del_timer(&emi_axi_vio_timer);
- } else {
- pr_err("invalid setting\n");
- }
- return count;
- }
- DRIVER_ATTR(emi_axi_vio, 0644, emi_axi_vio_show, emi_axi_vio_store);
- #endif /*#ifdef ENABLE_EMI_CHKER*/
- #ifdef ENABLE_EMI_WATCH_POINT
- static void emi_wp_set_address(unsigned int address)
- {
- mt_reg_sync_writel(address - emi_physical_offset, EMI_WP_ADR);
- }
- static void emi_wp_set_range(unsigned int range) /* 2^ range bytes */
- {
- unsigned int value;
- value = readl(IOMEM(EMI_WP_CTRL));
- value = (value & (~EMI_WP_RANGE)) | range;
- mt_reg_sync_writel(value, EMI_WP_CTRL);
- }
- static void emi_wp_set_monitor_type(unsigned int type)
- {
- unsigned int value;
- value = readl(IOMEM(EMI_WP_CTRL));
- value =
- (value & (~EMI_WP_RW_MONITOR)) | (type << EMI_WP_RW_MONITOR_SHIFT);
- mt_reg_sync_writel(value, EMI_WP_CTRL);
- }
- #if 0
- static void emi_wp_set_rw_disable(unsigned int type)
- {
- unsigned int value;
- value = readl(IOMEM(EMI_WP_CTRL));
- value =
- (value & (~EMI_WP_RW_DISABLE)) | (type << EMI_WP_RW_DISABLE_SHIFT);
- mt_reg_sync_writel(value, EMI_WP_CTRL);
- }
- #endif
- static void emi_wp_enable(int enable)
- {
- unsigned int value;
- /* Enable WP */
- value = readl(IOMEM(EMI_CHKER));
- value =
- (value & ~(1 << EMI_WP_ENABLE_SHIFT)) | (enable << EMI_WP_ENABLE_SHIFT);
- mt_reg_sync_writel(value, EMI_CHKER);
- }
- static void emi_wp_slave_error_enable(unsigned int enable)
- {
- unsigned int value;
- value = readl(IOMEM(EMI_WP_CTRL));
- value =
- (value & ~(1 << EMI_WP_SLVERR_SHIFT)) | (enable << EMI_WP_SLVERR_SHIFT);
- mt_reg_sync_writel(value, EMI_WP_CTRL);
- }
- static void emi_wp_int_enable(unsigned int enable)
- {
- unsigned int value;
- value = readl(IOMEM(EMI_WP_CTRL));
- value =
- (value & ~(1 << EMI_WP_INT_SHIFT)) | (enable << EMI_WP_INT_SHIFT);
- mt_reg_sync_writel(value, EMI_WP_CTRL);
- }
- static void emi_wp_clr_status(void)
- {
- unsigned int value;
- int result;
- value = readl(IOMEM(EMI_CHKER));
- value |= 1 << EMI_WP_VIO_CLR_SHIFT;
- mt_reg_sync_writel(value, EMI_CHKER);
- result = readl(IOMEM(EMI_CHKER)) & EMI_WP_AXI_ID;
- result |= readl(IOMEM(EMI_CHKER_TYPE));
- result |= readl(IOMEM(EMI_CHKER_ADR));
- if (result)
- pr_err("[EMI_WP] Clear WP status fail!!!!!!!!!!!!!!\n");
- }
- void emi_wp_get_status(void)
- {
- unsigned int value, master_ID;
- char *master_name;
- value = readl(IOMEM(EMI_CHKER));
- if ((value & 0x80000000) == 0) {
- pr_err("[EMI_WP] No watch point hit\n");
- return;
- }
- master_ID = (value & EMI_WP_AXI_ID);
- pr_err("[EMI_WP] Violation master ID is 0x%x.\n", master_ID);
- pr_err("[EMI_WP] Violation Address is : 0x%X\n",
- readl(IOMEM(EMI_CHKER_ADR)) + emi_physical_offset);
- master_name = __id2name(master_ID);
- pr_err("[EMI_WP] EMI_CHKER = 0x%x, module is %s.\n",
- value, master_name);
- value = readl(IOMEM(EMI_CHKER_TYPE));
- pr_err("[EMI_WP] Transaction Type is : %d beat, %d byte, %s burst type (0x%X)\n",
- (value & 0xF) + 1,
- 1 << ((value >> 4) & 0x7),
- (value >> 7 & 1) ? "INCR" : "WRAP",
- value);
- emi_wp_clr_status();
- }
- static int emi_wp_set(unsigned int enable,
- unsigned int address, unsigned int range, unsigned int rw)
- {
- if (address < emi_physical_offset) {
- pr_err("[EMI_WP] Address error, you can't set address less than 0x%X\n",
- emi_physical_offset);
- return -1;
- }
- if (range < 4 || range > 32) {
- pr_err("[EMI_WP] Range error, you can't set range less %s",
- "than 16 bytes and more than 4G bytes\n");
- return -1;
- }
- emi_wp_set_monitor_type(rw);
- emi_wp_set_address(address);
- emi_wp_set_range(range);
- emi_wp_slave_error_enable(1);
- emi_wp_int_enable(0);
- emi_wp_enable(enable);
- return 0;
- }
- static ssize_t emi_wp_vio_show(struct device_driver *driver, char *buf)
- {
- unsigned int value, master_ID, type, vio_addr;
- char *master_name;
- char *ptr = buf;
- value = readl(IOMEM(EMI_CHKER));
- if ((value & 0x80000000) == 0)
- return snprintf(buf, PAGE_SIZE,
- "[EMI_WP] No watch point hit\n");
- master_ID = (value & EMI_WP_AXI_ID);
- master_name = __id2name(master_ID);
- type = readl(IOMEM(EMI_CHKER_TYPE));
- vio_addr = readl(IOMEM(EMI_CHKER_ADR)) + emi_physical_offset;
- emi_wp_clr_status();
- ptr += snprintf(ptr, PAGE_SIZE, "[EMI WP] vio setting is: CHKER 0x%X, ",
- value);
- ptr += snprintf(ptr, PAGE_SIZE, "module is %s, Address is : 0x%X," ,
- master_name,
- vio_addr);
- ptr += snprintf(ptr, PAGE_SIZE, "Transaction Type is : %d beat, ",
- (type & 0xF) + 1);
- ptr += snprintf(ptr, PAGE_SIZE, "%d byte, %s burst type (0x%X)\n",
- 1 << ((type >> 4) & 0x7),
- (type >> 7 & 1) ? "INCR" : "WRAP",
- type);
- return ptr - buf;
- }
- ssize_t emi_wp_vio_store(struct device_driver *driver,
- const char *buf, size_t count)
- {
- int i;
- unsigned int wp_addr;
- unsigned int range, start_addr, end_addr;
- unsigned int rw;
- char *command;
- char *ptr;
- char *token[5];
- int err = 0;
- if ((strlen(buf) + 1) > MAX_EMI_MPU_STORE_CMD_LEN) {
- pr_err("emi_wp_store command overflow.");
- return count;
- }
- pr_err("emi_wp_store: %s\n", buf);
- command = kmalloc((size_t)MAX_EMI_MPU_STORE_CMD_LEN, GFP_KERNEL);
- if (!command)
- return count;
- strcpy(command, buf);
- ptr = (char *)buf;
- if (!strncmp(buf, EN_WP_STR, strlen(EN_WP_STR))) {
- i = 0;
- while (ptr != NULL) {
- ptr = strsep(&command, " ");
- token[i] = ptr;
- pr_debug("token[%d] = %s\n", i, token[i]);
- i++;
- }
- for (i = 0; i < 4; i++)
- pr_debug("token[%d] = %s\n", i, token[i]);
- err += kstrtoul(token[1], 16, (unsigned long *)&wp_addr);
- err += kstrtoul(token[2], 16, (unsigned long *)&range);
- err += kstrtoul(token[3], 16, (unsigned long *)&rw);
- if (err)
- goto out;
- emi_wp_set(1, wp_addr, range, rw);
- start_addr = (wp_addr >> range) << range;
- end_addr = start_addr + (1 << range) - 1;
- pr_err("Set EMI_WP: address: 0x%x, range:%d, start addr: 0x%x, end addr: 0x%x, rw: %d .\n",
- wp_addr, range, start_addr, end_addr, rw);
- } else if (!strncmp(buf, DIS_WP_STR, strlen(DIS_WP_STR))) {
- i = 0;
- while (ptr != NULL) {
- ptr = strsep(&command, " ");
- token[i] = ptr;
- pr_debug("token[%d] = %s\n", i, token[i]);
- i++;
- }
- for (i = 0; i < 4; i++)
- pr_debug("token[%d] = %s\n", i, token[i]);
- err += kstrtoul(token[1], 16, (unsigned long *)&wp_addr);
- err += kstrtoul(token[2], 16, (unsigned long *)&range);
- err += kstrtoul(token[3], 16, (unsigned long *)&rw);
- if (err)
- goto out;
- emi_wp_set(0, 0x40000000, 4, 2);
- pr_err("disable EMI WP\n");
- } else {
- pr_err("Unknown emi_wp command.\n");
- }
- out:
- kfree(command);
- return count;
- }
- DRIVER_ATTR(emi_wp_vio, 0644, emi_wp_vio_show, emi_wp_vio_store);
- #endif /*#ifdef ENABLE_EMI_WATCH_POINT*/
- #if defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6753)
- #define AP_REGION_ID 15
- #else /* MT6735M*/
- #define AP_REGION_ID 7
- #endif
- static void protect_ap_region(void)
- {
- unsigned int ap_mem_mpu_id, ap_mem_mpu_attr;
- unsigned int kernel_base;
- phys_addr_t dram_size;
- return; /* temp to disable */
- kernel_base = PHYS_OFFSET;
- dram_size = get_max_DRAM_size();
- ap_mem_mpu_id = AP_REGION_ID;
- #if defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6753)
- ap_mem_mpu_attr = SET_ACCESS_PERMISSON(FORBIDDEN,
- NO_PROTECTION,
- FORBIDDEN,
- NO_PROTECTION,
- FORBIDDEN,
- FORBIDDEN,
- FORBIDDEN,
- NO_PROTECTION);
- #else /* MT6735M*/
- ap_mem_mpu_attr = SET_ACCESS_PERMISSON(NO_PROTECTION,
- FORBIDDEN,
- FORBIDDEN,
- NO_PROTECTION);
- #endif
- pr_err("[EMI] protect_ap_region 0x%x~0x%x ,dram size=0x%x\n",
- kernel_base,
- (kernel_base + (unsigned int)dram_size - 1),
- (unsigned int)dram_size);
- emi_mpu_set_region_protection(kernel_base,
- (kernel_base+dram_size-1), ap_mem_mpu_id, ap_mem_mpu_attr);
- }
- /*
- static int emi_mpu_panic_cb(struct notifier_block *this,
- unsigned long event, void *ptr)
- {
- emi_axi_dump_info(1);
- return NOTIFY_DONE;
- }*/
- static struct platform_driver emi_mpu_ctrl = {
- .driver = {
- .name = "emi_mpu_ctrl",
- .bus = &platform_bus_type,
- .owner = THIS_MODULE,
- },
- .id_table = NULL,
- };
- /*
- static struct notifier_block emi_mpu_blk = {
- .notifier_call = emi_mpu_panic_cb,
- };*/
- static int __init emi_mpu_mod_init(void)
- {
- int ret;
- #if defined(CONFIG_ARCH_MT6753)
- struct basic_dram_setting DRAM_setting;
- #endif
- struct device_node *node;
- unsigned int mpu_irq;
- pr_err("[EMI MPU] Initialize EMI MPU.\n");
- /* DTS version */
- if (EMI_BASE_ADDR == NULL) {
- node = of_find_compatible_node(NULL, NULL, "mediatek,EMI");
- if (node) {
- EMI_BASE_ADDR = of_iomap(node, 0);
- pr_err("get EMI_BASE_ADDR @ %p\n", EMI_BASE_ADDR);
- } else {
- pr_err("can't find compatible node\n");
- return -1;
- }
- }
- node = of_find_compatible_node(NULL, NULL, "mediatek,DEVAPC");
- if (node) {
- mpu_irq = irq_of_parse_and_map(node, 0);
- pr_debug("get EMI_MPU irq = %d\n", mpu_irq);
- } else {
- pr_err("can't find compatible node DEVAPC\n");
- return -1;
- }
- spin_lock_init(&emi_mpu_lock);
- pr_err("[EMI MPU] EMI_MPUP = 0x%x\n", readl(IOMEM((EMI_MPUP))));
- pr_err("[EMI MPU] EMI_MPUQ = 0x%x\n", readl(IOMEM((EMI_MPUQ))));
- pr_err("[EMI MPU] EMI_MPUR = 0x%x\n", readl(IOMEM((EMI_MPUR))));
- pr_err("[EMI MPU] EMI_MPUY = 0x%x\n", readl(IOMEM(EMI_MPUY)));
- pr_err("[EMI MPU] EMI_MPUP2 = 0x%x\n", readl(IOMEM(EMI_MPUP2)));
- pr_err("[EMI MPU] EMI_MPUQ2 = 0x%x\n", readl(IOMEM(EMI_MPUQ2)));
- pr_err("[EMI MPU] EMI_MPUR2 = 0x%x\n", readl(IOMEM(EMI_MPUR2)));
- pr_err("[EMI MPU] EMI_MPUY2 = 0x%x\n", readl(IOMEM(EMI_MPUY2)));
- pr_err("[EMI MPU] EMI_MPUS = 0x%x\n", readl(IOMEM(EMI_MPUS)));
- pr_err("[EMI MPU] EMI_MPUT = 0x%x\n", readl(IOMEM(EMI_MPUT)));
- pr_err("[EMI MPU] EMI_WP_ADR = 0x%x\n", readl(IOMEM(EMI_WP_ADR)));
- pr_err("[EMI MPU] EMI_WP_CTRL = 0x%x\n", readl(IOMEM(EMI_WP_CTRL)));
- pr_err("[EMI MPU] EMI_CHKER = 0x%x\n", readl(IOMEM(EMI_CHKER)));
- pr_err("[EMI MPU] EMI_CHKER_TYPE = 0x%x\n",
- readl(IOMEM(EMI_CHKER_TYPE)));
- pr_err("[EMI MPU] EMI_CHKER_ADR = 0x%x\n", readl(IOMEM(EMI_CHKER_ADR)));
- __clear_emi_mpu_vio();
- /* Set Device APC initialization for EMI-MPU. */
- mt_devapc_emi_initial();
- if (1) /* (0 == enable_4G()) there is on 4G mode of MT6735~MT6753*/ {
- emi_physical_offset = 0x40000000;
- pr_err("[EMI MPU] Not 4G mode\n");
- } else {
- /*enable 4G mode*/
- emi_physical_offset = 0;
- pr_err("[EMI MPU] 4G mode\n");
- }
- /*
- * NoteXXX: Interrupts of violation (including SPC in SMI, or EMI MPU)
- * are triggered by the device APC.
- * Need to share the interrupt with the SPC driver.
- */
- ret = request_irq(mpu_irq,
- (irq_handler_t)mpu_violation_irq,
- IRQF_TRIGGER_LOW | IRQF_SHARED,
- "mt_emi_mpu",
- &emi_mpu_ctrl);
- if (ret != 0) {
- pr_err("Fail to request EMI_MPU interrupt. Error = %d.\n", ret);
- return ret;
- }
- protect_ap_region();
- #if defined(CONFIG_ARCH_MT6753)
- acquire_dram_setting(&DRAM_setting);
- pr_err("[EMI] EMI_CONA = 0x%x\n", readl(IOMEM((EMI_CONA))));
- pr_err("[EMI] Support channel number %d\n", DRAM_setting.channel_nr);
- pr_err("[EMI] Channel 0 : rank 0 : %d Gb, segment no : %d\n",
- DRAM_setting.channel[0].rank[0].rank_size,
- DRAM_setting.channel[0].rank[0].segment_nr);
- pr_err("[EMI] Channel 0 : rank 1 : %d Gb, segment no : %d\n",
- DRAM_setting.channel[0].rank[1].rank_size,
- DRAM_setting.channel[0].rank[1].segment_nr);
- pr_err("[EMI] Channel 1 : rank 0 : %d Gb, segment no : %d\n",
- DRAM_setting.channel[1].rank[0].rank_size,
- DRAM_setting.channel[1].rank[0].segment_nr);
- pr_err("[EMI] Channel 1 : rank 1 : %d Gb, segment no : %d\n",
- DRAM_setting.channel[1].rank[1].rank_size,
- DRAM_setting.channel[1].rank[1].segment_nr);
- #endif
- #ifdef ENABLE_EMI_CHKER
- /* AXI violation monitor setting and timer function create */
- mt_reg_sync_writel((1 << AXI_VIO_CLR) | readl(IOMEM(EMI_CHKER)),
- EMI_CHKER);
- emi_axi_set_master(MASTER_ALL);
- init_timer(&emi_axi_vio_timer);
- emi_axi_vio_timer.expires = jiffies + AXI_VIO_MONITOR_TIME;
- emi_axi_vio_timer.function = &emi_axi_vio_timer_func;
- emi_axi_vio_timer.data = ((unsigned long) 0);
- #endif /*#ifdef ENABLE_EMI_CHKER*/
- #if !defined(USER_BUILD_KERNEL)
- #ifdef ENABLE_EMI_CHKER
- /* Enable AXI 4KB boundary violation monitor timer */
- /*emi_axi_set_chker(1 << AXI_ADR_CHK_EN);*/
- /*add_timer_on(&emi_axi_vio_timer, 0);*/
- #endif
- /* register driver and create sysfs files */
- ret = platform_driver_register(&emi_mpu_ctrl);
- if (ret)
- pr_err("Fail to register EMI_MPU driver.\n");
- ret = driver_create_file(&emi_mpu_ctrl.driver, &driver_attr_mpu_config);
- if (ret)
- pr_err("Fail to create MPU config sysfs file.\n");
- #ifdef ENABLE_EMI_CHKER
- ret = driver_create_file(&emi_mpu_ctrl.driver,
- &driver_attr_emi_axi_vio);
- if (ret)
- pr_err("Fail to create AXI violation monitor sysfs file.\n");
- #endif
- ret = driver_create_file(&emi_mpu_ctrl.driver, &driver_attr_pgt_scan);
- if (ret)
- pr_err("Fail to create pgt scan sysfs file.\n");
- #ifdef ENABLE_EMI_WATCH_POINT
- ret = driver_create_file(&emi_mpu_ctrl.driver, &driver_attr_emi_wp_vio);
- if (ret)
- pr_err("Fail to create WP violation monitor sysfs file.\n");
- #endif
- #endif
- /*atomic_notifier_chain_register(&panic_notifier_list, &emi_mpu_blk);*/
- /* Create a workqueue to search pagetable entry */
- emi_mpu_workqueue = create_singlethread_workqueue("emi_mpu");
- INIT_WORK(&emi_mpu_work, emi_mpu_work_callback);
- return 0;
- }
- static void __exit emi_mpu_mod_exit(void)
- {
- }
- /*
- unsigned int enable_4G(void)
- {
- return 0;
- }
- */
- module_init(emi_mpu_mod_init);
- module_exit(emi_mpu_mod_exit);
- /*EXPORT_SYMBOL(start_mm_mau_protect);*/
|