mali_pp.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. /*
  2. * This confidential and proprietary software may be used only as
  3. * authorised by a licensing agreement from ARM Limited
  4. * (C) COPYRIGHT 2011-2013 ARM Limited
  5. * ALL RIGHTS RESERVED
  6. * The entire notice above must be reproduced on all authorised
  7. * copies and copies may only be made to the extent permitted
  8. * by a licensing agreement from ARM Limited.
  9. */
  10. #include "mali_pp_job.h"
  11. #include "mali_pp.h"
  12. #include "mali_hw_core.h"
  13. #include "mali_group.h"
  14. #include "regs/mali_200_regs.h"
  15. #include "mali_kernel_common.h"
  16. #include "mali_kernel_core.h"
  17. #include "mali_dma.h"
  18. #if defined(CONFIG_MALI400_PROFILING)
  19. #include "mali_osk_profiling.h"
  20. #endif
  21. /* Number of frame registers on Mali-200 */
  22. #define MALI_PP_MALI200_NUM_FRAME_REGISTERS ((0x04C/4)+1)
  23. /* Number of frame registers on Mali-300 and later */
  24. #define MALI_PP_MALI400_NUM_FRAME_REGISTERS ((0x058/4)+1)
  25. static struct mali_pp_core* mali_global_pp_cores[MALI_MAX_NUMBER_OF_PP_CORES] = { NULL };
  26. static u32 mali_global_num_pp_cores = 0;
  27. /* Interrupt handlers */
  28. static void mali_pp_irq_probe_trigger(void *data);
  29. static _mali_osk_errcode_t mali_pp_irq_probe_ack(void *data);
  30. struct mali_pp_core *mali_pp_create(const _mali_osk_resource_t *resource, struct mali_group *group, mali_bool is_virtual, u32 bcast_id)
  31. {
  32. struct mali_pp_core* core = NULL;
  33. MALI_DEBUG_PRINT(2, ("Mali PP: Creating Mali PP core: %s\n", resource->description));
  34. MALI_DEBUG_PRINT(2, ("Mali PP: Base address of PP core: 0x%x\n", resource->base));
  35. if (mali_global_num_pp_cores >= MALI_MAX_NUMBER_OF_PP_CORES) {
  36. MALI_PRINT_ERROR(("Mali PP: Too many PP core objects created\n"));
  37. return NULL;
  38. }
  39. core = _mali_osk_malloc(sizeof(struct mali_pp_core));
  40. if (NULL != core) {
  41. core->core_id = mali_global_num_pp_cores;
  42. core->bcast_id = bcast_id;
  43. if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALI200_REG_SIZEOF_REGISTER_BANK)) {
  44. _mali_osk_errcode_t ret;
  45. if (!is_virtual) {
  46. ret = mali_pp_reset(core);
  47. } else {
  48. ret = _MALI_OSK_ERR_OK;
  49. }
  50. if (_MALI_OSK_ERR_OK == ret) {
  51. ret = mali_group_add_pp_core(group, core);
  52. if (_MALI_OSK_ERR_OK == ret) {
  53. /* Setup IRQ handlers (which will do IRQ probing if needed) */
  54. MALI_DEBUG_ASSERT(!is_virtual || -1 != resource->irq);
  55. core->irq = _mali_osk_irq_init(resource->irq,
  56. mali_group_upper_half_pp,
  57. group,
  58. mali_pp_irq_probe_trigger,
  59. mali_pp_irq_probe_ack,
  60. core,
  61. resource->description);
  62. if (NULL != core->irq) {
  63. mali_global_pp_cores[mali_global_num_pp_cores] = core;
  64. mali_global_num_pp_cores++;
  65. return core;
  66. } else {
  67. MALI_PRINT_ERROR(("Mali PP: Failed to setup interrupt handlers for PP core %s\n", core->hw_core.description));
  68. }
  69. mali_group_remove_pp_core(group);
  70. } else {
  71. MALI_PRINT_ERROR(("Mali PP: Failed to add core %s to group\n", core->hw_core.description));
  72. }
  73. }
  74. mali_hw_core_delete(&core->hw_core);
  75. }
  76. _mali_osk_free(core);
  77. } else {
  78. MALI_PRINT_ERROR(("Mali PP: Failed to allocate memory for PP core\n"));
  79. }
  80. return NULL;
  81. }
  82. void mali_pp_delete(struct mali_pp_core *core)
  83. {
  84. u32 i;
  85. MALI_DEBUG_ASSERT_POINTER(core);
  86. _mali_osk_irq_term(core->irq);
  87. mali_hw_core_delete(&core->hw_core);
  88. /* Remove core from global list */
  89. for (i = 0; i < mali_global_num_pp_cores; i++) {
  90. if (mali_global_pp_cores[i] == core) {
  91. mali_global_pp_cores[i] = NULL;
  92. mali_global_num_pp_cores--;
  93. if (i != mali_global_num_pp_cores) {
  94. /* We removed a PP core from the middle of the array -- move the last
  95. * PP core to the current position to close the gap */
  96. mali_global_pp_cores[i] = mali_global_pp_cores[mali_global_num_pp_cores];
  97. mali_global_pp_cores[mali_global_num_pp_cores] = NULL;
  98. }
  99. break;
  100. }
  101. }
  102. _mali_osk_free(core);
  103. }
  104. void mali_pp_stop_bus(struct mali_pp_core *core)
  105. {
  106. MALI_DEBUG_ASSERT_POINTER(core);
  107. /* Will only send the stop bus command, and not wait for it to complete */
  108. mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_STOP_BUS);
  109. }
  110. _mali_osk_errcode_t mali_pp_stop_bus_wait(struct mali_pp_core *core)
  111. {
  112. int i;
  113. MALI_DEBUG_ASSERT_POINTER(core);
  114. /* Send the stop bus command. */
  115. mali_pp_stop_bus(core);
  116. /* Wait for bus to be stopped */
  117. for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++) {
  118. if (mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS) & MALI200_REG_VAL_STATUS_BUS_STOPPED)
  119. break;
  120. }
  121. if (MALI_REG_POLL_COUNT_FAST == i) {
  122. MALI_PRINT_ERROR(("Mali PP: Failed to stop bus on %s. Status: 0x%08x\n", core->hw_core.description, mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS)));
  123. return _MALI_OSK_ERR_FAULT;
  124. }
  125. return _MALI_OSK_ERR_OK;
  126. }
  127. /* Frame register reset values.
  128. * Taken from the Mali400 TRM, 3.6. Pixel processor control register summary */
  129. static const u32 mali_frame_registers_reset_values[_MALI_PP_MAX_FRAME_REGISTERS] = {
  130. 0x0, /* Renderer List Address Register */
  131. 0x0, /* Renderer State Word Base Address Register */
  132. 0x0, /* Renderer Vertex Base Register */
  133. 0x2, /* Feature Enable Register */
  134. 0x0, /* Z Clear Value Register */
  135. 0x0, /* Stencil Clear Value Register */
  136. 0x0, /* ABGR Clear Value 0 Register */
  137. 0x0, /* ABGR Clear Value 1 Register */
  138. 0x0, /* ABGR Clear Value 2 Register */
  139. 0x0, /* ABGR Clear Value 3 Register */
  140. 0x0, /* Bounding Box Left Right Register */
  141. 0x0, /* Bounding Box Bottom Register */
  142. 0x0, /* FS Stack Address Register */
  143. 0x0, /* FS Stack Size and Initial Value Register */
  144. 0x0, /* Reserved */
  145. 0x0, /* Reserved */
  146. 0x0, /* Origin Offset X Register */
  147. 0x0, /* Origin Offset Y Register */
  148. 0x75, /* Subpixel Specifier Register */
  149. 0x0, /* Tiebreak mode Register */
  150. 0x0, /* Polygon List Format Register */
  151. 0x0, /* Scaling Register */
  152. 0x0 /* Tilebuffer configuration Register */
  153. };
  154. /* WBx register reset values */
  155. static const u32 mali_wb_registers_reset_values[_MALI_PP_MAX_WB_REGISTERS] = {
  156. 0x0, /* WBx Source Select Register */
  157. 0x0, /* WBx Target Address Register */
  158. 0x0, /* WBx Target Pixel Format Register */
  159. 0x0, /* WBx Target AA Format Register */
  160. 0x0, /* WBx Target Layout */
  161. 0x0, /* WBx Target Scanline Length */
  162. 0x0, /* WBx Target Flags Register */
  163. 0x0, /* WBx MRT Enable Register */
  164. 0x0, /* WBx MRT Offset Register */
  165. 0x0, /* WBx Global Test Enable Register */
  166. 0x0, /* WBx Global Test Reference Value Register */
  167. 0x0 /* WBx Global Test Compare Function Register */
  168. };
  169. /* Performance Counter 0 Enable Register reset value */
  170. static const u32 mali_perf_cnt_enable_reset_value = 0;
  171. _mali_osk_errcode_t mali_pp_hard_reset(struct mali_pp_core *core)
  172. {
  173. /* Bus must be stopped before calling this function */
  174. const u32 reset_invalid_value = 0xC0FFE000;
  175. const u32 reset_check_value = 0xC01A0000;
  176. int i;
  177. MALI_DEBUG_ASSERT_POINTER(core);
  178. MALI_DEBUG_PRINT(2, ("Mali PP: Hard reset of core %s\n", core->hw_core.description));
  179. /* Set register to a bogus value. The register will be used to detect when reset is complete */
  180. mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, reset_invalid_value);
  181. mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_NONE);
  182. /* Force core to reset */
  183. mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_FORCE_RESET);
  184. /* Wait for reset to be complete */
  185. for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++) {
  186. mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, reset_check_value);
  187. if (reset_check_value == mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW)) {
  188. break;
  189. }
  190. }
  191. if (MALI_REG_POLL_COUNT_FAST == i) {
  192. MALI_PRINT_ERROR(("Mali PP: The hard reset loop didn't work, unable to recover\n"));
  193. }
  194. mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, 0x00000000); /* set it back to the default */
  195. /* Re-enable interrupts */
  196. mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL);
  197. mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
  198. return _MALI_OSK_ERR_OK;
  199. }
  200. void mali_pp_reset_async(struct mali_pp_core *core)
  201. {
  202. MALI_DEBUG_ASSERT_POINTER(core);
  203. MALI_DEBUG_PRINT(4, ("Mali PP: Reset of core %s\n", core->hw_core.description));
  204. mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, 0); /* disable the IRQs */
  205. mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT, MALI200_REG_VAL_IRQ_MASK_ALL);
  206. mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI400PP_REG_VAL_CTRL_MGMT_SOFT_RESET);
  207. }
  208. _mali_osk_errcode_t mali_pp_reset_wait(struct mali_pp_core *core)
  209. {
  210. int i;
  211. u32 rawstat = 0;
  212. for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++) {
  213. if (!(mali_pp_read_status(core) & MALI200_REG_VAL_STATUS_RENDERING_ACTIVE)) {
  214. rawstat = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT);
  215. if (rawstat == MALI400PP_REG_VAL_IRQ_RESET_COMPLETED) {
  216. break;
  217. }
  218. }
  219. }
  220. if (i == MALI_REG_POLL_COUNT_FAST) {
  221. MALI_PRINT_ERROR(("Mali PP: Failed to reset core %s, rawstat: 0x%08x\n",
  222. core->hw_core.description, rawstat));
  223. return _MALI_OSK_ERR_FAULT;
  224. }
  225. /* Re-enable interrupts */
  226. mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL);
  227. mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
  228. return _MALI_OSK_ERR_OK;
  229. }
  230. _mali_osk_errcode_t mali_pp_reset(struct mali_pp_core *core)
  231. {
  232. mali_pp_reset_async(core);
  233. return mali_pp_reset_wait(core);
  234. }
  235. void mali_pp_job_dma_cmd_prepare(struct mali_pp_core *core, struct mali_pp_job *job, u32 sub_job,
  236. mali_bool restart_virtual, mali_dma_cmd_buf *buf)
  237. {
  238. u32 relative_address;
  239. u32 start_index;
  240. u32 nr_of_regs;
  241. u32 *frame_registers = mali_pp_job_get_frame_registers(job);
  242. u32 *wb0_registers = mali_pp_job_get_wb0_registers(job);
  243. u32 *wb1_registers = mali_pp_job_get_wb1_registers(job);
  244. u32 *wb2_registers = mali_pp_job_get_wb2_registers(job);
  245. u32 counter_src0 = mali_pp_job_get_perf_counter_src0(job, sub_job);
  246. u32 counter_src1 = mali_pp_job_get_perf_counter_src1(job, sub_job);
  247. MALI_DEBUG_ASSERT_POINTER(core);
  248. /* Write frame registers */
  249. /*
  250. * There are two frame registers which are different for each sub job:
  251. * 1. The Renderer List Address Register (MALI200_REG_ADDR_FRAME)
  252. * 2. The FS Stack Address Register (MALI200_REG_ADDR_STACK)
  253. */
  254. mali_dma_write_conditional(buf, &core->hw_core, MALI200_REG_ADDR_FRAME, mali_pp_job_get_addr_frame(job, sub_job), mali_frame_registers_reset_values[MALI200_REG_ADDR_FRAME / sizeof(u32)]);
  255. /* For virtual jobs, the stack address shouldn't be broadcast but written individually */
  256. if (!mali_pp_job_is_virtual(job) || restart_virtual) {
  257. mali_dma_write_conditional(buf, &core->hw_core, MALI200_REG_ADDR_STACK, mali_pp_job_get_addr_stack(job, sub_job), mali_frame_registers_reset_values[MALI200_REG_ADDR_STACK / sizeof(u32)]);
  258. }
  259. /* Write registers between MALI200_REG_ADDR_FRAME and MALI200_REG_ADDR_STACK */
  260. relative_address = MALI200_REG_ADDR_RSW;
  261. start_index = MALI200_REG_ADDR_RSW / sizeof(u32);
  262. nr_of_regs = (MALI200_REG_ADDR_STACK - MALI200_REG_ADDR_RSW) / sizeof(u32);
  263. mali_dma_write_array_conditional(buf, &core->hw_core,
  264. relative_address, &frame_registers[start_index],
  265. nr_of_regs, &mali_frame_registers_reset_values[start_index]);
  266. /* MALI200_REG_ADDR_STACK_SIZE */
  267. relative_address = MALI200_REG_ADDR_STACK_SIZE;
  268. start_index = MALI200_REG_ADDR_STACK_SIZE / sizeof(u32);
  269. mali_dma_write_conditional(buf, &core->hw_core,
  270. relative_address, frame_registers[start_index],
  271. mali_frame_registers_reset_values[start_index]);
  272. /* Skip 2 reserved registers */
  273. /* Write remaining registers */
  274. relative_address = MALI200_REG_ADDR_ORIGIN_OFFSET_X;
  275. start_index = MALI200_REG_ADDR_ORIGIN_OFFSET_X / sizeof(u32);
  276. nr_of_regs = MALI_PP_MALI400_NUM_FRAME_REGISTERS - MALI200_REG_ADDR_ORIGIN_OFFSET_X / sizeof(u32);
  277. mali_dma_write_array_conditional(buf, &core->hw_core,
  278. relative_address, &frame_registers[start_index],
  279. nr_of_regs, &mali_frame_registers_reset_values[start_index]);
  280. /* Write WBx registers */
  281. if (wb0_registers[0]) { /* M200_WB0_REG_SOURCE_SELECT register */
  282. mali_dma_write_array_conditional(buf, &core->hw_core, MALI200_REG_ADDR_WB0, wb0_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values);
  283. }
  284. if (wb1_registers[0]) { /* M200_WB1_REG_SOURCE_SELECT register */
  285. mali_dma_write_array_conditional(buf, &core->hw_core, MALI200_REG_ADDR_WB1, wb1_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values);
  286. }
  287. if (wb2_registers[0]) { /* M200_WB2_REG_SOURCE_SELECT register */
  288. mali_dma_write_array_conditional(buf, &core->hw_core, MALI200_REG_ADDR_WB2, wb2_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values);
  289. }
  290. if (MALI_HW_CORE_NO_COUNTER != counter_src0) {
  291. mali_dma_write(buf, &core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC, counter_src0);
  292. mali_dma_write_conditional(buf, &core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE, mali_perf_cnt_enable_reset_value);
  293. }
  294. if (MALI_HW_CORE_NO_COUNTER != counter_src1) {
  295. mali_dma_write(buf, &core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC, counter_src1);
  296. mali_dma_write_conditional(buf, &core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE, mali_perf_cnt_enable_reset_value);
  297. }
  298. /* This is the command that starts the core. */
  299. mali_dma_write(buf, &core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_START_RENDERING);
  300. }
  301. void mali_pp_job_start(struct mali_pp_core *core, struct mali_pp_job *job, u32 sub_job, mali_bool restart_virtual)
  302. {
  303. u32 relative_address;
  304. u32 start_index;
  305. u32 nr_of_regs;
  306. u32 *frame_registers = mali_pp_job_get_frame_registers(job);
  307. u32 *wb0_registers = mali_pp_job_get_wb0_registers(job);
  308. u32 *wb1_registers = mali_pp_job_get_wb1_registers(job);
  309. u32 *wb2_registers = mali_pp_job_get_wb2_registers(job);
  310. u32 counter_src0 = mali_pp_job_get_perf_counter_src0(job, sub_job);
  311. u32 counter_src1 = mali_pp_job_get_perf_counter_src1(job, sub_job);
  312. MALI_DEBUG_ASSERT_POINTER(core);
  313. /* Write frame registers */
  314. /*
  315. * There are two frame registers which are different for each sub job:
  316. * 1. The Renderer List Address Register (MALI200_REG_ADDR_FRAME)
  317. * 2. The FS Stack Address Register (MALI200_REG_ADDR_STACK)
  318. */
  319. mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_FRAME, mali_pp_job_get_addr_frame(job, sub_job), mali_frame_registers_reset_values[MALI200_REG_ADDR_FRAME / sizeof(u32)]);
  320. /* For virtual jobs, the stack address shouldn't be broadcast but written individually */
  321. if (!mali_pp_job_is_virtual(job) || restart_virtual) {
  322. mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_STACK, mali_pp_job_get_addr_stack(job, sub_job), mali_frame_registers_reset_values[MALI200_REG_ADDR_STACK / sizeof(u32)]);
  323. }
  324. /* Write registers between MALI200_REG_ADDR_FRAME and MALI200_REG_ADDR_STACK */
  325. relative_address = MALI200_REG_ADDR_RSW;
  326. start_index = MALI200_REG_ADDR_RSW / sizeof(u32);
  327. nr_of_regs = (MALI200_REG_ADDR_STACK - MALI200_REG_ADDR_RSW) / sizeof(u32);
  328. mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core,
  329. relative_address, &frame_registers[start_index],
  330. nr_of_regs, &mali_frame_registers_reset_values[start_index]);
  331. /* MALI200_REG_ADDR_STACK_SIZE */
  332. relative_address = MALI200_REG_ADDR_STACK_SIZE;
  333. start_index = MALI200_REG_ADDR_STACK_SIZE / sizeof(u32);
  334. mali_hw_core_register_write_relaxed_conditional(&core->hw_core,
  335. relative_address, frame_registers[start_index],
  336. mali_frame_registers_reset_values[start_index]);
  337. /* Skip 2 reserved registers */
  338. /* Write remaining registers */
  339. relative_address = MALI200_REG_ADDR_ORIGIN_OFFSET_X;
  340. start_index = MALI200_REG_ADDR_ORIGIN_OFFSET_X / sizeof(u32);
  341. nr_of_regs = MALI_PP_MALI400_NUM_FRAME_REGISTERS - MALI200_REG_ADDR_ORIGIN_OFFSET_X / sizeof(u32);
  342. mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core,
  343. relative_address, &frame_registers[start_index],
  344. nr_of_regs, &mali_frame_registers_reset_values[start_index]);
  345. /* Write WBx registers */
  346. if (wb0_registers[0]) { /* M200_WB0_REG_SOURCE_SELECT register */
  347. mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB0, wb0_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values);
  348. }
  349. if (wb1_registers[0]) { /* M200_WB1_REG_SOURCE_SELECT register */
  350. mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB1, wb1_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values);
  351. }
  352. if (wb2_registers[0]) { /* M200_WB2_REG_SOURCE_SELECT register */
  353. mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB2, wb2_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values);
  354. }
  355. if (MALI_HW_CORE_NO_COUNTER != counter_src0) {
  356. mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC, counter_src0);
  357. mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE, mali_perf_cnt_enable_reset_value);
  358. }
  359. if (MALI_HW_CORE_NO_COUNTER != counter_src1) {
  360. mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC, counter_src1);
  361. mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE, mali_perf_cnt_enable_reset_value);
  362. }
  363. #ifdef CONFIG_MALI400_HEATMAPS_ENABLED
  364. if(job->uargs.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_HEATMAP_ENABLE) {
  365. mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_PERFMON_CONTR, ((job->uargs.tilesx & 0x3FF) << 16) | 1);
  366. mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_PERFMON_BASE, job->uargs.heatmap_mem & 0xFFFFFFF8);
  367. }
  368. #endif /* CONFIG_MALI400_HEATMAPS_ENABLED */
  369. MALI_DEBUG_PRINT(3, ("Mali PP: Starting job 0x%08X part %u/%u on PP core %s\n", job, sub_job + 1, mali_pp_job_get_sub_job_count(job), core->hw_core.description));
  370. /* Adding barrier to make sure all rester writes are finished */
  371. _mali_osk_write_mem_barrier();
  372. /* This is the command that starts the core. */
  373. mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_START_RENDERING);
  374. /* Adding barrier to make sure previous rester writes is finished */
  375. _mali_osk_write_mem_barrier();
  376. }
  377. u32 mali_pp_core_get_version(struct mali_pp_core *core)
  378. {
  379. MALI_DEBUG_ASSERT_POINTER(core);
  380. return mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_VERSION);
  381. }
  382. struct mali_pp_core* mali_pp_get_global_pp_core(u32 index)
  383. {
  384. if (mali_global_num_pp_cores > index) {
  385. return mali_global_pp_cores[index];
  386. }
  387. return NULL;
  388. }
  389. u32 mali_pp_get_glob_num_pp_cores(void)
  390. {
  391. return mali_global_num_pp_cores;
  392. }
  393. /* ------------- interrupt handling below ------------------ */
  394. static void mali_pp_irq_probe_trigger(void *data)
  395. {
  396. struct mali_pp_core *core = (struct mali_pp_core *)data;
  397. mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
  398. mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT, MALI200_REG_VAL_IRQ_FORCE_HANG);
  399. _mali_osk_mem_barrier();
  400. }
  401. static _mali_osk_errcode_t mali_pp_irq_probe_ack(void *data)
  402. {
  403. struct mali_pp_core *core = (struct mali_pp_core *)data;
  404. u32 irq_readout;
  405. irq_readout = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_STATUS);
  406. if (MALI200_REG_VAL_IRQ_FORCE_HANG & irq_readout) {
  407. mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_FORCE_HANG);
  408. _mali_osk_mem_barrier();
  409. return _MALI_OSK_ERR_OK;
  410. }
  411. return _MALI_OSK_ERR_FAULT;
  412. }
  413. #if 0
  414. static void mali_pp_print_registers(struct mali_pp_core *core)
  415. {
  416. MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_VERSION = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_VERSION)));
  417. MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_CURRENT_REND_LIST_ADDR = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_CURRENT_REND_LIST_ADDR)));
  418. MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS)));
  419. MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_RAWSTAT = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT)));
  420. MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_MASK = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK)));
  421. MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_STATUS)));
  422. MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_BUS_ERROR_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_BUS_ERROR_STATUS)));
  423. MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE)));
  424. MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC)));
  425. MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE)));
  426. MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE)));
  427. MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC)));
  428. MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE)));
  429. }
  430. #endif
  431. #if 0
  432. void mali_pp_print_state(struct mali_pp_core *core)
  433. {
  434. MALI_DEBUG_PRINT(2, ("Mali PP: State: 0x%08x\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS) ));
  435. }
  436. #endif
  437. void mali_pp_update_performance_counters(struct mali_pp_core *parent, struct mali_pp_core *child, struct mali_pp_job *job, u32 subjob)
  438. {
  439. u32 val0 = 0;
  440. u32 val1 = 0;
  441. u32 counter_src0 = mali_pp_job_get_perf_counter_src0(job, subjob);
  442. u32 counter_src1 = mali_pp_job_get_perf_counter_src1(job, subjob);
  443. #if defined(CONFIG_MALI400_PROFILING)
  444. int counter_index = COUNTER_FP_0_C0 + (2 * child->core_id);
  445. #endif
  446. if (MALI_HW_CORE_NO_COUNTER != counter_src0) {
  447. val0 = mali_hw_core_register_read(&child->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE);
  448. mali_pp_job_set_perf_counter_value0(job, subjob, val0);
  449. #if defined(CONFIG_MALI400_PROFILING)
  450. _mali_osk_profiling_report_hw_counter(counter_index, val0);
  451. #endif
  452. }
  453. if (MALI_HW_CORE_NO_COUNTER != counter_src1) {
  454. val1 = mali_hw_core_register_read(&child->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE);
  455. mali_pp_job_set_perf_counter_value1(job, subjob, val1);
  456. #if defined(CONFIG_MALI400_PROFILING)
  457. _mali_osk_profiling_report_hw_counter(counter_index + 1, val1);
  458. #endif
  459. }
  460. }
  461. #if MALI_STATE_TRACKING
  462. u32 mali_pp_dump_state(struct mali_pp_core *core, char *buf, u32 size)
  463. {
  464. int n = 0;
  465. n += _mali_osk_snprintf(buf + n, size - n, "\tPP #%d: %s\n", core->core_id, core->hw_core.description);
  466. return n;
  467. }
  468. #endif