ni.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. /*
  2. * Copyright 2010 Advanced Micro Devices, Inc.
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17. * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18. * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. * OTHER DEALINGS IN THE SOFTWARE.
  21. *
  22. * Authors: Alex Deucher
  23. */
  24. #include <linux/firmware.h>
  25. #include <linux/platform_device.h>
  26. #include <linux/slab.h>
  27. #include "drmP.h"
  28. #include "radeon.h"
  29. #include "radeon_asic.h"
  30. #include "radeon_drm.h"
  31. #include "nid.h"
  32. #include "atom.h"
  33. #include "ni_reg.h"
  34. #define EVERGREEN_PFP_UCODE_SIZE 1120
  35. #define EVERGREEN_PM4_UCODE_SIZE 1376
  36. #define EVERGREEN_RLC_UCODE_SIZE 768
  37. #define BTC_MC_UCODE_SIZE 6024
  38. #define CAYMAN_PFP_UCODE_SIZE 2176
  39. #define CAYMAN_PM4_UCODE_SIZE 2176
  40. #define CAYMAN_RLC_UCODE_SIZE 1024
  41. #define CAYMAN_MC_UCODE_SIZE 6037
  42. /* Firmware Names */
  43. MODULE_FIRMWARE("radeon/BARTS_pfp.bin");
  44. MODULE_FIRMWARE("radeon/BARTS_me.bin");
  45. MODULE_FIRMWARE("radeon/BARTS_mc.bin");
  46. MODULE_FIRMWARE("radeon/BTC_rlc.bin");
  47. MODULE_FIRMWARE("radeon/TURKS_pfp.bin");
  48. MODULE_FIRMWARE("radeon/TURKS_me.bin");
  49. MODULE_FIRMWARE("radeon/TURKS_mc.bin");
  50. MODULE_FIRMWARE("radeon/CAICOS_pfp.bin");
  51. MODULE_FIRMWARE("radeon/CAICOS_me.bin");
  52. MODULE_FIRMWARE("radeon/CAICOS_mc.bin");
  53. MODULE_FIRMWARE("radeon/CAYMAN_pfp.bin");
  54. MODULE_FIRMWARE("radeon/CAYMAN_me.bin");
  55. MODULE_FIRMWARE("radeon/CAYMAN_mc.bin");
  56. MODULE_FIRMWARE("radeon/CAYMAN_rlc.bin");
  57. #define BTC_IO_MC_REGS_SIZE 29
  58. static const u32 barts_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
  59. {0x00000077, 0xff010100},
  60. {0x00000078, 0x00000000},
  61. {0x00000079, 0x00001434},
  62. {0x0000007a, 0xcc08ec08},
  63. {0x0000007b, 0x00040000},
  64. {0x0000007c, 0x000080c0},
  65. {0x0000007d, 0x09000000},
  66. {0x0000007e, 0x00210404},
  67. {0x00000081, 0x08a8e800},
  68. {0x00000082, 0x00030444},
  69. {0x00000083, 0x00000000},
  70. {0x00000085, 0x00000001},
  71. {0x00000086, 0x00000002},
  72. {0x00000087, 0x48490000},
  73. {0x00000088, 0x20244647},
  74. {0x00000089, 0x00000005},
  75. {0x0000008b, 0x66030000},
  76. {0x0000008c, 0x00006603},
  77. {0x0000008d, 0x00000100},
  78. {0x0000008f, 0x00001c0a},
  79. {0x00000090, 0xff000001},
  80. {0x00000094, 0x00101101},
  81. {0x00000095, 0x00000fff},
  82. {0x00000096, 0x00116fff},
  83. {0x00000097, 0x60010000},
  84. {0x00000098, 0x10010000},
  85. {0x00000099, 0x00006000},
  86. {0x0000009a, 0x00001000},
  87. {0x0000009f, 0x00946a00}
  88. };
  89. static const u32 turks_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
  90. {0x00000077, 0xff010100},
  91. {0x00000078, 0x00000000},
  92. {0x00000079, 0x00001434},
  93. {0x0000007a, 0xcc08ec08},
  94. {0x0000007b, 0x00040000},
  95. {0x0000007c, 0x000080c0},
  96. {0x0000007d, 0x09000000},
  97. {0x0000007e, 0x00210404},
  98. {0x00000081, 0x08a8e800},
  99. {0x00000082, 0x00030444},
  100. {0x00000083, 0x00000000},
  101. {0x00000085, 0x00000001},
  102. {0x00000086, 0x00000002},
  103. {0x00000087, 0x48490000},
  104. {0x00000088, 0x20244647},
  105. {0x00000089, 0x00000005},
  106. {0x0000008b, 0x66030000},
  107. {0x0000008c, 0x00006603},
  108. {0x0000008d, 0x00000100},
  109. {0x0000008f, 0x00001c0a},
  110. {0x00000090, 0xff000001},
  111. {0x00000094, 0x00101101},
  112. {0x00000095, 0x00000fff},
  113. {0x00000096, 0x00116fff},
  114. {0x00000097, 0x60010000},
  115. {0x00000098, 0x10010000},
  116. {0x00000099, 0x00006000},
  117. {0x0000009a, 0x00001000},
  118. {0x0000009f, 0x00936a00}
  119. };
  120. static const u32 caicos_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
  121. {0x00000077, 0xff010100},
  122. {0x00000078, 0x00000000},
  123. {0x00000079, 0x00001434},
  124. {0x0000007a, 0xcc08ec08},
  125. {0x0000007b, 0x00040000},
  126. {0x0000007c, 0x000080c0},
  127. {0x0000007d, 0x09000000},
  128. {0x0000007e, 0x00210404},
  129. {0x00000081, 0x08a8e800},
  130. {0x00000082, 0x00030444},
  131. {0x00000083, 0x00000000},
  132. {0x00000085, 0x00000001},
  133. {0x00000086, 0x00000002},
  134. {0x00000087, 0x48490000},
  135. {0x00000088, 0x20244647},
  136. {0x00000089, 0x00000005},
  137. {0x0000008b, 0x66030000},
  138. {0x0000008c, 0x00006603},
  139. {0x0000008d, 0x00000100},
  140. {0x0000008f, 0x00001c0a},
  141. {0x00000090, 0xff000001},
  142. {0x00000094, 0x00101101},
  143. {0x00000095, 0x00000fff},
  144. {0x00000096, 0x00116fff},
  145. {0x00000097, 0x60010000},
  146. {0x00000098, 0x10010000},
  147. {0x00000099, 0x00006000},
  148. {0x0000009a, 0x00001000},
  149. {0x0000009f, 0x00916a00}
  150. };
  151. static const u32 cayman_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
  152. {0x00000077, 0xff010100},
  153. {0x00000078, 0x00000000},
  154. {0x00000079, 0x00001434},
  155. {0x0000007a, 0xcc08ec08},
  156. {0x0000007b, 0x00040000},
  157. {0x0000007c, 0x000080c0},
  158. {0x0000007d, 0x09000000},
  159. {0x0000007e, 0x00210404},
  160. {0x00000081, 0x08a8e800},
  161. {0x00000082, 0x00030444},
  162. {0x00000083, 0x00000000},
  163. {0x00000085, 0x00000001},
  164. {0x00000086, 0x00000002},
  165. {0x00000087, 0x48490000},
  166. {0x00000088, 0x20244647},
  167. {0x00000089, 0x00000005},
  168. {0x0000008b, 0x66030000},
  169. {0x0000008c, 0x00006603},
  170. {0x0000008d, 0x00000100},
  171. {0x0000008f, 0x00001c0a},
  172. {0x00000090, 0xff000001},
  173. {0x00000094, 0x00101101},
  174. {0x00000095, 0x00000fff},
  175. {0x00000096, 0x00116fff},
  176. {0x00000097, 0x60010000},
  177. {0x00000098, 0x10010000},
  178. {0x00000099, 0x00006000},
  179. {0x0000009a, 0x00001000},
  180. {0x0000009f, 0x00976b00}
  181. };
  182. int btc_mc_load_microcode(struct radeon_device *rdev)
  183. {
  184. const __be32 *fw_data;
  185. u32 mem_type, running, blackout = 0;
  186. u32 *io_mc_regs;
  187. int i, ucode_size, regs_size;
  188. if (!rdev->mc_fw)
  189. return -EINVAL;
  190. switch (rdev->family) {
  191. case CHIP_BARTS:
  192. io_mc_regs = (u32 *)&barts_io_mc_regs;
  193. ucode_size = BTC_MC_UCODE_SIZE;
  194. regs_size = BTC_IO_MC_REGS_SIZE;
  195. break;
  196. case CHIP_TURKS:
  197. io_mc_regs = (u32 *)&turks_io_mc_regs;
  198. ucode_size = BTC_MC_UCODE_SIZE;
  199. regs_size = BTC_IO_MC_REGS_SIZE;
  200. break;
  201. case CHIP_CAICOS:
  202. default:
  203. io_mc_regs = (u32 *)&caicos_io_mc_regs;
  204. ucode_size = BTC_MC_UCODE_SIZE;
  205. regs_size = BTC_IO_MC_REGS_SIZE;
  206. break;
  207. case CHIP_CAYMAN:
  208. io_mc_regs = (u32 *)&cayman_io_mc_regs;
  209. ucode_size = CAYMAN_MC_UCODE_SIZE;
  210. regs_size = BTC_IO_MC_REGS_SIZE;
  211. break;
  212. }
  213. mem_type = (RREG32(MC_SEQ_MISC0) & MC_SEQ_MISC0_GDDR5_MASK) >> MC_SEQ_MISC0_GDDR5_SHIFT;
  214. running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
  215. if ((mem_type == MC_SEQ_MISC0_GDDR5_VALUE) && (running == 0)) {
  216. if (running) {
  217. blackout = RREG32(MC_SHARED_BLACKOUT_CNTL);
  218. WREG32(MC_SHARED_BLACKOUT_CNTL, 1);
  219. }
  220. /* reset the engine and set to writable */
  221. WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
  222. WREG32(MC_SEQ_SUP_CNTL, 0x00000010);
  223. /* load mc io regs */
  224. for (i = 0; i < regs_size; i++) {
  225. WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]);
  226. WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
  227. }
  228. /* load the MC ucode */
  229. fw_data = (const __be32 *)rdev->mc_fw->data;
  230. for (i = 0; i < ucode_size; i++)
  231. WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
  232. /* put the engine back into the active state */
  233. WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
  234. WREG32(MC_SEQ_SUP_CNTL, 0x00000004);
  235. WREG32(MC_SEQ_SUP_CNTL, 0x00000001);
  236. /* wait for training to complete */
  237. while (!(RREG32(MC_IO_PAD_CNTL_D0) & MEM_FALL_OUT_CMD))
  238. udelay(10);
  239. if (running)
  240. WREG32(MC_SHARED_BLACKOUT_CNTL, blackout);
  241. }
  242. return 0;
  243. }
  244. int ni_init_microcode(struct radeon_device *rdev)
  245. {
  246. struct platform_device *pdev;
  247. const char *chip_name;
  248. const char *rlc_chip_name;
  249. size_t pfp_req_size, me_req_size, rlc_req_size, mc_req_size;
  250. char fw_name[30];
  251. int err;
  252. DRM_DEBUG("\n");
  253. pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0);
  254. err = IS_ERR(pdev);
  255. if (err) {
  256. printk(KERN_ERR "radeon_cp: Failed to register firmware\n");
  257. return -EINVAL;
  258. }
  259. switch (rdev->family) {
  260. case CHIP_BARTS:
  261. chip_name = "BARTS";
  262. rlc_chip_name = "BTC";
  263. pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
  264. me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
  265. rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
  266. mc_req_size = BTC_MC_UCODE_SIZE * 4;
  267. break;
  268. case CHIP_TURKS:
  269. chip_name = "TURKS";
  270. rlc_chip_name = "BTC";
  271. pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
  272. me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
  273. rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
  274. mc_req_size = BTC_MC_UCODE_SIZE * 4;
  275. break;
  276. case CHIP_CAICOS:
  277. chip_name = "CAICOS";
  278. rlc_chip_name = "BTC";
  279. pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
  280. me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
  281. rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
  282. mc_req_size = BTC_MC_UCODE_SIZE * 4;
  283. break;
  284. case CHIP_CAYMAN:
  285. chip_name = "CAYMAN";
  286. rlc_chip_name = "CAYMAN";
  287. pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4;
  288. me_req_size = CAYMAN_PM4_UCODE_SIZE * 4;
  289. rlc_req_size = CAYMAN_RLC_UCODE_SIZE * 4;
  290. mc_req_size = CAYMAN_MC_UCODE_SIZE * 4;
  291. break;
  292. default: BUG();
  293. }
  294. DRM_INFO("Loading %s Microcode\n", chip_name);
  295. snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
  296. err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev);
  297. if (err)
  298. goto out;
  299. if (rdev->pfp_fw->size != pfp_req_size) {
  300. printk(KERN_ERR
  301. "ni_cp: Bogus length %zu in firmware \"%s\"\n",
  302. rdev->pfp_fw->size, fw_name);
  303. err = -EINVAL;
  304. goto out;
  305. }
  306. snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
  307. err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev);
  308. if (err)
  309. goto out;
  310. if (rdev->me_fw->size != me_req_size) {
  311. printk(KERN_ERR
  312. "ni_cp: Bogus length %zu in firmware \"%s\"\n",
  313. rdev->me_fw->size, fw_name);
  314. err = -EINVAL;
  315. }
  316. snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name);
  317. err = request_firmware(&rdev->rlc_fw, fw_name, &pdev->dev);
  318. if (err)
  319. goto out;
  320. if (rdev->rlc_fw->size != rlc_req_size) {
  321. printk(KERN_ERR
  322. "ni_rlc: Bogus length %zu in firmware \"%s\"\n",
  323. rdev->rlc_fw->size, fw_name);
  324. err = -EINVAL;
  325. }
  326. snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
  327. err = request_firmware(&rdev->mc_fw, fw_name, &pdev->dev);
  328. if (err)
  329. goto out;
  330. if (rdev->mc_fw->size != mc_req_size) {
  331. printk(KERN_ERR
  332. "ni_mc: Bogus length %zu in firmware \"%s\"\n",
  333. rdev->mc_fw->size, fw_name);
  334. err = -EINVAL;
  335. }
  336. out:
  337. platform_device_unregister(pdev);
  338. if (err) {
  339. if (err != -EINVAL)
  340. printk(KERN_ERR
  341. "ni_cp: Failed to load firmware \"%s\"\n",
  342. fw_name);
  343. release_firmware(rdev->pfp_fw);
  344. rdev->pfp_fw = NULL;
  345. release_firmware(rdev->me_fw);
  346. rdev->me_fw = NULL;
  347. release_firmware(rdev->rlc_fw);
  348. rdev->rlc_fw = NULL;
  349. release_firmware(rdev->mc_fw);
  350. rdev->mc_fw = NULL;
  351. }
  352. return err;
  353. }