vg_lite_hal.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748
  1. /****************************************************************************
  2. *
  3. * The MIT License (MIT)
  4. *
  5. * Copyright (c) 2014 - 2022 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. *
  27. * The GPL License (GPL)
  28. *
  29. * Copyright (C) 2014 - 2022 Vivante Corporation
  30. *
  31. * This program is free software; you can redistribute it and/or
  32. * modify it under the terms of the GNU General Public License
  33. * as published by the Free Software Foundation; either version 2
  34. * of the License, or (at your option) any later version.
  35. *
  36. * This program is distributed in the hope that it will be useful,
  37. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  38. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  39. * GNU General Public License for more details.
  40. *
  41. * You should have received a copy of the GNU General Public License
  42. * along with this program; if not, write to the Free Software Foundation,
  43. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  44. *
  45. *****************************************************************************
  46. *
  47. * Note: This software is released under dual MIT and GPL licenses. A
  48. * recipient may use this file under the terms of either the MIT license or
  49. * GPL License. If you wish to use only one license not the other, you can
  50. * indicate your decision by deleting one of the above license notices in your
  51. * version of this file.
  52. *
  53. *****************************************************************************/
  54. #include "vg_lite_platform.h"
  55. #include "vg_lite_kernel.h"
  56. #include "vg_lite_hal.h"
  57. #include "vg_lite_hw.h"
  58. #if !_BAREMETAL
  59. #include "FreeRTOS.h"
  60. #include "semphr.h"
  61. #include "task.h"
  62. #else
  63. #include "xil_cache.h"
  64. #include "sleep.h"
  65. #endif
  66. #include <stdarg.h>
  67. #if !_BAREMETAL
  68. static void sleep(uint32_t msec)
  69. {
  70. vTaskDelay((configTICK_RATE_HZ * msec + 999)/ 1000);
  71. }
  72. #endif
  73. #if _BAREMETAL
  74. /* The followings should be configured by FPGA. */
  75. static uint32_t registerMemBase = 0x43c80000;
  76. #else
  77. static uint32_t registerMemBase = 0x40240000;
  78. #endif
  79. /* If bit31 is activated this indicates a bus error */
  80. #define IS_AXI_BUS_ERR(x) ((x)&(1U << 31))
  81. #define HEAP_NODE_USED 0xABBAF00D
  82. volatile void* contiguousMem[VG_SYSTEM_RESERVE_COUNT] = {
  83. [0 ... VG_SYSTEM_RESERVE_COUNT - 1] = NULL
  84. };
  85. uint32_t gpuMemBase[VG_SYSTEM_RESERVE_COUNT] = {
  86. [0 ... VG_SYSTEM_RESERVE_COUNT - 1] = 0
  87. };
  88. /* Default heap size is 16MB. */
  89. static uint32_t heap_size[VG_SYSTEM_RESERVE_COUNT] = {
  90. [0 ... VG_SYSTEM_RESERVE_COUNT - 1] = MAX_CONTIGUOUS_SIZE
  91. };
  92. void __attribute__((weak)) vg_lite_bus_error_handler();
  93. void vg_lite_init_mem(vg_module_parameters_t *param)
  94. {
  95. uint32_t i;
  96. registerMemBase = param->register_mem_base;
  97. for (i = 0; i< VG_SYSTEM_RESERVE_COUNT; i++) {
  98. gpuMemBase[i] = param->gpu_mem_base[i];
  99. contiguousMem[i] = param->contiguous_mem_base[i];
  100. heap_size[i] = param->contiguous_mem_size[i];
  101. }
  102. }
  103. /* Implementation of list. ****************************************/
  104. #define INIT_LIST_HEAD(entry) \
  105. (entry)->next = (entry);\
  106. (entry)->prev = (entry);
  107. /* Add the list item in front of "head". */
  108. static inline void add_list(list_head_t *to_add, list_head_t *head)
  109. {
  110. /* Link the new item. */
  111. to_add->next = head;
  112. to_add->prev = head->prev;
  113. /* Modify the neighbor. */
  114. head->prev = to_add;
  115. if (to_add->prev != NULL) {
  116. to_add->prev->next = to_add;
  117. }
  118. }
  119. /* Remove an entry out of the list. */
  120. static inline void delete_list(list_head_t *entry)
  121. {
  122. if (entry->prev != NULL) {
  123. entry->prev->next = entry->next;
  124. }
  125. if (entry->next != NULL) {
  126. entry->next->prev = entry->prev;
  127. }
  128. }
  129. /* End of list implementation. ***********/
  130. static inline void _memset(void *mem, unsigned char value, int size)
  131. {
  132. int i;
  133. for (i = 0; i < size; i++) {
  134. ((unsigned char *)mem)[i] = value;
  135. }
  136. }
  137. struct memory_heap {
  138. uint32_t free;
  139. list_head_t list;
  140. };
  141. struct mapped_memory {
  142. void *logical;
  143. uint32_t physical;
  144. int page_count;
  145. struct page **pages;
  146. };
  147. struct vg_lite_device {
  148. /* void * gpu; */
  149. uint32_t register_base; /* Always use physical for register access in RTOS. */
  150. /* struct page * pages; */
  151. volatile void *contiguous[VG_SYSTEM_RESERVE_COUNT];
  152. unsigned int order;
  153. unsigned int heap_size[VG_SYSTEM_RESERVE_COUNT];
  154. void *virtual[VG_SYSTEM_RESERVE_COUNT];
  155. uint32_t physical[VG_SYSTEM_RESERVE_COUNT];
  156. uint32_t size[VG_SYSTEM_RESERVE_COUNT];
  157. struct memory_heap heap[VG_SYSTEM_RESERVE_COUNT];
  158. int irq_enabled;
  159. volatile uint32_t int_flags;
  160. #if _BAREMETAL
  161. /* wait_queue_head_t int_queue; */
  162. xSemaphoreHandle int_queue;
  163. #else
  164. /* wait_queue_head_t int_queue; */
  165. SemaphoreHandle_t int_queue;
  166. #endif
  167. void *device;
  168. int registered;
  169. int major;
  170. struct class *class;
  171. int created;
  172. vg_lite_gpu_execute_state_t gpu_execute_state;
  173. };
  174. struct client_data {
  175. struct vg_lite_device *device;
  176. struct vm_area_struct *vm;
  177. void * contiguous_mapped;
  178. };
  179. static struct vg_lite_device *device;
  180. #if _BAREMETAL
  181. static struct vg_lite_device Device;
  182. #endif
  183. void vg_lite_set_gpu_execute_state(vg_lite_gpu_execute_state_t state)
  184. {
  185. device->gpu_execute_state = state;
  186. }
  187. vg_lite_error_t vg_lite_hal_allocate(uint32_t size, void **memory)
  188. {
  189. vg_lite_error_t error = VG_LITE_SUCCESS;
  190. #if _BAREMETAL
  191. /* Alloc is not supported in BAREMETAL / DDRLESS. */
  192. *memory = NULL;
  193. error = VG_LITE_NOT_SUPPORT;
  194. #else
  195. /* TODO: Allocate some memory. No more kernel mode in RTOS. */
  196. *memory = pvPortMalloc(size);
  197. if (NULL == *memory)
  198. error = VG_LITE_OUT_OF_MEMORY;
  199. #endif
  200. return error;
  201. }
  202. vg_lite_error_t vg_lite_hal_free(void *memory)
  203. {
  204. vg_lite_error_t error = VG_LITE_SUCCESS;
  205. #if !_BAREMETAL
  206. /* TODO: Free some memory. No more kernel mode in RTOS. */
  207. vPortFree(memory);
  208. #endif
  209. return error;
  210. }
  211. void vg_lite_hal_delay(uint32_t ms)
  212. {
  213. sleep(ms);
  214. }
  215. void vg_lite_hal_barrier(void)
  216. {
  217. /*Memory barrier. */
  218. #if _BAREMETAL
  219. Xil_DCacheFlush();
  220. #else
  221. __asm volatile("fence io, io");
  222. #endif
  223. }
  224. #include <hpm_soc.h>
  225. #ifndef GPU_MEM_SIZE_BYTES
  226. #define GPU_MEM_SIZE_BYTES 16 * 1024 * 1024
  227. #endif
  228. static uint8_t gpu_mem[GPU_MEM_SIZE_BYTES] __attribute__((aligned(64), section(".noncacheable.non_init")));
  229. static int vg_lite_init(void);
  230. void vg_lite_hal_initialize(void)
  231. {
  232. vg_module_parameters_t param;
  233. param.register_mem_base = HPM_GPU_BASE;
  234. param.gpu_mem_base[0] = 0;
  235. param.contiguous_mem_base[0] = gpu_mem;
  236. param.contiguous_mem_size[0] = GPU_MEM_SIZE_BYTES;
  237. vg_lite_init_mem(&param);
  238. intc_m_enable_irq_with_priority(IRQn_GPU, 2);
  239. /* TODO: Turn on the power. */
  240. vg_lite_init();
  241. /* TODO: Turn on the clock. */
  242. }
  243. void vg_lite_hal_deinitialize(void)
  244. {
  245. /* TODO: Remove clock. */
  246. vSemaphoreDelete(device->int_queue);
  247. /* TODO: Remove power. */
  248. }
  249. static int split_node(heap_node_t *node, unsigned long size)
  250. {
  251. /* TODO: the original is linux specific list based, needs rewrite.
  252. */
  253. heap_node_t *split;
  254. /* Allocate a new node. */
  255. vg_lite_hal_allocate(sizeof(heap_node_t), (void **)&split);
  256. if (split == NULL)
  257. return -1;
  258. /* Fill in the data of this node of the remaning size. */
  259. split->offset = node->offset + size;
  260. split->size = node->size - size;
  261. split->status = 0;
  262. /* Add the new node behind the current node. */
  263. add_list(&split->list, &node->list);
  264. /* Adjust the size of the current node. */
  265. node->size = size;
  266. return 0;
  267. }
  268. void vg_lite_hal_print(char *format, ...)
  269. {
  270. static char buffer[128];
  271. va_list args;
  272. va_start(args, format);
  273. vsnprintf(buffer, sizeof(buffer) - 1, format, args);
  274. buffer[sizeof(buffer) - 1] = 0;
  275. printf(buffer);
  276. va_end(args);
  277. }
  278. void vg_lite_hal_trace(char *format, ...)
  279. {
  280. static char buffer[128];
  281. va_list args;
  282. va_start(args, format);
  283. vsnprintf(buffer, sizeof(buffer) - 1, format, args);
  284. buffer[sizeof(buffer) - 1] = 0;
  285. printf(buffer);
  286. va_end(args);
  287. }
  288. const char* vg_lite_hal_Status2Name(vg_lite_error_t status)
  289. {
  290. switch (status) {
  291. case VG_LITE_SUCCESS:
  292. return "VG_LITE_SUCCESS";
  293. case VG_LITE_INVALID_ARGUMENT:
  294. return "VG_LITE_INVALID_ARGUMENT";
  295. case VG_LITE_OUT_OF_MEMORY:
  296. return "VG_LITE_OUT_OF_MEMORY";
  297. case VG_LITE_NO_CONTEXT:
  298. return "VG_LITE_NO_CONTEXT";
  299. case VG_LITE_TIMEOUT:
  300. return "VG_LITE_TIMEOUT";
  301. case VG_LITE_OUT_OF_RESOURCES:
  302. return "VG_LITE_OUT_OF_RESOURCES";
  303. case VG_LITE_GENERIC_IO:
  304. return "VG_LITE_GENERIC_IO";
  305. case VG_LITE_NOT_SUPPORT:
  306. return "VG_LITE_NOT_SUPPORT";
  307. case VG_LITE_ALREADY_EXISTS:
  308. return "VG_LITE_ALREADY_EXISTS";
  309. case VG_LITE_NOT_ALIGNED:
  310. return "VG_LITE_NOT_ALIGNED";
  311. case VG_LITE_FLEXA_TIME_OUT:
  312. return "VG_LITE_FLEXA_TIME_OUT";
  313. case VG_LITE_FLEXA_HANDSHAKE_FAIL:
  314. return "VG_LITE_FLEXA_HANDSHAKE_FAIL";
  315. case VG_LITE_SYSTEM_CALL_FAIL:
  316. return "VG_LITE_SYSTEM_CALL_FAIL";
  317. default:
  318. return "nil";
  319. }
  320. }
  321. vg_lite_error_t vg_lite_hal_allocate_contiguous(unsigned long size, vg_lite_vidmem_pool_t pool, void **logical, void **klogical, uint32_t *physical, void **node)
  322. {
  323. unsigned long aligned_size;
  324. heap_node_t *pos;
  325. /* Judge if it exceeds the range of pool */
  326. if (pool >= VG_SYSTEM_RESERVE_COUNT)
  327. pool = VG_SYSTEM_RESERVE_COUNT - 1;
  328. /* Align the size to 64 bytes. */
  329. aligned_size = (size + 63) & ~63;
  330. /* Check if there is enough free memory available. */
  331. if (aligned_size > device->heap[pool].free) {
  332. return VG_LITE_OUT_OF_MEMORY;
  333. }
  334. /* Walk the heap backwards. */
  335. for (pos = (heap_node_t *)device->heap[pool].list.prev;
  336. &pos->list != &device->heap[pool].list;
  337. pos = (heap_node_t*) pos->list.prev) {
  338. /* Check if the current node is free and is big enough. */
  339. if (pos->status == 0 && pos->size >= aligned_size) {
  340. /* See if we the current node is big enough to split. */
  341. if (0 != split_node(pos, aligned_size))
  342. {
  343. return VG_LITE_OUT_OF_RESOURCES;
  344. }
  345. /* Mark the current node as used. */
  346. pos->status = 0xABBAF00D;
  347. /* Return the logical/physical address. */
  348. /* *logical = (uint8_t *) private_data->contiguous_mapped + pos->offset; */
  349. *logical = (uint8_t *)device->virtual[pool] + pos->offset;
  350. *klogical = *logical;
  351. *physical = gpuMemBase[pool] + (uint32_t)(*logical);/* device->physical + pos->offset; */
  352. /* Mark which pool the pos belong to */
  353. pos->pool = pool;
  354. device->heap[pool].free -= aligned_size;
  355. *node = pos;
  356. return VG_LITE_SUCCESS;
  357. }
  358. }
  359. /* Out of memory. */
  360. return VG_LITE_OUT_OF_MEMORY;
  361. }
  362. void vg_lite_hal_free_contiguous(void *memory_handle)
  363. {
  364. /* TODO: no list available in RTOS. */
  365. heap_node_t *pos, *node;
  366. vg_lite_vidmem_pool_t pool;
  367. /* Get pointer to node. */
  368. node = memory_handle;
  369. if (node->status != 0xABBAF00D) {
  370. return;
  371. }
  372. /* Determine which pool the node belongs to */
  373. pool = node->pool;
  374. /* Mark node as free. */
  375. node->status = 0;
  376. /* Add node size to free count. */
  377. device->heap[pool].free += node->size;
  378. /* Check if next node is free. */
  379. pos = node;
  380. for (pos = (heap_node_t *)pos->list.next;
  381. &pos->list != &device->heap[pool].list;
  382. pos = (heap_node_t *)pos->list.next) {
  383. if (pos->status == 0) {
  384. /* Merge the nodes. */
  385. node->size += pos->size;
  386. if (node->offset > pos->offset)
  387. node->offset = pos->offset;
  388. /* Delete the next node from the list. */
  389. delete_list(&pos->list);
  390. vg_lite_hal_free(pos);
  391. }
  392. break;
  393. }
  394. /* Check if the previous node is free. */
  395. pos = node;
  396. for (pos = (heap_node_t *)pos->list.prev;
  397. &pos->list != &device->heap[pool].list;
  398. pos = (heap_node_t *)pos->list.prev) {
  399. if (pos->status == 0) {
  400. /* Merge the nodes. */
  401. pos->size += node->size;
  402. if (pos->offset > node->offset)
  403. pos->offset = node->offset;
  404. /* Delete the current node from the list. */
  405. delete_list(&node->list);
  406. vg_lite_hal_free(node);
  407. }
  408. break;
  409. }
  410. /* when release command buffer node and ts buffer node to exit,release the linked list*/
  411. /* if(device->heap[pool].list.next == device->heap[pool].list.prev) {
  412. delete_list(&pos->list);
  413. vg_lite_hal_free(pos);
  414. }*/
  415. }
  416. void vg_lite_hal_free_os_heap(void)
  417. {
  418. struct heap_node *pos, *n;
  419. uint32_t i;
  420. /* Check for valid device. */
  421. if (device != NULL) {
  422. /* Process each node. */
  423. for (i = 0; i < VG_SYSTEM_RESERVE_COUNT; i++) {
  424. for (pos = (heap_node_t *)device->heap[i].list.next,
  425. n = (heap_node_t *)pos->list.next;
  426. &pos->list != &device->heap[i].list;
  427. pos = n, n = (heap_node_t *)n->list.next) {
  428. /* Remove it from the linked list. */
  429. delete_list(&pos->list);
  430. /* Free up the memory. */
  431. vg_lite_hal_free(pos);
  432. }
  433. }
  434. }
  435. }
  436. /* Portable: read register value. */
  437. uint32_t vg_lite_hal_peek(uint32_t address)
  438. {
  439. /* Read data from the GPU register. */
  440. return (uint32_t) (*(volatile uint32_t *) (device->register_base + address));
  441. }
  442. /* Portable: write register. */
  443. void vg_lite_hal_poke(uint32_t address, uint32_t data)
  444. {
  445. /* Write data to the GPU register. */
  446. uint32_t *LocalAddr = (uint32_t *)(device->register_base + address);
  447. *LocalAddr = data;
  448. }
  449. vg_lite_error_t vg_lite_hal_query_mem(vg_lite_kernel_mem_t *mem)
  450. {
  451. if(device != NULL){
  452. mem->bytes = device->heap[mem->pool].free;
  453. return VG_LITE_SUCCESS;
  454. }
  455. mem->bytes = 0;
  456. return VG_LITE_NO_CONTEXT;
  457. }
  458. vg_lite_error_t vg_lite_hal_map_memory(vg_lite_kernel_map_memory_t *node)
  459. {
  460. node->logical = (void *)node->physical;
  461. return VG_LITE_SUCCESS;
  462. }
  463. vg_lite_error_t vg_lite_hal_unmap_memory(vg_lite_kernel_unmap_memory_t *node)
  464. {
  465. return VG_LITE_SUCCESS;
  466. }
  467. void __attribute__((weak)) vg_lite_bus_error_handler()
  468. {
  469. /*
  470. * Default implementation of the bus error handler does nothing. Application
  471. * should override this handler if it requires to be notified when a bus
  472. * error event occurs.
  473. */
  474. return;
  475. }
  476. SDK_DECLARE_EXT_ISR_M(IRQn_GPU, vg_lite_IRQHandler)
  477. void vg_lite_IRQHandler(void)
  478. {
  479. uint32_t flags = vg_lite_hal_peek(VG_LITE_INTR_STATUS);
  480. portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
  481. if (flags) {
  482. /* Combine with current interrupt flags. */
  483. device->int_flags |= flags;
  484. /* Wake up any waiters. */
  485. if(device->int_queue){
  486. xSemaphoreGiveFromISR(device->int_queue, &xHigherPriorityTaskWoken);
  487. if(xHigherPriorityTaskWoken != pdFALSE )
  488. {
  489. portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
  490. }
  491. }
  492. #if gcdVG_RECORD_HARDWARE_RUNNING_TIME
  493. record_running_time();
  494. #endif
  495. }
  496. #if 0
  497. if(flags = VGLITE_EVENT_FRAME_END){
  498. /* A callback function can be added here to inform that gpu is idle. */
  499. (*callback)();
  500. }
  501. #endif
  502. }
  503. int32_t vg_lite_hal_wait_interrupt(uint32_t timeout, uint32_t mask, uint32_t *value)
  504. {
  505. #if _BAREMETAL
  506. uint32_t int_status=0;
  507. int_status = vg_lite_hal_peek(VG_LITE_INTR_STATUS);
  508. (void)value;
  509. while (int_status==0){
  510. int_status = vg_lite_hal_peek(VG_LITE_INTR_STATUS);
  511. usleep(1);
  512. }
  513. if (IS_AXI_BUS_ERR(*value))
  514. {
  515. vg_lite_bus_error_handler();
  516. }
  517. return 1;
  518. #else /*for rt500*/
  519. if(device->int_queue) {
  520. if (xSemaphoreTake(device->int_queue, timeout / portTICK_PERIOD_MS) == pdTRUE) {
  521. if (value != NULL) {
  522. *value = device->int_flags & mask;
  523. }
  524. device->int_flags = 0;
  525. if (IS_AXI_BUS_ERR(*value))
  526. {
  527. vg_lite_bus_error_handler();
  528. }
  529. return 1;
  530. }
  531. }
  532. return 0;
  533. #endif
  534. }
  535. vg_lite_error_t vg_lite_hal_memory_export(int32_t *fd)
  536. {
  537. return VG_LITE_SUCCESS;
  538. }
  539. void * vg_lite_hal_map(uint32_t flags, uint32_t bytes, void *logical, uint32_t physical, int32_t dma_buf_fd, uint32_t *gpu)
  540. {
  541. (void) flags;
  542. (void) bytes;
  543. (void) logical;
  544. (void) physical;
  545. (void) dma_buf_fd;
  546. (void) gpu;
  547. return (void *)0;
  548. }
  549. void vg_lite_hal_unmap(void *handle)
  550. {
  551. (void) handle;
  552. }
  553. vg_lite_error_t vg_lite_hal_operation_cache(void *handle, vg_lite_cache_op_t cache_op)
  554. {
  555. (void) handle;
  556. (void) cache_op;
  557. return VG_LITE_SUCCESS;
  558. }
  559. static void vg_lite_exit(void)
  560. {
  561. heap_node_t *pos;
  562. heap_node_t *n;
  563. uint32_t i;
  564. /* Check for valid device. */
  565. if (device != NULL) {
  566. /* TODO: unmap register mem should be unnecessary. */
  567. device->register_base = 0;
  568. for (i = 0; i < VG_SYSTEM_RESERVE_COUNT; i++) {
  569. /* Process each node. */
  570. for (pos = (heap_node_t *)device->heap[i].list.next, n = (heap_node_t *)pos->list.next;
  571. &pos->list != &device->heap[i].list;
  572. pos = n, n = (heap_node_t *)n->list.next) {
  573. /* Remove it from the linked list. */
  574. delete_list(&pos->list);
  575. /* Free up the memory. */
  576. vg_lite_hal_free(pos);
  577. }
  578. }
  579. /* Free up the device structure. */
  580. vg_lite_hal_free(device);
  581. }
  582. }
  583. static int vg_lite_init(void)
  584. {
  585. heap_node_t *node;
  586. uint32_t i;
  587. /* Initialize memory and objects ***************************************/
  588. /* Create device structure. */
  589. #if _BAREMETAL
  590. device = &Device;
  591. #else
  592. vg_lite_hal_allocate(sizeof(struct vg_lite_device), (void **)&device);
  593. if (NULL == device)
  594. return -1;
  595. #endif
  596. /* Zero out the enture structure. */
  597. _memset(device, 0, sizeof(struct vg_lite_device));
  598. /* Setup register memory. **********************************************/
  599. device->register_base = registerMemBase;
  600. /* Initialize contiguous memory. ***************************************/
  601. /* Allocate the contiguous memory. */
  602. for (i = 0; i < VG_SYSTEM_RESERVE_COUNT; i++) {
  603. device->heap_size[i] = heap_size[i];
  604. device->contiguous[i] = (volatile void *)contiguousMem[i];
  605. /* Make 64byte aligned. */
  606. while ((((uint32_t)device->contiguous[i]) & 63) != 0)
  607. {
  608. device->contiguous[i] = ((unsigned char *)device->contiguous[i]) + 4;
  609. device->heap_size[i] -= 4;
  610. }
  611. /* Check if we allocated any contiguous memory or not. */
  612. if (device->contiguous[i] == NULL) {
  613. vg_lite_exit();
  614. return -1;
  615. }
  616. device->virtual[i] = (void *)device->contiguous[i];
  617. device->physical[i] = gpuMemBase[i] + (uint32_t)device->virtual[i];
  618. device->size[i] = device->heap_size[i];
  619. /* Create the heap. */
  620. INIT_LIST_HEAD(&device->heap[i].list);
  621. device->heap[i].free = device->size[i];
  622. vg_lite_hal_allocate(sizeof(heap_node_t), (void **)&node);
  623. if (node == NULL) {
  624. vg_lite_exit();
  625. return -1;
  626. }
  627. node->offset = 0;
  628. node->size = device->size[i];
  629. node->status = 0;
  630. add_list(&node->list, &device->heap[i].list);
  631. }
  632. #if !_BAREMETAL /*for rt500*/
  633. device->int_queue = xSemaphoreCreateBinary();
  634. device->int_flags = 0;
  635. #endif
  636. /* Success. */
  637. return 0;
  638. }