tegra186.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  1. /*
  2. * Copyright (C) 2017 NVIDIA CORPORATION. All rights reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 as
  6. * published by the Free Software Foundation.
  7. */
  8. #include <linux/io.h>
  9. #include <linux/module.h>
  10. #include <linux/mod_devicetable.h>
  11. #include <linux/platform_device.h>
  12. #include <dt-bindings/memory/tegra186-mc.h>
  13. struct tegra_mc {
  14. struct device *dev;
  15. void __iomem *regs;
  16. };
  17. struct tegra_mc_client {
  18. const char *name;
  19. unsigned int sid;
  20. struct {
  21. unsigned int override;
  22. unsigned int security;
  23. } regs;
  24. };
  25. static const struct tegra_mc_client tegra186_mc_clients[] = {
  26. {
  27. .name = "ptcr",
  28. .sid = TEGRA186_SID_PASSTHROUGH,
  29. .regs = {
  30. .override = 0x000,
  31. .security = 0x004,
  32. },
  33. }, {
  34. .name = "afir",
  35. .sid = TEGRA186_SID_AFI,
  36. .regs = {
  37. .override = 0x070,
  38. .security = 0x074,
  39. },
  40. }, {
  41. .name = "hdar",
  42. .sid = TEGRA186_SID_HDA,
  43. .regs = {
  44. .override = 0x0a8,
  45. .security = 0x0ac,
  46. },
  47. }, {
  48. .name = "host1xdmar",
  49. .sid = TEGRA186_SID_HOST1X,
  50. .regs = {
  51. .override = 0x0b0,
  52. .security = 0x0b4,
  53. },
  54. }, {
  55. .name = "nvencsrd",
  56. .sid = TEGRA186_SID_NVENC,
  57. .regs = {
  58. .override = 0x0e0,
  59. .security = 0x0e4,
  60. },
  61. }, {
  62. .name = "satar",
  63. .sid = TEGRA186_SID_SATA,
  64. .regs = {
  65. .override = 0x0f8,
  66. .security = 0x0fc,
  67. },
  68. }, {
  69. .name = "mpcorer",
  70. .sid = TEGRA186_SID_PASSTHROUGH,
  71. .regs = {
  72. .override = 0x138,
  73. .security = 0x13c,
  74. },
  75. }, {
  76. .name = "nvencswr",
  77. .sid = TEGRA186_SID_NVENC,
  78. .regs = {
  79. .override = 0x158,
  80. .security = 0x15c,
  81. },
  82. }, {
  83. .name = "afiw",
  84. .sid = TEGRA186_SID_AFI,
  85. .regs = {
  86. .override = 0x188,
  87. .security = 0x18c,
  88. },
  89. }, {
  90. .name = "hdaw",
  91. .sid = TEGRA186_SID_HDA,
  92. .regs = {
  93. .override = 0x1a8,
  94. .security = 0x1ac,
  95. },
  96. }, {
  97. .name = "mpcorew",
  98. .sid = TEGRA186_SID_PASSTHROUGH,
  99. .regs = {
  100. .override = 0x1c8,
  101. .security = 0x1cc,
  102. },
  103. }, {
  104. .name = "sataw",
  105. .sid = TEGRA186_SID_SATA,
  106. .regs = {
  107. .override = 0x1e8,
  108. .security = 0x1ec,
  109. },
  110. }, {
  111. .name = "ispra",
  112. .sid = TEGRA186_SID_ISP,
  113. .regs = {
  114. .override = 0x220,
  115. .security = 0x224,
  116. },
  117. }, {
  118. .name = "ispwa",
  119. .sid = TEGRA186_SID_ISP,
  120. .regs = {
  121. .override = 0x230,
  122. .security = 0x234,
  123. },
  124. }, {
  125. .name = "ispwb",
  126. .sid = TEGRA186_SID_ISP,
  127. .regs = {
  128. .override = 0x238,
  129. .security = 0x23c,
  130. },
  131. }, {
  132. .name = "xusb_hostr",
  133. .sid = TEGRA186_SID_XUSB_HOST,
  134. .regs = {
  135. .override = 0x250,
  136. .security = 0x254,
  137. },
  138. }, {
  139. .name = "xusb_hostw",
  140. .sid = TEGRA186_SID_XUSB_HOST,
  141. .regs = {
  142. .override = 0x258,
  143. .security = 0x25c,
  144. },
  145. }, {
  146. .name = "xusb_devr",
  147. .sid = TEGRA186_SID_XUSB_DEV,
  148. .regs = {
  149. .override = 0x260,
  150. .security = 0x264,
  151. },
  152. }, {
  153. .name = "xusb_devw",
  154. .sid = TEGRA186_SID_XUSB_DEV,
  155. .regs = {
  156. .override = 0x268,
  157. .security = 0x26c,
  158. },
  159. }, {
  160. .name = "tsecsrd",
  161. .sid = TEGRA186_SID_TSEC,
  162. .regs = {
  163. .override = 0x2a0,
  164. .security = 0x2a4,
  165. },
  166. }, {
  167. .name = "tsecswr",
  168. .sid = TEGRA186_SID_TSEC,
  169. .regs = {
  170. .override = 0x2a8,
  171. .security = 0x2ac,
  172. },
  173. }, {
  174. .name = "gpusrd",
  175. .sid = TEGRA186_SID_GPU,
  176. .regs = {
  177. .override = 0x2c0,
  178. .security = 0x2c4,
  179. },
  180. }, {
  181. .name = "gpuswr",
  182. .sid = TEGRA186_SID_GPU,
  183. .regs = {
  184. .override = 0x2c8,
  185. .security = 0x2cc,
  186. },
  187. }, {
  188. .name = "sdmmcra",
  189. .sid = TEGRA186_SID_SDMMC1,
  190. .regs = {
  191. .override = 0x300,
  192. .security = 0x304,
  193. },
  194. }, {
  195. .name = "sdmmcraa",
  196. .sid = TEGRA186_SID_SDMMC2,
  197. .regs = {
  198. .override = 0x308,
  199. .security = 0x30c,
  200. },
  201. }, {
  202. .name = "sdmmcr",
  203. .sid = TEGRA186_SID_SDMMC3,
  204. .regs = {
  205. .override = 0x310,
  206. .security = 0x314,
  207. },
  208. }, {
  209. .name = "sdmmcrab",
  210. .sid = TEGRA186_SID_SDMMC4,
  211. .regs = {
  212. .override = 0x318,
  213. .security = 0x31c,
  214. },
  215. }, {
  216. .name = "sdmmcwa",
  217. .sid = TEGRA186_SID_SDMMC1,
  218. .regs = {
  219. .override = 0x320,
  220. .security = 0x324,
  221. },
  222. }, {
  223. .name = "sdmmcwaa",
  224. .sid = TEGRA186_SID_SDMMC2,
  225. .regs = {
  226. .override = 0x328,
  227. .security = 0x32c,
  228. },
  229. }, {
  230. .name = "sdmmcw",
  231. .sid = TEGRA186_SID_SDMMC3,
  232. .regs = {
  233. .override = 0x330,
  234. .security = 0x334,
  235. },
  236. }, {
  237. .name = "sdmmcwab",
  238. .sid = TEGRA186_SID_SDMMC4,
  239. .regs = {
  240. .override = 0x338,
  241. .security = 0x33c,
  242. },
  243. }, {
  244. .name = "vicsrd",
  245. .sid = TEGRA186_SID_VIC,
  246. .regs = {
  247. .override = 0x360,
  248. .security = 0x364,
  249. },
  250. }, {
  251. .name = "vicswr",
  252. .sid = TEGRA186_SID_VIC,
  253. .regs = {
  254. .override = 0x368,
  255. .security = 0x36c,
  256. },
  257. }, {
  258. .name = "viw",
  259. .sid = TEGRA186_SID_VI,
  260. .regs = {
  261. .override = 0x390,
  262. .security = 0x394,
  263. },
  264. }, {
  265. .name = "nvdecsrd",
  266. .sid = TEGRA186_SID_NVDEC,
  267. .regs = {
  268. .override = 0x3c0,
  269. .security = 0x3c4,
  270. },
  271. }, {
  272. .name = "nvdecswr",
  273. .sid = TEGRA186_SID_NVDEC,
  274. .regs = {
  275. .override = 0x3c8,
  276. .security = 0x3cc,
  277. },
  278. }, {
  279. .name = "aper",
  280. .sid = TEGRA186_SID_APE,
  281. .regs = {
  282. .override = 0x3d0,
  283. .security = 0x3d4,
  284. },
  285. }, {
  286. .name = "apew",
  287. .sid = TEGRA186_SID_APE,
  288. .regs = {
  289. .override = 0x3d8,
  290. .security = 0x3dc,
  291. },
  292. }, {
  293. .name = "nvjpgsrd",
  294. .sid = TEGRA186_SID_NVJPG,
  295. .regs = {
  296. .override = 0x3f0,
  297. .security = 0x3f4,
  298. },
  299. }, {
  300. .name = "nvjpgswr",
  301. .sid = TEGRA186_SID_NVJPG,
  302. .regs = {
  303. .override = 0x3f8,
  304. .security = 0x3fc,
  305. },
  306. }, {
  307. .name = "sesrd",
  308. .sid = TEGRA186_SID_SE,
  309. .regs = {
  310. .override = 0x400,
  311. .security = 0x404,
  312. },
  313. }, {
  314. .name = "seswr",
  315. .sid = TEGRA186_SID_SE,
  316. .regs = {
  317. .override = 0x408,
  318. .security = 0x40c,
  319. },
  320. }, {
  321. .name = "etrr",
  322. .sid = TEGRA186_SID_ETR,
  323. .regs = {
  324. .override = 0x420,
  325. .security = 0x424,
  326. },
  327. }, {
  328. .name = "etrw",
  329. .sid = TEGRA186_SID_ETR,
  330. .regs = {
  331. .override = 0x428,
  332. .security = 0x42c,
  333. },
  334. }, {
  335. .name = "tsecsrdb",
  336. .sid = TEGRA186_SID_TSECB,
  337. .regs = {
  338. .override = 0x430,
  339. .security = 0x434,
  340. },
  341. }, {
  342. .name = "tsecswrb",
  343. .sid = TEGRA186_SID_TSECB,
  344. .regs = {
  345. .override = 0x438,
  346. .security = 0x43c,
  347. },
  348. }, {
  349. .name = "gpusrd2",
  350. .sid = TEGRA186_SID_GPU,
  351. .regs = {
  352. .override = 0x440,
  353. .security = 0x444,
  354. },
  355. }, {
  356. .name = "gpuswr2",
  357. .sid = TEGRA186_SID_GPU,
  358. .regs = {
  359. .override = 0x448,
  360. .security = 0x44c,
  361. },
  362. }, {
  363. .name = "axisr",
  364. .sid = TEGRA186_SID_GPCDMA_0,
  365. .regs = {
  366. .override = 0x460,
  367. .security = 0x464,
  368. },
  369. }, {
  370. .name = "axisw",
  371. .sid = TEGRA186_SID_GPCDMA_0,
  372. .regs = {
  373. .override = 0x468,
  374. .security = 0x46c,
  375. },
  376. }, {
  377. .name = "eqosr",
  378. .sid = TEGRA186_SID_EQOS,
  379. .regs = {
  380. .override = 0x470,
  381. .security = 0x474,
  382. },
  383. }, {
  384. .name = "eqosw",
  385. .sid = TEGRA186_SID_EQOS,
  386. .regs = {
  387. .override = 0x478,
  388. .security = 0x47c,
  389. },
  390. }, {
  391. .name = "ufshcr",
  392. .sid = TEGRA186_SID_UFSHC,
  393. .regs = {
  394. .override = 0x480,
  395. .security = 0x484,
  396. },
  397. }, {
  398. .name = "ufshcw",
  399. .sid = TEGRA186_SID_UFSHC,
  400. .regs = {
  401. .override = 0x488,
  402. .security = 0x48c,
  403. },
  404. }, {
  405. .name = "nvdisplayr",
  406. .sid = TEGRA186_SID_NVDISPLAY,
  407. .regs = {
  408. .override = 0x490,
  409. .security = 0x494,
  410. },
  411. }, {
  412. .name = "bpmpr",
  413. .sid = TEGRA186_SID_BPMP,
  414. .regs = {
  415. .override = 0x498,
  416. .security = 0x49c,
  417. },
  418. }, {
  419. .name = "bpmpw",
  420. .sid = TEGRA186_SID_BPMP,
  421. .regs = {
  422. .override = 0x4a0,
  423. .security = 0x4a4,
  424. },
  425. }, {
  426. .name = "bpmpdmar",
  427. .sid = TEGRA186_SID_BPMP,
  428. .regs = {
  429. .override = 0x4a8,
  430. .security = 0x4ac,
  431. },
  432. }, {
  433. .name = "bpmpdmaw",
  434. .sid = TEGRA186_SID_BPMP,
  435. .regs = {
  436. .override = 0x4b0,
  437. .security = 0x4b4,
  438. },
  439. }, {
  440. .name = "aonr",
  441. .sid = TEGRA186_SID_AON,
  442. .regs = {
  443. .override = 0x4b8,
  444. .security = 0x4bc,
  445. },
  446. }, {
  447. .name = "aonw",
  448. .sid = TEGRA186_SID_AON,
  449. .regs = {
  450. .override = 0x4c0,
  451. .security = 0x4c4,
  452. },
  453. }, {
  454. .name = "aondmar",
  455. .sid = TEGRA186_SID_AON,
  456. .regs = {
  457. .override = 0x4c8,
  458. .security = 0x4cc,
  459. },
  460. }, {
  461. .name = "aondmaw",
  462. .sid = TEGRA186_SID_AON,
  463. .regs = {
  464. .override = 0x4d0,
  465. .security = 0x4d4,
  466. },
  467. }, {
  468. .name = "scer",
  469. .sid = TEGRA186_SID_SCE,
  470. .regs = {
  471. .override = 0x4d8,
  472. .security = 0x4dc,
  473. },
  474. }, {
  475. .name = "scew",
  476. .sid = TEGRA186_SID_SCE,
  477. .regs = {
  478. .override = 0x4e0,
  479. .security = 0x4e4,
  480. },
  481. }, {
  482. .name = "scedmar",
  483. .sid = TEGRA186_SID_SCE,
  484. .regs = {
  485. .override = 0x4e8,
  486. .security = 0x4ec,
  487. },
  488. }, {
  489. .name = "scedmaw",
  490. .sid = TEGRA186_SID_SCE,
  491. .regs = {
  492. .override = 0x4f0,
  493. .security = 0x4f4,
  494. },
  495. }, {
  496. .name = "apedmar",
  497. .sid = TEGRA186_SID_APE,
  498. .regs = {
  499. .override = 0x4f8,
  500. .security = 0x4fc,
  501. },
  502. }, {
  503. .name = "apedmaw",
  504. .sid = TEGRA186_SID_APE,
  505. .regs = {
  506. .override = 0x500,
  507. .security = 0x504,
  508. },
  509. }, {
  510. .name = "nvdisplayr1",
  511. .sid = TEGRA186_SID_NVDISPLAY,
  512. .regs = {
  513. .override = 0x508,
  514. .security = 0x50c,
  515. },
  516. }, {
  517. .name = "vicsrd1",
  518. .sid = TEGRA186_SID_VIC,
  519. .regs = {
  520. .override = 0x510,
  521. .security = 0x514,
  522. },
  523. }, {
  524. .name = "nvdecsrd1",
  525. .sid = TEGRA186_SID_NVDEC,
  526. .regs = {
  527. .override = 0x518,
  528. .security = 0x51c,
  529. },
  530. },
  531. };
  532. static int tegra186_mc_probe(struct platform_device *pdev)
  533. {
  534. struct resource *res;
  535. struct tegra_mc *mc;
  536. unsigned int i;
  537. int err = 0;
  538. mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
  539. if (!mc)
  540. return -ENOMEM;
  541. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  542. mc->regs = devm_ioremap_resource(&pdev->dev, res);
  543. if (IS_ERR(mc->regs))
  544. return PTR_ERR(mc->regs);
  545. mc->dev = &pdev->dev;
  546. for (i = 0; i < ARRAY_SIZE(tegra186_mc_clients); i++) {
  547. const struct tegra_mc_client *client = &tegra186_mc_clients[i];
  548. u32 override, security;
  549. override = readl(mc->regs + client->regs.override);
  550. security = readl(mc->regs + client->regs.security);
  551. dev_dbg(&pdev->dev, "client %s: override: %x security: %x\n",
  552. client->name, override, security);
  553. dev_dbg(&pdev->dev, "setting SID %u for %s\n", client->sid,
  554. client->name);
  555. writel(client->sid, mc->regs + client->regs.override);
  556. override = readl(mc->regs + client->regs.override);
  557. security = readl(mc->regs + client->regs.security);
  558. dev_dbg(&pdev->dev, "client %s: override: %x security: %x\n",
  559. client->name, override, security);
  560. }
  561. platform_set_drvdata(pdev, mc);
  562. return err;
  563. }
  564. static const struct of_device_id tegra186_mc_of_match[] = {
  565. { .compatible = "nvidia,tegra186-mc", },
  566. { /* sentinel */ }
  567. };
  568. MODULE_DEVICE_TABLE(of, tegra186_mc_of_match);
  569. static struct platform_driver tegra186_mc_driver = {
  570. .driver = {
  571. .name = "tegra186-mc",
  572. .of_match_table = tegra186_mc_of_match,
  573. .suppress_bind_attrs = true,
  574. },
  575. .prevent_deferred_probe = true,
  576. .probe = tegra186_mc_probe,
  577. };
  578. module_platform_driver(tegra186_mc_driver);
  579. MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
  580. MODULE_DESCRIPTION("NVIDIA Tegra186 Memory Controller driver");
  581. MODULE_LICENSE("GPL v2");