vg_lite_kernel.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020
  1. /****************************************************************************
  2. *
  3. * The MIT License (MIT)
  4. *
  5. * Copyright (c) 2014 - 2020 Vivante Corporation
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a
  8. * copy of this software and associated documentation files (the "Software"),
  9. * to deal in the Software without restriction, including without limitation
  10. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11. * and/or sell copies of the Software, and to permit persons to whom the
  12. * Software is furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  23. * DEALINGS IN THE SOFTWARE.
  24. *
  25. *****************************************************************************/
  26. #include "vg_lite_platform.h"
  27. #include "vg_lite_kernel.h"
  28. #include "vg_lite_hal.h"
  29. #include "vg_lite_hw.h"
  30. #if defined(__linux__) && !EMULATOR
  31. #include <asm/uaccess.h>
  32. #include <linux/version.h>
  33. #endif
  34. static int s_reference = 0;
  35. #if !defined(VG_DRIVER_SINGLE_THREAD)
  36. static int task_num = 0;
  37. static vg_lite_kernel_initialize_t ts_initialize = {0};
  38. static uint8_t ts_init = 0;
  39. #endif /* not defined(VG_DRIVER_SINGLE_THREAD) */
  40. #if defined(VG_DRIVER_SINGLE_THREAD)
  41. #define VG_LITE_OS_LOCK() VG_LITE_SUCCESS
  42. #define VG_LITE_OS_UNLOCK()
  43. #else
  44. #define VG_LITE_OS_LOCK() vg_lite_os_lock()
  45. #define VG_LITE_OS_UNLOCK() vg_lite_os_unlock()
  46. #endif /* VG_DRIVER_SINGLE_THREAD */
  47. static vg_lite_error_t do_terminate(vg_lite_kernel_terminate_t * data);
  48. static void soft_reset(void);
  49. static void gpu(int enable)
  50. {
  51. vg_lite_hw_clock_control_t value;
  52. uint32_t reset_timer = 2;
  53. #ifdef VG_GPU_AUTO_CLOCK_GATING
  54. uint32_t temp;
  55. #endif /* VG_GPU_AUTO_CLOCK_GATING */
  56. const uint32_t reset_timer_limit = 1000;
  57. if (enable) {
  58. /* Disable clock gating. */
  59. value.data = vg_lite_hal_peek(VG_LITE_HW_CLOCK_CONTROL);
  60. value.control.clock_gate = 0;
  61. vg_lite_hal_poke(VG_LITE_HW_CLOCK_CONTROL, value.data);
  62. vg_lite_hal_delay(1);
  63. /* Set clock speed. */
  64. value.control.scale = 64;
  65. value.control.scale_load = 1;
  66. vg_lite_hal_poke(VG_LITE_HW_CLOCK_CONTROL, value.data);
  67. vg_lite_hal_delay(1);
  68. value.control.scale_load = 0;
  69. vg_lite_hal_poke(VG_LITE_HW_CLOCK_CONTROL, value.data);
  70. vg_lite_hal_delay(5);
  71. do {
  72. /* Perform a soft reset. */
  73. soft_reset();
  74. vg_lite_hal_delay(reset_timer);
  75. reset_timer *= 2; // If reset failed, try again with a longer wait. Need to check why if dead lopp happens here.
  76. } while (!VG_LITE_KERNEL_IS_GPU_IDLE());
  77. #ifdef VG_GPU_AUTO_CLOCK_GATING
  78. temp = vg_lite_hal_peek(VG_LITE_HW_POWER_CONTROL);
  79. temp |= 0x1;
  80. vg_lite_hal_poke(VG_LITE_HW_POWER_CONTROL, temp);
  81. vg_lite_hal_delay(1);
  82. #endif /* VG_GPU_AUTO_CLOCK_GATING */
  83. }
  84. else
  85. {
  86. while (!VG_LITE_KERNEL_IS_GPU_IDLE() &&
  87. (reset_timer < reset_timer_limit) // Force shutdown if timeout.
  88. ) {
  89. vg_lite_hal_delay(reset_timer);
  90. reset_timer *= 2;
  91. }
  92. /* Set idle speed. */
  93. value.data = vg_lite_hal_peek(VG_LITE_HW_CLOCK_CONTROL);
  94. value.control.scale = 1;
  95. value.control.scale_load = 1;
  96. vg_lite_hal_poke(VG_LITE_HW_CLOCK_CONTROL, value.data);
  97. vg_lite_hal_delay(1);
  98. value.control.scale_load = 0;
  99. vg_lite_hal_poke(VG_LITE_HW_CLOCK_CONTROL, value.data);
  100. vg_lite_hal_delay(5);
  101. /* Enable clock gating. */
  102. value.control.clock_gate = 1;
  103. vg_lite_hal_poke(VG_LITE_HW_CLOCK_CONTROL, value.data);
  104. vg_lite_hal_delay(1);
  105. }
  106. }
  107. /* Initialize some customized modeuls [DDRLess]. */
  108. static vg_lite_error_t init_3rd(vg_lite_kernel_initialize_t * data)
  109. {
  110. vg_lite_error_t error = VG_LITE_SUCCESS;
  111. /* TODO: Init the YUV<->RGB converters. Reserved for SOC. */
  112. /* vg_lite_hal_poke(0x00514, data->yuv_pre);
  113. vg_lite_hal_poke(0x00518, data->yuv_post); */
  114. return error;
  115. }
  116. #if defined(VG_DRIVER_SINGLE_THREAD)
  117. static vg_lite_error_t init_vglite(vg_lite_kernel_initialize_t * data)
  118. {
  119. vg_lite_error_t error = VG_LITE_SUCCESS;
  120. vg_lite_kernel_context_t * context;
  121. uint32_t id;
  122. int i;
  123. uint32_t chip_id = 0;
  124. #if defined(__linux__) && !EMULATOR
  125. vg_lite_kernel_context_t __user * context_usr;
  126. vg_lite_kernel_context_t mycontext = { 0 };
  127. // Construct the context.
  128. context_usr = (vg_lite_kernel_context_t __user *) data->context;
  129. #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)
  130. if (!access_ok(VERIFY_READ, context_usr, sizeof(*context_usr)) ||
  131. !access_ok(VERIFY_WRITE, context_usr, sizeof(*context_usr))) {
  132. #else
  133. if (!access_ok(context_usr, sizeof(*context_usr)) ||
  134. !access_ok(context_usr, sizeof(*context_usr))) {
  135. #endif
  136. /* Out of memory. */
  137. return VG_LITE_OUT_OF_MEMORY;
  138. }
  139. context = &mycontext;
  140. #else
  141. // Construct the context.
  142. context = data->context;
  143. if (context == NULL)
  144. {
  145. /* Out of memory. */
  146. return VG_LITE_OUT_OF_MEMORY;
  147. }
  148. #endif
  149. /* Zero out all pointers. */
  150. for (i = 0; i < CMDBUF_COUNT; i++){
  151. context->command_buffer[i] = NULL;
  152. context->command_buffer_logical[i] = NULL;
  153. context->command_buffer_physical[i] = 0;
  154. }
  155. context->tessellation_buffer = NULL;
  156. context->tessellation_buffer_logical = NULL;
  157. context->tessellation_buffer_physical = 0;
  158. /* Increment reference counter. */
  159. if (s_reference++ == 0) {
  160. /* Initialize the SOC. */
  161. vg_lite_hal_initialize();
  162. /* Enable the GPU. */
  163. gpu(1);
  164. }
  165. /* Fill in hardware capabilities. */
  166. data->capabilities.data = 0;
  167. id = vg_lite_hal_peek(VG_LITE_HW_CHIP_ID);
  168. if (id >= 0x300) {
  169. data->capabilities.cap.l2_cache = 1;
  170. }
  171. /* Allocate the command buffer. */
  172. if (data->command_buffer_size) {
  173. int32_t i;
  174. for (i = 0; i < 2; i ++)
  175. {
  176. /* Allocate the memory. */
  177. error = vg_lite_hal_allocate_contiguous(data->command_buffer_size,
  178. &context->command_buffer_logical[i],
  179. &context->command_buffer_physical[i],
  180. &context->command_buffer[i]);
  181. if (error != VG_LITE_SUCCESS) {
  182. /* Free any allocated memory. */
  183. vg_lite_kernel_terminate_t terminate = { context };
  184. do_terminate(&terminate);
  185. /* Out of memory. */
  186. return error;
  187. }
  188. /* Return command buffer logical pointer and GPU address. */
  189. data->command_buffer[i] = context->command_buffer_logical[i];
  190. data->command_buffer_gpu[i] = context->command_buffer_physical[i];
  191. }
  192. }
  193. /* Allocate the tessellation buffer. */
  194. if ((data->tessellation_width > 0) && (data->tessellation_height > 0))
  195. {
  196. int width = data->tessellation_width;
  197. int height = 0;
  198. unsigned long stride, buffer_size, l1_size, l2_size;
  199. height = VG_LITE_ALIGN(data->tessellation_height, 16);
  200. chip_id = vg_lite_hal_peek(0x20);
  201. if(chip_id == GPU_CHIP_ID_GC355)
  202. width = VG_LITE_ALIGN(width, 128);
  203. /* Check if we can used tiled tessellation (128x16). */
  204. if (((width & 127) == 0) && ((height & 15) == 0)) {
  205. data->capabilities.cap.tiled = 0x3;
  206. } else {
  207. data->capabilities.cap.tiled = 0x2;
  208. }
  209. /* Compute tessellation buffer size. */
  210. stride = VG_LITE_ALIGN(width * 8, 64);
  211. buffer_size = VG_LITE_ALIGN(stride * height, 64);
  212. /* Each bit in the L1 cache represents 64 bytes of tessellation data. */
  213. l1_size = VG_LITE_ALIGN(VG_LITE_ALIGN(buffer_size / 64, 64) / 8, 64);
  214. /* Each bit in the L2 cache represents 32 bytes of L1 data. */
  215. l2_size = data->capabilities.cap.l2_cache ? VG_LITE_ALIGN(VG_LITE_ALIGN(l1_size / 32, 64) / 8, 64) : 0;
  216. /* Allocate the memory. */
  217. error = vg_lite_hal_allocate_contiguous(buffer_size + l1_size + l2_size,
  218. &context->tessellation_buffer_logical,
  219. &context->tessellation_buffer_physical,
  220. &context->tessellation_buffer);
  221. if (error != VG_LITE_SUCCESS) {
  222. /* Free any allocated memory. */
  223. vg_lite_kernel_terminate_t terminate = { context };
  224. do_terminate(&terminate);
  225. /* Out of memory. */
  226. return error;
  227. }
  228. /* Return the tessellation buffer pointers and GPU addresses. */
  229. data->tessellation_buffer_gpu[0] = context->tessellation_buffer_physical;
  230. data->tessellation_buffer_gpu[1] = context->tessellation_buffer_physical + buffer_size;
  231. data->tessellation_buffer_gpu[2] = (l2_size ? data->tessellation_buffer_gpu[1] + l1_size
  232. : data->tessellation_buffer_gpu[1]);
  233. data->tessellation_buffer_logic[0] = (uint8_t *)context->tessellation_buffer_logical;
  234. data->tessellation_buffer_logic[1] = data->tessellation_buffer_logic[0] + buffer_size;
  235. data->tessellation_buffer_logic[2] = (l2_size ? data->tessellation_buffer_logic[1] + l1_size
  236. : data->tessellation_buffer_logic[1]);
  237. data->tessellation_buffer_size[0] = buffer_size;
  238. data->tessellation_buffer_size[1] = l1_size;
  239. data->tessellation_buffer_size[2] = l2_size;
  240. data->tessellation_stride = stride;
  241. data->tessellation_width_height = width | (height << 16);
  242. data->tessellation_shift = 0;
  243. }
  244. /* Enable all interrupts. */
  245. vg_lite_hal_poke(VG_LITE_INTR_ENABLE, 0xFFFFFFFF);
  246. #if defined(__linux__) && !EMULATOR
  247. if (copy_to_user(context_usr, context, sizeof(vg_lite_kernel_context_t)) != 0) {
  248. // Free any allocated memory.
  249. vg_lite_kernel_terminate_t terminate = { context };
  250. do_terminate(&terminate);
  251. return VG_LITE_NO_CONTEXT;
  252. }
  253. #endif
  254. return error;
  255. }
  256. #else
  257. static vg_lite_error_t init_vglite(vg_lite_kernel_initialize_t * data)
  258. {
  259. vg_lite_error_t error = VG_LITE_SUCCESS;
  260. vg_lite_kernel_context_t * context;
  261. uint32_t id;
  262. int i;
  263. uint32_t chip_id = 0;
  264. uint32_t semaphore_id = 0;
  265. #if defined(__linux__) && !EMULATOR
  266. vg_lite_kernel_context_t __user * context_usr;
  267. vg_lite_kernel_context_t mycontext = { 0 };
  268. // Construct the context.
  269. context_usr = (vg_lite_kernel_context_t __user *) data->context;
  270. #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)
  271. if (!access_ok(VERIFY_READ, context_usr, sizeof(*context_usr)) ||
  272. !access_ok(VERIFY_WRITE, context_usr, sizeof(*context_usr))) {
  273. #else
  274. if (!access_ok(context_usr, sizeof(*context_usr)) ||
  275. !access_ok(context_usr, sizeof(*context_usr))) {
  276. #endif
  277. /* Out of memory. */
  278. return VG_LITE_OUT_OF_MEMORY;
  279. }
  280. context = &mycontext;
  281. #else
  282. // Construct the context.
  283. context = data->context;
  284. if (context == NULL)
  285. {
  286. /* Out of memory. */
  287. return VG_LITE_OUT_OF_MEMORY;
  288. }
  289. #endif
  290. /* Zero out all pointers. */
  291. for (i = 0; i < CMDBUF_COUNT; i++){
  292. context->command_buffer[i] = NULL;
  293. context->command_buffer_logical[i] = NULL;
  294. context->command_buffer_physical[i] = 0;
  295. }
  296. context->tessellation_buffer = NULL;
  297. context->tessellation_buffer_logical = NULL;
  298. context->tessellation_buffer_physical = 0;
  299. /* Increment reference counter. */
  300. if (s_reference++ == 0) {
  301. /* Initialize the SOC. */
  302. error = vg_lite_hal_initialize();
  303. if(error != VG_LITE_SUCCESS)
  304. {
  305. s_reference--;
  306. vg_lite_hal_free_os_heap();
  307. vg_lite_hal_deinitialize();
  308. return error;
  309. }
  310. /* Enable the GPU. */
  311. gpu(1);
  312. }
  313. else
  314. {
  315. while(!task_num)
  316. {
  317. vg_lite_hal_delay(5);
  318. }
  319. }
  320. if((error = (vg_lite_error_t)VG_LITE_OS_LOCK()) == VG_LITE_SUCCESS){
  321. ++task_num;
  322. for(semaphore_id = 0; semaphore_id < THREAD_LENGTH ; semaphore_id++)
  323. {
  324. if (vg_lite_os_init_event(&context->async_event[0],
  325. semaphore_id,
  326. VG_LITE_IDLE) == VG_LITE_SUCCESS)
  327. {
  328. for (i = 1; i < CMDBUF_COUNT; i++)
  329. vg_lite_os_config_event(&context->async_event[i],
  330. semaphore_id,
  331. VG_LITE_IDLE);
  332. break;
  333. }
  334. }
  335. VG_LITE_OS_UNLOCK();
  336. }
  337. else
  338. return error;
  339. if(semaphore_id == THREAD_LENGTH)
  340. return VG_LITE_MULTI_THREAD_FAIL;
  341. /* Fill in hardware capabilities. */
  342. data->capabilities.data = 0;
  343. id = vg_lite_hal_peek(VG_LITE_HW_CHIP_ID);
  344. if (id >= 0x300) {
  345. data->capabilities.cap.l2_cache = 1;
  346. }
  347. /* Allocate the command buffer. */
  348. if (data->command_buffer_size) {
  349. int32_t i;
  350. for (i = 0; i < CMDBUF_COUNT; i ++)
  351. {
  352. /* Allocate the memory. */
  353. VG_LITE_OS_LOCK();
  354. error = vg_lite_hal_allocate_contiguous(data->command_buffer_size,
  355. &context->command_buffer_logical[i],
  356. &context->command_buffer_physical[i],
  357. &context->command_buffer[i]);
  358. VG_LITE_OS_UNLOCK();
  359. if (error != VG_LITE_SUCCESS) {
  360. /* Free any allocated memory. */
  361. vg_lite_kernel_terminate_t terminate = { context };
  362. do_terminate(&terminate);
  363. /* Out of memory. */
  364. return error;
  365. }
  366. /* Return command buffer logical pointer and GPU address. */
  367. data->command_buffer[i] = context->command_buffer_logical[i];
  368. data->command_buffer_gpu[i] = context->command_buffer_physical[i];
  369. }
  370. }
  371. /* Allocate the context buffer. */
  372. if (data->context_buffer_size) {
  373. int32_t i;
  374. for (i = 0; i < CMDBUF_COUNT; i ++)
  375. {
  376. /* Allocate the memory. */
  377. VG_LITE_OS_LOCK();
  378. error = vg_lite_hal_allocate_contiguous(data->context_buffer_size,
  379. &context->context_buffer_logical[i],
  380. &context->context_buffer_physical[i],
  381. &context->context_buffer[i]);
  382. VG_LITE_OS_UNLOCK();
  383. if (error != VG_LITE_SUCCESS) {
  384. /* Free any allocated memory. */
  385. vg_lite_kernel_terminate_t terminate = { context };
  386. do_terminate(&terminate);
  387. /* Out of memory. */
  388. return error;
  389. }
  390. /* Return context buffer logical pointer and GPU address. */
  391. data->context_buffer[i] = context->context_buffer_logical[i];
  392. data->context_buffer_gpu[i] = context->context_buffer_physical[i];
  393. }
  394. }
  395. /* Allocate the tessellation buffer. */
  396. if ((data->tessellation_width > 0) && (data->tessellation_height > 0))
  397. {
  398. int width = data->tessellation_width;
  399. int height = 0;
  400. height = VG_LITE_ALIGN(data->tessellation_height, 16);
  401. chip_id = vg_lite_hal_peek(0x20);
  402. if(chip_id == GPU_CHIP_ID_GC355)
  403. width = VG_LITE_ALIGN(width, 128);
  404. /* Check if we can used tiled tessellation (128x16). */
  405. if (((width & 127) == 0) && ((height & 15) == 0)) {
  406. data->capabilities.cap.tiled = 0x3;
  407. } else {
  408. data->capabilities.cap.tiled = 0x2;
  409. }
  410. if(ts_init++ == 0)
  411. {
  412. unsigned long stride, buffer_size, l1_size, l2_size;
  413. /* Compute tessellation buffer size. */
  414. stride = VG_LITE_ALIGN(width * 8, 64);
  415. buffer_size = VG_LITE_ALIGN(stride * height, 64);
  416. /* Each bit in the L1 cache represents 64 bytes of tessellation data. */
  417. l1_size = VG_LITE_ALIGN(VG_LITE_ALIGN(buffer_size / 64, 64) / 8, 64);
  418. /* Each bit in the L2 cache represents 32 bytes of L1 data. */
  419. l2_size = data->capabilities.cap.l2_cache ? VG_LITE_ALIGN(VG_LITE_ALIGN(l1_size / 32, 64) / 8, 64) : 0;
  420. /* Allocate the memory. */
  421. VG_LITE_OS_LOCK();
  422. error = vg_lite_hal_allocate_contiguous(buffer_size + l1_size + l2_size,
  423. &context->tessellation_buffer_logical,
  424. &context->tessellation_buffer_physical,
  425. &context->tessellation_buffer);
  426. VG_LITE_OS_UNLOCK();
  427. if (error != VG_LITE_SUCCESS) {
  428. /* Free any allocated memory. */
  429. vg_lite_kernel_terminate_t terminate = { context };
  430. do_terminate(&terminate);
  431. /* Out of memory. */
  432. return error;
  433. }
  434. /* Return the tessellation buffer pointers and GPU addresses. */
  435. ts_initialize.tessellation_buffer_gpu[0] = context->tessellation_buffer_physical;
  436. ts_initialize.tessellation_buffer_gpu[1] = context->tessellation_buffer_physical + buffer_size;
  437. ts_initialize.tessellation_buffer_gpu[2] = (l2_size ? ts_initialize.tessellation_buffer_gpu[1] + l1_size
  438. : ts_initialize.tessellation_buffer_gpu[1]);
  439. ts_initialize.tessellation_buffer_logic[0] = (uint8_t *)context->tessellation_buffer_logical;
  440. ts_initialize.tessellation_buffer_logic[1] = ts_initialize.tessellation_buffer_logic[0] + buffer_size;
  441. ts_initialize.tessellation_buffer_logic[2] = (l2_size ? ts_initialize.tessellation_buffer_logic[1] + l1_size
  442. : ts_initialize.tessellation_buffer_logic[1]);
  443. ts_initialize.tessellation_buffer_size[0] = buffer_size;
  444. ts_initialize.tessellation_buffer_size[1] = l1_size;
  445. ts_initialize.tessellation_buffer_size[2] = l2_size;
  446. ts_initialize.tessellation_stride = stride;
  447. ts_initialize.tessellation_width_height = width | (height << 16);
  448. ts_initialize.tessellation_shift = 0;
  449. }
  450. data->tessellation_buffer_gpu[0] = ts_initialize.tessellation_buffer_gpu[0];
  451. data->tessellation_buffer_gpu[1] = ts_initialize.tessellation_buffer_gpu[1];
  452. data->tessellation_buffer_gpu[2] = ts_initialize.tessellation_buffer_gpu[2];
  453. data->tessellation_buffer_logic[0] = ts_initialize.tessellation_buffer_logic[0];
  454. data->tessellation_buffer_logic[1] = ts_initialize.tessellation_buffer_logic[1];
  455. data->tessellation_buffer_logic[2] = ts_initialize.tessellation_buffer_logic[2];
  456. data->tessellation_buffer_size[0] = ts_initialize.tessellation_buffer_size[0];
  457. data->tessellation_buffer_size[1] = ts_initialize.tessellation_buffer_size[1];
  458. data->tessellation_buffer_size[2] = ts_initialize.tessellation_buffer_size[2];
  459. data->tessellation_stride = ts_initialize.tessellation_stride;
  460. data->tessellation_width_height = ts_initialize.tessellation_width_height;
  461. data->tessellation_shift = ts_initialize.tessellation_shift;
  462. }
  463. if(task_num == 1)
  464. /* Enable all interrupts. */
  465. vg_lite_hal_poke(VG_LITE_INTR_ENABLE, 0xFFFFFFFF);
  466. #if defined(__linux__) && !EMULATOR
  467. if (copy_to_user(context_usr, context, sizeof(vg_lite_kernel_context_t)) != 0) {
  468. // Free any allocated memory.
  469. vg_lite_kernel_terminate_t terminate = { context };
  470. do_terminate(&terminate);
  471. return VG_LITE_NO_CONTEXT;
  472. }
  473. #endif
  474. return error;
  475. }
  476. #endif /* VG_DRIVER_SINGLE_THREAD */
  477. static vg_lite_error_t do_initialize(vg_lite_kernel_initialize_t * data)
  478. {
  479. vg_lite_error_t error = VG_LITE_SUCCESS;
  480. /* Free any allocated memory for the context. */
  481. do {
  482. error = init_vglite(data);
  483. if (error != VG_LITE_SUCCESS)
  484. break;
  485. error = init_3rd(data);
  486. if (error != VG_LITE_SUCCESS)
  487. break;
  488. } while (0);
  489. return error;
  490. }
  491. #if defined(VG_DRIVER_SINGLE_THREAD)
  492. static vg_lite_error_t terminate_vglite(vg_lite_kernel_terminate_t * data)
  493. {
  494. vg_lite_kernel_context_t *context = NULL;
  495. #if defined(__linux__) && !EMULATOR
  496. vg_lite_kernel_context_t mycontext = {0};
  497. if (copy_from_user(&mycontext, data->context, sizeof(vg_lite_kernel_context_t)) != 0) {
  498. return VG_LITE_NO_CONTEXT;
  499. }
  500. context = &mycontext;
  501. #else
  502. context = data->context;
  503. #endif
  504. /* Free any allocated memory for the context. */
  505. if (context->command_buffer[0]) {
  506. /* Free the command buffer. */
  507. vg_lite_hal_free_contiguous(context->command_buffer[0]);
  508. context->command_buffer[0] = NULL;
  509. }
  510. if (context->command_buffer[1]) {
  511. /* Free the command buffer. */
  512. vg_lite_hal_free_contiguous(context->command_buffer[1]);
  513. context->command_buffer[1] = NULL;
  514. }
  515. if (context->tessellation_buffer) {
  516. /* Free the tessellation buffer. */
  517. vg_lite_hal_free_contiguous(context->tessellation_buffer);
  518. context->tessellation_buffer = NULL;
  519. }
  520. vg_lite_hal_free_os_heap();
  521. /* Decrement reference counter. */
  522. if (--s_reference == 0) {
  523. /* Disable the GPU. */
  524. gpu(0);
  525. /* De-initialize the SOC. */
  526. vg_lite_hal_deinitialize();
  527. }
  528. #if defined(__linux__) && !EMULATOR
  529. if (copy_to_user((vg_lite_kernel_context_t __user *) data->context,
  530. &mycontext, sizeof(vg_lite_kernel_context_t)) != 0) {
  531. return VG_LITE_NO_CONTEXT;
  532. }
  533. #endif
  534. return VG_LITE_SUCCESS;
  535. }
  536. #else
  537. static vg_lite_error_t terminate_vglite(vg_lite_kernel_terminate_t * data)
  538. {
  539. vg_lite_kernel_context_t *context = NULL;
  540. vg_lite_error_t error = VG_LITE_SUCCESS;
  541. int32_t i;
  542. #if defined(__linux__) && !EMULATOR
  543. vg_lite_kernel_context_t mycontext = {0};
  544. if (copy_from_user(&mycontext, data->context, sizeof(vg_lite_kernel_context_t)) != 0) {
  545. return VG_LITE_NO_CONTEXT;
  546. }
  547. context = &mycontext;
  548. #else
  549. context = data->context;
  550. #endif
  551. /* Free any allocated memory for the context. */
  552. if (context->command_buffer[0]) {
  553. /* Free the command buffer. */
  554. vg_lite_hal_free_contiguous(context->command_buffer[0]);
  555. context->command_buffer[0] = NULL;
  556. }
  557. if (context->command_buffer[1]) {
  558. /* Free the command buffer. */
  559. vg_lite_hal_free_contiguous(context->command_buffer[1]);
  560. context->command_buffer[1] = NULL;
  561. }
  562. if (context->context_buffer[0]) {
  563. /* Free the context buffer. */
  564. vg_lite_hal_free_contiguous(context->context_buffer[0]);
  565. context->context_buffer[0] = NULL;
  566. }
  567. if (context->context_buffer[1]) {
  568. /* Free the context buffer. */
  569. vg_lite_hal_free_contiguous(context->context_buffer[1]);
  570. context->context_buffer[1] = NULL;
  571. }
  572. if((error = (vg_lite_error_t)VG_LITE_OS_LOCK()) == VG_LITE_SUCCESS){
  573. --task_num;
  574. --s_reference;
  575. VG_LITE_OS_UNLOCK();
  576. }
  577. else
  578. return error;
  579. /* Delete all async events associated to command buffers */
  580. for (i = 0; i < CMDBUF_COUNT; i++)
  581. vg_lite_os_delete_event(&context->async_event[i]);
  582. if(task_num == 0){
  583. if (context->tessellation_buffer) {
  584. /* Free the tessellation buffer. */
  585. vg_lite_hal_free_contiguous(context->tessellation_buffer);
  586. context->tessellation_buffer = NULL;
  587. }
  588. ts_init = 0;
  589. /* Disable the GPU. */
  590. gpu(0);
  591. vg_lite_hal_free_os_heap();
  592. /* De-initialize the SOC. */
  593. vg_lite_hal_deinitialize();
  594. }
  595. #if defined(__linux__) && !EMULATOR
  596. if (copy_to_user((vg_lite_kernel_context_t __user *) data->context,
  597. &mycontext, sizeof(vg_lite_kernel_context_t)) != 0) {
  598. return VG_LITE_NO_CONTEXT;
  599. }
  600. #endif
  601. return VG_LITE_SUCCESS;
  602. }
  603. #endif /* VG_DRIVER_SINGLE_THREAD */
  604. static vg_lite_error_t terminate_3rd(vg_lite_kernel_terminate_t * data)
  605. {
  606. /* TODO: Terminate the converters. */
  607. return VG_LITE_SUCCESS;
  608. }
  609. static vg_lite_error_t do_terminate(vg_lite_kernel_terminate_t * data)
  610. {
  611. terminate_vglite(data);
  612. terminate_3rd(data);
  613. return VG_LITE_SUCCESS;
  614. }
  615. static vg_lite_error_t do_allocate(vg_lite_kernel_allocate_t * data)
  616. {
  617. vg_lite_error_t error;
  618. if((error = (vg_lite_error_t)VG_LITE_OS_LOCK()) == VG_LITE_SUCCESS)
  619. {
  620. error = vg_lite_hal_allocate_contiguous(data->bytes, &data->memory, &data->memory_gpu, &data->memory_handle);
  621. VG_LITE_OS_UNLOCK();
  622. }
  623. return error;
  624. }
  625. static vg_lite_error_t do_free(vg_lite_kernel_free_t * data)
  626. {
  627. vg_lite_hal_free_contiguous(data->memory_handle);
  628. return VG_LITE_SUCCESS;
  629. }
  630. #if defined(VG_DRIVER_SINGLE_THREAD)
  631. static vg_lite_error_t do_submit(vg_lite_kernel_submit_t * data)
  632. {
  633. uint32_t offset;
  634. vg_lite_kernel_context_t *context = NULL;
  635. uint32_t physical = data->context->command_buffer_physical[data->command_id];
  636. #if defined(__linux__) && !EMULATOR
  637. vg_lite_kernel_context_t mycontext = { 0 };
  638. if (copy_from_user(&mycontext, data->context, sizeof(vg_lite_kernel_context_t)) != 0) {
  639. return VG_LITE_NO_CONTEXT;
  640. }
  641. context = &mycontext;
  642. physical = context->command_buffer_physical[data->command_id];
  643. #else
  644. context = data->context;
  645. if (context == NULL)
  646. {
  647. return VG_LITE_NO_CONTEXT;
  648. }
  649. #endif
  650. /* Perform a memory barrier. */
  651. vg_lite_hal_barrier();
  652. offset = (uint8_t *) data->commands - (uint8_t *)context->command_buffer_logical[data->command_id];
  653. #if defined(PRINT_COMMAND_BUFFER)
  654. int i = 0;
  655. for(i=0;i < (peek_queue->cmd_size + 3) / 4; i++)
  656. {
  657. if(i % 4 == 0)
  658. printf("\r\n");
  659. printf("0x%08x ",((uint32_t*)(peek_queue->cmd_physical + peek_queue->cmd_offset))[i]);
  660. }
  661. #endif
  662. /* Write the registers to kick off the command execution (CMDBUF_SIZE). */
  663. vg_lite_hal_poke(VG_LITE_HW_CMDBUF_ADDRESS, physical + offset);
  664. vg_lite_hal_poke(VG_LITE_HW_CMDBUF_SIZE, (data->command_size + 7) / 8);
  665. return VG_LITE_SUCCESS;
  666. }
  667. static vg_lite_error_t do_wait(vg_lite_kernel_wait_t * data)
  668. {
  669. /* Wait for interrupt. */
  670. if (!vg_lite_hal_wait_interrupt(data->timeout_ms, data->event_mask, &data->event_got)) {
  671. /* Timeout. */
  672. #if defined(PRINT_DEBUG_REGISTER)
  673. unsigned int debug;
  674. unsigned int iter;
  675. for(iter =0; iter < 16 ; iter ++)
  676. {
  677. vg_lite_hal_poke(0x470, iter);
  678. debug = vg_lite_hal_peek(0x450);
  679. printf("0x450[%d] = 0x%x\n", iter,debug);
  680. }
  681. for(iter =0; iter < 16 ; iter ++)
  682. {
  683. vg_lite_hal_poke(0x470, iter <<16);
  684. debug = vg_lite_hal_peek(0x454);
  685. printf("0x454[%d] = 0x%x\n", iter,debug);
  686. }
  687. for(iter =0; iter < 16 ; iter ++)
  688. {
  689. vg_lite_hal_poke(0x478, iter);
  690. debug = vg_lite_hal_peek(0x468);
  691. printf("0x468[%d] = 0x%x\n", iter,debug);
  692. }
  693. for(iter =0; iter < 16 ; iter ++)
  694. {
  695. vg_lite_hal_poke(0x478, iter);
  696. debug = vg_lite_hal_peek(0x46C);
  697. printf("0x46C[%d] = 0x%x\n", iter,debug);
  698. }
  699. #endif
  700. return VG_LITE_TIMEOUT;
  701. }
  702. return VG_LITE_SUCCESS;
  703. }
  704. #else
  705. static vg_lite_error_t do_submit(vg_lite_kernel_submit_t * data)
  706. {
  707. vg_lite_error_t error;
  708. uint32_t offset;
  709. vg_lite_kernel_context_t *context = NULL;
  710. uint32_t physical;
  711. #if defined(__linux__) && !EMULATOR
  712. vg_lite_kernel_context_t mycontext = { 0 };
  713. if (copy_from_user(&mycontext, data->context, sizeof(vg_lite_kernel_context_t)) != 0) {
  714. return VG_LITE_NO_CONTEXT;
  715. }
  716. context = &mycontext;
  717. physical = context->command_buffer_physical[data->command_id];
  718. #else
  719. context = data->context;
  720. if (context == NULL)
  721. {
  722. return VG_LITE_NO_CONTEXT;
  723. }
  724. #endif
  725. /* Perform a memory barrier. */
  726. vg_lite_hal_barrier();
  727. physical = data->context->command_buffer_physical[data->command_id];
  728. offset = (uint8_t *) data->commands - (uint8_t *)context->command_buffer_logical[data->command_id];
  729. /* Send the current command buffer to the command queue. */
  730. error = vg_lite_hal_submit((uint32_t)context, physical, offset, data->command_size,
  731. &data->context->async_event[data->command_id]);
  732. if(error != VG_LITE_SUCCESS)
  733. return error;
  734. return VG_LITE_SUCCESS;
  735. }
  736. static vg_lite_error_t do_wait(vg_lite_kernel_wait_t * data)
  737. {
  738. vg_lite_error_t error;
  739. /* Wait for the signal of current command buffer to 1. */
  740. error = vg_lite_hal_wait(data->timeout_ms,
  741. &data->context->async_event[data->command_id]);
  742. return error;
  743. }
  744. #endif /* VG_DRIVER_SINGLE_THREAD */
  745. static vg_lite_error_t do_reset(void)
  746. {
  747. /* Disable and enable the GPU. */
  748. gpu(1);
  749. vg_lite_hal_poke(VG_LITE_INTR_ENABLE, 0xFFFFFFFF);
  750. return VG_LITE_SUCCESS;
  751. }
  752. static vg_lite_error_t do_debug(void)
  753. {
  754. return VG_LITE_SUCCESS;
  755. }
  756. static vg_lite_error_t do_map(vg_lite_kernel_map_t * data)
  757. { data->memory_handle = vg_lite_hal_map(data->bytes, data->logical, data->physical, &data->memory_gpu);
  758. if (data->memory_handle == NULL)
  759. {
  760. return VG_LITE_OUT_OF_RESOURCES;
  761. }
  762. return VG_LITE_SUCCESS;
  763. }
  764. static vg_lite_error_t do_unmap(vg_lite_kernel_unmap_t * data)
  765. {
  766. vg_lite_hal_unmap(data->memory_handle);
  767. return VG_LITE_SUCCESS;
  768. }
  769. static vg_lite_error_t do_peek(vg_lite_kernel_info_t * data)
  770. {
  771. data->reg = vg_lite_hal_peek(data->addr);
  772. return VG_LITE_SUCCESS;
  773. }
  774. static vg_lite_error_t do_query_mem(vg_lite_kernel_mem_t * data)
  775. {
  776. vg_lite_error_t error = VG_LITE_SUCCESS;
  777. error = vg_lite_hal_query_mem(data);
  778. return error;
  779. }
  780. #if !defined(VG_DRIVER_SINGLE_THREAD)
  781. static vg_lite_error_t do_query_context_switch(vg_lite_kernel_context_switch_t * data)
  782. {
  783. data->isContextSwitched = vg_lite_os_query_context_switch(data->context);
  784. return VG_LITE_SUCCESS;
  785. }
  786. #endif /* not defined(VG_DRIVER_SINGLE_THREAD) */
  787. static void soft_reset(void)
  788. {
  789. vg_lite_hw_clock_control_t value;
  790. value.data = vg_lite_hal_peek(VG_LITE_HW_CLOCK_CONTROL);
  791. /* Perform a soft reset. */
  792. value.control.isolate = 1;
  793. vg_lite_hal_poke(VG_LITE_HW_CLOCK_CONTROL, value.data);
  794. value.control.soft_reset = 1;
  795. vg_lite_hal_poke(VG_LITE_HW_CLOCK_CONTROL, value.data);
  796. vg_lite_hal_delay(5);
  797. value.control.soft_reset = 0;
  798. vg_lite_hal_poke(VG_LITE_HW_CLOCK_CONTROL, value.data);
  799. value.control.isolate = 0;
  800. vg_lite_hal_poke(VG_LITE_HW_CLOCK_CONTROL, value.data);
  801. }
  802. #if !defined(VG_DRIVER_SINGLE_THREAD)
  803. static vg_lite_error_t do_mutex_lock()
  804. {
  805. return (vg_lite_error_t)VG_LITE_OS_LOCK();
  806. }
  807. static vg_lite_error_t do_mutex_unlock()
  808. {
  809. return (vg_lite_error_t)VG_LITE_OS_UNLOCK();
  810. }
  811. #endif /* not defined(VG_DRIVER_SINGLE_THREAD) */
  812. vg_lite_error_t vg_lite_kernel(vg_lite_kernel_command_t command, void * data)
  813. {
  814. /* Dispatch on command. */
  815. switch (command) {
  816. case VG_LITE_INITIALIZE:
  817. /* Initialize the context. */
  818. return do_initialize(data);
  819. case VG_LITE_TERMINATE:
  820. /* Terminate the context. */
  821. return do_terminate(data);
  822. case VG_LITE_ALLOCATE:
  823. /* Allocate contiguous memory. */
  824. return do_allocate(data);
  825. case VG_LITE_FREE:
  826. /* Free contiguous memory. */
  827. return do_free(data);
  828. case VG_LITE_SUBMIT:
  829. /* Submit a command buffer. */
  830. return do_submit(data);
  831. case VG_LITE_WAIT:
  832. /* Wait for the GPU. */
  833. return do_wait(data);
  834. case VG_LITE_RESET:
  835. /* Reset the GPU. */
  836. return do_reset();
  837. case VG_LITE_DEBUG:
  838. /* Perform debugging features. */
  839. return do_debug();
  840. case VG_LITE_MAP:
  841. /* Map some memory. */
  842. return do_map(data);
  843. case VG_LITE_UNMAP:
  844. /* Unmap some memory. */
  845. return do_unmap(data);
  846. /* Get register info. */
  847. case VG_LITE_CHECK:
  848. /* Get register value. */
  849. return do_peek(data);
  850. case VG_LITE_QUERY_MEM:
  851. return do_query_mem(data);
  852. #if !defined(VG_DRIVER_SINGLE_THREAD)
  853. case VG_LITE_LOCK:
  854. /* Mutex lock */
  855. return do_mutex_lock();
  856. case VG_LITE_UNLOCK:
  857. /* Mutex unlock */
  858. return do_mutex_unlock();
  859. case VG_LITE_QUERY_CONTEXT_SWITCH:
  860. /* query context switch */
  861. return do_query_context_switch(data);
  862. #endif /* not defined(VG_DRIVER_SINGLE_THREAD) */
  863. default:
  864. break;
  865. }
  866. /* Invalid command. */
  867. return VG_LITE_INVALID_ARGUMENT;
  868. }