vdi.c 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771
  1. // SPDX-License-Identifier: LGPL-2.1 OR BSD-3-Clause
  2. /*
  3. * Copyright (c) 2019, Chips&Media
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this
  10. * list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  16. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  19. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  20. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  21. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  22. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  24. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #if defined(linux) || defined(__linux) || defined(ANDROID)
  27. #include <ctype.h>
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include <unistd.h>
  32. #ifdef _KERNEL_
  33. #include <linux/delay.h>
  34. #endif
  35. #include <signal.h> /* SIGIO */
  36. #include <fcntl.h> /* fcntl */
  37. #include <pthread.h>
  38. #include <sys/mman.h> /* mmap */
  39. #include <sys/ioctl.h> /* fopen/fread */
  40. #include <sys/errno.h> /* fopen/fread */
  41. #include <sys/types.h>
  42. #include <sys/time.h>
  43. #include "driver/vpu.h"
  44. #include "../vdi.h"
  45. #include "../vdi_osal.h"
  46. #include "coda9/coda9_regdefine.h"
  47. #include "wave/wave5_regdefine.h"
  48. #include "main_helper.h"
  49. #include "misc/debug.h"
  50. #define VPU_DEVICE_NAME "/dev/vdec"
  51. #define VPU_MUTEX_NAME "/vpumutex"
  52. static int mutex_fd = -1;
  53. typedef pthread_mutex_t MUTEX_HANDLE;
  54. # define SUPPORT_INTERRUPT
  55. # define VDI_SRAM_BASE_ADDR 0x00000000 // if we can know the sram address in SOC directly for vdi layer. it is possible to set in vdi layer without allocation from driver
  56. #define VDI_SYSTEM_ENDIAN VDI_LITTLE_ENDIAN
  57. #define VDI_128BIT_BUS_SYSTEM_ENDIAN VDI_128BIT_LITTLE_ENDIAN
  58. #define VPU_BIT_REG_SIZE (0x4000*MAX_NUM_VPU_CORE)
  59. #define VDI_CODA9_SRAM_SIZE 0x34600 // FHD MAX size, 0x17D00 4K MAX size 0x34600
  60. #define VDI_WAVE511_SRAM_SIZE 0x2D000 /* H.265 Main10 : 8Kx4K -> 184320, 4Kx2K -> 92160
  61. * H.265 Main : 8Kx4K -> 155648, 4Kx2K -> 77824
  62. */
  63. #define VDI_WAVE521_SRAM_SIZE 0x20400 /* 10bit profile : 8Kx8K -> 132096, 4Kx2K -> 66560
  64. * 8bit profile : 8Kx8K -> 99328, 4Kx2K -> 51176
  65. */
  66. #define VDI_WAVE521C_SRAM_SIZE 0x2D000 /* H.265 Main10 : 8Kx4K -> 184320, 4Kx2K -> 92160
  67. * H.265 Main : 8Kx4K -> 155648, 4Kx2K -> 77824
  68. * NOTE: Decoder > Encoder
  69. */
  70. #define VDI_NUM_LOCK_HANDLES 4
  71. #ifdef SUPPORT_MULTI_CORE_IN_ONE_DRIVER
  72. #define VPU_CORE_BASE_OFFSET 0x4000
  73. #endif
  74. typedef struct vpudrv_buffer_pool_t
  75. {
  76. vpudrv_buffer_t vdb;
  77. int inuse;
  78. } vpudrv_buffer_pool_t;
  79. typedef struct {
  80. unsigned long core_idx;
  81. unsigned int product_code;
  82. int vpu_fd;
  83. vpu_instance_pool_t *pvip;
  84. int task_num;
  85. int clock_state;
  86. vpudrv_buffer_t vdb_register;
  87. vpu_buffer_t vpu_common_memory;
  88. vpudrv_buffer_pool_t vpu_buffer_pool[MAX_VPU_BUFFER_POOL];
  89. int vpu_buffer_pool_count;
  90. void* vpu_mutex;
  91. void* vpu_omx_mutex;
  92. void* vpu_disp_mutex;
  93. void* vmem_mutex;
  94. } vdi_info_t;
  95. static vdi_info_t s_vdi_info[MAX_NUM_VPU_CORE];
  96. static int swap_endian(unsigned long core_idx, unsigned char *data, int len, int endian);
  97. void vdi_flush_ddr(unsigned long core_idx,unsigned long start,unsigned long size,unsigned char flag)
  98. {
  99. vdi_info_t *vdi;
  100. vpudrv_flush_cache_t cache_info;
  101. vdi = &s_vdi_info[core_idx];
  102. cache_info.start = start;
  103. cache_info.size = size;
  104. cache_info.flag = flag;
  105. ioctl(vdi->vpu_fd, VDI_IOCTL_FLUSH_DCACHE, &cache_info);
  106. }
  107. #if defined(ANDROID) || !defined(PTHREAD_MUTEX_ROBUST_NP)
  108. static void restore_mutex_in_dead(MUTEX_HANDLE *mutex)
  109. {
  110. int mutex_value;
  111. if (!mutex)
  112. return;
  113. #if defined(ANDROID)
  114. mutex_value = mutex->value;
  115. #else
  116. memcpy(&mutex_value, mutex, sizeof(mutex_value));
  117. #endif
  118. if (mutex_value == (int)0xdead10cc) // destroy by device driver
  119. {
  120. pthread_mutexattr_t mutexattr;
  121. pthread_mutexattr_init(&mutexattr);
  122. pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED);
  123. pthread_mutex_init(mutex, &mutexattr);
  124. }
  125. }
  126. #endif //defined(ANDROID) || !defined(PTHREAD_MUTEX_ROBUST_NP)
  127. static void vmem_lock(vdi_info_t* vdi)
  128. {
  129. #if defined(ANDROID) || !defined(PTHREAD_MUTEX_ROBUST_NP)
  130. restore_mutex_in_dead((MUTEX_HANDLE *)vdi->vmem_mutex);
  131. pthread_mutex_lock((MUTEX_HANDLE*)vdi->vmem_mutex);
  132. #else
  133. int ret = -1;
  134. ret = pthread_mutex_lock((MUTEX_HANDLE *)vdi->vmem_mutex);
  135. if (ret != 0) {
  136. if (ret == EOWNERDEAD)
  137. ret = pthread_mutex_consistent((MUTEX_HANDLE *)vdi->vmem_mutex);
  138. if (ret != 0)
  139. VLOG(ERR, "%s:%d failed to pthread_mutex_locK\n", __FUNCTION__, __LINE__);
  140. }
  141. #endif
  142. return; //lint !e454
  143. }
  144. static void vmem_unlock(vdi_info_t* vdi)
  145. {
  146. pthread_mutex_unlock((MUTEX_HANDLE *)vdi->vmem_mutex);//lint !e455
  147. }
  148. int vdi_probe(unsigned long core_idx)
  149. {
  150. int ret;
  151. ret = vdi_init(core_idx);
  152. vdi_release(core_idx);
  153. return ret;
  154. }
  155. void set_cpu_freq_fixed(void)
  156. {
  157. int vpu_fd = open(VPU_DEVICE_NAME, O_RDWR);
  158. if (vpu_fd < 0)
  159. VLOG(ERR, "[VDI] Can't open vpu driver \n");
  160. ioctl(vpu_fd, VDI_IOCTL_CPUFREQ_SAVEENV, NULL);
  161. close(vpu_fd);
  162. }
  163. void realese_cpu_freq_fixed(void)
  164. {
  165. int vpu_fd = open(VPU_DEVICE_NAME, O_RDWR);
  166. if (vpu_fd < 0)
  167. VLOG(ERR, "[VDI] Can't open vpu driver \n");
  168. ioctl(vpu_fd, VDI_IOCTL_CPUFREQ_PUTENV, NULL);
  169. close(vpu_fd);
  170. }
  171. int vdi_init(unsigned long core_idx)
  172. {
  173. vdi_info_t *vdi;
  174. int i;
  175. if (core_idx >= MAX_NUM_VPU_CORE)
  176. return 0;
  177. vdi = &s_vdi_info[core_idx];
  178. if (vdi->vpu_fd != -1 && vdi->vpu_fd != 0x00)
  179. {
  180. vdi->task_num++;
  181. return 0;
  182. }
  183. set_cpu_freq_fixed();
  184. vdi->vpu_fd = open(VPU_DEVICE_NAME, O_RDWR); // if this API supports VPU parallel processing using multi VPU. the driver should be made to open multiple times.
  185. if (vdi->vpu_fd < 0) {
  186. VLOG(ERR, "[VDI] Can't open vpu driver. [error=%s]. try to load vpu driver first \n", strerror(errno));
  187. return -1;
  188. }
  189. memset(vdi->vpu_buffer_pool, 0x00, sizeof(vpudrv_buffer_pool_t)*MAX_VPU_BUFFER_POOL);
  190. if (!vdi_get_instance_pool(core_idx))
  191. {
  192. VLOG(INFO, "[VDI] fail to create shared info for saving context \n");
  193. goto ERR_VDI_INIT;
  194. }
  195. if (vdi->pvip->instance_pool_inited == FALSE)
  196. {
  197. int* pCodecInst;
  198. pthread_mutexattr_t mutexattr;
  199. pthread_mutexattr_init(&mutexattr);
  200. pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED);
  201. #if defined(ANDROID) || !defined(PTHREAD_MUTEX_ROBUST_NP)
  202. #else
  203. /* If a process or a thread is terminated abnormally,
  204. * pthread_mutexattr_setrobust_np(attr, PTHREAD_MUTEX_ROBUST_NP) makes
  205. * next onwer call pthread_mutex_lock() without deadlock.
  206. */
  207. pthread_mutexattr_setrobust(&mutexattr, PTHREAD_MUTEX_ROBUST);
  208. #endif
  209. pthread_mutex_init((MUTEX_HANDLE *)vdi->vpu_mutex, &mutexattr);
  210. pthread_mutex_init((MUTEX_HANDLE *)vdi->vpu_disp_mutex, &mutexattr);
  211. pthread_mutex_init((MUTEX_HANDLE *)vdi->vmem_mutex, &mutexattr);
  212. for( i = 0; i < MAX_NUM_INSTANCE; i++) {
  213. pCodecInst = (int *)vdi->pvip->codecInstPool[i];
  214. pCodecInst[1] = i; // indicate instIndex of CodecInst
  215. pCodecInst[0] = 0; // indicate inUse of CodecInst
  216. }
  217. vdi->pvip->instance_pool_inited = TRUE;
  218. pthread_mutexattr_destroy(&mutexattr);
  219. }
  220. #ifdef USE_VMALLOC_FOR_INSTANCE_POOL_MEMORY
  221. if (ioctl(vdi->vpu_fd, VDI_IOCTL_GET_REGISTER_INFO, &vdi->vdb_register) < 0)
  222. {
  223. VLOG(ERR, "[VDI] fail to get host interface register\n");
  224. goto ERR_VDI_INIT;
  225. }
  226. #endif
  227. #ifdef USE_VMALLOC_FOR_INSTANCE_POOL_MEMORY
  228. vdi->vdb_register.virt_addr = (unsigned long)mmap(NULL, vdi->vdb_register.size, PROT_READ | PROT_WRITE, MAP_SHARED, vdi->vpu_fd, vdi->vdb_register.phys_addr);
  229. #else
  230. vdi->vdb_register.size = VPU_BIT_REG_SIZE;
  231. vdi->vdb_register.virt_addr = (unsigned long)mmap(NULL, vdi->vdb_register.size, PROT_READ | PROT_WRITE, MAP_SHARED, vdi->vpu_fd, 0);
  232. #endif
  233. if ((void *)vdi->vdb_register.virt_addr == MAP_FAILED)
  234. {
  235. VLOG(ERR, "[VDI] fail to map vpu registers \n");
  236. goto ERR_VDI_INIT;
  237. }
  238. VLOG(INFO, "[VDI] map vdb_register core_idx=%d, virtaddr=0x%lx, size=%d\n", core_idx, vdi->vdb_register.virt_addr, vdi->vdb_register.size);
  239. if (vdi_lock(core_idx) < 0)
  240. {
  241. VLOG(ERR, "[VDI] fail to handle lock function\n");
  242. goto ERR_VDI_INIT;
  243. }
  244. vdi_set_clock_gate(core_idx, 1);
  245. vdi->product_code = vdi_read_register(core_idx, VPU_PRODUCT_CODE_REGISTER);
  246. if (vdi_allocate_common_memory(core_idx) < 0)
  247. {
  248. VLOG(ERR, "[VDI] fail to get vpu common buffer from driver\n");
  249. goto ERR_VDI_INIT;
  250. }
  251. vdi->core_idx = core_idx;
  252. vdi->task_num++;
  253. vdi_set_clock_gate(core_idx, 0);
  254. vdi_unlock(core_idx);
  255. VLOG(INFO, "[VDI] success to init driver \n");
  256. return 0;
  257. ERR_VDI_INIT:
  258. vdi_unlock(core_idx);
  259. vdi_release(core_idx);
  260. return -1;
  261. }
  262. int vdi_set_bit_firmware_to_pm(unsigned long core_idx, const unsigned short *code)
  263. {
  264. int i;
  265. vpu_bit_firmware_info_t bit_firmware_info;
  266. vdi_info_t *vdi;
  267. if (core_idx >= MAX_NUM_VPU_CORE)
  268. return 0;
  269. vdi = &s_vdi_info[core_idx];
  270. if (!vdi || vdi->vpu_fd == -1 || vdi->vpu_fd == 0x00)
  271. return 0;
  272. bit_firmware_info.size = sizeof(vpu_bit_firmware_info_t);
  273. bit_firmware_info.core_idx = core_idx;
  274. #ifdef SUPPORT_MULTI_CORE_IN_ONE_DRIVER
  275. bit_firmware_info.reg_base_offset = (core_idx*VPU_CORE_BASE_OFFSET);
  276. #else
  277. bit_firmware_info.reg_base_offset = 0;
  278. #endif
  279. for (i=0; i<512; i++)
  280. bit_firmware_info.bit_code[i] = code[i];
  281. if (write(vdi->vpu_fd, &bit_firmware_info, bit_firmware_info.size) < 0)
  282. {
  283. VLOG(ERR, "[VDI] fail to vdi_set_bit_firmware core=%d\n", bit_firmware_info.core_idx);
  284. return -1;
  285. }
  286. return 0;
  287. }
  288. #if defined(SUPPORT_SW_UART) || defined(SUPPORT_SW_UART_V2)
  289. int vdi_get_task_num(unsigned long core_idx)
  290. {
  291. vdi_info_t *vdi;
  292. vdi = &s_vdi_info[core_idx];
  293. if (!vdi || vdi->vpu_fd == -1 || vdi->vpu_fd == 0x00)
  294. return -1;
  295. return vdi->task_num;
  296. }
  297. #endif
  298. int vdi_release(unsigned long core_idx)
  299. {
  300. int i;
  301. vpudrv_buffer_t vdb;
  302. vdi_info_t *vdi;
  303. if (core_idx >= MAX_NUM_VPU_CORE)
  304. return 0;
  305. vdi = &s_vdi_info[core_idx];
  306. if (!vdi || vdi->vpu_fd == -1 || vdi->vpu_fd == 0x00)
  307. return 0;
  308. if (vdi_lock(core_idx) < 0)
  309. {
  310. VLOG(ERR, "[VDI] fail to handle lock function\n");
  311. return -1;
  312. }
  313. if (vdi->task_num > 1) // means that the opened instance remains
  314. {
  315. vdi->task_num--;
  316. vdi_unlock(core_idx);
  317. return 0;
  318. }
  319. if (vdi->vdb_register.virt_addr)
  320. munmap((void *)vdi->vdb_register.virt_addr, vdi->vdb_register.size);
  321. osal_memset(&vdi->vdb_register, 0x00, sizeof(vpudrv_buffer_t));
  322. vdb.size = 0;
  323. // get common memory information to free virtual address
  324. for (i=0; i<MAX_VPU_BUFFER_POOL; i++)
  325. {
  326. if (vdi->vpu_common_memory.phys_addr >= vdi->vpu_buffer_pool[i].vdb.phys_addr &&
  327. vdi->vpu_common_memory.phys_addr < (vdi->vpu_buffer_pool[i].vdb.phys_addr + vdi->vpu_buffer_pool[i].vdb.size))
  328. {
  329. vdi->vpu_buffer_pool[i].inuse = 0;
  330. vdi->vpu_buffer_pool_count--;
  331. vdb = vdi->vpu_buffer_pool[i].vdb;
  332. break;
  333. }
  334. }
  335. vdi_unlock(core_idx);
  336. if (vdb.size > 0)
  337. {
  338. munmap((void *)vdb.virt_addr, vdb.size);
  339. memset(&vdi->vpu_common_memory, 0x00, sizeof(vpu_buffer_t));
  340. }
  341. vdi->task_num--;
  342. if (vdi->vpu_fd != -1 && vdi->vpu_fd != 0x00)
  343. {
  344. close(vdi->vpu_fd);
  345. vdi->vpu_fd = -1;
  346. }
  347. realese_cpu_freq_fixed();
  348. if (vdi->vpu_mutex)
  349. {
  350. munmap(vdi->vpu_mutex, sizeof(MUTEX_HANDLE) * VDI_NUM_LOCK_HANDLES);
  351. close(mutex_fd);
  352. vdi->vpu_mutex = NULL;
  353. vdi->vpu_disp_mutex = NULL;
  354. vdi->vmem_mutex = NULL;
  355. mutex_fd = -1;
  356. }
  357. memset(vdi, 0x00, sizeof(vdi_info_t));
  358. return 0;
  359. }
  360. int vdi_get_common_memory(unsigned long core_idx, vpu_buffer_t *vb)
  361. {
  362. vdi_info_t *vdi;
  363. if (core_idx >= MAX_NUM_VPU_CORE)
  364. return -1;
  365. vdi = &s_vdi_info[core_idx];
  366. if(!vdi || vdi->vpu_fd==-1 || vdi->vpu_fd==0x00)
  367. return -1;
  368. osal_memcpy(vb, &vdi->vpu_common_memory, sizeof(vpu_buffer_t));
  369. return 0;
  370. }
  371. int vdi_allocate_common_memory(unsigned long core_idx)
  372. {
  373. vdi_info_t *vdi = &s_vdi_info[core_idx];
  374. vpudrv_buffer_t vdb;
  375. int i;
  376. if (core_idx >= MAX_NUM_VPU_CORE)
  377. return -1;
  378. if(!vdi || vdi->vpu_fd==-1 || vdi->vpu_fd==0x00)
  379. return -1;
  380. osal_memset(&vdb, 0x00, sizeof(vpudrv_buffer_t));
  381. vdb.size = SIZE_COMMON*MAX_NUM_VPU_CORE;
  382. if (ioctl(vdi->vpu_fd, VDI_IOCTL_GET_COMMON_MEMORY, &vdb) < 0)
  383. {
  384. VLOG(ERR, "[VDI] fail to vdi_allocate_dma_memory size=%d\n", vdb.size);
  385. return -1;
  386. }
  387. vdb.virt_addr = (unsigned long)mmap(NULL, vdb.size, PROT_READ | PROT_WRITE, MAP_SHARED, vdi->vpu_fd, vdb.phys_addr);
  388. if ((void *)vdb.virt_addr == MAP_FAILED)
  389. {
  390. VLOG(ERR, "[VDI] fail to map common memory phyaddr=%#lx, size = %d\n", vdb.phys_addr, vdb.size);
  391. return -1;
  392. }
  393. VLOG(INFO, "[VDI] vdi_allocate_common_memory, physaddr=%#lx, virtaddr=%#lx\n", vdb.phys_addr, vdb.virt_addr);
  394. // convert os driver buffer type to vpu buffer type
  395. #ifdef SUPPORT_MULTI_CORE_IN_ONE_DRIVER
  396. vdi->pvip->vpu_common_buffer.size = SIZE_COMMON;
  397. vdi->pvip->vpu_common_buffer.phys_addr = (unsigned long)(vdb.phys_addr + (core_idx*SIZE_COMMON));
  398. vdi->pvip->vpu_common_buffer.base = (unsigned long)(vdb.base + (core_idx*SIZE_COMMON));
  399. vdi->pvip->vpu_common_buffer.virt_addr = (unsigned long)(vdb.virt_addr + (core_idx*SIZE_COMMON));
  400. #else
  401. vdi->pvip->vpu_common_buffer.size = SIZE_COMMON;
  402. vdi->pvip->vpu_common_buffer.phys_addr = (unsigned long)(vdb.phys_addr);
  403. vdi->pvip->vpu_common_buffer.base = (unsigned long)(vdb.base);
  404. vdi->pvip->vpu_common_buffer.virt_addr = (unsigned long)(vdb.virt_addr);
  405. #endif
  406. osal_memcpy(&vdi->vpu_common_memory, &vdi->pvip->vpu_common_buffer, sizeof(vpu_buffer_t));
  407. for (i=0; i<MAX_VPU_BUFFER_POOL; i++)
  408. {
  409. if (vdi->vpu_buffer_pool[i].inuse == 0)
  410. {
  411. vdi->vpu_buffer_pool[i].vdb = vdb;
  412. vdi->vpu_buffer_pool_count++;
  413. vdi->vpu_buffer_pool[i].inuse = 1;
  414. break;
  415. }
  416. }
  417. VLOG(INFO, "[VDI] vdi_get_common_memory physaddr=0x%lx, size=%d, virtaddr=0x%lx\n", (int)vdi->vpu_common_memory.phys_addr, (int)vdi->vpu_common_memory.size, (int)vdi->vpu_common_memory.virt_addr);
  418. return 0;
  419. }
  420. vpu_instance_pool_t *vdi_get_instance_pool(unsigned long core_idx)
  421. {
  422. vdi_info_t *vdi;
  423. vpudrv_buffer_t vdb;
  424. if (core_idx >= MAX_NUM_VPU_CORE)
  425. return NULL;
  426. vdi = &s_vdi_info[core_idx];
  427. if(!vdi || vdi->vpu_fd == -1 || vdi->vpu_fd == 0x00 )
  428. return NULL;
  429. osal_memset(&vdb, 0x00, sizeof(vpudrv_buffer_t));
  430. if (!vdi->pvip)
  431. {
  432. void *mutex_addr = NULL;
  433. vdb.size = sizeof(vpu_instance_pool_t);
  434. #ifdef SUPPORT_MULTI_CORE_IN_ONE_DRIVER
  435. vdb.size *= MAX_NUM_VPU_CORE;
  436. #endif
  437. if (ioctl(vdi->vpu_fd, VDI_IOCTL_GET_INSTANCE_POOL, &vdb) < 0)
  438. {
  439. VLOG(ERR, "[VDI] fail to allocate get instance pool physical space=%d\n", (int)vdb.size);
  440. return NULL;
  441. }
  442. #ifdef USE_VMALLOC_FOR_INSTANCE_POOL_MEMORY
  443. vdb.virt_addr = (unsigned long)mmap(NULL, vdb.size, PROT_READ | PROT_WRITE, MAP_SHARED, vdi->vpu_fd, 0);
  444. #else
  445. vdb.virt_addr = (unsigned long)mmap(NULL, vdb.size, PROT_READ | PROT_WRITE, MAP_SHARED, vdi->vpu_fd, vdb.phys_addr);
  446. #endif
  447. if ((void *)vdb.virt_addr == MAP_FAILED)
  448. {
  449. VLOG(ERR, "[VDI] fail to map instance pool phyaddr=0x%lx, size = %d\n", (int)vdb.phys_addr, (int)vdb.size);
  450. return NULL;
  451. }
  452. #ifdef SUPPORT_MULTI_CORE_IN_ONE_DRIVER
  453. vdi->pvip = (vpu_instance_pool_t *)(vdb.virt_addr + (core_idx*sizeof(vpu_instance_pool_t)));
  454. #else
  455. vdi->pvip = (vpu_instance_pool_t *)(vdb.virt_addr);
  456. #endif
  457. if (vdi->pvip && (vdi->pvip->instance_pool_inited == FALSE)) {
  458. mutex_fd = shm_open(VPU_MUTEX_NAME, O_CREAT | O_RDWR | O_TRUNC, S_IRWXU | S_IRWXG);
  459. if (mutex_fd < 0)
  460. {
  461. VLOG(ERR, "[VDI] shm_open failed with %s\n", VPU_MUTEX_NAME);
  462. return NULL;
  463. }
  464. if (ftruncate(mutex_fd, sizeof(MUTEX_HANDLE) * VDI_NUM_LOCK_HANDLES) == -1)
  465. {
  466. shm_unlink(VPU_MUTEX_NAME);
  467. VLOG(ERR, "[VDI] ftruncate failed with %s\n" VPU_MUTEX_NAME);
  468. return NULL;
  469. }
  470. } else {
  471. mutex_fd = shm_open(VPU_MUTEX_NAME, O_RDWR, S_IRWXU | S_IRWXG);
  472. if (mutex_fd < 0)
  473. {
  474. VLOG(ERR, "[VDI] shm_open exist mutex failed with %s\n", VPU_MUTEX_NAME);
  475. return NULL;
  476. }
  477. }
  478. mutex_addr = mmap(NULL, sizeof(MUTEX_HANDLE) * VDI_NUM_LOCK_HANDLES, PROT_READ | PROT_WRITE, MAP_SHARED, mutex_fd, 0);
  479. if (mutex_addr == MAP_FAILED)
  480. {
  481. VLOG(ERR, "[VDI] mmap failed with %s\n", VPU_MUTEX_NAME);
  482. return NULL;
  483. }
  484. vdi->vpu_mutex = mutex_addr;
  485. vdi->vpu_disp_mutex = mutex_addr + sizeof(MUTEX_HANDLE);
  486. vdi->vmem_mutex = mutex_addr + 2 * sizeof(MUTEX_HANDLE);
  487. VLOG(INFO, "[VDI] instance pool physaddr=0x%lx, virtaddr=0x%lx, base=0x%lx, size=%ld\n", (int)vdb.phys_addr, (int)vdb.virt_addr, (int)vdb.base, (int)vdb.size);
  488. }
  489. return (vpu_instance_pool_t *)vdi->pvip;
  490. }
  491. int vdi_open_instance(unsigned long core_idx, unsigned long inst_idx)
  492. {
  493. vdi_info_t *vdi;
  494. vpudrv_inst_info_t inst_info;
  495. if (core_idx >= MAX_NUM_VPU_CORE)
  496. return -1;
  497. vdi = &s_vdi_info[core_idx];
  498. if(!vdi || vdi->vpu_fd == -1 || vdi->vpu_fd == 0x00)
  499. return -1;
  500. inst_info.core_idx = core_idx;
  501. inst_info.inst_idx = inst_idx;
  502. if (ioctl(vdi->vpu_fd, VDI_IOCTL_OPEN_INSTANCE, &inst_info) < 0)
  503. {
  504. VLOG(ERR, "[VDI] fail to deliver open instance num inst_idx=%d\n", (int)inst_idx);
  505. return -1;
  506. }
  507. vdi->pvip->vpu_instance_num = inst_info.inst_open_count;
  508. return 0;
  509. }
  510. int vdi_close_instance(unsigned long core_idx, unsigned long inst_idx)
  511. {
  512. vdi_info_t *vdi;
  513. vpudrv_inst_info_t inst_info = {0, };;
  514. if (core_idx >= MAX_NUM_VPU_CORE)
  515. return -1;
  516. vdi = &s_vdi_info[core_idx];
  517. if(!vdi || vdi->vpu_fd == -1 || vdi->vpu_fd == 0x00)
  518. return -1;
  519. inst_info.core_idx = core_idx;
  520. inst_info.inst_idx = inst_idx;
  521. if (ioctl(vdi->vpu_fd, VDI_IOCTL_CLOSE_INSTANCE, &inst_info) < 0)
  522. {
  523. VLOG(ERR, "[VDI] fail to deliver open instance num inst_idx=%d\n", (int)inst_idx);
  524. return -1;
  525. }
  526. vdi->pvip->vpu_instance_num = inst_info.inst_open_count;
  527. return 0;
  528. }
  529. int vdi_get_instance_num(unsigned long core_idx)
  530. {
  531. vdi_info_t *vdi;
  532. if (core_idx >= MAX_NUM_VPU_CORE)
  533. return -1;
  534. vdi = &s_vdi_info[core_idx];
  535. if(!vdi || vdi->vpu_fd == -1 || vdi->vpu_fd == 0x00)
  536. return -1;
  537. return vdi->pvip->vpu_instance_num;
  538. }
  539. int vdi_hw_reset(unsigned long core_idx) // DEVICE_ADDR_SW_RESET
  540. {
  541. vdi_info_t *vdi;
  542. if (core_idx >= MAX_NUM_VPU_CORE)
  543. return -1;
  544. vdi = &s_vdi_info[core_idx];
  545. if(!vdi || vdi->vpu_fd == -1 || vdi->vpu_fd == 0x00)
  546. return -1;
  547. return ioctl(vdi->vpu_fd, VDI_IOCTL_RESET, 0);
  548. }
  549. int vdi_lock(unsigned long core_idx)
  550. {
  551. vdi_info_t *vdi;
  552. if (core_idx >= MAX_NUM_VPU_CORE)
  553. return -1;
  554. vdi = &s_vdi_info[core_idx];
  555. if(!vdi || vdi->vpu_fd == -1 || vdi->vpu_fd == 0x00)
  556. return -1;
  557. #if defined(ANDROID) || !defined(PTHREAD_MUTEX_ROBUST_NP)
  558. restore_mutex_in_dead((MUTEX_HANDLE *)vdi->vpu_mutex);
  559. pthread_mutex_lock((MUTEX_HANDLE*)vdi->vpu_mutex);
  560. #else
  561. int ret = -1;
  562. ret = pthread_mutex_lock((MUTEX_HANDLE *)vdi->vpu_mutex);
  563. if (ret != 0)
  564. {
  565. if (ret == EOWNERDEAD)
  566. ret = pthread_mutex_consistent((MUTEX_HANDLE *)vdi->vpu_mutex);
  567. if (ret != 0)
  568. {
  569. VLOG(ERR, "%s:%d failed to pthread_mutex_locK\n", __FUNCTION__, __LINE__);
  570. return -1;
  571. }
  572. }
  573. #endif
  574. return 0;//lint !e454
  575. }
  576. void vdi_unlock(unsigned long core_idx)
  577. {
  578. vdi_info_t *vdi;
  579. if (core_idx >= MAX_NUM_VPU_CORE)
  580. return;
  581. vdi = &s_vdi_info[core_idx];
  582. if(!vdi || vdi->vpu_fd == -1 || vdi->vpu_fd == 0x00)
  583. return;
  584. pthread_mutex_unlock((MUTEX_HANDLE *)vdi->vpu_mutex);//lint !e455
  585. }
  586. int vdi_disp_lock(unsigned long core_idx)
  587. {
  588. vdi_info_t *vdi;
  589. if (core_idx >= MAX_NUM_VPU_CORE)
  590. return -1;
  591. vdi = &s_vdi_info[core_idx];
  592. if(!vdi || vdi->vpu_fd == -1 || vdi->vpu_fd == 0x00)
  593. return -1;
  594. #if defined(ANDROID) || !defined(PTHREAD_MUTEX_ROBUST_NP)
  595. restore_mutex_in_dead((MUTEX_HANDLE *)vdi->vpu_disp_mutex);
  596. pthread_mutex_lock((MUTEX_HANDLE*)vdi->vpu_disp_mutex);
  597. #else
  598. int ret = -1;
  599. ret = pthread_mutex_lock((MUTEX_HANDLE *)vdi->vpu_disp_mutex);
  600. if (ret != 0)
  601. {
  602. if (ret == EOWNERDEAD)
  603. ret = pthread_mutex_consistent((MUTEX_HANDLE *)vdi->vpu_disp_mutex);
  604. if (ret != 0)
  605. {
  606. VLOG(ERR, "%s:%d failed to pthread_mutex_lock\n", __FUNCTION__, __LINE__);
  607. return -1;
  608. }
  609. }
  610. #endif /* ANDROID */
  611. return 0;//lint !e454
  612. }
  613. void vdi_disp_unlock(unsigned long core_idx)
  614. {
  615. vdi_info_t *vdi;
  616. if (core_idx >= MAX_NUM_VPU_CORE)
  617. return;
  618. vdi = &s_vdi_info[core_idx];
  619. if(!vdi || vdi->vpu_fd == -1 || vdi->vpu_fd == 0x00)
  620. return;
  621. pthread_mutex_unlock((MUTEX_HANDLE *)vdi->vpu_disp_mutex);//lint !e455
  622. }
  623. void vdi_write_register(unsigned long core_idx, unsigned int addr, unsigned int data)
  624. {
  625. vdi_info_t *vdi;
  626. unsigned long *reg_addr;
  627. if (core_idx >= MAX_NUM_VPU_CORE)
  628. return;
  629. vdi = &s_vdi_info[core_idx];
  630. if(!vdi || vdi->vpu_fd == -1 || vdi->vpu_fd == 0x00)
  631. return;
  632. #ifdef SUPPORT_MULTI_CORE_IN_ONE_DRIVER
  633. reg_addr = (unsigned long *)(addr + (unsigned long)vdi->vdb_register.virt_addr + (core_idx*VPU_CORE_BASE_OFFSET));
  634. #else
  635. reg_addr = (unsigned long *)(addr + (unsigned long)vdi->vdb_register.virt_addr);
  636. #endif
  637. *(volatile unsigned int *)reg_addr = data;
  638. }
  639. unsigned int vdi_read_register(unsigned long core_idx, unsigned int addr)
  640. {
  641. vdi_info_t *vdi;
  642. unsigned long *reg_addr;
  643. if (core_idx >= MAX_NUM_VPU_CORE)
  644. return (unsigned int)-1;
  645. vdi = &s_vdi_info[core_idx];
  646. if(!vdi || vdi->vpu_fd == -1 || vdi->vpu_fd == 0x00)
  647. return (unsigned int)-1;
  648. #ifdef SUPPORT_MULTI_CORE_IN_ONE_DRIVER
  649. reg_addr = (unsigned long *)(addr + (unsigned long)vdi->vdb_register.virt_addr + (core_idx*VPU_CORE_BASE_OFFSET));
  650. #else
  651. reg_addr = (unsigned long *)(addr + (unsigned long)vdi->vdb_register.virt_addr);
  652. #endif
  653. return *(volatile unsigned int *)reg_addr;
  654. }
  655. #define FIO_TIMEOUT 100
  656. unsigned int vdi_fio_read_register(unsigned long core_idx, unsigned int addr)
  657. {
  658. unsigned int ctrl;
  659. unsigned int count = 0;
  660. unsigned int data = 0xffffffff;
  661. ctrl = (addr&0xffff);
  662. ctrl |= (0<<16); /* read operation */
  663. vdi_write_register(core_idx, W5_VPU_FIO_CTRL_ADDR, ctrl);
  664. count = FIO_TIMEOUT;
  665. while (count--) {
  666. ctrl = vdi_read_register(core_idx, W5_VPU_FIO_CTRL_ADDR);
  667. if (ctrl & 0x80000000) {
  668. data = vdi_read_register(core_idx, W5_VPU_FIO_DATA);
  669. break;
  670. }
  671. }
  672. return data;
  673. }
  674. void vdi_fio_write_register(unsigned long core_idx, unsigned int addr, unsigned int data)
  675. {
  676. unsigned int ctrl;
  677. unsigned int count = 0;
  678. vdi_write_register(core_idx, W5_VPU_FIO_DATA, data);
  679. ctrl = (addr&0xffff);
  680. ctrl |= (1<<16); /* write operation */
  681. vdi_write_register(core_idx, W5_VPU_FIO_CTRL_ADDR, ctrl);
  682. count = FIO_TIMEOUT;
  683. while (count--) {
  684. ctrl = vdi_read_register(core_idx, W5_VPU_FIO_CTRL_ADDR);
  685. if (ctrl & 0x80000000) {
  686. break;
  687. }
  688. }
  689. }
  690. int vdi_clear_memory(unsigned long core_idx, PhysicalAddress addr, int len, int endian)
  691. {
  692. vdi_info_t *vdi;
  693. vpudrv_buffer_t vdb;
  694. unsigned long offset;
  695. int i;
  696. Uint8* zero;
  697. #ifdef SUPPORT_MULTI_CORE_IN_ONE_DRIVER
  698. core_idx = 0;
  699. #endif
  700. if (core_idx >= MAX_NUM_VPU_CORE)
  701. return -1;
  702. vdi = &s_vdi_info[core_idx];
  703. if(!vdi || vdi->vpu_fd == -1 || vdi->vpu_fd == 0x00)
  704. return -1;
  705. osal_memset(&vdb, 0x00, sizeof(vpudrv_buffer_t));
  706. for (i=0; i<MAX_VPU_BUFFER_POOL; i++)
  707. {
  708. if (vdi->vpu_buffer_pool[i].inuse == 1)
  709. {
  710. vdb = vdi->vpu_buffer_pool[i].vdb;
  711. if (addr >= vdb.phys_addr && addr < (vdb.phys_addr + vdb.size))
  712. break;
  713. }
  714. }
  715. if (!vdb.size) {
  716. VLOG(ERR, "address 0x%08x is not mapped address!!!\n", (int)addr);
  717. return -1;
  718. }
  719. zero = (Uint8*)osal_malloc(len);
  720. osal_memset((void*)zero, 0x00, len);
  721. offset = addr - (unsigned long)vdb.phys_addr;
  722. osal_memcpy((void *)((unsigned long)vdb.virt_addr+offset), zero, len);
  723. vdi_flush_ddr(core_idx,(unsigned long )(vdb.phys_addr+offset),len,1);
  724. osal_free(zero);
  725. return len;
  726. }
  727. int vdi_write_memory(unsigned long core_idx, PhysicalAddress addr, unsigned char *data, int len, int endian)
  728. {
  729. vdi_info_t *vdi;
  730. vpudrv_buffer_t vdb;
  731. unsigned long offset;
  732. int i;
  733. #ifdef SUPPORT_MULTI_CORE_IN_ONE_DRIVER
  734. core_idx = 0;
  735. #endif
  736. if (core_idx >= MAX_NUM_VPU_CORE)
  737. return -1;
  738. if (!data)
  739. return -1;
  740. vdi = &s_vdi_info[core_idx];
  741. if(!vdi || vdi->vpu_fd==-1 || vdi->vpu_fd == 0x00)
  742. return -1;
  743. osal_memset(&vdb, 0x00, sizeof(vpudrv_buffer_t));
  744. for (i=0; i<MAX_VPU_BUFFER_POOL; i++)
  745. {
  746. if (vdi->vpu_buffer_pool[i].inuse == 1)
  747. {
  748. vdb = vdi->vpu_buffer_pool[i].vdb;
  749. if (addr >= vdb.phys_addr && addr < (vdb.phys_addr + vdb.size)) {
  750. break;
  751. }
  752. }
  753. }
  754. if (!vdb.size) {
  755. VLOG(ERR, "address 0x%08x is not mapped address!!!\n", (int)addr);
  756. return -1;
  757. }
  758. #if 0 //def CNM_FPGA_PLATFORM
  759. // to check some writing of common buffer
  760. if (vdb.phys_addr >= vdi->vpu_common_memory.phys_addr &&
  761. vdb.phys_addr < (vdi->vpu_common_memory.phys_addr + SIZE_COMMON))
  762. {
  763. if (PRODUCT_CODE_W_SERIES(vdi->product_code))
  764. {
  765. if (vdi_read_register(core_idx, W5_VCPU_CUR_PC) != 0)
  766. {
  767. VLOG(ERR, "not to permit writing common buffer addr=%lx, size=%d\n", vdb.phys_addr, vdb.size);
  768. VLOG(ERR, "this process will be exit\n");
  769. exit(-1);
  770. }
  771. }
  772. else if (PRODUCT_CODE_NOT_W_SERIES(vdi->product_code)) {
  773. }
  774. else {
  775. VLOG(ERR, "Unknown product id : %08x\n", vdi->product_code);
  776. return -1;
  777. }
  778. }
  779. #endif
  780. offset = addr - (unsigned long)vdb.phys_addr;
  781. swap_endian(core_idx, data, len, endian);
  782. osal_memcpy((void *)((unsigned long)vdb.virt_addr+offset), data, len);
  783. vdi_flush_ddr(core_idx,(unsigned long )(vdb.phys_addr+offset),len,1);
  784. return len;
  785. }
  786. int vdi_read_memory(unsigned long core_idx, PhysicalAddress addr, unsigned char *data, int len, int endian)
  787. {
  788. vdi_info_t *vdi;
  789. vpudrv_buffer_t vdb;
  790. unsigned long offset;
  791. int i;
  792. #ifdef SUPPORT_MULTI_CORE_IN_ONE_DRIVER
  793. core_idx = 0;
  794. #endif
  795. if (core_idx >= MAX_NUM_VPU_CORE)
  796. return -1;
  797. vdi = &s_vdi_info[core_idx];
  798. if(!vdi || vdi->vpu_fd==-1 || vdi->vpu_fd == 0x00)
  799. return -1;
  800. osal_memset(&vdb, 0x00, sizeof(vpudrv_buffer_t));
  801. for (i=0; i<MAX_VPU_BUFFER_POOL; i++)
  802. {
  803. if (vdi->vpu_buffer_pool[i].inuse == 1)
  804. {
  805. vdb = vdi->vpu_buffer_pool[i].vdb;
  806. if (addr >= vdb.phys_addr && addr < (vdb.phys_addr + vdb.size))
  807. break;
  808. }
  809. }
  810. if (!vdb.size)
  811. return -1;
  812. offset = addr - (unsigned long)vdb.phys_addr;
  813. //vdi_flush_ddr(core_idx,(unsigned long )(vdb.phys_addr+offset),len,1);
  814. osal_memcpy(data, (const void *)((unsigned long)vdb.virt_addr+offset), len);
  815. swap_endian(core_idx, data, len, endian);
  816. return len;
  817. }
  818. // return the vpudrv_buffer_t virt addr, not copy data
  819. int vdi_read_memory2(unsigned long core_idx, PhysicalAddress addr, unsigned char **ppdata, int len, int endian)
  820. {
  821. vdi_info_t *vdi;
  822. vpudrv_buffer_t vdb;
  823. unsigned long offset;
  824. int i;
  825. #ifdef SUPPORT_MULTI_CORE_IN_ONE_DRIVER
  826. core_idx = 0;
  827. #endif
  828. if (core_idx >= MAX_NUM_VPU_CORE)
  829. return -1;
  830. vdi = &s_vdi_info[core_idx];
  831. if(!vdi || vdi->vpu_fd==-1 || vdi->vpu_fd == 0x00)
  832. return -1;
  833. osal_memset(&vdb, 0x00, sizeof(vpudrv_buffer_t));
  834. for (i=0; i<MAX_VPU_BUFFER_POOL; i++)
  835. {
  836. if (vdi->vpu_buffer_pool[i].inuse == 1)
  837. {
  838. vdb = vdi->vpu_buffer_pool[i].vdb;
  839. if (addr >= vdb.phys_addr && addr < (vdb.phys_addr + vdb.size))
  840. break;
  841. }
  842. }
  843. if (!vdb.size)
  844. return -1;
  845. offset = addr - (unsigned long)vdb.phys_addr;
  846. //vdi_flush_ddr(core_idx,(unsigned long )(vdb.phys_addr+offset),len,1);
  847. *ppdata = (unsigned char *)(vdb.virt_addr + offset);
  848. swap_endian(core_idx, *ppdata, len, endian);
  849. return len;
  850. }
  851. void* vdi_map_virt2(unsigned long core_idx, int size, PhysicalAddress bufY)
  852. {
  853. vdi_info_t *vdi = &s_vdi_info[core_idx];
  854. void *virt_addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, vdi->vpu_fd, bufY);
  855. return virt_addr;
  856. }
  857. int vdi_virt_to_phys(unsigned long core_idx, vpu_buffer_t *vb)
  858. {
  859. vdi_info_t *vdi;
  860. vpudrv_buffer_t vdb;
  861. #ifdef SUPPORT_MULTI_CORE_IN_ONE_DRIVER
  862. core_idx = 0;
  863. #endif
  864. if (core_idx >= MAX_NUM_VPU_CORE)
  865. return -1;
  866. vdi = &s_vdi_info[core_idx];
  867. if(!vdi || vdi->vpu_fd==-1 || vdi->vpu_fd == 0x00)
  868. return -1;
  869. osal_memset(&vdb, 0x00, sizeof(vpudrv_buffer_t));
  870. vdb.virt_addr = vb->virt_addr;
  871. if (ioctl(vdi->vpu_fd, VDI_IOCTL_GET_PHYSICAL_MEMORY, &vdb) < 0)
  872. {
  873. VLOG(ERR, "[VDI] fail to GET_PHYSICAL_MEMORY\n");
  874. return -1;
  875. }
  876. vb->phys_addr = (unsigned long)vdb.phys_addr;
  877. vb->base = (unsigned long)vdb.base;
  878. VLOG(INFO, "get phy = %#x vb->phy = %#x, base=%lx\n", vdb.phys_addr, vb->phys_addr, vb->base);
  879. return 0;
  880. }
  881. void* vdi_remap_vaddr(unsigned long coreIndex, unsigned long virtAddress, unsigned int size)
  882. {
  883. vpu_buffer_t vb;
  884. vdi_info_t *vdi;
  885. void *vaddr;
  886. if (coreIndex >= MAX_NUM_VPU_CORE)
  887. return NULL;
  888. vb.virt_addr = virtAddress;
  889. vb.size = size;
  890. vdi = &s_vdi_info[coreIndex];
  891. vdi_virt_to_phys(coreIndex, &vb);
  892. vaddr = (void *)mmap(NULL, vb.size, PROT_READ | PROT_WRITE,
  893. MAP_SHARED, vdi->vpu_fd, vb.phys_addr);
  894. return vaddr;
  895. }
  896. int vdi_allocate_dma_memory(unsigned long core_idx, vpu_buffer_t *vb, int memTypes, int instIndex)
  897. {
  898. vdi_info_t *vdi;
  899. int i;
  900. vpudrv_buffer_t vdb;
  901. #ifdef SUPPORT_MULTI_CORE_IN_ONE_DRIVER
  902. core_idx = 0;
  903. #endif
  904. if (core_idx >= MAX_NUM_VPU_CORE)
  905. return -1;
  906. vdi = &s_vdi_info[core_idx];
  907. if(!vdi || vdi->vpu_fd==-1 || vdi->vpu_fd == 0x00)
  908. return -1;
  909. osal_memset(&vdb, 0x00, sizeof(vpudrv_buffer_t));
  910. vdb.size = vb->size;
  911. if (ioctl(vdi->vpu_fd, VDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY, &vdb) < 0)
  912. {
  913. VLOG(ERR, "[VDI] fail to vdi_allocate_dma_memory size=%d\n", vb->size);
  914. return -1;
  915. }
  916. vb->phys_addr = (unsigned long)vdb.phys_addr;
  917. vb->base = (unsigned long)vdb.base;
  918. //map to virtual address
  919. vdb.virt_addr = (unsigned long)mmap(NULL, vdb.size, PROT_READ | PROT_WRITE,
  920. MAP_SHARED, vdi->vpu_fd, vdb.phys_addr);
  921. if ((void *)vdb.virt_addr == MAP_FAILED)
  922. {
  923. memset(vb, 0x00, sizeof(vpu_buffer_t));
  924. return -1;
  925. }
  926. vb->virt_addr = vdb.virt_addr;
  927. vmem_lock(vdi);
  928. for (i=0; i<MAX_VPU_BUFFER_POOL; i++)
  929. {
  930. if (vdi->vpu_buffer_pool[i].inuse == 0)
  931. {
  932. vdi->vpu_buffer_pool[i].vdb = vdb;
  933. vdi->vpu_buffer_pool_count++;
  934. vdi->vpu_buffer_pool[i].inuse = 1;
  935. break;
  936. }
  937. }
  938. vmem_unlock(vdi);
  939. VLOG(INFO, "[VDI] vdi_allocate_dma_memory, physaddr=%#x, virtaddr=%#lx~0x%#lx, size=%d, memType=%d\n",
  940. vb->phys_addr, vb->virt_addr, vb->virt_addr + vb->size, vb->size, memTypes);
  941. return 0;
  942. }
  943. unsigned long vdi_get_dma_memory_free_size(unsigned long coreIdx)
  944. {
  945. vdi_info_t *vdi;
  946. int size;
  947. vdi = &s_vdi_info[coreIdx];
  948. if(!vdi || vdi->vpu_fd==-1 || vdi->vpu_fd == 0x00)
  949. return (unsigned long)-1;
  950. if (ioctl(vdi->vpu_fd, VDI_IOCTL_GET_FREE_MEM_SIZE, &size) < 0) {
  951. VLOG(ERR, "[VDI] fail VDI_IOCTL_GET_FREE_MEM_SIZE size=%d\n", size);
  952. return 0;
  953. }
  954. return size;
  955. }
  956. int vdi_attach_dma_memory(unsigned long core_idx, vpu_buffer_t *vb)
  957. {
  958. vdi_info_t *vdi;
  959. int i;
  960. vpudrv_buffer_t vdb;
  961. #ifdef SUPPORT_MULTI_CORE_IN_ONE_DRIVER
  962. core_idx = 0;
  963. #endif
  964. if (core_idx >= MAX_NUM_VPU_CORE)
  965. return -1;
  966. vdi = &s_vdi_info[core_idx];
  967. if(!vdi || vdi->vpu_fd==-1 || vdi->vpu_fd == 0x00)
  968. return -1;
  969. osal_memset(&vdb, 0x00, sizeof(vpudrv_buffer_t));
  970. vdb.size = vb->size;
  971. vdb.phys_addr = vb->phys_addr;
  972. vdb.base = vb->base;
  973. vdb.virt_addr = vb->virt_addr;
  974. vmem_lock(vdi);
  975. for (i=0; i<MAX_VPU_BUFFER_POOL; i++)
  976. {
  977. if (vdi->vpu_buffer_pool[i].vdb.phys_addr == vb->phys_addr)
  978. {
  979. vdi->vpu_buffer_pool[i].vdb = vdb;
  980. vdi->vpu_buffer_pool[i].inuse = 1;
  981. break;
  982. }
  983. else
  984. {
  985. if (vdi->vpu_buffer_pool[i].inuse == 0)
  986. {
  987. vdi->vpu_buffer_pool[i].vdb = vdb;
  988. vdi->vpu_buffer_pool_count++;
  989. vdi->vpu_buffer_pool[i].inuse = 1;
  990. break;
  991. }
  992. }
  993. }
  994. vmem_unlock(vdi);
  995. VLOG(INFO, "[VDI] vdi_attach_dma_memory, physaddr=0x%#x, virtaddr=0x%lx, size=%d, index=%d\n", vb->phys_addr, vb->virt_addr, vb->size, i);
  996. return 0;
  997. }
  998. int vdi_dettach_dma_memory(unsigned long core_idx, vpu_buffer_t *vb)
  999. {
  1000. vdi_info_t *vdi;
  1001. int i;
  1002. #ifdef SUPPORT_MULTI_CORE_IN_ONE_DRIVER
  1003. core_idx = 0;
  1004. #endif
  1005. if (core_idx >= MAX_NUM_VPU_CORE)
  1006. return -1;
  1007. vdi = &s_vdi_info[core_idx];
  1008. if(!vb || !vdi || vdi->vpu_fd==-1 || vdi->vpu_fd == 0x00)
  1009. return -1;
  1010. if (vb->size == 0)
  1011. return -1;
  1012. vmem_lock(vdi);
  1013. for (i=0; i<MAX_VPU_BUFFER_POOL; i++)
  1014. {
  1015. if (vdi->vpu_buffer_pool[i].vdb.phys_addr == vb->phys_addr)
  1016. {
  1017. vdi->vpu_buffer_pool[i].inuse = 0;
  1018. vdi->vpu_buffer_pool_count--;
  1019. break;
  1020. }
  1021. }
  1022. vmem_unlock(vdi);
  1023. return 0;
  1024. }
  1025. void vdi_free_dma_memory(unsigned long core_idx, vpu_buffer_t *vb, int memTypes, int instIndex)
  1026. {
  1027. vdi_info_t *vdi;
  1028. int i;
  1029. vpudrv_buffer_t vdb;
  1030. #ifdef SUPPORT_MULTI_CORE_IN_ONE_DRIVER
  1031. core_idx = 0;
  1032. #endif
  1033. if (core_idx >= MAX_NUM_VPU_CORE)
  1034. return;
  1035. vdi = &s_vdi_info[core_idx];
  1036. if(!vb || !vdi || vdi->vpu_fd==-1 || vdi->vpu_fd == 0x00)
  1037. return;
  1038. if (vb->size == 0)
  1039. return ;
  1040. osal_memset(&vdb, 0x00, sizeof(vpudrv_buffer_t));
  1041. vmem_lock(vdi);
  1042. for (i=0; i<MAX_VPU_BUFFER_POOL; i++)
  1043. {
  1044. /* add more constraints for finding the correct buffer */
  1045. if ((vdi->vpu_buffer_pool[i].vdb.phys_addr == vb->phys_addr)
  1046. && (vdi->vpu_buffer_pool[i].vdb.size == vb->size)
  1047. && (vdi->vpu_buffer_pool[i].vdb.virt_addr == vb->virt_addr))
  1048. {
  1049. vdi->vpu_buffer_pool[i].inuse = 0;
  1050. vdi->vpu_buffer_pool_count--;
  1051. vdb = vdi->vpu_buffer_pool[i].vdb;
  1052. break;
  1053. }
  1054. }
  1055. vmem_unlock(vdi);
  1056. if (!vdb.size)
  1057. {
  1058. VLOG(ERR, "[VDI] invalid buffer to free address = 0x%lx\n", (int)vdb.virt_addr);
  1059. return ;
  1060. }
  1061. ioctl(vdi->vpu_fd, VDI_IOCTL_FREE_PHYSICALMEMORY, &vdb);
  1062. if (munmap((void *)vdb.virt_addr, vdb.size) != 0)
  1063. {
  1064. VLOG(ERR, "[VDI] fail to vdi_free_dma_memory virtial address = 0x%lx\n", (int)vdb.virt_addr);
  1065. }
  1066. osal_memset(vb, 0, sizeof(vpu_buffer_t));
  1067. }
  1068. int vdi_get_sram_memory(unsigned long core_idx, vpu_buffer_t *vb)
  1069. {
  1070. vdi_info_t *vdi = NULL;
  1071. vpudrv_buffer_t vdb;
  1072. unsigned int sram_size = 0;
  1073. if (core_idx >= MAX_NUM_VPU_CORE)
  1074. return -1;
  1075. vdi = &s_vdi_info[core_idx];
  1076. if(!vb || !vdi || vdi->vpu_fd==-1 || vdi->vpu_fd == 0x00)
  1077. return -1;
  1078. osal_memset(&vdb, 0x00, sizeof(vpudrv_buffer_t));
  1079. switch (vdi->product_code) {
  1080. case BODA950_CODE:
  1081. case CODA960_CODE:
  1082. case CODA980_CODE:
  1083. sram_size = VDI_CODA9_SRAM_SIZE; break;
  1084. case WAVE511_CODE:
  1085. sram_size = VDI_WAVE511_SRAM_SIZE; break;
  1086. case WAVE521_CODE:
  1087. sram_size = VDI_WAVE521_SRAM_SIZE; break;
  1088. case WAVE521C_CODE:
  1089. sram_size = VDI_WAVE521C_SRAM_SIZE; break;
  1090. case WAVE521C_DUAL_CODE:
  1091. sram_size = VDI_WAVE521C_SRAM_SIZE; break;
  1092. case WAVE517_CODE:
  1093. sram_size = VDI_WAVE521C_SRAM_SIZE; break;
  1094. default:
  1095. VLOG(ERR, "[VDI] check product_code(%x)\n", vdi->product_code);
  1096. break;
  1097. }
  1098. if (sram_size > 0) // if we can know the sram address directly in vdi layer, we use it first for sdram address
  1099. {
  1100. vb->phys_addr = VDI_SRAM_BASE_ADDR+(core_idx*sram_size); // HOST can set DRAM base addr to VDI_SRAM_BASE_ADDR.
  1101. vb->size = sram_size;
  1102. return 0;
  1103. }
  1104. return 0;
  1105. }
  1106. int vdi_set_clock_gate(unsigned long core_idx, int enable)
  1107. {
  1108. vdi_info_t *vdi = NULL;
  1109. int ret;
  1110. if (core_idx >= MAX_NUM_VPU_CORE)
  1111. return -1;
  1112. vdi = &s_vdi_info[core_idx];
  1113. if(!vdi || vdi->vpu_fd==-1 || vdi->vpu_fd == 0x00)
  1114. return -1;
  1115. if (vdi->product_code == WAVE512_CODE || vdi->product_code == WAVE515_CODE || vdi->product_code == WAVE517_CODE ||
  1116. vdi->product_code == WAVE521_CODE || vdi->product_code == WAVE521C_CODE || vdi->product_code == WAVE521C_DUAL_CODE ) {
  1117. return 0;
  1118. }
  1119. vdi->clock_state = enable;
  1120. ret = ioctl(vdi->vpu_fd, VDI_IOCTL_SET_CLOCK_GATE, &enable);
  1121. return ret;
  1122. }
  1123. int vdi_get_clock_gate(unsigned long core_idx)
  1124. {
  1125. vdi_info_t *vdi;
  1126. int ret;
  1127. if (core_idx >= MAX_NUM_VPU_CORE)
  1128. return -1;
  1129. vdi = &s_vdi_info[core_idx];
  1130. if(!vdi || vdi->vpu_fd==-1 || vdi->vpu_fd == 0x00)
  1131. return -1;
  1132. ret = vdi->clock_state;
  1133. return ret;
  1134. }
  1135. static int get_pc_addr(Uint32 product_code)
  1136. {
  1137. if (PRODUCT_CODE_W_SERIES(product_code)) {
  1138. return W5_VCPU_CUR_PC;
  1139. }
  1140. else if (PRODUCT_CODE_NOT_W_SERIES(product_code)) {
  1141. return BIT_CUR_PC;
  1142. }
  1143. else {
  1144. VLOG(ERR, "Unknown product id : %08x\n", product_code);
  1145. return -1;
  1146. }
  1147. }
  1148. int vdi_wait_bus_busy(unsigned long core_idx, int timeout, unsigned int gdi_busy_flag)
  1149. {
  1150. Uint64 elapse, cur;
  1151. Uint32 pc;
  1152. vdi_info_t *vdi;
  1153. vdi = &s_vdi_info[core_idx];
  1154. elapse = osal_gettime();
  1155. pc = get_pc_addr(vdi->product_code);
  1156. while(1)
  1157. {
  1158. if (vdi->product_code == WAVE521_CODE || vdi->product_code == WAVE521C_CODE || vdi->product_code == WAVE511_CODE || vdi->product_code == WAVE521C_DUAL_CODE ||
  1159. vdi->product_code == WAVE517_CODE) {
  1160. if (vdi_fio_read_register(core_idx, gdi_busy_flag) == 0x3f) break;
  1161. }
  1162. else if (PRODUCT_CODE_W_SERIES(vdi->product_code)) {
  1163. if (vdi_fio_read_register(core_idx, gdi_busy_flag) == 0x738) break;
  1164. }
  1165. else if (PRODUCT_CODE_NOT_W_SERIES(vdi->product_code)) {
  1166. if (vdi_read_register(core_idx, gdi_busy_flag) == 0x77) break;
  1167. }
  1168. else {
  1169. VLOG(ERR, "Unknown product id : %08x\n", vdi->product_code);
  1170. return -1;
  1171. }
  1172. if (timeout > 0) {
  1173. cur = osal_gettime();
  1174. if ((cur - elapse) > timeout) {
  1175. print_busy_timeout_status(core_idx, vdi->product_code, pc);
  1176. return -1;
  1177. }
  1178. }
  1179. }
  1180. return 0;
  1181. }
  1182. int vdi_wait_vpu_busy(unsigned long core_idx, int timeout, unsigned int addr_bit_busy_flag)
  1183. {
  1184. Uint64 elapse, cur;
  1185. Uint32 pc;
  1186. Uint32 normalReg = TRUE;
  1187. vdi_info_t *vdi;
  1188. vdi = &s_vdi_info[core_idx];
  1189. elapse = osal_gettime();
  1190. pc = get_pc_addr(vdi->product_code);
  1191. if (PRODUCT_CODE_W_SERIES(vdi->product_code) && (addr_bit_busy_flag&0x8000) ) {
  1192. normalReg = FALSE;
  1193. }
  1194. while(1)
  1195. {
  1196. if (normalReg == TRUE) {
  1197. if (vdi_read_register(core_idx, addr_bit_busy_flag) == 0) break;
  1198. }
  1199. else {
  1200. if (vdi_fio_read_register(core_idx, addr_bit_busy_flag) == 0) break;
  1201. }
  1202. if (timeout > 0) {
  1203. cur = osal_gettime();
  1204. if ((cur - elapse) > timeout) {
  1205. print_busy_timeout_status(core_idx, vdi->product_code, pc);
  1206. return -1;
  1207. }
  1208. }
  1209. }
  1210. return 0;
  1211. }
  1212. int vdi_wait_vcpu_bus_busy(unsigned long core_idx, int timeout, unsigned int addr_bit_busy_flag)
  1213. {
  1214. Uint64 elapse, cur;
  1215. Uint32 pc;
  1216. Uint32 normalReg = TRUE;
  1217. vdi_info_t *vdi;
  1218. vdi = &s_vdi_info[core_idx];
  1219. elapse = osal_gettime();
  1220. pc = get_pc_addr(vdi->product_code);
  1221. if (PRODUCT_CODE_W_SERIES(vdi->product_code) && (addr_bit_busy_flag&0x8000) ) {
  1222. normalReg = FALSE;
  1223. }
  1224. while(1)
  1225. {
  1226. if (normalReg == TRUE) {
  1227. if (vdi_read_register(core_idx, addr_bit_busy_flag) == 0x40) break;
  1228. }
  1229. else {
  1230. if (vdi_fio_read_register(core_idx, addr_bit_busy_flag) == 0x40) break;
  1231. }
  1232. if (timeout > 0) {
  1233. cur = osal_gettime();
  1234. if ((cur - elapse) > timeout) {
  1235. print_busy_timeout_status(core_idx, vdi->product_code, pc);
  1236. return -1;
  1237. }
  1238. }
  1239. }
  1240. return 0;
  1241. }
  1242. #ifdef SUPPORT_MULTI_INST_INTR
  1243. int vdi_wait_interrupt(unsigned long coreIdx, unsigned int instIdx, int timeout)
  1244. #else
  1245. int vdi_wait_interrupt(unsigned long coreIdx, int timeout)
  1246. #endif
  1247. {
  1248. int intr_reason = 0;
  1249. #ifdef SUPPORT_INTERRUPT
  1250. int ret;
  1251. #endif
  1252. vdi_info_t *vdi;
  1253. vpudrv_intr_info_t intr_info;
  1254. if (coreIdx >= MAX_NUM_VPU_CORE)
  1255. return -1;
  1256. vdi = &s_vdi_info[coreIdx];
  1257. if(!vdi || vdi->vpu_fd == -1 || vdi->vpu_fd == 0x00)
  1258. return -1;
  1259. #ifdef SUPPORT_INTERRUPT
  1260. intr_info.timeout = timeout;
  1261. intr_info.intr_reason = 0;
  1262. #ifdef SUPPORT_MULTI_INST_INTR
  1263. intr_info.intr_inst_index = instIdx;
  1264. #endif
  1265. ret = ioctl(vdi->vpu_fd, VDI_IOCTL_WAIT_INTERRUPT, (void*)&intr_info);
  1266. if (ret != 0)
  1267. return -1;
  1268. intr_reason = intr_info.intr_reason;
  1269. #else
  1270. struct timeval tv = {0};
  1271. Uint32 int_sts_reg;
  1272. Uint32 int_reason_reg;
  1273. Uint64 startTime, endTime;
  1274. UNREFERENCED_PARAMETER(intr_info);
  1275. if (PRODUCT_CODE_W_SERIES(vdi->product_code)) {
  1276. int_sts_reg = W5_VPU_VPU_INT_STS;
  1277. }
  1278. else if (PRODUCT_CODE_NOT_W_SERIES(vdi->product_code)) {
  1279. int_sts_reg = BIT_INT_STS;
  1280. }
  1281. else {
  1282. VLOG(ERR, "Unknown product id : %08x\n", vdi->product_code);
  1283. return -1;
  1284. }
  1285. if (PRODUCT_CODE_W_SERIES(vdi->product_code)) {
  1286. int_reason_reg = W5_VPU_VINT_REASON;
  1287. }
  1288. else {
  1289. int_reason_reg = BIT_INT_REASON;
  1290. }
  1291. startTime = osal_gettime();
  1292. while (TRUE) {
  1293. if (vdi_read_register(coreIdx, int_sts_reg)) {
  1294. if ((intr_reason=vdi_read_register(coreIdx, int_reason_reg))) {
  1295. if (PRODUCT_CODE_W_SERIES(vdi->product_code)) {
  1296. vdi_write_register(coreIdx, W5_VPU_VINT_REASON_CLR, intr_reason);
  1297. vdi_write_register(coreIdx, W5_VPU_VINT_CLEAR, 0x1);
  1298. }
  1299. else {
  1300. vdi_write_register(coreIdx, BIT_INT_CLEAR, 0x1);
  1301. }
  1302. break;
  1303. }
  1304. }
  1305. endTime = osal_gettime();
  1306. if (timeout > 0 && (endTime-startTime) >= timeout) {
  1307. return -1;
  1308. }
  1309. }
  1310. #endif
  1311. return intr_reason;
  1312. }
  1313. //------------------------------------------------------------------------------
  1314. // LOG & ENDIAN functions
  1315. //------------------------------------------------------------------------------
  1316. int vdi_get_system_endian(unsigned long core_idx)
  1317. {
  1318. vdi_info_t *vdi;
  1319. if (core_idx >= MAX_NUM_VPU_CORE)
  1320. return -1;
  1321. vdi = &s_vdi_info[core_idx];
  1322. if(!vdi || vdi->vpu_fd == -1 || vdi->vpu_fd == 0x00)
  1323. return -1;
  1324. if (PRODUCT_CODE_W_SERIES(vdi->product_code)) {
  1325. return VDI_128BIT_BUS_SYSTEM_ENDIAN;
  1326. }
  1327. else if(PRODUCT_CODE_NOT_W_SERIES(vdi->product_code)) {
  1328. return VDI_SYSTEM_ENDIAN;
  1329. }
  1330. else {
  1331. VLOG(ERR, "Unknown product id : %08x\n", vdi->product_code);
  1332. return -1;
  1333. }
  1334. }
  1335. int vdi_convert_endian(unsigned long core_idx, unsigned int endian)
  1336. {
  1337. vdi_info_t *vdi;
  1338. if (core_idx >= MAX_NUM_VPU_CORE)
  1339. return -1;
  1340. vdi = &s_vdi_info[core_idx];
  1341. if(!vdi || !vdi || vdi->vpu_fd == -1 || vdi->vpu_fd == 0x00)
  1342. return -1;
  1343. if (PRODUCT_CODE_W_SERIES(vdi->product_code)) {
  1344. switch (endian) {
  1345. case VDI_LITTLE_ENDIAN: endian = 0x00; break;
  1346. case VDI_BIG_ENDIAN: endian = 0x0f; break;
  1347. case VDI_32BIT_LITTLE_ENDIAN: endian = 0x04; break;
  1348. case VDI_32BIT_BIG_ENDIAN: endian = 0x03; break;
  1349. }
  1350. }
  1351. else if(PRODUCT_CODE_NOT_W_SERIES(vdi->product_code)) {
  1352. }
  1353. else {
  1354. VLOG(ERR, "Unknown product id : %08x\n", vdi->product_code);
  1355. return -1;
  1356. }
  1357. return (endian&0x0f);
  1358. }
  1359. static Uint32 convert_endian_coda9_to_wave4(Uint32 endian)
  1360. {
  1361. Uint32 converted_endian = endian;
  1362. switch(endian) {
  1363. case VDI_LITTLE_ENDIAN: converted_endian = 0; break;
  1364. case VDI_BIG_ENDIAN: converted_endian = 7; break;
  1365. case VDI_32BIT_LITTLE_ENDIAN: converted_endian = 4; break;
  1366. case VDI_32BIT_BIG_ENDIAN: converted_endian = 3; break;
  1367. }
  1368. return converted_endian;
  1369. }
  1370. int swap_endian(unsigned long core_idx, unsigned char *data, int len, int endian)
  1371. {
  1372. vdi_info_t *vdi;
  1373. int changes;
  1374. int sys_endian;
  1375. BOOL byteChange, wordChange, dwordChange, lwordChange;
  1376. if (core_idx >= MAX_NUM_VPU_CORE)
  1377. return -1;
  1378. vdi = &s_vdi_info[core_idx];
  1379. if(!vdi || vdi->vpu_fd == -1 || vdi->vpu_fd == 0x00)
  1380. return -1;
  1381. if (PRODUCT_CODE_W_SERIES(vdi->product_code)) {
  1382. sys_endian = VDI_128BIT_BUS_SYSTEM_ENDIAN;
  1383. }
  1384. else if(PRODUCT_CODE_NOT_W_SERIES(vdi->product_code)) {
  1385. sys_endian = VDI_SYSTEM_ENDIAN;
  1386. }
  1387. else {
  1388. VLOG(ERR, "Unknown product id : %08x\n", vdi->product_code);
  1389. return -1;
  1390. }
  1391. endian = vdi_convert_endian(core_idx, endian);
  1392. sys_endian = vdi_convert_endian(core_idx, sys_endian);
  1393. if (endian == sys_endian)
  1394. return 0;
  1395. if (PRODUCT_CODE_W_SERIES(vdi->product_code)) {
  1396. }
  1397. else if (PRODUCT_CODE_NOT_W_SERIES(vdi->product_code)) {
  1398. endian = convert_endian_coda9_to_wave4(endian);
  1399. sys_endian = convert_endian_coda9_to_wave4(sys_endian);
  1400. }
  1401. else {
  1402. VLOG(ERR, "Unknown product id : %08x\n", vdi->product_code);
  1403. return -1;
  1404. }
  1405. changes = endian ^ sys_endian;
  1406. byteChange = changes&0x01;
  1407. wordChange = ((changes&0x02) == 0x02);
  1408. dwordChange = ((changes&0x04) == 0x04);
  1409. lwordChange = ((changes&0x08) == 0x08);
  1410. if (byteChange) byte_swap(data, len);
  1411. if (wordChange) word_swap(data, len);
  1412. if (dwordChange) dword_swap(data, len);
  1413. if (lwordChange) lword_swap(data, len);
  1414. return 1;
  1415. }
  1416. #endif //#if defined(linux) || defined(__linux) || defined(ANDROID)