vidstabinternal.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  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 : Video stabilization standalone control
  17. -
  18. ------------------------------------------------------------------------------*/
  19. #include "basetype.h"
  20. #include "vidstabcommon.h"
  21. #include "vidstabinternal.h"
  22. #include "vidstabcfg.h"
  23. #include "ewl.h"
  24. #include "encswhwregisters.h"
  25. #ifdef ASIC_WAVE_TRACE_TRIGGER
  26. extern i32 trigger_point; /* picture which will be traced */
  27. #endif
  28. /* Mask fields */
  29. #define mask_2b (u32)0x00000003
  30. #define mask_3b (u32)0x00000007
  31. #define mask_4b (u32)0x0000000F
  32. #define mask_5b (u32)0x0000001F
  33. #define mask_6b (u32)0x0000003F
  34. #define mask_11b (u32)0x000007FF
  35. #define mask_14b (u32)0x00003FFF
  36. #define mask_16b (u32)0x0000FFFF
  37. #define HSWREG(n) ((n)*4)
  38. /*------------------------------------------------------------------------------
  39. Function name : VSCheckInput
  40. Description :
  41. Return type : i32
  42. Argument : const VideoStbParam * param
  43. ------------------------------------------------------------------------------*/
  44. i32 VSCheckInput(const VideoStbParam * param)
  45. {
  46. /* Input picture minimum dimensions */
  47. if((param->inputWidth < 104) || (param->inputHeight < 104))
  48. return 1;
  49. /* Stabilized picture minimum values */
  50. if((param->stabilizedWidth < 96) || (param->stabilizedHeight < 96))
  51. return 1;
  52. /* Stabilized dimensions multiple of 4 */
  53. if(((param->stabilizedWidth & 3) != 0) ||
  54. ((param->stabilizedHeight & 3) != 0))
  55. return 1;
  56. /* Edge >= 4 pixels */
  57. if((param->inputWidth < (param->stabilizedWidth + 8)) ||
  58. (param->inputHeight < (param->stabilizedHeight + 8)))
  59. return 1;
  60. /* stride 8 multiple */
  61. if((param->stride < param->inputWidth) || (param->stride & 7) != 0)
  62. return 1;
  63. /* input format */
  64. if(param->format > VIDEOSTB_BGR101010)
  65. {
  66. return 1;
  67. }
  68. return 0;
  69. }
  70. /*------------------------------------------------------------------------------
  71. Function name : VSInitAsicCtrl
  72. Description :
  73. Return type : void
  74. Argument : VideoStb * pVidStab
  75. ------------------------------------------------------------------------------*/
  76. void VSInitAsicCtrl(VideoStb * pVidStab)
  77. {
  78. RegValues *val = &pVidStab->regval;
  79. u32 *regMirror = pVidStab->regMirror;
  80. ASSERT(pVidStab != NULL);
  81. /* Initialize default values from defined configuration */
  82. val->asicCfgReg =
  83. ((VS8290_AXI_WRITE_ID & (255)) << 24) |
  84. ((VS8290_AXI_READ_ID & (255)) << 16) |
  85. ((VS8290_BURST_LENGTH & (63)) << 8) |
  86. ((VS8290_BURST_INCR_TYPE_ENABLED & (1)) << 6) |
  87. ((VS8290_BURST_DATA_DISCARD_ENABLED & (1)) << 5) |
  88. ((VS8290_ASIC_CLOCK_GATING_ENABLED & (1)) << 4);
  89. val->irqDisable = VS8290_IRQ_DISABLE;
  90. val->rwStabMode = ASIC_VS_MODE_ALONE;
  91. (void) EWLmemset(regMirror, 0, sizeof(regMirror));
  92. }
  93. /*------------------------------------------------------------------------------
  94. VSSetRegisterValue
  95. Set a value into a defined register field
  96. ------------------------------------------------------------------------------*/
  97. void VSSetRegisterValue(u32 *regMirror, regName name, u32 value)
  98. {
  99. const regField_s *field;
  100. u32 regVal;
  101. u32 mask;
  102. field = &asicRegisterDesc[name];
  103. ASSERT(field->base < ASIC_SWREG_AMOUNT*4);
  104. regVal = regMirror[field->base/4];
  105. /* Create bitmask for the field */
  106. mask = field->mask >> field->lsb;
  107. /* Check that value fits in field */
  108. ASSERT(mask >= value);
  109. /* Clear previous value of field in register */
  110. regVal = regVal & ~(mask << field->lsb);
  111. /* Put new value of field in register */
  112. regVal = regVal | ((value & mask) << field->lsb);
  113. regMirror[field->base/4] = regVal;
  114. }
  115. /*------------------------------------------------------------------------------
  116. Function name : VSSetupAsicAll
  117. Description :
  118. Return type : void
  119. Argument : VideoStb * pVidStab
  120. ------------------------------------------------------------------------------*/
  121. void VSSetupAsicAll(VideoStb * pVidStab)
  122. {
  123. const void *ewl = pVidStab->ewl;
  124. RegValues *val = &pVidStab->regval;
  125. u32 *regMirror = pVidStab->regMirror;
  126. regMirror[1] = ((val->irqDisable & 1) << 1); /* clear IRQ status */
  127. regMirror[14] = 0; /* clear enable */
  128. /* system configuration */
  129. if (val->inputImageFormat < ASIC_INPUT_RGB565) /* YUV input */
  130. regMirror[2] = val->asicCfgReg |
  131. ((VS8290_INPUT_SWAP_16_YUV & (1)) << 14) |
  132. ((VS8290_INPUT_SWAP_32_YUV & (1)) << 2) |
  133. (VS8290_INPUT_SWAP_8_YUV & (1));
  134. else if (val->inputImageFormat < ASIC_INPUT_RGB888) /* 16-bit RGB input */
  135. regMirror[2] = val->asicCfgReg |
  136. ((VS8290_INPUT_SWAP_16_RGB16 & (1)) << 14) |
  137. ((VS8290_INPUT_SWAP_32_RGB16 & (1)) << 2) |
  138. (VS8290_INPUT_SWAP_8_RGB16 & (1));
  139. else /* 32-bit RGB input */
  140. regMirror[2] = val->asicCfgReg |
  141. ((VS8290_INPUT_SWAP_16_RGB32 & (1)) << 14) |
  142. ((VS8290_INPUT_SWAP_32_RGB32 & (1)) << 2) |
  143. (VS8290_INPUT_SWAP_8_RGB32 & (1));
  144. /* Input picture buffers */
  145. VSSetRegisterValue(regMirror, HEncBaseInLum, val->inputLumBase);
  146. /* Common control register, use INTRA mode */
  147. VSSetRegisterValue(regMirror, HEncWidth, val->mbsInRow);
  148. VSSetRegisterValue(regMirror, HEncHeight, val->mbsInCol);
  149. VSSetRegisterValue(regMirror, HEncPictureType, 1);
  150. /* PreP control */
  151. VSSetRegisterValue(regMirror, HEncLumOffset, val->inputLumaBaseOffset);
  152. VSSetRegisterValue(regMirror, HEncRowLength, val->pixelsOnRow);
  153. VSSetRegisterValue(regMirror, HEncXFill, val->xFill);
  154. VSSetRegisterValue(regMirror, HEncYFill, val->yFill);
  155. VSSetRegisterValue(regMirror, HEncInputFormat, val->inputImageFormat);
  156. VSSetRegisterValue(regMirror, HEncBaseNextLum, val->rwNextLumaBase);
  157. VSSetRegisterValue(regMirror, HEncStabMode, val->rwStabMode);
  158. VSSetRegisterValue(regMirror, HEncRGBCoeffA,
  159. val->colorConversionCoeffA & mask_16b);
  160. VSSetRegisterValue(regMirror, HEncRGBCoeffB,
  161. val->colorConversionCoeffB & mask_16b);
  162. VSSetRegisterValue(regMirror, HEncRGBCoeffC,
  163. val->colorConversionCoeffC & mask_16b);
  164. VSSetRegisterValue(regMirror, HEncRGBCoeffE,
  165. val->colorConversionCoeffE & mask_16b);
  166. VSSetRegisterValue(regMirror, HEncRGBCoeffF,
  167. val->colorConversionCoeffF & mask_16b);
  168. VSSetRegisterValue(regMirror, HEncRMaskMSB, val->rMaskMsb & mask_5b);
  169. VSSetRegisterValue(regMirror, HEncGMaskMSB, val->gMaskMsb & mask_5b);
  170. VSSetRegisterValue(regMirror, HEncBMaskMSB, val->bMaskMsb & mask_5b);
  171. #ifdef ASIC_WAVE_TRACE_TRIGGER
  172. if(val->vop_count++ == trigger_point)
  173. {
  174. /* logic analyzer triggered by writing to the ID reg */
  175. EWLWriteReg(ewl, 0x00, ~0);
  176. }
  177. #endif
  178. {
  179. i32 i;
  180. for(i = 1; i <= 63; i++)
  181. {
  182. /* Write all regs except 0xA0 with standalone stab enable */
  183. if(i != 40)
  184. EWLWriteReg(ewl, HSWREG(i), regMirror[i]);
  185. }
  186. }
  187. #ifdef TRACE_REGS
  188. EncTraceRegs(ewl, 0, 0);
  189. #endif
  190. /* Register with enable bit is written last */
  191. EWLWriteReg(ewl, HSWREG(40), regMirror[40]);
  192. regMirror[14] |= ASIC_STATUS_ENABLE;
  193. EWLEnableHW(ewl, HSWREG(14), regMirror[14]);
  194. }
  195. /*------------------------------------------------------------------------------
  196. Function name : CheckAsicStatus
  197. Description :
  198. Return type : i32
  199. Argument : u32 status
  200. ------------------------------------------------------------------------------*/
  201. i32 CheckAsicStatus(u32 status)
  202. {
  203. i32 ret;
  204. if(status & ASIC_STATUS_HW_RESET)
  205. {
  206. ret = VIDEOSTB_HW_RESET;
  207. }
  208. else if(status & ASIC_STATUS_FRAME_READY)
  209. {
  210. ret = VIDEOSTB_OK;
  211. }
  212. else
  213. {
  214. ret = VIDEOSTB_HW_BUS_ERROR;
  215. }
  216. return ret;
  217. }
  218. /*------------------------------------------------------------------------------
  219. Function name : VSWaitAsicReady
  220. Description :
  221. Return type : i32
  222. Argument : VideoStb * pVidStab
  223. ------------------------------------------------------------------------------*/
  224. i32 VSWaitAsicReady(VideoStb * pVidStab)
  225. {
  226. const void *ewl = pVidStab->ewl;
  227. u32 *regMirror = pVidStab->regMirror;
  228. i32 ret;
  229. /* Wait for IRQ */
  230. ret = EWLWaitHwRdy(ewl, NULL);
  231. if(ret != EWL_OK)
  232. {
  233. if(ret == EWL_ERROR)
  234. {
  235. /* IRQ error => Stop and release HW */
  236. ret = VIDEOSTB_SYSTEM_ERROR;
  237. }
  238. else /*if(ewl_ret == EWL_HW_WAIT_TIMEOUT) */
  239. {
  240. /* IRQ Timeout => Stop and release HW */
  241. ret = VIDEOSTB_HW_TIMEOUT;
  242. }
  243. EWLWriteReg(ewl, HSWREG(40), 0);
  244. EWLDisableHW(ewl, HSWREG(14), 0); /* make sure ASIC is OFF */
  245. }
  246. else
  247. {
  248. i32 i;
  249. regMirror[1] = EWLReadReg(ewl, HSWREG(1)); /* IRQ status */
  250. for(i = 40; i <= 50; i++)
  251. {
  252. regMirror[i] = EWLReadReg(ewl, HSWREG(i)); /* VS results */
  253. }
  254. ret = CheckAsicStatus(regMirror[1]);
  255. }
  256. #ifdef TRACE_REGS
  257. EncTraceRegs(ewl, 1, 0);
  258. #endif
  259. return ret;
  260. }
  261. /*------------------------------------------------------------------------------
  262. Function name : VSSetCropping
  263. Description :
  264. Return type : void
  265. Argument : VideoStb * pVidStab
  266. Argument : u32 currentPictBus
  267. Argument : u32 nextPictBus
  268. ------------------------------------------------------------------------------*/
  269. void VSSetCropping(VideoStb * pVidStab, u32 currentPictBus, u32 nextPictBus)
  270. {
  271. u32 byteOffsetCurrent;
  272. u32 width, height;
  273. RegValues *regs;
  274. ASSERT(pVidStab != NULL && currentPictBus != 0 && nextPictBus != 0);
  275. regs = &pVidStab->regval;
  276. regs->inputLumBase = currentPictBus;
  277. regs->rwNextLumaBase = nextPictBus;
  278. /* RGB conversion coefficients for RGB input */
  279. if (pVidStab->yuvFormat >= 4) {
  280. regs->colorConversionCoeffA = 19589;
  281. regs->colorConversionCoeffB = 38443;
  282. regs->colorConversionCoeffC = 7504;
  283. regs->colorConversionCoeffE = 37008;
  284. regs->colorConversionCoeffF = 46740;
  285. }
  286. /* Setup masks to separate R, G and B from RGB */
  287. switch ((i32)pVidStab->yuvFormat)
  288. {
  289. case 4: /* RGB565 */
  290. regs->rMaskMsb = 15;
  291. regs->gMaskMsb = 10;
  292. regs->bMaskMsb = 4;
  293. break;
  294. case 5: /* BGR565 */
  295. regs->bMaskMsb = 15;
  296. regs->gMaskMsb = 10;
  297. regs->rMaskMsb = 4;
  298. break;
  299. case 6: /* RGB555 */
  300. regs->rMaskMsb = 14;
  301. regs->gMaskMsb = 9;
  302. regs->bMaskMsb = 4;
  303. break;
  304. case 7: /* BGR555 */
  305. regs->bMaskMsb = 14;
  306. regs->gMaskMsb = 9;
  307. regs->rMaskMsb = 4;
  308. break;
  309. case 8: /* RGB444 */
  310. regs->rMaskMsb = 11;
  311. regs->gMaskMsb = 7;
  312. regs->bMaskMsb = 3;
  313. break;
  314. case 9: /* BGR444 */
  315. regs->bMaskMsb = 11;
  316. regs->gMaskMsb = 7;
  317. regs->rMaskMsb = 3;
  318. break;
  319. case 10: /* RGB888 */
  320. regs->rMaskMsb = 23;
  321. regs->gMaskMsb = 15;
  322. regs->bMaskMsb = 7;
  323. break;
  324. case 11: /* BGR888 */
  325. regs->bMaskMsb = 23;
  326. regs->gMaskMsb = 15;
  327. regs->rMaskMsb = 7;
  328. break;
  329. case 12: /* RGB101010 */
  330. regs->rMaskMsb = 29;
  331. regs->gMaskMsb = 19;
  332. regs->bMaskMsb = 9;
  333. break;
  334. case 13: /* BGR101010 */
  335. regs->bMaskMsb = 29;
  336. regs->gMaskMsb = 19;
  337. regs->rMaskMsb = 9;
  338. break;
  339. default:
  340. /* No masks needed for YUV format */
  341. regs->rMaskMsb = regs->gMaskMsb = regs->bMaskMsb = 0;
  342. }
  343. if (pVidStab->yuvFormat <= 3)
  344. regs->inputImageFormat = pVidStab->yuvFormat; /* YUV */
  345. else if (pVidStab->yuvFormat <= 5)
  346. regs->inputImageFormat = ASIC_INPUT_RGB565; /* 16-bit RGB */
  347. else if (pVidStab->yuvFormat <= 7)
  348. regs->inputImageFormat = ASIC_INPUT_RGB555; /* 15-bit RGB */
  349. else if (pVidStab->yuvFormat <= 9)
  350. regs->inputImageFormat = ASIC_INPUT_RGB444; /* 12-bit RGB */
  351. else if (pVidStab->yuvFormat <= 11)
  352. regs->inputImageFormat = ASIC_INPUT_RGB888; /* 24-bit RGB */
  353. else
  354. regs->inputImageFormat = ASIC_INPUT_RGB101010; /* 30-bit RGB */
  355. regs->pixelsOnRow = pVidStab->stride;
  356. /* cropping */
  357. /* Current image position */
  358. byteOffsetCurrent = pVidStab->data.stabOffsetY;
  359. byteOffsetCurrent *= pVidStab->stride;
  360. byteOffsetCurrent += pVidStab->data.stabOffsetX;
  361. if(pVidStab->yuvFormat >=2 && pVidStab->yuvFormat <= 9) /* YUV 422 / RGB 16bpp */
  362. {
  363. byteOffsetCurrent *= 2;
  364. }
  365. else if(pVidStab->yuvFormat > 9) /* RGB 32bpp */
  366. {
  367. byteOffsetCurrent *= 4;
  368. }
  369. regs->inputLumBase += (byteOffsetCurrent & (~7));
  370. if(pVidStab->yuvFormat >= 10)
  371. {
  372. /* Note: HW does the cropping AFTER RGB to YUYV conversion
  373. * so the offset is calculated using 16bpp */
  374. regs->inputLumaBaseOffset = (byteOffsetCurrent & 7)/2;
  375. }
  376. else
  377. {
  378. regs->inputLumaBaseOffset = (byteOffsetCurrent & 7);
  379. }
  380. /* next picture's offset same as above */
  381. regs->rwNextLumaBase += (byteOffsetCurrent & (~7));
  382. /* source image setup, size and fill */
  383. width = pVidStab->data.stabilizedWidth;
  384. height = pVidStab->data.stabilizedHeight;
  385. /* Set stabilized picture dimensions */
  386. regs->mbsInRow = (width + 15) / 16;
  387. regs->mbsInCol = (height + 15) / 16;
  388. /* Set the overfill values */
  389. if(width & 0x0F)
  390. regs->xFill = (16 - (width & 0x0F)) / 4;
  391. else
  392. regs->xFill = 0;
  393. if(height & 0x0F)
  394. regs->yFill = 16 - (height & 0x0F);
  395. else
  396. regs->yFill = 0;
  397. return;
  398. }