tegra186.c 11 KB

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