emi_mpu.c 69 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745
  1. #include <linux/kernel.h>
  2. #include <linux/module.h>
  3. #include <linux/interrupt.h>
  4. #include <linux/device.h>
  5. #include <linux/platform_device.h>
  6. #include <linux/mm.h>
  7. #include <linux/uaccess.h>
  8. #include <linux/slab.h>
  9. #include <linux/spinlock.h>
  10. #include <linux/irq.h>
  11. #include <linux/sched.h>
  12. #include <linux/list.h>
  13. #ifdef CONFIG_MTK_AEE_FEATURE
  14. #include <mt-plat/aee.h>
  15. #endif
  16. #include <linux/timer.h>
  17. #include <linux/workqueue.h>
  18. #include <mt-plat/mt_device_apc.h>
  19. #include <mt-plat/sync_write.h>
  20. #include "mach/irqs.h"
  21. #include <mt-plat/dma.h>
  22. #include <linux/of.h>
  23. #include <linux/of_address.h>
  24. #include <linux/of_irq.h>
  25. #include <mt-plat/mt_io.h>
  26. #include "mach/emi_mpu.h"
  27. #define ENABLE_EMI_CHKER
  28. #define ENABLE_EMI_WATCH_POINT
  29. #define NR_REGION_ABORT 15
  30. #define MAX_EMI_MPU_STORE_CMD_LEN 128
  31. #define TIMEOUT 100
  32. #define AXI_VIO_MONITOR_TIME (1 * HZ)
  33. static struct work_struct emi_mpu_work;
  34. static struct workqueue_struct *emi_mpu_workqueue;
  35. static unsigned int vio_addr;
  36. static unsigned int emi_physical_offset;
  37. struct mst_tbl_entry {
  38. u32 master;
  39. u32 port;
  40. u32 id_mask;
  41. u32 id_val;
  42. char *note;
  43. char *name;
  44. };
  45. struct emi_mpu_notifier_block {
  46. struct list_head list;
  47. emi_mpu_notifier notifier;
  48. };
  49. static const struct mst_tbl_entry mst_tbl[] = {
  50. /* apmcu */
  51. #if defined(CONFIG_ARCH_MT6753)
  52. /* --cluster 0 Write */
  53. {
  54. .master = MST_ID_APMCU_0,
  55. .port = 0x0,
  56. .id_mask = 0x3E7,
  57. .id_val = 0x004,
  58. .note = "CA53: Core nn system",
  59. .name = "CA53"
  60. },
  61. {
  62. .master = MST_ID_APMCU_1,
  63. .port = 0x0,
  64. .id_mask = 0x3E7,
  65. .id_val = 0x024,
  66. .note = "CA53: Core nn barrier",
  67. .name = "CA53"
  68. },
  69. {
  70. .master = MST_ID_APMCU_2,
  71. .port = 0x0,
  72. .id_mask = 0x3FF,
  73. .id_val = 0x044,
  74. .note = "CA53: Unused",
  75. .name = "CA53"
  76. },
  77. {
  78. .master = MST_ID_APMCU_3,
  79. .port = 0x0,
  80. .id_mask = 0x3FF,
  81. .id_val = 0x04C,
  82. .note = "CA53: SCU generated barrier",
  83. .name = "CA53"
  84. },
  85. {
  86. .master = MST_ID_APMCU_4,
  87. .port = 0x0,
  88. .id_mask = 0x3F7,
  89. .id_val = 0x054,
  90. .note = "CA53: Unused",
  91. .name = "CA53"
  92. },
  93. {
  94. .master = MST_ID_APMCU_5,
  95. .port = 0x0,
  96. .id_mask = 0x3E7,
  97. .id_val = 0x064,
  98. .note = "CA53: Core nn non-re-orderable device write",
  99. .name = "CA53"
  100. },
  101. {
  102. .master = MST_ID_APMCU_6,
  103. .port = 0x0,
  104. .id_mask = 0x387,
  105. .id_val = 0x084,
  106. .note =
  107. "CA53: Write to normal memory, or re-orderable device memory",
  108. .name = "CA53"
  109. },
  110. /*--cluster 0 Read */
  111. {
  112. .master = MST_ID_APMCU_7,
  113. .port = 0x0,
  114. .id_mask = 0x39F,
  115. .id_val = 0x084,
  116. .note = "CA53: ACP read",
  117. .name = "CA53"
  118. },
  119. {
  120. .master = MST_ID_APMCU_8,
  121. .port = 0x0,
  122. .id_mask = 0x39F,
  123. .id_val = 0x08C,
  124. .note = "CA53: Unused",
  125. .name = "CA53"
  126. },
  127. {
  128. .master = MST_ID_APMCU_9,
  129. .port = 0x0,
  130. .id_mask = 0x397,
  131. .id_val = 0x094,
  132. .note = "CA53: Unused",
  133. .name = "CA53"
  134. },
  135. {
  136. .master = MST_ID_APMCU_10,
  137. .port = 0x0,
  138. .id_mask = 0x307,
  139. .id_val = 0x104,
  140. .note = "CA53: Core nn read",
  141. .name = "CA53"
  142. },
  143. /*--cluster 1 Write*/
  144. {
  145. .master = MST_ID_APMCU_11,
  146. .port = 0x0,
  147. .id_mask = 0x3E7,
  148. .id_val = 0x003,
  149. .note = "CA53: Core nn system",
  150. .name = "CA53"
  151. },
  152. {
  153. .master = MST_ID_APMCU_12,
  154. .port = 0x0,
  155. .id_mask = 0x3E7,
  156. .id_val = 0x023,
  157. .note = "CA53: Core nn barrier",
  158. .name = "CA53"
  159. },
  160. {
  161. .master = MST_ID_APMCU_13,
  162. .port = 0x0,
  163. .id_mask = 0x3FF,
  164. .id_val = 0x043,
  165. .note = "CA53: Unused",
  166. .name = "CA53"
  167. },
  168. {
  169. .master = MST_ID_APMCU_14,
  170. .port = 0x0,
  171. .id_mask = 0x3FF,
  172. .id_val = 0x04B,
  173. .note = "CA53: SCU generated barrier",
  174. .name = "CA53"
  175. },
  176. {
  177. .master = MST_ID_APMCU_15,
  178. .port = 0x0,
  179. .id_mask = 0x3F7,
  180. .id_val = 0x053,
  181. .note = "CA53: Unused",
  182. .name = "CA53"
  183. },
  184. {
  185. .master = MST_ID_APMCU_16,
  186. .port = 0x0,
  187. .id_mask = 0x3E7,
  188. .id_val = 0x063,
  189. .note = "CA53: Core nn non-re-orderable device write",
  190. .name = "CA53"
  191. },
  192. {
  193. .master = MST_ID_APMCU_17,
  194. .port = 0x0,
  195. .id_mask = 0x387,
  196. .id_val = 0x083,
  197. .note =
  198. "CA53: Write to normal memory, or re-orderable device memory",
  199. .name = "CA53"
  200. },
  201. /*--cluster 1 Read*/
  202. {
  203. .master = MST_ID_APMCU_18,
  204. .port = 0x0,
  205. .id_mask = 0x39F,
  206. .id_val = 0x083,
  207. .note = "CA53: ACP read",
  208. .name = "CA53"
  209. },
  210. {
  211. .master = MST_ID_APMCU_19,
  212. .port = 0x0,
  213. .id_mask = 0x39F,
  214. .id_val = 0x08B,
  215. .note = "CA53: Unused",
  216. .name = "CA53"
  217. },
  218. {
  219. .master = MST_ID_APMCU_20,
  220. .port = 0x0,
  221. .id_mask = 0x397,
  222. .id_val = 0x093,
  223. .note = "CA53: Unused",
  224. .name = "CA53"
  225. },
  226. {
  227. .master = MST_ID_APMCU_21,
  228. .port = 0x0,
  229. .id_mask = 0x307,
  230. .id_val = 0x103,
  231. .note = "CA53: Core nn read",
  232. .name = "CA53"
  233. },
  234. #else
  235. {
  236. .master = MST_ID_APMCU_0,
  237. .port = 0x0,
  238. .id_mask = 0x3FC,
  239. .id_val = 0x000,
  240. .note = "CA53: Core nn system",
  241. .name = "CA53"
  242. },
  243. {
  244. .master = MST_ID_APMCU_1,
  245. .port = 0x0,
  246. .id_mask = 0x3FC,
  247. .id_val = 0x004,
  248. .note = "CA53: Core nn barrier",
  249. .name = "CA53"
  250. },
  251. {
  252. .master = MST_ID_APMCU_2,
  253. .port = 0x0,
  254. .id_mask = 0x3FF,
  255. .id_val = 0x008,
  256. .note = "CA53: Unused",
  257. .name = "CA53"
  258. },
  259. {
  260. .master = MST_ID_APMCU_3,
  261. .port = 0x0,
  262. .id_mask = 0x3FF,
  263. .id_val = 0x009,
  264. .note = "CA53: SCU generated barrier",
  265. .name = "CA53"
  266. },
  267. {
  268. .master = MST_ID_APMCU_4,
  269. .port = 0x0,
  270. .id_mask = 0x3FE,
  271. .id_val = 0x006,
  272. .note = "CA53: Unused",
  273. .name = "CA53"
  274. },
  275. {
  276. .master = MST_ID_APMCU_5,
  277. .port = 0x0,
  278. .id_mask = 0x3FC,
  279. .id_val = 0x00C,
  280. .note = "CA53: Core nn non-re-orderable device write",
  281. .name = "CA53"
  282. },
  283. {
  284. .master = MST_ID_APMCU_6,
  285. .port = 0x0,
  286. .id_mask = 0x3F0,
  287. .id_val = 0x010,
  288. .note =
  289. "CA53: Write to normal memory, or re-orderable device memory",
  290. .name = "CA53"
  291. },
  292. {
  293. .master = MST_ID_APMCU_7,
  294. .port = 0x0,
  295. .id_mask = 0x3F3,
  296. .id_val = 0x010,
  297. .note = "CA53: ACP read",
  298. .name = "CA53"
  299. },
  300. {
  301. .master = MST_ID_APMCU_8,
  302. .port = 0x0,
  303. .id_mask = 0x3F3,
  304. .id_val = 0x011,
  305. .note = "CA53: Unused",
  306. .name = "CA53"
  307. },
  308. {
  309. .master = MST_ID_APMCU_9,
  310. .port = 0x0,
  311. .id_mask = 0x3F2,
  312. .id_val = 0x012,
  313. .note = "CA53: Unused",
  314. .name = "CA53"
  315. },
  316. {
  317. .master = MST_ID_APMCU_10,
  318. .port = 0x0,
  319. .id_mask = 0x3E0,
  320. .id_val = 0x020,
  321. .note = "CA53: Core nn read",
  322. .name = "CA53"
  323. },
  324. #endif
  325. /* MM */
  326. {
  327. .master = MST_ID_MM_0,
  328. .port = 0x1,
  329. .id_mask = 0x380,
  330. .id_val = 0x000,
  331. .note = "MM: Larb0",
  332. .name = "MM_Larb0"
  333. },
  334. {
  335. .master = MST_ID_MM_1,
  336. .port = 0x1,
  337. .id_mask = 0x380,
  338. .id_val = 0x080,
  339. .note = "MM: Larb1",
  340. .name = "MM_Larb1"
  341. },
  342. {
  343. .master = MST_ID_MM_2,
  344. .port = 0x1,
  345. .id_mask = 0x380,
  346. .id_val = 0x100,
  347. .note = "MM: Larb2",
  348. .name = "MM_Larb2"
  349. },
  350. {
  351. .master = MST_ID_MM_3,
  352. .port = 0x1,
  353. .id_mask = 0x380,
  354. .id_val = 0x180,
  355. .note = "MM: Larb3",
  356. .name = "MM_Larb3"
  357. },
  358. {
  359. .master = MST_ID_MM_4,
  360. .port = 0x1,
  361. .id_mask = 0x3FE,
  362. .id_val = 0x3FC,
  363. .note = "MM IOMMU Internal Used",
  364. .name = "MM_IOMMU"
  365. },
  366. /* Periperal */
  367. {
  368. .master = MST_ID_PERI_0,
  369. .port = 0x2,
  370. .id_mask = 0x3F7,
  371. .id_val = 0x000,
  372. .note = "PERI: DebugTop",
  373. .name = "DebugTop"
  374. },
  375. {
  376. .master = MST_ID_PERI_1,
  377. .port = 0x2,
  378. .id_mask = 0x3FF,
  379. .id_val = 0x002,
  380. .note = "PERI: MSDC0",
  381. .name = "MSDC0"
  382. },
  383. {
  384. .master = MST_ID_PERI_2,
  385. .port = 0x2,
  386. .id_mask = 0x3FF,
  387. .id_val = 0x001,
  388. .note = "PERI: reserve",
  389. .name = "reserve"
  390. },
  391. {
  392. .master = MST_ID_PERI_3,
  393. .port = 0x2,
  394. .id_mask = 0x3FF,
  395. .id_val = 0x021,
  396. .note = "PERI: reserve",
  397. .name = "reserve"
  398. },
  399. {
  400. .master = MST_ID_PERI_4,
  401. .port = 0x2,
  402. .id_mask = 0x3FF,
  403. .id_val = 0x041,
  404. .note = "PERI: MSDC3",
  405. .name = "MSDC3"
  406. },
  407. {
  408. .master = MST_ID_PERI_5,
  409. .port = 0x2,
  410. .id_mask = 0x3FF,
  411. .id_val = 0x061,
  412. .note = "PERI: USB2.0",
  413. .name = "USB"
  414. },
  415. {
  416. .master = MST_ID_PERI_6,
  417. .port = 0x2,
  418. .id_mask = 0x3FF,
  419. .id_val = 0x009,
  420. .note = "PERI: PWM",
  421. .name = "PWM"
  422. },
  423. {
  424. .master = MST_ID_PERI_7,
  425. .port = 0x2,
  426. .id_mask = 0x3FF,
  427. .id_val = 0x029,
  428. .note = "PERI: MSDC1",
  429. .name = "MSDC1"
  430. },
  431. {
  432. .master = MST_ID_PERI_8,
  433. .port = 0x2,
  434. .id_mask = 0x3FF,
  435. .id_val = 0x049,
  436. .note = "PERI: MSDC2",
  437. .name = "MSDC2"
  438. },
  439. {
  440. .master = MST_ID_PERI_9,
  441. .port = 0x2,
  442. .id_mask = 0x3FF,
  443. .id_val = 0x069,
  444. .note = "PERI: SPI0",
  445. .name = "SPI0"
  446. },
  447. {
  448. .master = MST_ID_PERI_10,
  449. .port = 0x2,
  450. .id_mask = 0x3FF,
  451. .id_val = 0x011,
  452. .note = "PERI: MD1 + MD2",
  453. .name = "MD1_MD2"
  454. },
  455. {
  456. .master = MST_ID_PERI_11,
  457. .port = 0x2,
  458. .id_mask = 0x3FF,
  459. .id_val = 0x031,
  460. .note = "PERI: SPM",
  461. .name = "SPM"
  462. },
  463. {
  464. .master = MST_ID_PERI_12,
  465. .port = 0x2,
  466. .id_mask = 0x3FF,
  467. .id_val = 0x051,
  468. .note = "PERI: AUDIO",
  469. .name = "AUDIO"
  470. },
  471. {
  472. .master = MST_ID_PERI_13,
  473. .port = 0x2,
  474. .id_mask = 0x3FF,
  475. .id_val = 0x071,
  476. .note = "PERI: THERM",
  477. .name = "THERM"
  478. },
  479. {
  480. .master = MST_ID_PERI_14,
  481. .port = 0x2,
  482. .id_mask = 0x3FF,
  483. .id_val = 0x019,
  484. .note = "PERI: DMA",
  485. .name = "DMA"
  486. },
  487. {
  488. .master = MST_ID_PERI_15,
  489. .port = 0x2,
  490. .id_mask = 0x3FF,
  491. .id_val = 0x003,
  492. .note = "PERI: CONNSYS",
  493. .name = "CONNSYS"
  494. },
  495. {
  496. .master = MST_ID_PERI_16,
  497. .port = 0x2,
  498. .id_mask = 0x3FF,
  499. .id_val = 0x004,
  500. .note = "PERI: GCPU_M",
  501. .name = "GCPU_M"
  502. },
  503. {
  504. .master = MST_ID_PERI_17,
  505. .port = 0x2,
  506. .id_mask = 0x3E7,
  507. .id_val = 0x005,
  508. .note = "PERI: GCE_M",
  509. .name = "GCE_M"
  510. },
  511. {
  512. .master = MST_ID_PERI_18,
  513. .port = 0x2,
  514. .id_mask = 0x3FF,
  515. .id_val = 0x006,
  516. .note = "PERI: CLDMA_AP",
  517. .name = "CLDMA_AP"
  518. },
  519. {
  520. .master = MST_ID_PERI_19,
  521. .port = 0x2,
  522. .id_mask = 0x3FF,
  523. .id_val = 0x00E,
  524. .note = "PERI: CLDMA_MD",
  525. .name = "CLDMA_MD"
  526. },
  527. /* Modem */
  528. {
  529. .master = MST_ID_MDMCU_0,
  530. .port = 0x3,
  531. .id_mask = 0x30F,
  532. .id_val = 0x000,
  533. .note = "MDMCU: ARM7",
  534. .name = "MDMCU"
  535. },
  536. {
  537. .master = MST_ID_MDMCU_1,
  538. .port = 0x3,
  539. .id_mask = 0x3FF,
  540. .id_val = 0x002,
  541. .note = "MDMCU",
  542. .name = "MDMCU"
  543. },
  544. {
  545. .master = MST_ID_MDMCU_2,
  546. .port = 0x3,
  547. .id_mask = 0x30F,
  548. .id_val = 0x004,
  549. .note = "MDMCU: PREFETCH",
  550. .name = "MDMCU"
  551. },
  552. {
  553. .master = MST_ID_MDMCU_3,
  554. .port = 0x3,
  555. .id_mask = 0x30F,
  556. .id_val = 0x008,
  557. .note = "MDMCU: ALC",
  558. .name = "MDMCU"
  559. },
  560. {
  561. .master = MST_ID_C2KMCU_0,
  562. .port = 0x3,
  563. .id_mask = 0x3FF,
  564. .id_val = 0x003,
  565. .note = "MDMCU: CK2 MCUP+ HW:ARM D PORT",
  566. .name = "MDMCU_C2K"
  567. },
  568. {
  569. .master = MST_ID_C2KMCU_1,
  570. .port = 0x3,
  571. .id_mask = 0x3FF,
  572. .id_val = 0x009,
  573. .note = "MDMCU: CK2 MCUP+ HW:ARM I PORT",
  574. .name = "MDMCU_C2K"
  575. },
  576. {
  577. .master = MST_ID_C2KMCU_2,
  578. .port = 0x3,
  579. .id_mask = 0x3FF,
  580. .id_val = 0x013,
  581. .note = "MDMCU: CK2 MCUP+ HW:DMA PORT",
  582. .name = "MDMCU_C2K"
  583. },
  584. /* Modem HW (2G/3G) */
  585. {
  586. .master = MST_ID_MDHW_0,
  587. .port = 0x4,
  588. .id_mask = 0x3FF,
  589. .id_val = 0x000,
  590. .note = "MDHW: MDGDMA",
  591. .name = "MDHW_MDGDMA"
  592. },
  593. {
  594. .master = MST_ID_MDHW_1,
  595. .port = 0x4,
  596. .id_mask = 0x3FB,
  597. .id_val = 0x001,
  598. .note = "MDHW: CLDMA_MD",
  599. .name = "MDHW_CLDMA_MD"
  600. },
  601. {
  602. .master = MST_ID_MDHW_2,
  603. .port = 0x4,
  604. .id_mask = 0x3FB,
  605. .id_val = 0x002,
  606. .note = "MDHW: ABM",
  607. .name = "MDHW_ABM"
  608. },
  609. {
  610. .master = MST_ID_MDHW_3,
  611. .port = 0x4,
  612. .id_mask = 0x3FB,
  613. .id_val = 0x003,
  614. .note = "MDHW: CLDMA_AP",
  615. .name = "MDHW_CLDMA_AP"
  616. },
  617. {
  618. .master = MST_ID_MDHW_4,
  619. .port = 0x4,
  620. .id_mask = 0x3F8,
  621. .id_val = 0x008,
  622. .note = "MDHW: MODEMSYS",
  623. .name = "MDHW_MODEMSYS"
  624. },
  625. {
  626. .master = MST_ID_MDHW_5,
  627. .port = 0x4,
  628. .id_mask = 0x3FE,
  629. .id_val = 0x010,
  630. .note = "MDHW: LTEL2_DMA",
  631. .name = "MDHW_LTEL2_DMA"
  632. },
  633. {
  634. .master = MST_ID_MDHW_6,
  635. .port = 0x4,
  636. .id_mask = 0x3FF,
  637. .id_val = 0x018,
  638. .note = "MDHW: TDDSYS, LTEL1_DMA",
  639. .name = "MDHW_TDDSYS_LTEL1_DMA"
  640. },
  641. {
  642. .master = MST_ID_MDHW_7,
  643. .port = 0x4,
  644. .id_mask = 0x3FE,
  645. .id_val = 0x020,
  646. .note = "MDHW: MODEM_HARQ",
  647. .name = "MDHW_MODEM_HARQ"
  648. },
  649. {
  650. .master = MST_ID_MDHW_8,
  651. .port = 0x4,
  652. .id_mask = 0x3FF,
  653. .id_val = 0x100,
  654. .note = "MDHW: HARQ ID",
  655. .name = "MDHW_HARQ_ID"
  656. },
  657. {
  658. .master = MST_ID_MDHW_9,
  659. .port = 0x4,
  660. .id_mask = 0x3FF,
  661. .id_val = 0x102,
  662. .note = "MDHW: POSITION ID",
  663. .name = "MDHW_POSITION_ID"
  664. },
  665. /* MFG */
  666. {
  667. .master = MST_ID_MFG_0,
  668. .port = 0x5,
  669. .id_mask = 0x3C0,
  670. .id_val = 0x000,
  671. .note = "MFG",
  672. .name = "MFG"
  673. },
  674. };
  675. static const char *UNKNOWN_MASTER = "unknown";
  676. static spinlock_t emi_mpu_lock;
  677. #ifdef ENABLE_EMI_CHKER
  678. struct timer_list emi_axi_vio_timer;
  679. #endif
  680. char *smi_larb0_port[7] = {
  681. "disp_ovl_0",
  682. "disp_rdma_0",
  683. "disp_wdma_0",
  684. "disp_rdma_1",
  685. "mdp_rdma",
  686. "mdp_wdma",
  687. "mdp_wrot"
  688. };
  689. char *smi_larb1_port[7] = {
  690. "hw_vdec_mc_ext",
  691. "hw_vdec_pp_ext",
  692. "hw_vdec_avc_mv_ext" ,
  693. "hw_vdec_pred_rd_ext",
  694. "hw_vdec_pred_wr_ext",
  695. "hw_vdec_vld_ext",
  696. "hw_vdec_ppwarp_ext"
  697. };
  698. char *smi_larb2_port[21] = {
  699. "cam_imgo",
  700. "cam_rrzo",
  701. "cam_aao",
  702. "cam_isco",
  703. "cam_esfko",
  704. "cam_imgo_s",
  705. "cam_isci",
  706. "cam_isci_d",
  707. "cam_bpci",
  708. "cam_bpci_d",
  709. "cam_ufdi",
  710. "cam_imgi",
  711. "cam_img2o",
  712. "cam_img3o",
  713. "cam_vipi",
  714. "cam_vip2i",
  715. "cam_vip3i",
  716. "cam_icei" ,
  717. "cam_rb" ,
  718. "cam_rp" ,
  719. "cam_wr"
  720. };
  721. char *smi_larb3_port[13] = {
  722. "venc_rcpu",
  723. "venc_rec",
  724. "venc_bsdma",
  725. "venc_sv_comv",
  726. "venc_rd_comv",
  727. "jpgenc_rdma",
  728. "jpgenc_bsdma",
  729. "jpgdec_wdma",
  730. "jpgdec_bsdma",
  731. "venc_cur_luma",
  732. "venc_cur_chroma",
  733. "venc_ref_luma",
  734. "vend_ref_chroma"
  735. };
  736. static int __match_id(u32 axi_id, int tbl_idx, u32 port_ID)
  737. {
  738. u32 mm_larb;
  739. u32 smi_port;
  740. if (((axi_id & mst_tbl[tbl_idx].id_mask) == mst_tbl[tbl_idx].id_val) &&
  741. (port_ID == mst_tbl[tbl_idx].port)) {
  742. switch (port_ID) {
  743. case 0: /* ARM */
  744. case 2: /* Peripheral */
  745. case 3: /* MDMCU ,C2K MCU */
  746. case 4: /* MD HW ,LTE */
  747. case 5: /* MFG */
  748. case 6:
  749. case 7:
  750. pr_err("Violation master name is %s.\n",
  751. mst_tbl[tbl_idx].name);
  752. break;
  753. case 1: /*MM*/
  754. mm_larb = axi_id>>7;
  755. smi_port = (axi_id & 0x7F) >> 2;
  756. if (mm_larb == 0x0) {
  757. /*smi_larb0 */
  758. if (smi_port >= ARRAY_SIZE(smi_larb0_port)) {
  759. pr_err("[EMI MPU ERROR] Invalidatemaster ID! %s",
  760. "lookup smi table failed!\n");
  761. return 0;
  762. }
  763. pr_err("Violation master name is %s (%s).\n",
  764. mst_tbl[tbl_idx].name,
  765. smi_larb0_port[smi_port]);
  766. } else if (mm_larb == 0x1) {
  767. /*smi_larb1*/
  768. if (smi_port >= ARRAY_SIZE(smi_larb1_port)) {
  769. pr_err("[EMI MPU ERROR] Invalidate master ID! %s",
  770. "lookup smi table failed!\n");
  771. return 0;
  772. }
  773. pr_err("Violation master name is %s (%s).\n",
  774. mst_tbl[tbl_idx].name,
  775. smi_larb1_port[smi_port]);
  776. } else if (mm_larb == 0x2) {
  777. /*smi_larb2*/
  778. if (smi_port >= ARRAY_SIZE(smi_larb2_port)) {
  779. pr_err("[EMI MPU ERROR] Invalidate master ID! %s",
  780. "lookup smi table failed!\n");
  781. return 0;
  782. }
  783. pr_err("Violation master name is %s (%s).\n",
  784. mst_tbl[tbl_idx].name,
  785. smi_larb2_port[smi_port]);
  786. } else if (mm_larb == 0x3) {
  787. /*smi_larb3*/
  788. if (smi_port >= ARRAY_SIZE(smi_larb3_port)) {
  789. pr_err("[EMI MPU ERROR] Invalidate master ID! %s",
  790. "lookup smi table failed!\n");
  791. return 0;
  792. }
  793. pr_err("Violation master name is %s (%s).\n",
  794. mst_tbl[tbl_idx].name,
  795. smi_larb3_port[smi_port]);
  796. } else /*MM IOMMU Internal Used*/ {
  797. pr_err("Violation master name is %s.\n",
  798. mst_tbl[tbl_idx].name);
  799. }
  800. break;
  801. default:
  802. pr_err("[EMI MPU ERROR] Invalidate port ID! lookup bus ID table failed!\n");
  803. break;
  804. }
  805. return 1;
  806. } else {
  807. return 0;
  808. }
  809. }
  810. static u32 __id2mst(u32 id)
  811. {
  812. int i;
  813. u32 axi_ID;
  814. u32 port_ID;
  815. axi_ID = (id >> 3) & 0x000001FFF;
  816. port_ID = id & 0x00000007;
  817. pr_err("[EMI MPU] axi_id = %x, port_id = %x\n", axi_ID, port_ID);
  818. for (i = 0; i < ARRAY_SIZE(mst_tbl); i++) {
  819. if (__match_id(axi_ID, i, port_ID))
  820. return mst_tbl[i].master;
  821. }
  822. return MST_INVALID;
  823. }
  824. static char *__id2name(u32 id)
  825. {
  826. int i;
  827. u32 axi_ID;
  828. u32 port_ID;
  829. axi_ID = (id >> 3) & 0x00001FFF;
  830. port_ID = id & 0x00000007;
  831. pr_err("[EMI MPU] axi_id = %x, port_id = %x\n", axi_ID, port_ID);
  832. for (i = 0; i < ARRAY_SIZE(mst_tbl); i++) {
  833. if (__match_id(axi_ID, i, port_ID))
  834. return mst_tbl[i].name;
  835. }
  836. return (char *)UNKNOWN_MASTER;
  837. }
  838. static void __clear_emi_mpu_vio(void)
  839. {
  840. u32 dbg_s, dbg_t;
  841. /* clear violation status */
  842. mt_reg_sync_writel(0x00FF03FF, EMI_MPUP);
  843. mt_reg_sync_writel(0x00FF03FF, EMI_MPUQ);
  844. mt_reg_sync_writel(0x00FF03FF, EMI_MPUR);
  845. mt_reg_sync_writel(0x00FF03FF, EMI_MPUY);
  846. mt_reg_sync_writel(0x00FF03FF, EMI_MPUP2);
  847. mt_reg_sync_writel(0x00FF03FF, EMI_MPUQ2);
  848. mt_reg_sync_writel(0x00FF03FF, EMI_MPUR2);
  849. mt_reg_sync_writel(0x00FF03FF, EMI_MPUY2);
  850. /* clear debug info */
  851. mt_reg_sync_writel(0x80000000, EMI_MPUS);
  852. dbg_s = readl(IOMEM(EMI_MPUS));
  853. dbg_t = readl(IOMEM(EMI_MPUT));
  854. /* MT6582 EMI hw bug EMI_MPUS[10:0] and EMI_MPUT can't be cleared */
  855. if (dbg_s) {
  856. pr_err("Fail to clear EMI MPU violation\n");
  857. pr_err("EMI_MPUS = %x, EMI_MPUT = %x", dbg_s, dbg_t);
  858. }
  859. }
  860. /*EMI MPU violation handler*/
  861. static irqreturn_t mpu_violation_irq(int irq, void *dev_id)
  862. {
  863. u32 dbg_s, dbg_t, dbg_pqry;
  864. u32 master_ID, domain_ID, wr_vio;
  865. s32 region;
  866. int res;
  867. char *master_name;
  868. /* Need DEVAPC owner porting */
  869. res = mt_devapc_check_emi_violation();
  870. if (res)
  871. return IRQ_NONE;
  872. pr_debug("It's a MPU violation.\n");
  873. dbg_s = readl(IOMEM(EMI_MPUS));
  874. dbg_t = readl(IOMEM(EMI_MPUT));
  875. pr_debug("Clear status.\n");
  876. /*in 6735 Master ID valid bit is [13:0] */
  877. master_ID = (dbg_s & 0x00003FFF);
  878. domain_ID = (dbg_s >> 21) & 0x00000007;
  879. wr_vio = (dbg_s >> 28) & 0x00000003;
  880. region = (dbg_s >> 16) & 0xF;
  881. switch (domain_ID) {
  882. case 0:
  883. dbg_pqry = readl(IOMEM(EMI_MPUP));
  884. break;
  885. case 1:
  886. dbg_pqry = readl(IOMEM(EMI_MPUQ));
  887. break;
  888. case 2:
  889. dbg_pqry = readl(IOMEM(EMI_MPUR));
  890. break;
  891. case 3:
  892. dbg_pqry = readl(IOMEM(EMI_MPUY));
  893. break;
  894. #if defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6753)
  895. case 4:
  896. dbg_pqry = readl(IOMEM(EMI_MPUP2));
  897. break;
  898. case 5:
  899. dbg_pqry = readl(IOMEM(EMI_MPUQ2));
  900. break;
  901. case 6:
  902. dbg_pqry = readl(IOMEM(EMI_MPUR2));
  903. break;
  904. case 7:
  905. dbg_pqry = readl(IOMEM(EMI_MPUY2));
  906. break;
  907. #endif
  908. default:
  909. dbg_pqry = 0;
  910. break;
  911. }
  912. /*TBD: print the abort region*/
  913. pr_err("EMI MPU violation.\n");
  914. pr_err("[EMI MPU] Debug info start ----------------------------------------\n");
  915. pr_err("EMI_MPUS = %x, EMI_MPUT = %x.\n", dbg_s, dbg_t);
  916. pr_err("Current process is \"%s \" (pid: %i).\n",
  917. current->comm, current->pid);
  918. pr_err("Violation address is 0x%x.\n", dbg_t + emi_physical_offset);
  919. pr_err("Violation master ID is 0x%x.\n", master_ID);
  920. /*print out the murderer name*/
  921. master_name = __id2name(master_ID);
  922. pr_err("Violation domain ID is 0x%x.\n", domain_ID);
  923. pr_err("%s violation.\n", (wr_vio == 1) ? "Write" : "Read");
  924. pr_err("Corrupted region is %d\n\r", region);
  925. if (dbg_pqry & OOR_VIO)
  926. pr_err("Out of range violation.\n");
  927. pr_err("[EMI MPU] Debug info end------------------------------------------\n");
  928. #if 0
  929. /* For MDHW debug usage, 0x6C -> MDHW, Master is 3G */
  930. if (dbg_s & 0x6C)
  931. exec_ccci_kern_func_by_md_id(0, ID_FORCE_MD_ASSERT, NULL, 0);
  932. #endif
  933. #ifdef CONFIG_MTK_AEE_FEATURE
  934. /*FIXME: skip ca53 violation to trigger root-cause KE*/
  935. if ((0 != dbg_s) &&
  936. (__id2mst(master_ID) != MST_ID_APMCU_0)
  937. && (__id2mst(master_ID) != MST_ID_APMCU_1)) {
  938. aee_kernel_exception("EMI MPU",
  939. "EMI MPU violation.\nEMI_MPUS = 0x%x,EMI_MPUT = 0x%x\nCRDISPATCH_KEY:EMI MPU Violation Issue/%s\n",
  940. dbg_s, dbg_t+emi_physical_offset, master_name);
  941. }
  942. #endif
  943. __clear_emi_mpu_vio();
  944. mt_devapc_clear_emi_violation();
  945. #if 0
  946. list_for_each(p, &(emi_mpu_notifier_list[__id2mst(master_ID)])) {
  947. block = list_entry(p, struct emi_mpu_notifier_block, list);
  948. block->notifier(dbg_t + emi_physical_offset, wr_vio);
  949. }
  950. #endif
  951. vio_addr = dbg_t + emi_physical_offset;
  952. return IRQ_HANDLED;
  953. }
  954. #if defined(CONFIG_ARCH_MT6753)
  955. /* Acquire DRAM Setting for PASR/DPD */
  956. void acquire_dram_setting(struct basic_dram_setting *pasrdpd)
  957. {
  958. int ch_nr = MAX_CHANNELS;
  959. unsigned int emi_cona, emi_conh, col_bit, row_bit;
  960. unsigned int ch0_rank0_size, ch0_rank1_size;
  961. unsigned int ch1_rank0_size, ch1_rank1_size;
  962. pasrdpd->channel_nr = ch_nr;
  963. emi_cona = readl(IOMEM(EMI_CONA));
  964. emi_conh = readl(IOMEM(EMI_CONH));
  965. ch0_rank0_size = (emi_conh >> 16) & 0xf;
  966. ch0_rank1_size = (emi_conh >> 20) & 0xf;
  967. ch1_rank0_size = (emi_conh >> 24) & 0xf;
  968. ch1_rank1_size = (emi_conh >> 28) & 0xf;
  969. /*channel 0*/
  970. {
  971. /*rank 0*/
  972. pasrdpd->channel[0].rank[0].valid_rank = true;
  973. if (ch0_rank0_size == 0) {
  974. col_bit = ((emi_cona >> 4) & 0x03) + 9;
  975. row_bit = ((emi_cona >> 12) & 0x03) + 13;
  976. /* 32 bits * 8 banks, unit Gb*/
  977. pasrdpd->channel[0].rank[0].rank_size =
  978. (1 << (row_bit + col_bit)) >> 22;
  979. pasrdpd->channel[0].rank[0].segment_nr = 8;
  980. } else {
  981. pasrdpd->channel[0].rank[0].rank_size =
  982. (ch0_rank0_size * 2);
  983. /*unit Gb*/
  984. pasrdpd->channel[0].rank[0].segment_nr = 6;
  985. }
  986. if (0 != (emi_cona & (1 << 17))) {
  987. /*rank 1 exist*/
  988. pasrdpd->channel[0].rank[1].valid_rank = true;
  989. if (ch0_rank1_size == 0) {
  990. col_bit = ((emi_cona >> 6) & 0x03) + 9;
  991. row_bit = ((emi_cona >> 14) & 0x03) + 13;
  992. pasrdpd->channel[0].rank[1].rank_size =
  993. (1 << (row_bit + col_bit)) >> 22;
  994. /*32 bits * 8 banks, unit Gb*/
  995. pasrdpd->channel[0].rank[1].segment_nr = 8;
  996. } else {
  997. pasrdpd->channel[0].rank[1].rank_size =
  998. (ch0_rank1_size * 2);
  999. /* unit Gb*/
  1000. pasrdpd->channel[0].rank[1].segment_nr = 6;
  1001. }
  1002. } else {
  1003. pasrdpd->channel[0].rank[1].valid_rank = false;
  1004. pasrdpd->channel[0].rank[1].segment_nr = 0;
  1005. pasrdpd->channel[0].rank[1].rank_size = 0;
  1006. }
  1007. }
  1008. if (0 != (emi_cona & 0x01)) {
  1009. /*channel 1 exist*/
  1010. /*rank0 setting*/
  1011. pasrdpd->channel[1].rank[0].valid_rank = true;
  1012. if (ch1_rank0_size == 0) {
  1013. col_bit = ((emi_cona >> 20) & 0x03) + 9;
  1014. row_bit = ((emi_cona >> 28) & 0x03) + 13;
  1015. pasrdpd->channel[1].rank[0].rank_size =
  1016. (1 << (row_bit + col_bit)) >> 22;
  1017. /* 32 bits * 8 banks, unit Gb*/
  1018. pasrdpd->channel[1].rank[0].segment_nr = 8;
  1019. } else {
  1020. pasrdpd->channel[1].rank[0].rank_size =
  1021. (ch1_rank0_size * 2);
  1022. /* unit Gb*/
  1023. pasrdpd->channel[1].rank[0].segment_nr = 6;
  1024. }
  1025. if (0 != (emi_cona & (1 << 16))) {
  1026. /*rank 1 exist*/
  1027. pasrdpd->channel[1].rank[1].valid_rank = true;
  1028. if (ch1_rank1_size == 0) {
  1029. col_bit = ((emi_cona >> 22) & 0x03) + 9;
  1030. row_bit = ((emi_cona >> 30) & 0x03) + 13;
  1031. pasrdpd->channel[1].rank[1].rank_size =
  1032. (1 << (row_bit + col_bit)) >> 22;
  1033. /* 32 bits * 8 banks, unit Gb*/
  1034. pasrdpd->channel[1].rank[1].segment_nr = 8;
  1035. } else {
  1036. pasrdpd->channel[1].rank[1].rank_size =
  1037. (ch1_rank1_size * 2);
  1038. /* unit Gb*/
  1039. pasrdpd->channel[1].rank[1].segment_nr = 6;
  1040. }
  1041. } else {
  1042. pasrdpd->channel[1].rank[1].valid_rank = false;
  1043. pasrdpd->channel[1].rank[1].segment_nr = 0;
  1044. pasrdpd->channel[1].rank[1].rank_size = 0;
  1045. }
  1046. } else {
  1047. /*channel 2 does not exist*/
  1048. pasrdpd->channel[1].rank[0].valid_rank = false;
  1049. pasrdpd->channel[1].rank[0].segment_nr = 0;
  1050. pasrdpd->channel[1].rank[0].rank_size = 0;
  1051. pasrdpd->channel[1].rank[1].valid_rank = false;
  1052. pasrdpd->channel[1].rank[1].segment_nr = 0;
  1053. pasrdpd->channel[1].rank[1].rank_size = 0;
  1054. }
  1055. }
  1056. #endif
  1057. /*
  1058. * emi_mpu_set_region_protection: protect a region.
  1059. * @start: start address of the region
  1060. * @end: end address of the region
  1061. * @region: EMI MPU region id
  1062. * @access_permission: EMI MPU access permission
  1063. * Return 0 for success, otherwise negative status code.
  1064. */
  1065. int emi_mpu_set_region_protection(unsigned int start,
  1066. unsigned int end, int region, unsigned int access_permission)
  1067. {
  1068. int ret = 0;
  1069. unsigned int tmp, tmp2;
  1070. unsigned int ax_pm, ax_pm2;
  1071. unsigned long flags;
  1072. if ((end != 0) || (start != 0)) {
  1073. /*Address 64KB alignment*/
  1074. start -= emi_physical_offset;
  1075. end -= emi_physical_offset;
  1076. start = start >> 16;
  1077. end = end >> 16;
  1078. if (end < start)
  1079. return -EINVAL;
  1080. }
  1081. ax_pm = (access_permission << 16) >> 16;
  1082. ax_pm2 = (access_permission >> 16);
  1083. spin_lock_irqsave(&emi_mpu_lock, flags);
  1084. switch (region) {
  1085. case 0:
  1086. /* Clear access right before setting MPU address*/
  1087. tmp = readl(IOMEM(EMI_MPUI)) & 0xFFFF0000;
  1088. tmp2 = readl(IOMEM(EMI_MPUI_2ND)) & 0xFFFF0000;
  1089. mt_reg_sync_writel(0, EMI_MPUI);
  1090. mt_reg_sync_writel(0, EMI_MPUI_2ND);
  1091. mt_reg_sync_writel((start << 16) | end, EMI_MPUA);
  1092. mt_reg_sync_writel(tmp | ax_pm, EMI_MPUI);
  1093. mt_reg_sync_writel(tmp2 | ax_pm2, EMI_MPUI_2ND);
  1094. break;
  1095. case 1:
  1096. /* Clear access right before setting MPU address */
  1097. tmp = readl(IOMEM(EMI_MPUI)) & 0x0000FFFF;
  1098. tmp2 = readl(IOMEM(EMI_MPUI_2ND)) & 0x0000FFFF;
  1099. mt_reg_sync_writel(0, EMI_MPUI);
  1100. mt_reg_sync_writel(0, EMI_MPUI_2ND);
  1101. mt_reg_sync_writel((start << 16) | end, EMI_MPUB);
  1102. mt_reg_sync_writel(tmp | (ax_pm << 16), EMI_MPUI);
  1103. mt_reg_sync_writel(tmp2 | (ax_pm2 << 16), EMI_MPUI_2ND);
  1104. break;
  1105. case 2:
  1106. /* Clear access right before setting MPU address */
  1107. tmp = readl(IOMEM(EMI_MPUJ)) & 0xFFFF0000;
  1108. tmp2 = readl(IOMEM(EMI_MPUJ_2ND)) & 0xFFFF0000;
  1109. mt_reg_sync_writel(0, EMI_MPUJ);
  1110. mt_reg_sync_writel(0, EMI_MPUJ_2ND);
  1111. mt_reg_sync_writel((start << 16) | end, EMI_MPUC);
  1112. mt_reg_sync_writel(tmp | ax_pm, EMI_MPUJ);
  1113. mt_reg_sync_writel(tmp2 | ax_pm2, EMI_MPUJ_2ND);
  1114. break;
  1115. case 3:
  1116. /* Clear access right before setting MPU address */
  1117. tmp = readl(IOMEM(EMI_MPUJ)) & 0x0000FFFF;
  1118. tmp2 = readl(IOMEM(EMI_MPUJ_2ND)) & 0x0000FFFF;
  1119. mt_reg_sync_writel(0, EMI_MPUJ);
  1120. mt_reg_sync_writel(0, EMI_MPUJ_2ND);
  1121. mt_reg_sync_writel((start << 16) | end, EMI_MPUD);
  1122. mt_reg_sync_writel(tmp | (ax_pm << 16), EMI_MPUJ);
  1123. mt_reg_sync_writel(tmp2 | (ax_pm2 << 16), EMI_MPUJ_2ND);
  1124. break;
  1125. case 4:
  1126. /* Clear access right before setting MPU address */
  1127. tmp = readl(IOMEM(EMI_MPUK)) & 0xFFFF0000;
  1128. tmp2 = readl(IOMEM(EMI_MPUK_2ND)) & 0xFFFF0000;
  1129. mt_reg_sync_writel(0, EMI_MPUK);
  1130. mt_reg_sync_writel(0, EMI_MPUK_2ND);
  1131. mt_reg_sync_writel((start << 16) | end, EMI_MPUE);
  1132. mt_reg_sync_writel(tmp | ax_pm, EMI_MPUK);
  1133. mt_reg_sync_writel(tmp2 | ax_pm2, EMI_MPUK_2ND);
  1134. break;
  1135. case 5:
  1136. /* Clear access right before setting MPU address */
  1137. tmp = readl(IOMEM(EMI_MPUK)) & 0x0000FFFF;
  1138. tmp2 = readl(IOMEM(EMI_MPUK_2ND)) & 0x0000FFFF;
  1139. mt_reg_sync_writel(0, EMI_MPUK);
  1140. mt_reg_sync_writel(0, EMI_MPUK_2ND);
  1141. mt_reg_sync_writel((start << 16) | end, EMI_MPUF);
  1142. mt_reg_sync_writel(tmp | (ax_pm << 16), EMI_MPUK);
  1143. mt_reg_sync_writel(tmp2 | (ax_pm2 << 16), EMI_MPUK_2ND);
  1144. break;
  1145. case 6:
  1146. /* Clear access right before setting MPU address */
  1147. tmp = readl(IOMEM(EMI_MPUL)) & 0xFFFF0000;
  1148. tmp2 = readl(IOMEM(EMI_MPUL_2ND)) & 0xFFFF0000;
  1149. mt_reg_sync_writel(0, EMI_MPUL);
  1150. mt_reg_sync_writel(0, EMI_MPUL_2ND);
  1151. mt_reg_sync_writel((start << 16) | end, EMI_MPUG);
  1152. mt_reg_sync_writel(tmp | ax_pm, EMI_MPUL);
  1153. mt_reg_sync_writel(tmp2 | ax_pm2, EMI_MPUL_2ND);
  1154. break;
  1155. case 7:
  1156. /* Clear access right before setting MPU address */
  1157. tmp = readl(IOMEM(EMI_MPUL)) & 0x0000FFFF;
  1158. tmp2 = readl(IOMEM(EMI_MPUL_2ND)) & 0x0000FFFF;
  1159. mt_reg_sync_writel(0, EMI_MPUL);
  1160. mt_reg_sync_writel(0, EMI_MPUL_2ND);
  1161. mt_reg_sync_writel((start << 16) | end, EMI_MPUH);
  1162. mt_reg_sync_writel(tmp | (ax_pm << 16), EMI_MPUL);
  1163. mt_reg_sync_writel(tmp2 | (ax_pm2 << 16), EMI_MPUL_2ND);
  1164. break;
  1165. #if defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6753)
  1166. case 8:
  1167. /* Clear access right before setting MPU address */
  1168. tmp = readl(IOMEM(EMI_MPUI2)) & 0xFFFF0000;
  1169. tmp2 = readl(IOMEM(EMI_MPUI2_2ND)) & 0xFFFF0000;
  1170. mt_reg_sync_writel(0, EMI_MPUI2);
  1171. mt_reg_sync_writel(0, EMI_MPUI2_2ND);
  1172. mt_reg_sync_writel((start << 16) | end, EMI_MPUA2);
  1173. mt_reg_sync_writel(tmp | ax_pm, EMI_MPUI2);
  1174. mt_reg_sync_writel(tmp2 | ax_pm2, EMI_MPUI2_2ND);
  1175. break;
  1176. case 9:
  1177. /* Clear access right before setting MPU address */
  1178. tmp = readl(IOMEM(EMI_MPUI2)) & 0x0000FFFF;
  1179. tmp2 = readl(IOMEM(EMI_MPUI2_2ND)) & 0x0000FFFF;
  1180. mt_reg_sync_writel(0, EMI_MPUI2);
  1181. mt_reg_sync_writel(0, EMI_MPUI2_2ND);
  1182. mt_reg_sync_writel((start << 16) | end, EMI_MPUB2);
  1183. mt_reg_sync_writel(tmp | (ax_pm << 16), EMI_MPUI2);
  1184. mt_reg_sync_writel(tmp2 | (ax_pm2 << 16), EMI_MPUI2_2ND);
  1185. break;
  1186. case 10:
  1187. /* Clear access right before setting MPU address */
  1188. tmp = readl(IOMEM(EMI_MPUJ2)) & 0xFFFF0000;
  1189. tmp2 = readl(IOMEM(EMI_MPUJ2_2ND)) & 0xFFFF0000;
  1190. mt_reg_sync_writel(0, EMI_MPUJ2);
  1191. mt_reg_sync_writel(0, EMI_MPUJ2_2ND);
  1192. mt_reg_sync_writel((start << 16) | end, EMI_MPUC2);
  1193. mt_reg_sync_writel(tmp | ax_pm, EMI_MPUJ2);
  1194. mt_reg_sync_writel(tmp2 | ax_pm2, EMI_MPUJ2_2ND);
  1195. break;
  1196. case 11:
  1197. /* Clear access right before setting MPU address */
  1198. tmp = readl(IOMEM(EMI_MPUJ2)) & 0x0000FFFF;
  1199. tmp2 = readl(IOMEM(EMI_MPUJ2_2ND)) & 0x0000FFFF;
  1200. mt_reg_sync_writel(0, EMI_MPUJ2);
  1201. mt_reg_sync_writel(0, EMI_MPUJ2_2ND);
  1202. mt_reg_sync_writel((start << 16) | end, EMI_MPUD2);
  1203. mt_reg_sync_writel(tmp | (ax_pm << 16), EMI_MPUJ2);
  1204. mt_reg_sync_writel(tmp2 | (ax_pm2 << 16), EMI_MPUJ2_2ND);
  1205. break;
  1206. case 12:
  1207. /* Clear access right before setting MPU address */
  1208. tmp = readl(IOMEM(EMI_MPUK2)) & 0xFFFF0000;
  1209. tmp2 = readl(IOMEM(EMI_MPUK2_2ND)) & 0xFFFF0000;
  1210. mt_reg_sync_writel(0, EMI_MPUK2);
  1211. mt_reg_sync_writel(0, EMI_MPUK2_2ND);
  1212. mt_reg_sync_writel((start << 16) | end, EMI_MPUE2);
  1213. mt_reg_sync_writel(tmp | ax_pm, EMI_MPUK2);
  1214. mt_reg_sync_writel(tmp2 | ax_pm2, EMI_MPUK2_2ND);
  1215. break;
  1216. case 13:
  1217. /* Clear access right before setting MPU address */
  1218. tmp = readl(IOMEM(EMI_MPUK2)) & 0x0000FFFF;
  1219. tmp2 = readl(IOMEM(EMI_MPUK2_2ND)) & 0x0000FFFF;
  1220. mt_reg_sync_writel(0, EMI_MPUK2);
  1221. mt_reg_sync_writel(0, EMI_MPUK2_2ND);
  1222. mt_reg_sync_writel((start << 16) | end, EMI_MPUF2);
  1223. mt_reg_sync_writel(tmp | (ax_pm << 16), EMI_MPUK2);
  1224. mt_reg_sync_writel(tmp2 | (ax_pm2 << 16), EMI_MPUK2_2ND);
  1225. break;
  1226. case 14:
  1227. /* Clear access right before setting MPU address */
  1228. tmp = readl(IOMEM(EMI_MPUL2)) & 0xFFFF0000;
  1229. tmp2 = readl(IOMEM(EMI_MPUL2_2ND)) & 0xFFFF0000;
  1230. mt_reg_sync_writel(0, EMI_MPUL2);
  1231. mt_reg_sync_writel(0, EMI_MPUL2_2ND);
  1232. mt_reg_sync_writel((start << 16) | end, EMI_MPUG2);
  1233. mt_reg_sync_writel(tmp | ax_pm, EMI_MPUL2);
  1234. mt_reg_sync_writel(tmp2 | ax_pm2, EMI_MPUL2_2ND);
  1235. break;
  1236. case 15:
  1237. /* Clear access right before setting MPU address */
  1238. tmp = readl(IOMEM(EMI_MPUL2)) & 0x0000FFFF;
  1239. tmp2 = readl(IOMEM(EMI_MPUL2_2ND)) & 0x0000FFFF;
  1240. mt_reg_sync_writel(0, EMI_MPUL2);
  1241. mt_reg_sync_writel(0, EMI_MPUL2_2ND);
  1242. mt_reg_sync_writel((start << 16) | end, EMI_MPUH2);
  1243. mt_reg_sync_writel(tmp | (ax_pm << 16), EMI_MPUL2);
  1244. mt_reg_sync_writel(tmp2 | (ax_pm2 << 16), EMI_MPUL2_2ND);
  1245. break;
  1246. #endif
  1247. default:
  1248. ret = -EINVAL;
  1249. break;
  1250. }
  1251. spin_unlock_irqrestore(&emi_mpu_lock, flags);
  1252. #if 0
  1253. pr_debug("[EMI MPU] emi_physical_offset = 0x%x\n", emi_physical_offset);
  1254. pr_debug("[EMI MPU] EMI_MPUA = 0x%x\n", readl(IOMEM(EMI_MPUA)));
  1255. pr_debug("[EMI MPU] EMI_MPUB = 0x%x\n", readl(IOMEM(EMI_MPUB)));
  1256. pr_debug("[EMI MPU] EMI_MPUC = 0x%x\n", readl(IOMEM(EMI_MPUC)));
  1257. pr_debug("[EMI MPU] EMI_MPUD = 0x%x\n", readl(IOMEM(EMI_MPUD)));
  1258. pr_debug("[EMI MPU] EMI_MPUE = 0x%x\n", readl(IOMEM(EMI_MPUE)));
  1259. pr_debug("[EMI MPU] EMI_MPUF = 0x%x\n", readl(IOMEM(EMI_MPUF)));
  1260. pr_debug("[EMI MPU] EMI_MPUG = 0x%x\n", readl(IOMEM(EMI_MPUG)));
  1261. pr_debug("[EMI MPU] EMI_MPUH = 0x%x\n", readl(IOMEM(EMI_MPUH)));
  1262. pr_debug("[EMI MPU] EMI_MPUA2 = 0x%x\n", readl(IOMEM(EMI_MPUA2)));
  1263. pr_debug("[EMI MPU] EMI_MPUB2 = 0x%x\n", readl(IOMEM(EMI_MPUB2)));
  1264. pr_debug("[EMI MPU] EMI_MPUC2 = 0x%x\n", readl(IOMEM(EMI_MPUC2)));
  1265. pr_debug("[EMI MPU] EMI_MPUD2 = 0x%x\n", readl(IOMEM(EMI_MPUD2)));
  1266. pr_debug("[EMI MPU] EMI_MPUE2 = 0x%x\n", readl(IOMEM(EMI_MPUE2)));
  1267. pr_debug("[EMI MPU] EMI_MPUF2 = 0x%x\n", readl(IOMEM(EMI_MPUF2)));
  1268. pr_debug("[EMI MPU] EMI_MPUG2 = 0x%x\n", readl(IOMEM(EMI_MPUG2)));
  1269. pr_debug("[EMI MPU] EMI_MPUH2 = 0x%x\n", readl(IOMEM(EMI_MPUH2)));
  1270. #endif
  1271. return ret;
  1272. }
  1273. EXPORT_SYMBOL(emi_mpu_set_region_protection);
  1274. /*
  1275. * emi_mpu_notifier_register: register a notifier.
  1276. * master: MST_ID_xxx
  1277. * notifier: the callback function
  1278. * Return 0 for success, otherwise negative error code.
  1279. */
  1280. #if 0
  1281. int emi_mpu_notifier_register(int master, emi_mpu_notifier notifier)
  1282. {
  1283. struct emi_mpu_notifier_block *block;
  1284. static int emi_mpu_notifier_init;
  1285. int i;
  1286. if (master >= MST_INVALID)
  1287. return -EINVAL;
  1288. block = kmalloc(sizeof(struct emi_mpu_notifier_block), GFP_KERNEL);
  1289. if (!block)
  1290. return -ENOMEM;
  1291. if (!emi_mpu_notifier_init) {
  1292. for (i = 0; i < NR_MST; i++)
  1293. INIT_LIST_HEAD(&(emi_mpu_notifier_list[i]));
  1294. emi_mpu_notifier_init = 1;
  1295. }
  1296. block->notifier = notifier;
  1297. list_add(&(block->list), &(emi_mpu_notifier_list[master]));
  1298. return 0;
  1299. }
  1300. #endif
  1301. static ssize_t emi_mpu_show(struct device_driver *driver, char *buf)
  1302. {
  1303. char *ptr = buf;
  1304. unsigned int start, end;
  1305. unsigned int reg_value;
  1306. unsigned int d0, d1, d2, d3;
  1307. #if defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6753)
  1308. unsigned int d4, d5, d6, d7, reg_value2;
  1309. #endif
  1310. static const char *permission[7] = {
  1311. "No protect",
  1312. "Only R/W for secure access",
  1313. "Only R/W for secure access, and non-secure read access",
  1314. "Only R/W for secure access, and non-secure write access",
  1315. "Only R for secure/non-secure",
  1316. "Both R/W are forbidden",
  1317. "Only secure W is forbidden"
  1318. };
  1319. reg_value = readl(IOMEM(EMI_MPUA));
  1320. start = ((reg_value >> 16) << 16) + emi_physical_offset;
  1321. end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
  1322. ptr += sprintf(ptr, "Region 0 --> 0x%x to 0x%x\n", start, end);
  1323. reg_value = readl(IOMEM(EMI_MPUB));
  1324. start = ((reg_value >> 16) << 16) + emi_physical_offset;
  1325. end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
  1326. ptr += sprintf(ptr, "Region 1 --> 0x%x to 0x%x\n", start, end);
  1327. reg_value = readl(IOMEM(EMI_MPUC));
  1328. start = ((reg_value >> 16) << 16) + emi_physical_offset;
  1329. end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
  1330. ptr += sprintf(ptr, "Region 2 --> 0x%x to 0x%x\n", start, end);
  1331. reg_value = readl(IOMEM(EMI_MPUD));
  1332. start = ((reg_value >> 16) << 16) + emi_physical_offset;
  1333. end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
  1334. ptr += sprintf(ptr, "Region 3 --> 0x%x to 0x%x\n", start, end);
  1335. reg_value = readl(IOMEM(EMI_MPUE));
  1336. start = ((reg_value >> 16) << 16) + emi_physical_offset;
  1337. end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
  1338. ptr += sprintf(ptr, "Region 4 --> 0x%x to 0x%x\n", start, end);
  1339. reg_value = readl(IOMEM(EMI_MPUF));
  1340. start = ((reg_value >> 16) << 16) + emi_physical_offset;
  1341. end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
  1342. ptr += sprintf(ptr, "Region 5 --> 0x%x to 0x%x\n", start, end);
  1343. reg_value = readl(IOMEM(EMI_MPUG));
  1344. start = ((reg_value >> 16) << 16) + emi_physical_offset;
  1345. end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
  1346. ptr += sprintf(ptr, "Region 6 --> 0x%x to 0x%x\n", start, end);
  1347. reg_value = readl(IOMEM(EMI_MPUH));
  1348. start = ((reg_value >> 16) << 16) + emi_physical_offset;
  1349. end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
  1350. ptr += sprintf(ptr, "Region 7 --> 0x%x to 0x%x\n", start, end);
  1351. #if defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6753)
  1352. reg_value = readl(IOMEM(EMI_MPUA2));
  1353. start = ((reg_value >> 16) << 16) + emi_physical_offset;
  1354. end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
  1355. ptr += sprintf(ptr, "Region 8 --> 0x%x to 0x%x\n", start, end);
  1356. reg_value = readl(IOMEM(EMI_MPUB2));
  1357. start = ((reg_value >> 16) << 16) + emi_physical_offset;
  1358. end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
  1359. ptr += sprintf(ptr, "Region 9 --> 0x%x to 0x%x\n", start, end);
  1360. reg_value = readl(IOMEM(EMI_MPUC2));
  1361. start = ((reg_value >> 16) << 16) + emi_physical_offset;
  1362. end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
  1363. ptr += sprintf(ptr, "Region 10 --> 0x%x to 0x%x\n", start, end);
  1364. reg_value = readl(IOMEM(EMI_MPUD2));
  1365. start = ((reg_value >> 16) << 16) + emi_physical_offset;
  1366. end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
  1367. ptr += sprintf(ptr, "Region 11 --> 0x%x to 0x%x\n", start, end);
  1368. reg_value = readl(IOMEM(EMI_MPUE2));
  1369. start = ((reg_value >> 16) << 16) + emi_physical_offset;
  1370. end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
  1371. ptr += sprintf(ptr, "Region 12 --> 0x%x to 0x%x\n", start, end);
  1372. reg_value = readl(IOMEM(EMI_MPUF2));
  1373. start = ((reg_value >> 16) << 16) + emi_physical_offset;
  1374. end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
  1375. ptr += sprintf(ptr, "Region 13 --> 0x%x to 0x%x\n", start, end);
  1376. reg_value = readl(IOMEM(EMI_MPUG2));
  1377. start = ((reg_value >> 16) << 16) + emi_physical_offset;
  1378. end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
  1379. ptr += sprintf(ptr, "Region 14 --> 0x%x to 0x%x\n", start, end);
  1380. reg_value = readl(IOMEM(EMI_MPUH2));
  1381. start = ((reg_value >> 16) << 16) + emi_physical_offset;
  1382. end = ((reg_value & 0xFFFF) << 16) + emi_physical_offset + 0xFFFF;
  1383. ptr += sprintf(ptr, "Region 15 --> 0x%x to 0x%x\n", start, end);
  1384. #endif
  1385. ptr += sprintf(ptr, "\n");
  1386. #if defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6753)
  1387. reg_value = readl(IOMEM(EMI_MPUI));
  1388. reg_value2 = readl(IOMEM(EMI_MPUI_2ND));
  1389. d0 = (reg_value & 0x7);
  1390. d1 = (reg_value >> 3) & 0x7;
  1391. d2 = (reg_value >> 6) & 0x7;
  1392. d3 = (reg_value >> 9) & 0x7;
  1393. d4 = (reg_value2 & 0x7);
  1394. d5 = (reg_value2 >> 3) & 0x7;
  1395. d6 = (reg_value2 >> 6) & 0x7;
  1396. d7 = (reg_value2 >> 9) & 0x7;
  1397. ptr += sprintf(ptr, "Region 0 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
  1398. permission[d0],
  1399. permission[d1],
  1400. permission[d2],
  1401. permission[d3]);
  1402. ptr += sprintf(ptr, "Region 0 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
  1403. permission[d4],
  1404. permission[d5],
  1405. permission[d6],
  1406. permission[d7]);
  1407. d0 = ((reg_value>>16) & 0x7);
  1408. d1 = ((reg_value>>16) >> 3) & 0x7;
  1409. d2 = ((reg_value>>16) >> 6) & 0x7;
  1410. d3 = ((reg_value>>16) >> 9) & 0x7;
  1411. d4 = ((reg_value2>>16) & 0x7);
  1412. d5 = ((reg_value2>>16) >> 3) & 0x7;
  1413. d6 = ((reg_value2>>16) >> 6) & 0x7;
  1414. d7 = ((reg_value2>>16) >> 9) & 0x7;
  1415. ptr += sprintf(ptr, "Region 1 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
  1416. permission[d0],
  1417. permission[d1],
  1418. permission[d2],
  1419. permission[d3]);
  1420. ptr += sprintf(ptr, "Region 1 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
  1421. permission[d4],
  1422. permission[d5],
  1423. permission[d6],
  1424. permission[d7]);
  1425. reg_value = readl(IOMEM(EMI_MPUJ));
  1426. reg_value2 = readl(IOMEM(EMI_MPUJ_2ND));
  1427. d0 = (reg_value & 0x7);
  1428. d1 = (reg_value >> 3) & 0x7;
  1429. d2 = (reg_value >> 6) & 0x7;
  1430. d3 = (reg_value >> 9) & 0x7;
  1431. d4 = (reg_value2 & 0x7);
  1432. d5 = (reg_value2 >> 3) & 0x7;
  1433. d6 = (reg_value2 >> 6) & 0x7;
  1434. d7 = (reg_value2 >> 9) & 0x7;
  1435. ptr += sprintf(ptr, "Region 2 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
  1436. permission[d0],
  1437. permission[d1],
  1438. permission[d2],
  1439. permission[d3]);
  1440. ptr += sprintf(ptr, "Region 2 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
  1441. permission[d4],
  1442. permission[d5],
  1443. permission[d6],
  1444. permission[d7]);
  1445. d0 = ((reg_value>>16) & 0x7);
  1446. d1 = ((reg_value>>16) >> 3) & 0x7;
  1447. d2 = ((reg_value>>16) >> 6) & 0x7;
  1448. d3 = ((reg_value>>16) >> 9) & 0x7;
  1449. d4 = ((reg_value2>>16) & 0x7);
  1450. d5 = ((reg_value2>>16) >> 3) & 0x7;
  1451. d6 = ((reg_value2>>16) >> 6) & 0x7;
  1452. d7 = ((reg_value2>>16) >> 9) & 0x7;
  1453. ptr += sprintf(ptr, "Region 3 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
  1454. permission[d0],
  1455. permission[d1],
  1456. permission[d2],
  1457. permission[d3]);
  1458. ptr += sprintf(ptr, "Region 3 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
  1459. permission[d4],
  1460. permission[d5],
  1461. permission[d6],
  1462. permission[d7]);
  1463. reg_value = readl(IOMEM(EMI_MPUK));
  1464. reg_value2 = readl(IOMEM(EMI_MPUK_2ND));
  1465. d0 = (reg_value & 0x7);
  1466. d1 = (reg_value >> 3) & 0x7;
  1467. d2 = (reg_value >> 6) & 0x7;
  1468. d3 = (reg_value >> 9) & 0x7;
  1469. d4 = (reg_value2 & 0x7);
  1470. d5 = (reg_value2 >> 3) & 0x7;
  1471. d6 = (reg_value2 >> 6) & 0x7;
  1472. d7 = (reg_value2 >> 9) & 0x7;
  1473. ptr += sprintf(ptr, "Region 4 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
  1474. permission[d0],
  1475. permission[d1],
  1476. permission[d2],
  1477. permission[d3]);
  1478. ptr += sprintf(ptr, "Region 4 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
  1479. permission[d4],
  1480. permission[d5],
  1481. permission[d6],
  1482. permission[d7]);
  1483. d0 = ((reg_value>>16) & 0x7);
  1484. d1 = ((reg_value>>16) >> 3) & 0x7;
  1485. d2 = ((reg_value>>16) >> 6) & 0x7;
  1486. d3 = ((reg_value>>16) >> 9) & 0x7;
  1487. d4 = ((reg_value2>>16) & 0x7);
  1488. d5 = ((reg_value2>>16) >> 3) & 0x7;
  1489. d6 = ((reg_value2>>16) >> 6) & 0x7;
  1490. d7 = ((reg_value2>>16) >> 9) & 0x7;
  1491. ptr += sprintf(ptr, "Region 5 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
  1492. permission[d0],
  1493. permission[d1],
  1494. permission[d2],
  1495. permission[d3]);
  1496. ptr += sprintf(ptr, "Region 5 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
  1497. permission[d4],
  1498. permission[d5],
  1499. permission[d6],
  1500. permission[d7]);
  1501. reg_value = readl(IOMEM(EMI_MPUL));
  1502. reg_value2 = readl(IOMEM(EMI_MPUL_2ND));
  1503. d0 = (reg_value & 0x7);
  1504. d1 = (reg_value >> 3) & 0x7;
  1505. d2 = (reg_value >> 6) & 0x7;
  1506. d3 = (reg_value >> 9) & 0x7;
  1507. d4 = (reg_value2 & 0x7);
  1508. d5 = (reg_value2 >> 3) & 0x7;
  1509. d6 = (reg_value2 >> 6) & 0x7;
  1510. d7 = (reg_value2 >> 9) & 0x7;
  1511. ptr += sprintf(ptr, "Region 6 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
  1512. permission[d0],
  1513. permission[d1],
  1514. permission[d2],
  1515. permission[d3]);
  1516. ptr += sprintf(ptr, "Region 6 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
  1517. permission[d4],
  1518. permission[d5],
  1519. permission[d6],
  1520. permission[d7]);
  1521. d0 = ((reg_value>>16) & 0x7);
  1522. d1 = ((reg_value>>16) >> 3) & 0x7;
  1523. d2 = ((reg_value>>16) >> 6) & 0x7;
  1524. d3 = ((reg_value>>16) >> 9) & 0x7;
  1525. d4 = ((reg_value2>>16) & 0x7);
  1526. d5 = ((reg_value2>>16) >> 3) & 0x7;
  1527. d6 = ((reg_value2>>16) >> 6) & 0x7;
  1528. d7 = ((reg_value2>>16) >> 9) & 0x7;
  1529. ptr += sprintf(ptr, "Region 7 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
  1530. permission[d0],
  1531. permission[d1],
  1532. permission[d2],
  1533. permission[d3]);
  1534. ptr += sprintf(ptr, "Region 7 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
  1535. permission[d4],
  1536. permission[d5],
  1537. permission[d6],
  1538. permission[d7]);
  1539. reg_value = readl(IOMEM(EMI_MPUI2));
  1540. reg_value2 = readl(IOMEM(EMI_MPUI2_2ND));
  1541. d0 = (reg_value & 0x7);
  1542. d1 = (reg_value >> 3) & 0x7;
  1543. d2 = (reg_value >> 6) & 0x7;
  1544. d3 = (reg_value >> 9) & 0x7;
  1545. d4 = (reg_value2 & 0x7);
  1546. d5 = (reg_value2 >> 3) & 0x7;
  1547. d6 = (reg_value2 >> 6) & 0x7;
  1548. d7 = (reg_value2 >> 9) & 0x7;
  1549. ptr += sprintf(ptr, "Region 8 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
  1550. permission[d0],
  1551. permission[d1],
  1552. permission[d2],
  1553. permission[d3]);
  1554. ptr += sprintf(ptr, "Region 8 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
  1555. permission[d4],
  1556. permission[d5],
  1557. permission[d6],
  1558. permission[d7]);
  1559. d0 = ((reg_value>>16) & 0x7);
  1560. d1 = ((reg_value>>16) >> 3) & 0x7;
  1561. d2 = ((reg_value>>16) >> 6) & 0x7;
  1562. d3 = ((reg_value>>16) >> 9) & 0x7;
  1563. d4 = ((reg_value2>>16) & 0x7);
  1564. d5 = ((reg_value2>>16) >> 3) & 0x7;
  1565. d6 = ((reg_value2>>16) >> 6) & 0x7;
  1566. d7 = ((reg_value2>>16) >> 9) & 0x7;
  1567. ptr += sprintf(ptr, "Region 9 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
  1568. permission[d0],
  1569. permission[d1],
  1570. permission[d2],
  1571. permission[d3]);
  1572. ptr += sprintf(ptr, "Region 9 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
  1573. permission[d4],
  1574. permission[d5],
  1575. permission[d6],
  1576. permission[d7]);
  1577. reg_value = readl(IOMEM(EMI_MPUJ2));
  1578. reg_value2 = readl(IOMEM(EMI_MPUJ2_2ND));
  1579. d0 = (reg_value & 0x7);
  1580. d1 = (reg_value >> 3) & 0x7;
  1581. d2 = (reg_value >> 6) & 0x7;
  1582. d3 = (reg_value >> 9) & 0x7;
  1583. d4 = (reg_value2 & 0x7);
  1584. d5 = (reg_value2 >> 3) & 0x7;
  1585. d6 = (reg_value2 >> 6) & 0x7;
  1586. d7 = (reg_value2 >> 9) & 0x7;
  1587. ptr += sprintf(ptr,
  1588. "Region 10 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
  1589. permission[d0],
  1590. permission[d1],
  1591. permission[d2],
  1592. permission[d3]);
  1593. ptr += sprintf(ptr,
  1594. "Region 10 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
  1595. permission[d4],
  1596. permission[d5],
  1597. permission[d6],
  1598. permission[d7]);
  1599. d0 = ((reg_value>>16) & 0x7);
  1600. d1 = ((reg_value>>16) >> 3) & 0x7;
  1601. d2 = ((reg_value>>16) >> 6) & 0x7;
  1602. d3 = ((reg_value>>16) >> 9) & 0x7;
  1603. d4 = ((reg_value2>>16) & 0x7);
  1604. d5 = ((reg_value2>>16) >> 3) & 0x7;
  1605. d6 = ((reg_value2>>16) >> 6) & 0x7;
  1606. d7 = ((reg_value2>>16) >> 9) & 0x7;
  1607. ptr += sprintf(ptr,
  1608. "Region 11 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
  1609. permission[d0],
  1610. permission[d1],
  1611. permission[d2],
  1612. permission[d3]);
  1613. ptr += sprintf(ptr,
  1614. "Region 11 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
  1615. permission[d4],
  1616. permission[d5],
  1617. permission[d6],
  1618. permission[d7]);
  1619. reg_value = readl(IOMEM(EMI_MPUK2));
  1620. reg_value2 = readl(IOMEM(EMI_MPUK2_2ND));
  1621. d0 = (reg_value & 0x7);
  1622. d1 = (reg_value >> 3) & 0x7;
  1623. d2 = (reg_value >> 6) & 0x7;
  1624. d3 = (reg_value >> 9) & 0x7;
  1625. d4 = (reg_value2 & 0x7);
  1626. d5 = (reg_value2 >> 3) & 0x7;
  1627. d6 = (reg_value2 >> 6) & 0x7;
  1628. d7 = (reg_value2 >> 9) & 0x7;
  1629. ptr += sprintf(ptr,
  1630. "Region 12 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
  1631. permission[d0],
  1632. permission[d1],
  1633. permission[d2],
  1634. permission[d3]);
  1635. ptr += sprintf(ptr,
  1636. "Region 12 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
  1637. permission[d4],
  1638. permission[d5],
  1639. permission[d6],
  1640. permission[d7]);
  1641. d0 = ((reg_value>>16) & 0x7);
  1642. d1 = ((reg_value>>16) >> 3) & 0x7;
  1643. d2 = ((reg_value>>16) >> 6) & 0x7;
  1644. d3 = ((reg_value>>16) >> 9) & 0x7;
  1645. d4 = ((reg_value2>>16) & 0x7);
  1646. d5 = ((reg_value2>>16) >> 3) & 0x7;
  1647. d6 = ((reg_value2>>16) >> 6) & 0x7;
  1648. d7 = ((reg_value2>>16) >> 9) & 0x7;
  1649. ptr += sprintf(ptr,
  1650. "Region 13 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
  1651. permission[d0],
  1652. permission[d1],
  1653. permission[d2],
  1654. permission[d3]);
  1655. ptr += sprintf(ptr,
  1656. "Region 13 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
  1657. permission[d4],
  1658. permission[d5],
  1659. permission[d6],
  1660. permission[d7]);
  1661. reg_value = readl(IOMEM(EMI_MPUL2));
  1662. reg_value2 = readl(IOMEM(EMI_MPUL2_2ND));
  1663. d0 = (reg_value & 0x7);
  1664. d1 = (reg_value >> 3) & 0x7;
  1665. d2 = (reg_value >> 6) & 0x7;
  1666. d3 = (reg_value >> 9) & 0x7;
  1667. d4 = (reg_value2 & 0x7);
  1668. d5 = (reg_value2 >> 3) & 0x7;
  1669. d6 = (reg_value2 >> 6) & 0x7;
  1670. d7 = (reg_value2 >> 9) & 0x7;
  1671. ptr += sprintf(ptr,
  1672. "Region 14 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
  1673. permission[d0],
  1674. permission[d1],
  1675. permission[d2],
  1676. permission[d3]);
  1677. ptr += sprintf(ptr,
  1678. "Region 14 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
  1679. permission[d4],
  1680. permission[d5],
  1681. permission[d6],
  1682. permission[d7]);
  1683. d0 = ((reg_value>>16) & 0x7);
  1684. d1 = ((reg_value>>16) >> 3) & 0x7;
  1685. d2 = ((reg_value>>16) >> 6) & 0x7;
  1686. d3 = ((reg_value>>16) >> 9) & 0x7;
  1687. d4 = ((reg_value2>>16) & 0x7);
  1688. d5 = ((reg_value2>>16) >> 3) & 0x7;
  1689. d6 = ((reg_value2>>16) >> 6) & 0x7;
  1690. d7 = ((reg_value2>>16) >> 9) & 0x7;
  1691. ptr += sprintf(ptr,
  1692. "Region 15 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
  1693. permission[d0],
  1694. permission[d1],
  1695. permission[d2],
  1696. permission[d3]);
  1697. ptr += sprintf(ptr,
  1698. "Region 15 --> d4 = %s, d5 = %s, d6 = %s, d7 = %s\n",
  1699. permission[d4],
  1700. permission[d5],
  1701. permission[d6],
  1702. permission[d7]);
  1703. #else /*MT6735M*/
  1704. reg_value = readl(IOMEM(EMI_MPUI));
  1705. d0 = (reg_value & 0x7);
  1706. d1 = (reg_value >> 3) & 0x7;
  1707. d2 = (reg_value >> 6) & 0x7;
  1708. d3 = (reg_value >> 9) & 0x7;
  1709. ptr += sprintf(ptr, "Region 0 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
  1710. permission[d0],
  1711. permission[d1],
  1712. permission[d2],
  1713. permission[d3]);
  1714. d0 = ((reg_value>>16) & 0x7);
  1715. d1 = ((reg_value>>16) >> 3) & 0x7;
  1716. d2 = ((reg_value>>16) >> 6) & 0x7;
  1717. d3 = ((reg_value>>16) >> 9) & 0x7;
  1718. ptr += sprintf(ptr, "Region 1 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
  1719. permission[d0],
  1720. permission[d1],
  1721. permission[d2],
  1722. permission[d3]);
  1723. reg_value = readl(IOMEM(EMI_MPUJ));
  1724. d0 = (reg_value & 0x7);
  1725. d1 = (reg_value >> 3) & 0x7;
  1726. d2 = (reg_value >> 6) & 0x7;
  1727. d3 = (reg_value >> 9) & 0x7;
  1728. ptr += sprintf(ptr, "Region 2 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
  1729. permission[d0],
  1730. permission[d1],
  1731. permission[d2],
  1732. permission[d3]);
  1733. d0 = ((reg_value>>16) & 0x7);
  1734. d1 = ((reg_value>>16) >> 3) & 0x7;
  1735. d2 = ((reg_value>>16) >> 6) & 0x7;
  1736. d3 = ((reg_value>>16) >> 9) & 0x7;
  1737. ptr += sprintf(ptr, "Region 3 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
  1738. permission[d0],
  1739. permission[d1],
  1740. permission[d2],
  1741. permission[d3]);
  1742. reg_value = readl(IOMEM(EMI_MPUK));
  1743. d0 = (reg_value & 0x7);
  1744. d1 = (reg_value >> 3) & 0x7;
  1745. d2 = (reg_value >> 6) & 0x7;
  1746. d3 = (reg_value >> 9) & 0x7;
  1747. ptr += sprintf(ptr, "Region 4 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
  1748. permission[d0],
  1749. permission[d1],
  1750. permission[d2],
  1751. permission[d3]);
  1752. d0 = ((reg_value>>16) & 0x7);
  1753. d1 = ((reg_value>>16) >> 3) & 0x7;
  1754. d2 = ((reg_value>>16) >> 6) & 0x7;
  1755. d3 = ((reg_value>>16) >> 9) & 0x7;
  1756. ptr += sprintf(ptr, "Region 5 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
  1757. permission[d0],
  1758. permission[d1],
  1759. permission[d2],
  1760. permission[d3]);
  1761. reg_value = readl(IOMEM(EMI_MPUL));
  1762. d0 = (reg_value & 0x7);
  1763. d1 = (reg_value >> 3) & 0x7;
  1764. d2 = (reg_value >> 6) & 0x7;
  1765. d3 = (reg_value >> 9) & 0x7;
  1766. ptr += sprintf(ptr, "Region 6 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
  1767. permission[d0],
  1768. permission[d1],
  1769. permission[d2],
  1770. permission[d3]);
  1771. d0 = ((reg_value>>16) & 0x7);
  1772. d1 = ((reg_value>>16) >> 3) & 0x7;
  1773. d2 = ((reg_value>>16) >> 6) & 0x7;
  1774. d3 = ((reg_value>>16) >> 9) & 0x7;
  1775. ptr += sprintf(ptr, "Region 7 --> d0 = %s, d1 = %s, d2 = %s, d3 = %s\n",
  1776. permission[d0],
  1777. permission[d1],
  1778. permission[d2],
  1779. permission[d3]);
  1780. #endif
  1781. return strlen(buf);
  1782. }
  1783. static ssize_t emi_mpu_store(struct device_driver *driver,
  1784. const char *buf, size_t count)
  1785. {
  1786. int i;
  1787. unsigned int start_addr;
  1788. unsigned int end_addr;
  1789. unsigned int region;
  1790. unsigned int access_permission;
  1791. char *command;
  1792. char *ptr;
  1793. char *token[5];
  1794. int err = 0;
  1795. if ((strlen(buf) + 1) > MAX_EMI_MPU_STORE_CMD_LEN) {
  1796. pr_err("emi_mpu_store command overflow.");
  1797. return count;
  1798. }
  1799. pr_err("emi_mpu_store: %s\n", buf);
  1800. command = kmalloc((size_t)MAX_EMI_MPU_STORE_CMD_LEN, GFP_KERNEL);
  1801. if (!command)
  1802. return count;
  1803. strcpy(command, buf);
  1804. ptr = (char *)buf;
  1805. if (!strncmp(buf, EN_MPU_STR, strlen(EN_MPU_STR))) {
  1806. i = 0;
  1807. while (ptr != NULL) {
  1808. ptr = strsep(&command, " ");
  1809. token[i] = ptr;
  1810. pr_debug("token[%d] = %s\n", i, token[i]);
  1811. i++;
  1812. }
  1813. for (i = 0; i < 5; i++)
  1814. pr_debug("token[%d] = %s\n", i, token[i]);
  1815. err += kstrtoul(token[1], 16, (unsigned long *)&start_addr);
  1816. err += kstrtoul(token[2], 16, (unsigned long *)&end_addr);
  1817. err += kstrtoul(token[3], 16, (unsigned long *)&region);
  1818. err += kstrtoul(token[4],
  1819. 16, (unsigned long *)&access_permission);
  1820. if (err)
  1821. goto out;
  1822. emi_mpu_set_region_protection(start_addr,
  1823. end_addr,
  1824. region,
  1825. access_permission);
  1826. pr_err("Set EMI_MPU: start: 0x%x, end: 0x%x, region: %d, permission: 0x%x.\n",
  1827. start_addr,
  1828. end_addr,
  1829. region,
  1830. access_permission);
  1831. } else if (!strncmp(buf, DIS_MPU_STR, strlen(DIS_MPU_STR))) {
  1832. i = 0;
  1833. while (ptr != NULL) {
  1834. ptr = strsep(&command, " ");
  1835. token[i] = ptr;
  1836. pr_debug("token[%d] = %s\n", i, token[i]);
  1837. i++;
  1838. }
  1839. for (i = 0; i < 5; i++)
  1840. pr_debug("token[%d] = %s\n", i, token[i]);
  1841. err += kstrtoul(token[1], 16, (unsigned long *)&start_addr);
  1842. err += kstrtoul(token[2], 16, (unsigned long *)&end_addr);
  1843. err += kstrtoul(token[3], 16, (unsigned long *)&region);
  1844. if (err)
  1845. goto out;
  1846. access_permission = SET_ACCESS_PERMISSON(NO_PROTECTION,
  1847. #if defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6753)
  1848. NO_PROTECTION,
  1849. NO_PROTECTION,
  1850. NO_PROTECTION,
  1851. NO_PROTECTION,
  1852. #endif
  1853. NO_PROTECTION,
  1854. NO_PROTECTION,
  1855. NO_PROTECTION);
  1856. emi_mpu_set_region_protection(0x0,
  1857. 0x0,
  1858. region,
  1859. access_permission);
  1860. pr_err("set EMI MPU: start: 0x%x, end: 0x%x, region: %d, permission: 0x%x\n",
  1861. 0,
  1862. 0,
  1863. region,
  1864. access_permission);
  1865. } else {
  1866. pr_err("Unknown emi_mpu command.\n");
  1867. }
  1868. out:
  1869. kfree(command);
  1870. return count;
  1871. }
  1872. DRIVER_ATTR(mpu_config, 0644, emi_mpu_show, emi_mpu_store);
  1873. void mtk_search_full_pgtab(void)
  1874. {
  1875. pgd_t *pgd;
  1876. pud_t *pud;
  1877. pmd_t *pmd;
  1878. unsigned long addr;
  1879. #ifndef CONFIG_ARM_LPAE
  1880. pte_t *pte;
  1881. unsigned long addr_2nd, addr_2nd_end;
  1882. #endif
  1883. unsigned int v_addr = vio_addr;
  1884. /*FIXME: testing*/
  1885. for (addr = 0xC0000000; addr < 0xFFF00000; addr += 0x100000) {
  1886. pgd = pgd_offset(&init_mm, addr);
  1887. if (pgd_none(*pgd) || !pgd_present(*pgd))
  1888. continue;
  1889. pud = pud_offset(pgd, addr);
  1890. if (pud_none(*pud) || !pud_present(*pud))
  1891. continue;
  1892. pmd = pmd_offset(pud, addr);
  1893. if (pmd_none(*pmd) || !pmd_present(*pmd))
  1894. continue;
  1895. #ifndef CONFIG_ARM_LPAE
  1896. if ((pmd_val(*pmd) & PMD_TYPE_MASK) == PMD_TYPE_TABLE) {
  1897. /* Page table entry*/
  1898. addr_2nd = addr;
  1899. addr_2nd_end = addr_2nd + 0x100000;
  1900. for (; addr_2nd < (addr_2nd_end); addr_2nd += 0x1000) {
  1901. pte = pte_offset_map(pmd, addr_2nd);
  1902. if (((unsigned long)v_addr & PAGE_MASK) ==
  1903. ((unsigned long)pte_val(*(pte))
  1904. & PAGE_MASK)) {
  1905. pr_err("%s %lx. violation address = 0x%x\n",
  1906. "[EMI MPU] Find page entry section at pte:",
  1907. (unsigned long)(pte), v_addr);
  1908. return;
  1909. }
  1910. }
  1911. } else {
  1912. /* Section */
  1913. unsigned long a0;
  1914. unsigned long a1;
  1915. a0 = (unsigned long)pmd_val(*(pmd)) & SECTION_MASK;
  1916. a1 = (unsigned long)v_addr & SECTION_MASK;
  1917. if (a0 == a1) {
  1918. pr_err("[EMI MPU] Find page entry section at pmd: %lx. violation address = 0x%x\n",
  1919. (unsigned long)(pmd),
  1920. v_addr);
  1921. return;
  1922. }
  1923. }
  1924. #else
  1925. /* TBD */
  1926. #endif
  1927. }
  1928. pr_err("[EMI MPU] ****** Can not find page table entry! violation address = 0x%x ******\n",
  1929. v_addr);
  1930. }
  1931. void emi_mpu_work_callback(struct work_struct *work)
  1932. {
  1933. pr_err("[EMI MPU] Enter EMI MPU workqueue!\n");
  1934. mtk_search_full_pgtab();
  1935. pr_err("[EMI MPU] Exit EMI MPU workqueue!\n");
  1936. }
  1937. static ssize_t pgt_scan_show(struct device_driver *driver, char *buf)
  1938. {
  1939. return 0;
  1940. }
  1941. static ssize_t pgt_scan_store(struct device_driver *driver,
  1942. const char *buf, size_t count)
  1943. {
  1944. unsigned int value;
  1945. unsigned int ret;
  1946. if (unlikely(kstrtoint(buf, 0, &value) != 1))
  1947. return -EINVAL;
  1948. if (value == 1) {
  1949. ret = queue_work(emi_mpu_workqueue, &emi_mpu_work);
  1950. if (!ret)
  1951. pr_debug("[EMI MPU] submit workqueue failed, ret = %d\n",
  1952. ret);
  1953. }
  1954. return count;
  1955. }
  1956. DRIVER_ATTR(pgt_scan, 0644, pgt_scan_show, pgt_scan_store);
  1957. #ifdef ENABLE_EMI_CHKER
  1958. static void emi_axi_set_chker(const unsigned int setting)
  1959. {
  1960. int value;
  1961. value = readl(IOMEM(EMI_CHKER));
  1962. value &= ~(0x7 << 16);
  1963. value |= (setting);
  1964. mt_reg_sync_writel(value, EMI_CHKER);
  1965. }
  1966. static void emi_axi_set_master(const unsigned int setting)
  1967. {
  1968. int value;
  1969. value = readl(IOMEM(EMI_CHKER));
  1970. value &= ~(0x0F << AXI_NON_ALIGN_CHK_MST);
  1971. value |= (setting & 0xF) << AXI_NON_ALIGN_CHK_MST;
  1972. mt_reg_sync_writel(value, EMI_CHKER);
  1973. }
  1974. static void emi_axi_dump_info(int aee_ke_en)
  1975. {
  1976. int value, master_ID;
  1977. char *master_name;
  1978. value = readl(IOMEM(EMI_CHKER));
  1979. master_ID = (value & 0x0000FFFF);
  1980. if (value & 0x0000FFFF) {
  1981. pr_err("AXI violation.\n");
  1982. pr_err("[EMI MPU AXI] Debug info start ------\n");
  1983. pr_err("EMI_CHKER = %x.\n", value);
  1984. pr_err("Violation address is 0x%x.\n",
  1985. readl(IOMEM(EMI_CHKER_ADR)));
  1986. pr_err("Violation master ID is 0x%x.\n", master_ID);
  1987. pr_err("Violation type is: AXI_ADR_CHK_EN(%d), AXI_LOCK_CHK_EN(%d), AXI_NON_ALIGN_CHK_EN(%d).\n",
  1988. (value & (1 << AXI_ADR_VIO)) ? 1 : 0,
  1989. (value & (1 << AXI_LOCK_ISSUE)) ? 1 : 0,
  1990. (value & (1 << AXI_NON_ALIGN_ISSUE)) ? 1 : 0);
  1991. pr_err("%s violation.\n",
  1992. (value & (1 << AXI_VIO_WR)) ? "Write" : "Read");
  1993. pr_err("[EMI MPU AXI] Debug info end ---------\n");
  1994. master_name = __id2name(master_ID);
  1995. #ifdef CONFIG_MTK_AEE_FEATURE
  1996. if (aee_ke_en)
  1997. aee_kernel_exception("EMI MPU AXI",
  1998. "AXI violation.\nEMI_CHKER = 0x%x\nCRDISPATCH_KEY:EMI MPU Violation Issue/%s\n",
  1999. value, master_name);
  2000. #endif
  2001. mt_reg_sync_writel((1 << AXI_VIO_CLR) | readl(IOMEM(EMI_CHKER)),
  2002. EMI_CHKER);
  2003. }
  2004. }
  2005. static void emi_axi_vio_timer_func(unsigned long a)
  2006. {
  2007. emi_axi_dump_info(1);
  2008. mod_timer(&emi_axi_vio_timer, jiffies + AXI_VIO_MONITOR_TIME);
  2009. }
  2010. static ssize_t emi_axi_vio_show(struct device_driver *driver, char *buf)
  2011. {
  2012. int value;
  2013. value = readl(IOMEM(EMI_CHKER));
  2014. emi_axi_dump_info(0);
  2015. return snprintf(buf,
  2016. PAGE_SIZE,
  2017. "AXI vio setting is: ADR_CHK_EN %s, LOCK_CHK_EN %s, NON_ALIGN_CHK_EN %s\n",
  2018. (value & (1 << AXI_ADR_CHK_EN)) ? "ON" : "OFF",
  2019. (value & (1 << AXI_LOCK_CHK_EN)) ? "ON" : "OFF",
  2020. (value & (1 << AXI_NON_ALIGN_CHK_EN)) ? "ON" : "OFF");
  2021. }
  2022. ssize_t emi_axi_vio_store(struct device_driver *driver,
  2023. const char *buf, size_t count)
  2024. {
  2025. int value;
  2026. int cpu = 0;
  2027. value = readl(IOMEM(EMI_CHKER));
  2028. if (!strncmp(buf, "ADR_CHK_ON", strlen("ADR_CHK_ON"))) {
  2029. emi_axi_set_chker(1 << AXI_ADR_CHK_EN);
  2030. add_timer_on(&emi_axi_vio_timer, cpu);
  2031. } else if (!strncmp(buf, "LOCK_CHK_ON", strlen("LOCK_CHK_ON"))) {
  2032. emi_axi_set_chker(1 << AXI_LOCK_CHK_EN);
  2033. add_timer_on(&emi_axi_vio_timer, cpu);
  2034. } else if (!strncmp(buf, "NON_ALIGN_CHK_ON",
  2035. strlen("NON_ALIGN_CHK_ON"))) {
  2036. emi_axi_set_chker(1 << AXI_NON_ALIGN_CHK_EN);
  2037. add_timer_on(&emi_axi_vio_timer, cpu);
  2038. } else if (!strncmp(buf, "OFF", strlen("OFF"))) {
  2039. emi_axi_set_chker(0);
  2040. del_timer(&emi_axi_vio_timer);
  2041. } else {
  2042. pr_err("invalid setting\n");
  2043. }
  2044. return count;
  2045. }
  2046. DRIVER_ATTR(emi_axi_vio, 0644, emi_axi_vio_show, emi_axi_vio_store);
  2047. #endif /*#ifdef ENABLE_EMI_CHKER*/
  2048. #ifdef ENABLE_EMI_WATCH_POINT
  2049. static void emi_wp_set_address(unsigned int address)
  2050. {
  2051. mt_reg_sync_writel(address - emi_physical_offset, EMI_WP_ADR);
  2052. }
  2053. static void emi_wp_set_range(unsigned int range) /* 2^ range bytes */
  2054. {
  2055. unsigned int value;
  2056. value = readl(IOMEM(EMI_WP_CTRL));
  2057. value = (value & (~EMI_WP_RANGE)) | range;
  2058. mt_reg_sync_writel(value, EMI_WP_CTRL);
  2059. }
  2060. static void emi_wp_set_monitor_type(unsigned int type)
  2061. {
  2062. unsigned int value;
  2063. value = readl(IOMEM(EMI_WP_CTRL));
  2064. value =
  2065. (value & (~EMI_WP_RW_MONITOR)) | (type << EMI_WP_RW_MONITOR_SHIFT);
  2066. mt_reg_sync_writel(value, EMI_WP_CTRL);
  2067. }
  2068. #if 0
  2069. static void emi_wp_set_rw_disable(unsigned int type)
  2070. {
  2071. unsigned int value;
  2072. value = readl(IOMEM(EMI_WP_CTRL));
  2073. value =
  2074. (value & (~EMI_WP_RW_DISABLE)) | (type << EMI_WP_RW_DISABLE_SHIFT);
  2075. mt_reg_sync_writel(value, EMI_WP_CTRL);
  2076. }
  2077. #endif
  2078. static void emi_wp_enable(int enable)
  2079. {
  2080. unsigned int value;
  2081. /* Enable WP */
  2082. value = readl(IOMEM(EMI_CHKER));
  2083. value =
  2084. (value & ~(1 << EMI_WP_ENABLE_SHIFT)) | (enable << EMI_WP_ENABLE_SHIFT);
  2085. mt_reg_sync_writel(value, EMI_CHKER);
  2086. }
  2087. static void emi_wp_slave_error_enable(unsigned int enable)
  2088. {
  2089. unsigned int value;
  2090. value = readl(IOMEM(EMI_WP_CTRL));
  2091. value =
  2092. (value & ~(1 << EMI_WP_SLVERR_SHIFT)) | (enable << EMI_WP_SLVERR_SHIFT);
  2093. mt_reg_sync_writel(value, EMI_WP_CTRL);
  2094. }
  2095. static void emi_wp_int_enable(unsigned int enable)
  2096. {
  2097. unsigned int value;
  2098. value = readl(IOMEM(EMI_WP_CTRL));
  2099. value =
  2100. (value & ~(1 << EMI_WP_INT_SHIFT)) | (enable << EMI_WP_INT_SHIFT);
  2101. mt_reg_sync_writel(value, EMI_WP_CTRL);
  2102. }
  2103. static void emi_wp_clr_status(void)
  2104. {
  2105. unsigned int value;
  2106. int result;
  2107. value = readl(IOMEM(EMI_CHKER));
  2108. value |= 1 << EMI_WP_VIO_CLR_SHIFT;
  2109. mt_reg_sync_writel(value, EMI_CHKER);
  2110. result = readl(IOMEM(EMI_CHKER)) & EMI_WP_AXI_ID;
  2111. result |= readl(IOMEM(EMI_CHKER_TYPE));
  2112. result |= readl(IOMEM(EMI_CHKER_ADR));
  2113. if (result)
  2114. pr_err("[EMI_WP] Clear WP status fail!!!!!!!!!!!!!!\n");
  2115. }
  2116. void emi_wp_get_status(void)
  2117. {
  2118. unsigned int value, master_ID;
  2119. char *master_name;
  2120. value = readl(IOMEM(EMI_CHKER));
  2121. if ((value & 0x80000000) == 0) {
  2122. pr_err("[EMI_WP] No watch point hit\n");
  2123. return;
  2124. }
  2125. master_ID = (value & EMI_WP_AXI_ID);
  2126. pr_err("[EMI_WP] Violation master ID is 0x%x.\n", master_ID);
  2127. pr_err("[EMI_WP] Violation Address is : 0x%X\n",
  2128. readl(IOMEM(EMI_CHKER_ADR)) + emi_physical_offset);
  2129. master_name = __id2name(master_ID);
  2130. pr_err("[EMI_WP] EMI_CHKER = 0x%x, module is %s.\n",
  2131. value, master_name);
  2132. value = readl(IOMEM(EMI_CHKER_TYPE));
  2133. pr_err("[EMI_WP] Transaction Type is : %d beat, %d byte, %s burst type (0x%X)\n",
  2134. (value & 0xF) + 1,
  2135. 1 << ((value >> 4) & 0x7),
  2136. (value >> 7 & 1) ? "INCR" : "WRAP",
  2137. value);
  2138. emi_wp_clr_status();
  2139. }
  2140. static int emi_wp_set(unsigned int enable,
  2141. unsigned int address, unsigned int range, unsigned int rw)
  2142. {
  2143. if (address < emi_physical_offset) {
  2144. pr_err("[EMI_WP] Address error, you can't set address less than 0x%X\n",
  2145. emi_physical_offset);
  2146. return -1;
  2147. }
  2148. if (range < 4 || range > 32) {
  2149. pr_err("[EMI_WP] Range error, you can't set range less %s",
  2150. "than 16 bytes and more than 4G bytes\n");
  2151. return -1;
  2152. }
  2153. emi_wp_set_monitor_type(rw);
  2154. emi_wp_set_address(address);
  2155. emi_wp_set_range(range);
  2156. emi_wp_slave_error_enable(1);
  2157. emi_wp_int_enable(0);
  2158. emi_wp_enable(enable);
  2159. return 0;
  2160. }
  2161. static ssize_t emi_wp_vio_show(struct device_driver *driver, char *buf)
  2162. {
  2163. unsigned int value, master_ID, type, vio_addr;
  2164. char *master_name;
  2165. char *ptr = buf;
  2166. value = readl(IOMEM(EMI_CHKER));
  2167. if ((value & 0x80000000) == 0)
  2168. return snprintf(buf, PAGE_SIZE,
  2169. "[EMI_WP] No watch point hit\n");
  2170. master_ID = (value & EMI_WP_AXI_ID);
  2171. master_name = __id2name(master_ID);
  2172. type = readl(IOMEM(EMI_CHKER_TYPE));
  2173. vio_addr = readl(IOMEM(EMI_CHKER_ADR)) + emi_physical_offset;
  2174. emi_wp_clr_status();
  2175. ptr += snprintf(ptr, PAGE_SIZE, "[EMI WP] vio setting is: CHKER 0x%X, ",
  2176. value);
  2177. ptr += snprintf(ptr, PAGE_SIZE, "module is %s, Address is : 0x%X," ,
  2178. master_name,
  2179. vio_addr);
  2180. ptr += snprintf(ptr, PAGE_SIZE, "Transaction Type is : %d beat, ",
  2181. (type & 0xF) + 1);
  2182. ptr += snprintf(ptr, PAGE_SIZE, "%d byte, %s burst type (0x%X)\n",
  2183. 1 << ((type >> 4) & 0x7),
  2184. (type >> 7 & 1) ? "INCR" : "WRAP",
  2185. type);
  2186. return ptr - buf;
  2187. }
  2188. ssize_t emi_wp_vio_store(struct device_driver *driver,
  2189. const char *buf, size_t count)
  2190. {
  2191. int i;
  2192. unsigned int wp_addr;
  2193. unsigned int range, start_addr, end_addr;
  2194. unsigned int rw;
  2195. char *command;
  2196. char *ptr;
  2197. char *token[5];
  2198. int err = 0;
  2199. if ((strlen(buf) + 1) > MAX_EMI_MPU_STORE_CMD_LEN) {
  2200. pr_err("emi_wp_store command overflow.");
  2201. return count;
  2202. }
  2203. pr_err("emi_wp_store: %s\n", buf);
  2204. command = kmalloc((size_t)MAX_EMI_MPU_STORE_CMD_LEN, GFP_KERNEL);
  2205. if (!command)
  2206. return count;
  2207. strcpy(command, buf);
  2208. ptr = (char *)buf;
  2209. if (!strncmp(buf, EN_WP_STR, strlen(EN_WP_STR))) {
  2210. i = 0;
  2211. while (ptr != NULL) {
  2212. ptr = strsep(&command, " ");
  2213. token[i] = ptr;
  2214. pr_debug("token[%d] = %s\n", i, token[i]);
  2215. i++;
  2216. }
  2217. for (i = 0; i < 4; i++)
  2218. pr_debug("token[%d] = %s\n", i, token[i]);
  2219. err += kstrtoul(token[1], 16, (unsigned long *)&wp_addr);
  2220. err += kstrtoul(token[2], 16, (unsigned long *)&range);
  2221. err += kstrtoul(token[3], 16, (unsigned long *)&rw);
  2222. if (err)
  2223. goto out;
  2224. emi_wp_set(1, wp_addr, range, rw);
  2225. start_addr = (wp_addr >> range) << range;
  2226. end_addr = start_addr + (1 << range) - 1;
  2227. pr_err("Set EMI_WP: address: 0x%x, range:%d, start addr: 0x%x, end addr: 0x%x, rw: %d .\n",
  2228. wp_addr, range, start_addr, end_addr, rw);
  2229. } else if (!strncmp(buf, DIS_WP_STR, strlen(DIS_WP_STR))) {
  2230. i = 0;
  2231. while (ptr != NULL) {
  2232. ptr = strsep(&command, " ");
  2233. token[i] = ptr;
  2234. pr_debug("token[%d] = %s\n", i, token[i]);
  2235. i++;
  2236. }
  2237. for (i = 0; i < 4; i++)
  2238. pr_debug("token[%d] = %s\n", i, token[i]);
  2239. err += kstrtoul(token[1], 16, (unsigned long *)&wp_addr);
  2240. err += kstrtoul(token[2], 16, (unsigned long *)&range);
  2241. err += kstrtoul(token[3], 16, (unsigned long *)&rw);
  2242. if (err)
  2243. goto out;
  2244. emi_wp_set(0, 0x40000000, 4, 2);
  2245. pr_err("disable EMI WP\n");
  2246. } else {
  2247. pr_err("Unknown emi_wp command.\n");
  2248. }
  2249. out:
  2250. kfree(command);
  2251. return count;
  2252. }
  2253. DRIVER_ATTR(emi_wp_vio, 0644, emi_wp_vio_show, emi_wp_vio_store);
  2254. #endif /*#ifdef ENABLE_EMI_WATCH_POINT*/
  2255. #if defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6753)
  2256. #define AP_REGION_ID 15
  2257. #else /* MT6735M*/
  2258. #define AP_REGION_ID 7
  2259. #endif
  2260. static void protect_ap_region(void)
  2261. {
  2262. unsigned int ap_mem_mpu_id, ap_mem_mpu_attr;
  2263. unsigned int kernel_base;
  2264. phys_addr_t dram_size;
  2265. return; /* temp to disable */
  2266. kernel_base = PHYS_OFFSET;
  2267. dram_size = get_max_DRAM_size();
  2268. ap_mem_mpu_id = AP_REGION_ID;
  2269. #if defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6753)
  2270. ap_mem_mpu_attr = SET_ACCESS_PERMISSON(FORBIDDEN,
  2271. NO_PROTECTION,
  2272. FORBIDDEN,
  2273. NO_PROTECTION,
  2274. FORBIDDEN,
  2275. FORBIDDEN,
  2276. FORBIDDEN,
  2277. NO_PROTECTION);
  2278. #else /* MT6735M*/
  2279. ap_mem_mpu_attr = SET_ACCESS_PERMISSON(NO_PROTECTION,
  2280. FORBIDDEN,
  2281. FORBIDDEN,
  2282. NO_PROTECTION);
  2283. #endif
  2284. pr_err("[EMI] protect_ap_region 0x%x~0x%x ,dram size=0x%x\n",
  2285. kernel_base,
  2286. (kernel_base + (unsigned int)dram_size - 1),
  2287. (unsigned int)dram_size);
  2288. emi_mpu_set_region_protection(kernel_base,
  2289. (kernel_base+dram_size-1), ap_mem_mpu_id, ap_mem_mpu_attr);
  2290. }
  2291. /*
  2292. static int emi_mpu_panic_cb(struct notifier_block *this,
  2293. unsigned long event, void *ptr)
  2294. {
  2295. emi_axi_dump_info(1);
  2296. return NOTIFY_DONE;
  2297. }*/
  2298. static struct platform_driver emi_mpu_ctrl = {
  2299. .driver = {
  2300. .name = "emi_mpu_ctrl",
  2301. .bus = &platform_bus_type,
  2302. .owner = THIS_MODULE,
  2303. },
  2304. .id_table = NULL,
  2305. };
  2306. /*
  2307. static struct notifier_block emi_mpu_blk = {
  2308. .notifier_call = emi_mpu_panic_cb,
  2309. };*/
  2310. static int __init emi_mpu_mod_init(void)
  2311. {
  2312. int ret;
  2313. #if defined(CONFIG_ARCH_MT6753)
  2314. struct basic_dram_setting DRAM_setting;
  2315. #endif
  2316. struct device_node *node;
  2317. unsigned int mpu_irq;
  2318. pr_err("[EMI MPU] Initialize EMI MPU.\n");
  2319. /* DTS version */
  2320. if (EMI_BASE_ADDR == NULL) {
  2321. node = of_find_compatible_node(NULL, NULL, "mediatek,EMI");
  2322. if (node) {
  2323. EMI_BASE_ADDR = of_iomap(node, 0);
  2324. pr_err("get EMI_BASE_ADDR @ %p\n", EMI_BASE_ADDR);
  2325. } else {
  2326. pr_err("can't find compatible node\n");
  2327. return -1;
  2328. }
  2329. }
  2330. node = of_find_compatible_node(NULL, NULL, "mediatek,DEVAPC");
  2331. if (node) {
  2332. mpu_irq = irq_of_parse_and_map(node, 0);
  2333. pr_debug("get EMI_MPU irq = %d\n", mpu_irq);
  2334. } else {
  2335. pr_err("can't find compatible node DEVAPC\n");
  2336. return -1;
  2337. }
  2338. spin_lock_init(&emi_mpu_lock);
  2339. pr_err("[EMI MPU] EMI_MPUP = 0x%x\n", readl(IOMEM((EMI_MPUP))));
  2340. pr_err("[EMI MPU] EMI_MPUQ = 0x%x\n", readl(IOMEM((EMI_MPUQ))));
  2341. pr_err("[EMI MPU] EMI_MPUR = 0x%x\n", readl(IOMEM((EMI_MPUR))));
  2342. pr_err("[EMI MPU] EMI_MPUY = 0x%x\n", readl(IOMEM(EMI_MPUY)));
  2343. pr_err("[EMI MPU] EMI_MPUP2 = 0x%x\n", readl(IOMEM(EMI_MPUP2)));
  2344. pr_err("[EMI MPU] EMI_MPUQ2 = 0x%x\n", readl(IOMEM(EMI_MPUQ2)));
  2345. pr_err("[EMI MPU] EMI_MPUR2 = 0x%x\n", readl(IOMEM(EMI_MPUR2)));
  2346. pr_err("[EMI MPU] EMI_MPUY2 = 0x%x\n", readl(IOMEM(EMI_MPUY2)));
  2347. pr_err("[EMI MPU] EMI_MPUS = 0x%x\n", readl(IOMEM(EMI_MPUS)));
  2348. pr_err("[EMI MPU] EMI_MPUT = 0x%x\n", readl(IOMEM(EMI_MPUT)));
  2349. pr_err("[EMI MPU] EMI_WP_ADR = 0x%x\n", readl(IOMEM(EMI_WP_ADR)));
  2350. pr_err("[EMI MPU] EMI_WP_CTRL = 0x%x\n", readl(IOMEM(EMI_WP_CTRL)));
  2351. pr_err("[EMI MPU] EMI_CHKER = 0x%x\n", readl(IOMEM(EMI_CHKER)));
  2352. pr_err("[EMI MPU] EMI_CHKER_TYPE = 0x%x\n",
  2353. readl(IOMEM(EMI_CHKER_TYPE)));
  2354. pr_err("[EMI MPU] EMI_CHKER_ADR = 0x%x\n", readl(IOMEM(EMI_CHKER_ADR)));
  2355. __clear_emi_mpu_vio();
  2356. /* Set Device APC initialization for EMI-MPU. */
  2357. mt_devapc_emi_initial();
  2358. if (1) /* (0 == enable_4G()) there is on 4G mode of MT6735~MT6753*/ {
  2359. emi_physical_offset = 0x40000000;
  2360. pr_err("[EMI MPU] Not 4G mode\n");
  2361. } else {
  2362. /*enable 4G mode*/
  2363. emi_physical_offset = 0;
  2364. pr_err("[EMI MPU] 4G mode\n");
  2365. }
  2366. /*
  2367. * NoteXXX: Interrupts of violation (including SPC in SMI, or EMI MPU)
  2368. * are triggered by the device APC.
  2369. * Need to share the interrupt with the SPC driver.
  2370. */
  2371. ret = request_irq(mpu_irq,
  2372. (irq_handler_t)mpu_violation_irq,
  2373. IRQF_TRIGGER_LOW | IRQF_SHARED,
  2374. "mt_emi_mpu",
  2375. &emi_mpu_ctrl);
  2376. if (ret != 0) {
  2377. pr_err("Fail to request EMI_MPU interrupt. Error = %d.\n", ret);
  2378. return ret;
  2379. }
  2380. protect_ap_region();
  2381. #if defined(CONFIG_ARCH_MT6753)
  2382. acquire_dram_setting(&DRAM_setting);
  2383. pr_err("[EMI] EMI_CONA = 0x%x\n", readl(IOMEM((EMI_CONA))));
  2384. pr_err("[EMI] Support channel number %d\n", DRAM_setting.channel_nr);
  2385. pr_err("[EMI] Channel 0 : rank 0 : %d Gb, segment no : %d\n",
  2386. DRAM_setting.channel[0].rank[0].rank_size,
  2387. DRAM_setting.channel[0].rank[0].segment_nr);
  2388. pr_err("[EMI] Channel 0 : rank 1 : %d Gb, segment no : %d\n",
  2389. DRAM_setting.channel[0].rank[1].rank_size,
  2390. DRAM_setting.channel[0].rank[1].segment_nr);
  2391. pr_err("[EMI] Channel 1 : rank 0 : %d Gb, segment no : %d\n",
  2392. DRAM_setting.channel[1].rank[0].rank_size,
  2393. DRAM_setting.channel[1].rank[0].segment_nr);
  2394. pr_err("[EMI] Channel 1 : rank 1 : %d Gb, segment no : %d\n",
  2395. DRAM_setting.channel[1].rank[1].rank_size,
  2396. DRAM_setting.channel[1].rank[1].segment_nr);
  2397. #endif
  2398. #ifdef ENABLE_EMI_CHKER
  2399. /* AXI violation monitor setting and timer function create */
  2400. mt_reg_sync_writel((1 << AXI_VIO_CLR) | readl(IOMEM(EMI_CHKER)),
  2401. EMI_CHKER);
  2402. emi_axi_set_master(MASTER_ALL);
  2403. init_timer(&emi_axi_vio_timer);
  2404. emi_axi_vio_timer.expires = jiffies + AXI_VIO_MONITOR_TIME;
  2405. emi_axi_vio_timer.function = &emi_axi_vio_timer_func;
  2406. emi_axi_vio_timer.data = ((unsigned long) 0);
  2407. #endif /*#ifdef ENABLE_EMI_CHKER*/
  2408. #if !defined(USER_BUILD_KERNEL)
  2409. #ifdef ENABLE_EMI_CHKER
  2410. /* Enable AXI 4KB boundary violation monitor timer */
  2411. /*emi_axi_set_chker(1 << AXI_ADR_CHK_EN);*/
  2412. /*add_timer_on(&emi_axi_vio_timer, 0);*/
  2413. #endif
  2414. /* register driver and create sysfs files */
  2415. ret = platform_driver_register(&emi_mpu_ctrl);
  2416. if (ret)
  2417. pr_err("Fail to register EMI_MPU driver.\n");
  2418. ret = driver_create_file(&emi_mpu_ctrl.driver, &driver_attr_mpu_config);
  2419. if (ret)
  2420. pr_err("Fail to create MPU config sysfs file.\n");
  2421. #ifdef ENABLE_EMI_CHKER
  2422. ret = driver_create_file(&emi_mpu_ctrl.driver,
  2423. &driver_attr_emi_axi_vio);
  2424. if (ret)
  2425. pr_err("Fail to create AXI violation monitor sysfs file.\n");
  2426. #endif
  2427. ret = driver_create_file(&emi_mpu_ctrl.driver, &driver_attr_pgt_scan);
  2428. if (ret)
  2429. pr_err("Fail to create pgt scan sysfs file.\n");
  2430. #ifdef ENABLE_EMI_WATCH_POINT
  2431. ret = driver_create_file(&emi_mpu_ctrl.driver, &driver_attr_emi_wp_vio);
  2432. if (ret)
  2433. pr_err("Fail to create WP violation monitor sysfs file.\n");
  2434. #endif
  2435. #endif
  2436. /*atomic_notifier_chain_register(&panic_notifier_list, &emi_mpu_blk);*/
  2437. /* Create a workqueue to search pagetable entry */
  2438. emi_mpu_workqueue = create_singlethread_workqueue("emi_mpu");
  2439. INIT_WORK(&emi_mpu_work, emi_mpu_work_callback);
  2440. return 0;
  2441. }
  2442. static void __exit emi_mpu_mod_exit(void)
  2443. {
  2444. }
  2445. /*
  2446. unsigned int enable_4G(void)
  2447. {
  2448. return 0;
  2449. }
  2450. */
  2451. module_init(emi_mpu_mod_init);
  2452. module_exit(emi_mpu_mod_exit);
  2453. /*EXPORT_SYMBOL(start_mm_mau_protect);*/