encasiccontroller_v2.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /*------------------------------------------------------------------------------
  2. -- --
  3. -- This software is confidential and proprietary and may be used --
  4. -- only as expressly authorized by a licensing agreement from --
  5. -- --
  6. -- Hantro Products Oy. --
  7. -- --
  8. -- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
  9. -- ALL RIGHTS RESERVED --
  10. -- --
  11. -- The entire notice above must be reproduced --
  12. -- on all copies and should not be removed. --
  13. -- --
  14. --------------------------------------------------------------------------------
  15. --
  16. -- Description : ASIC low level controller
  17. --
  18. ------------------------------------------------------------------------------*/
  19. /*------------------------------------------------------------------------------
  20. Include headers
  21. ------------------------------------------------------------------------------*/
  22. #include "encpreprocess.h"
  23. #include "encasiccontroller.h"
  24. #include "enccommon.h"
  25. #include "ewl.h"
  26. /*------------------------------------------------------------------------------
  27. External compiler flags
  28. ------------------------------------------------------------------------------*/
  29. /*------------------------------------------------------------------------------
  30. Module defines
  31. ------------------------------------------------------------------------------*/
  32. /* Mask fields */
  33. #define mask_2b (u32)0x00000003
  34. #define mask_3b (u32)0x00000007
  35. #define mask_4b (u32)0x0000000F
  36. #define mask_5b (u32)0x0000001F
  37. #define mask_6b (u32)0x0000003F
  38. #define mask_11b (u32)0x000007FF
  39. #define mask_14b (u32)0x00003FFF
  40. #define mask_16b (u32)0x0000FFFF
  41. #define HSWREG(n) ((n)*4)
  42. /*------------------------------------------------------------------------------
  43. Local function prototypes
  44. ------------------------------------------------------------------------------*/
  45. /*------------------------------------------------------------------------------
  46. EncAsicMemAlloc_V2
  47. Allocate HW/SW shared memory
  48. Input:
  49. asic asicData structure
  50. width width of encoded image, multiple of four
  51. height height of encoded image
  52. type ASIC_MPEG4 / ASIC_H263 / ASIC_JPEG
  53. numRefBuffs amount of reference luma frame buffers to be allocated
  54. Output:
  55. asic base addresses point to allocated memory areas
  56. Return:
  57. ENCHW_OK Success.
  58. ENCHW_NOK Error: memory allocation failed, no memories allocated
  59. and EWL instance released
  60. ------------------------------------------------------------------------------*/
  61. i32 EncAsicMemAlloc_V2(asicData_s * asic, u32 width, u32 height,
  62. u32 encodingType, u32 numRefBuffsLum, u32 numRefBuffsChr)
  63. {
  64. u32 mbTotal, i;
  65. regValues_s *regs;
  66. EWLLinearMem_t *buff = NULL;
  67. ASSERT(asic != NULL);
  68. ASSERT(width != 0);
  69. ASSERT(height != 0);
  70. ASSERT((height % 2) == 0);
  71. ASSERT((width % 4) == 0);
  72. regs = &asic->regs;
  73. regs->codingType = encodingType;
  74. width = (width + 15) / 16;
  75. height = (height + 15) / 16;
  76. mbTotal = width * height;
  77. /* Allocate H.264 internal memories */
  78. if(regs->codingType != ASIC_JPEG)
  79. {
  80. /* The sizes of the memories */
  81. u32 internalImageLumaSize = mbTotal * (16 * 16);
  82. u32 internalImageChromaSize = mbTotal * (2 * 8 * 8);
  83. ASSERT((numRefBuffsLum >= 1) && (numRefBuffsLum <= 2));
  84. ASSERT((numRefBuffsChr >= 2) && (numRefBuffsChr <= 3));
  85. for (i = 0; i < numRefBuffsLum; i++)
  86. {
  87. if(EWLMallocRefFrm(asic->ewl, internalImageLumaSize,
  88. &asic->internalImageLuma[i]) != EWL_OK)
  89. {
  90. EncAsicMemFree_V2(asic);
  91. return ENCHW_NOK;
  92. }
  93. }
  94. for (i = 0; i < numRefBuffsChr; i++)
  95. {
  96. if(EWLMallocRefFrm(asic->ewl, internalImageChromaSize,
  97. &asic->internalImageChroma[i]) != EWL_OK)
  98. {
  99. EncAsicMemFree_V2(asic);
  100. return ENCHW_NOK;
  101. }
  102. }
  103. /* Set base addresses to the registers */
  104. regs->internalImageLumBaseW = asic->internalImageLuma[0].busAddress;
  105. regs->internalImageChrBaseW = asic->internalImageChroma[0].busAddress;
  106. if (numRefBuffsLum > 1)
  107. regs->internalImageLumBaseR = asic->internalImageLuma[1].busAddress;
  108. else
  109. regs->internalImageLumBaseR = asic->internalImageLuma[0].busAddress;
  110. regs->internalImageChrBaseR = asic->internalImageChroma[1].busAddress;
  111. /* NAL size table, table size must be 64-bit multiple,
  112. * space for SEI, MVC prefix, filler and zero at the end of table */
  113. if(regs->codingType == ASIC_H264)
  114. {
  115. /* Atleast 1 macroblock row in every slice */
  116. buff = &asic->sizeTbl.nal;
  117. asic->sizeTblSize = (sizeof(u32) * (height+4) + 7) & (~7);
  118. }
  119. if(EWLMallocLinear(asic->ewl, asic->sizeTblSize, buff) != EWL_OK)
  120. {
  121. EncAsicMemFree_V2(asic);
  122. return ENCHW_NOK;
  123. }
  124. /* CABAC context tables: all qps, intra+inter, 464 bytes/table */
  125. if(EWLMallocLinear(asic->ewl, 52*2*464, &asic->cabacCtx) != EWL_OK)
  126. {
  127. EncAsicMemFree_V2(asic);
  128. return ENCHW_NOK;
  129. }
  130. regs->cabacCtxBase = asic->cabacCtx.busAddress;
  131. /* MV output table: 4 bytes per MB */
  132. if(EWLMallocLinear(asic->ewl, mbTotal*4, &asic->mvOutput) != EWL_OK)
  133. {
  134. EncAsicMemFree_V2(asic);
  135. return ENCHW_NOK;
  136. }
  137. regs->mvOutputBase = asic->mvOutput.busAddress;
  138. /* Clear mv output memory*/
  139. for (i = 0; i < mbTotal; i++)
  140. asic->mvOutput.virtualAddress[i] = 0;
  141. }
  142. return ENCHW_OK;
  143. }
  144. /*------------------------------------------------------------------------------
  145. EncAsicMemFree_V2
  146. Free HW/SW shared memory
  147. ------------------------------------------------------------------------------*/
  148. void EncAsicMemFree_V2(asicData_s * asic)
  149. {
  150. ASSERT(asic != NULL);
  151. if(asic->internalImageLuma[0].virtualAddress != NULL)
  152. EWLFreeRefFrm(asic->ewl, &asic->internalImageLuma[0]);
  153. if(asic->internalImageLuma[1].virtualAddress != NULL)
  154. EWLFreeRefFrm(asic->ewl, &asic->internalImageLuma[1]);
  155. if(asic->internalImageChroma[0].virtualAddress != NULL)
  156. EWLFreeRefFrm(asic->ewl, &asic->internalImageChroma[0]);
  157. if(asic->internalImageChroma[1].virtualAddress != NULL)
  158. EWLFreeRefFrm(asic->ewl, &asic->internalImageChroma[1]);
  159. if(asic->internalImageChroma[2].virtualAddress != NULL)
  160. EWLFreeRefFrm(asic->ewl, &asic->internalImageChroma[2]);
  161. if(asic->sizeTbl.nal.virtualAddress != NULL)
  162. EWLFreeLinear(asic->ewl, &asic->sizeTbl.nal);
  163. if(asic->cabacCtx.virtualAddress != NULL)
  164. EWLFreeLinear(asic->ewl, &asic->cabacCtx);
  165. if(asic->mvOutput.virtualAddress != NULL)
  166. EWLFreeLinear(asic->ewl, &asic->mvOutput);
  167. asic->internalImageLuma[0].virtualAddress = NULL;
  168. asic->internalImageLuma[1].virtualAddress = NULL;
  169. asic->internalImageChroma[0].virtualAddress = NULL;
  170. asic->internalImageChroma[1].virtualAddress = NULL;
  171. asic->internalImageChroma[2].virtualAddress = NULL;
  172. asic->sizeTbl.nal.virtualAddress = NULL;
  173. asic->cabacCtx.virtualAddress = NULL;
  174. asic->mvOutput.virtualAddress = NULL;
  175. }
  176. /*------------------------------------------------------------------------------
  177. ------------------------------------------------------------------------------*/
  178. i32 EncAsicCheckStatus_V2(asicData_s * asic)
  179. {
  180. i32 ret;
  181. u32 status;
  182. status = EncAsicGetStatus(asic->ewl);
  183. if(status & ASIC_STATUS_ERROR)
  184. {
  185. ret = ASIC_STATUS_ERROR;
  186. EWLReleaseHw(asic->ewl);
  187. }
  188. else if(status & ASIC_STATUS_HW_RESET)
  189. {
  190. ret = ASIC_STATUS_HW_RESET;
  191. EWLReleaseHw(asic->ewl);
  192. }
  193. else if(status & ASIC_STATUS_FRAME_READY)
  194. {
  195. regValues_s *regs = &asic->regs;
  196. EncAsicGetRegisters(asic->ewl, regs);
  197. ret = ASIC_STATUS_FRAME_READY;
  198. EWLReleaseHw(asic->ewl);
  199. }
  200. else if(status & ASIC_STATUS_BUFF_FULL)
  201. {
  202. ret = ASIC_STATUS_BUFF_FULL;
  203. /* we do not support recovery from buffer full situation so */
  204. /* ASIC has to be stopped */
  205. EncAsicStop(asic->ewl);
  206. EWLReleaseHw(asic->ewl);
  207. }
  208. else /* Don't check SLICE_READY status bit, it is reseted by IRQ handler */
  209. {
  210. /* IRQ received but none of the status bits is high, so it must be
  211. * slice ready. */
  212. ret = ASIC_STATUS_SLICE_READY;
  213. }
  214. return ret;
  215. }