tegra20.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. /*
  2. * Copyright (C) 2012 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 <dt-bindings/memory/tegra20-mc.h>
  9. #include "mc.h"
  10. static const struct tegra_mc_client tegra20_mc_clients[] = {
  11. {
  12. .id = 0x00,
  13. .name = "display0a",
  14. }, {
  15. .id = 0x01,
  16. .name = "display0ab",
  17. }, {
  18. .id = 0x02,
  19. .name = "display0b",
  20. }, {
  21. .id = 0x03,
  22. .name = "display0bb",
  23. }, {
  24. .id = 0x04,
  25. .name = "display0c",
  26. }, {
  27. .id = 0x05,
  28. .name = "display0cb",
  29. }, {
  30. .id = 0x06,
  31. .name = "display1b",
  32. }, {
  33. .id = 0x07,
  34. .name = "display1bb",
  35. }, {
  36. .id = 0x08,
  37. .name = "eppup",
  38. }, {
  39. .id = 0x09,
  40. .name = "g2pr",
  41. }, {
  42. .id = 0x0a,
  43. .name = "g2sr",
  44. }, {
  45. .id = 0x0b,
  46. .name = "mpeunifbr",
  47. }, {
  48. .id = 0x0c,
  49. .name = "viruv",
  50. }, {
  51. .id = 0x0d,
  52. .name = "avpcarm7r",
  53. }, {
  54. .id = 0x0e,
  55. .name = "displayhc",
  56. }, {
  57. .id = 0x0f,
  58. .name = "displayhcb",
  59. }, {
  60. .id = 0x10,
  61. .name = "fdcdrd",
  62. }, {
  63. .id = 0x11,
  64. .name = "g2dr",
  65. }, {
  66. .id = 0x12,
  67. .name = "host1xdmar",
  68. }, {
  69. .id = 0x13,
  70. .name = "host1xr",
  71. }, {
  72. .id = 0x14,
  73. .name = "idxsrd",
  74. }, {
  75. .id = 0x15,
  76. .name = "mpcorer",
  77. }, {
  78. .id = 0x16,
  79. .name = "mpe_ipred",
  80. }, {
  81. .id = 0x17,
  82. .name = "mpeamemrd",
  83. }, {
  84. .id = 0x18,
  85. .name = "mpecsrd",
  86. }, {
  87. .id = 0x19,
  88. .name = "ppcsahbdmar",
  89. }, {
  90. .id = 0x1a,
  91. .name = "ppcsahbslvr",
  92. }, {
  93. .id = 0x1b,
  94. .name = "texsrd",
  95. }, {
  96. .id = 0x1c,
  97. .name = "vdebsevr",
  98. }, {
  99. .id = 0x1d,
  100. .name = "vdember",
  101. }, {
  102. .id = 0x1e,
  103. .name = "vdemcer",
  104. }, {
  105. .id = 0x1f,
  106. .name = "vdetper",
  107. }, {
  108. .id = 0x20,
  109. .name = "eppu",
  110. }, {
  111. .id = 0x21,
  112. .name = "eppv",
  113. }, {
  114. .id = 0x22,
  115. .name = "eppy",
  116. }, {
  117. .id = 0x23,
  118. .name = "mpeunifbw",
  119. }, {
  120. .id = 0x24,
  121. .name = "viwsb",
  122. }, {
  123. .id = 0x25,
  124. .name = "viwu",
  125. }, {
  126. .id = 0x26,
  127. .name = "viwv",
  128. }, {
  129. .id = 0x27,
  130. .name = "viwy",
  131. }, {
  132. .id = 0x28,
  133. .name = "g2dw",
  134. }, {
  135. .id = 0x29,
  136. .name = "avpcarm7w",
  137. }, {
  138. .id = 0x2a,
  139. .name = "fdcdwr",
  140. }, {
  141. .id = 0x2b,
  142. .name = "host1xw",
  143. }, {
  144. .id = 0x2c,
  145. .name = "ispw",
  146. }, {
  147. .id = 0x2d,
  148. .name = "mpcorew",
  149. }, {
  150. .id = 0x2e,
  151. .name = "mpecswr",
  152. }, {
  153. .id = 0x2f,
  154. .name = "ppcsahbdmaw",
  155. }, {
  156. .id = 0x30,
  157. .name = "ppcsahbslvw",
  158. }, {
  159. .id = 0x31,
  160. .name = "vdebsevw",
  161. }, {
  162. .id = 0x32,
  163. .name = "vdembew",
  164. }, {
  165. .id = 0x33,
  166. .name = "vdetpmw",
  167. },
  168. };
  169. #define TEGRA20_MC_RESET(_name, _control, _status, _reset, _bit) \
  170. { \
  171. .name = #_name, \
  172. .id = TEGRA20_MC_RESET_##_name, \
  173. .control = _control, \
  174. .status = _status, \
  175. .reset = _reset, \
  176. .bit = _bit, \
  177. }
  178. static const struct tegra_mc_reset tegra20_mc_resets[] = {
  179. TEGRA20_MC_RESET(AVPC, 0x100, 0x140, 0x104, 0),
  180. TEGRA20_MC_RESET(DC, 0x100, 0x144, 0x104, 1),
  181. TEGRA20_MC_RESET(DCB, 0x100, 0x148, 0x104, 2),
  182. TEGRA20_MC_RESET(EPP, 0x100, 0x14c, 0x104, 3),
  183. TEGRA20_MC_RESET(2D, 0x100, 0x150, 0x104, 4),
  184. TEGRA20_MC_RESET(HC, 0x100, 0x154, 0x104, 5),
  185. TEGRA20_MC_RESET(ISP, 0x100, 0x158, 0x104, 6),
  186. TEGRA20_MC_RESET(MPCORE, 0x100, 0x15c, 0x104, 7),
  187. TEGRA20_MC_RESET(MPEA, 0x100, 0x160, 0x104, 8),
  188. TEGRA20_MC_RESET(MPEB, 0x100, 0x164, 0x104, 9),
  189. TEGRA20_MC_RESET(MPEC, 0x100, 0x168, 0x104, 10),
  190. TEGRA20_MC_RESET(3D, 0x100, 0x16c, 0x104, 11),
  191. TEGRA20_MC_RESET(PPCS, 0x100, 0x170, 0x104, 12),
  192. TEGRA20_MC_RESET(VDE, 0x100, 0x174, 0x104, 13),
  193. TEGRA20_MC_RESET(VI, 0x100, 0x178, 0x104, 14),
  194. };
  195. static int terga20_mc_hotreset_assert(struct tegra_mc *mc,
  196. const struct tegra_mc_reset *rst)
  197. {
  198. unsigned long flags;
  199. u32 value;
  200. spin_lock_irqsave(&mc->lock, flags);
  201. value = mc_readl(mc, rst->reset);
  202. mc_writel(mc, value & ~BIT(rst->bit), rst->reset);
  203. spin_unlock_irqrestore(&mc->lock, flags);
  204. return 0;
  205. }
  206. static int terga20_mc_hotreset_deassert(struct tegra_mc *mc,
  207. const struct tegra_mc_reset *rst)
  208. {
  209. unsigned long flags;
  210. u32 value;
  211. spin_lock_irqsave(&mc->lock, flags);
  212. value = mc_readl(mc, rst->reset);
  213. mc_writel(mc, value | BIT(rst->bit), rst->reset);
  214. spin_unlock_irqrestore(&mc->lock, flags);
  215. return 0;
  216. }
  217. static int terga20_mc_block_dma(struct tegra_mc *mc,
  218. const struct tegra_mc_reset *rst)
  219. {
  220. unsigned long flags;
  221. u32 value;
  222. spin_lock_irqsave(&mc->lock, flags);
  223. value = mc_readl(mc, rst->control) & ~BIT(rst->bit);
  224. mc_writel(mc, value, rst->control);
  225. spin_unlock_irqrestore(&mc->lock, flags);
  226. return 0;
  227. }
  228. static bool terga20_mc_dma_idling(struct tegra_mc *mc,
  229. const struct tegra_mc_reset *rst)
  230. {
  231. return mc_readl(mc, rst->status) == 0;
  232. }
  233. static int terga20_mc_reset_status(struct tegra_mc *mc,
  234. const struct tegra_mc_reset *rst)
  235. {
  236. return (mc_readl(mc, rst->reset) & BIT(rst->bit)) == 0;
  237. }
  238. static int terga20_mc_unblock_dma(struct tegra_mc *mc,
  239. const struct tegra_mc_reset *rst)
  240. {
  241. unsigned long flags;
  242. u32 value;
  243. spin_lock_irqsave(&mc->lock, flags);
  244. value = mc_readl(mc, rst->control) | BIT(rst->bit);
  245. mc_writel(mc, value, rst->control);
  246. spin_unlock_irqrestore(&mc->lock, flags);
  247. return 0;
  248. }
  249. const struct tegra_mc_reset_ops terga20_mc_reset_ops = {
  250. .hotreset_assert = terga20_mc_hotreset_assert,
  251. .hotreset_deassert = terga20_mc_hotreset_deassert,
  252. .block_dma = terga20_mc_block_dma,
  253. .dma_idling = terga20_mc_dma_idling,
  254. .unblock_dma = terga20_mc_unblock_dma,
  255. .reset_status = terga20_mc_reset_status,
  256. };
  257. const struct tegra_mc_soc tegra20_mc_soc = {
  258. .clients = tegra20_mc_clients,
  259. .num_clients = ARRAY_SIZE(tegra20_mc_clients),
  260. .num_address_bits = 32,
  261. .client_id_mask = 0x3f,
  262. .intmask = MC_INT_SECURITY_VIOLATION | MC_INT_INVALID_GART_PAGE |
  263. MC_INT_DECERR_EMEM,
  264. .reset_ops = &terga20_mc_reset_ops,
  265. .resets = tegra20_mc_resets,
  266. .num_resets = ARRAY_SIZE(tegra20_mc_resets),
  267. };