g2d_wb.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /*
  2. * g2d_wb/g2d_wb.c
  3. *
  4. * Copyright (c) 2007-2019 Allwinnertech Co., Ltd.
  5. * Author: zhengxiaobin <zhengxiaobin@allwinnertech.com>
  6. *
  7. * This software is licensed under the terms of the GNU General Public
  8. * License version 2, as published by the Free Software Foundation, and
  9. * may be copied, distributed, and modified under those terms.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. */
  17. #include <stdlib.h>
  18. #include "g2d_wb.h"
  19. static int wb_rcq_setup(struct wb_submodule *p_wb, u8 *base,
  20. struct g2d_rcq_mem_info *p_rcq_info)
  21. {
  22. u8 *reg_base = base + G2D_WB;
  23. int ret = -1;
  24. if (!p_wb) {
  25. G2D_ERR_MSG("Null pointer!\n");
  26. goto OUT;
  27. }
  28. p_wb->reg_info->size = sizeof(struct g2d_mixer_write_back_reg);
  29. p_wb->reg_info->vir_addr = (u8 *)g2d_top_reg_memory_alloc(
  30. p_wb->reg_info->size, (void *)&(p_wb->reg_info->phy_addr),
  31. p_rcq_info);
  32. if (!p_wb->reg_info->vir_addr) {
  33. G2D_ERR_MSG("Malloc writeback reg rcq memory fail!\n");
  34. goto OUT;
  35. }
  36. p_wb->reg_blks->vir_addr = p_wb->reg_info->vir_addr;
  37. p_wb->reg_blks->phy_addr = p_wb->reg_info->phy_addr;
  38. p_wb->reg_blks->size = p_wb->reg_info->size;
  39. p_wb->reg_blks->reg_addr = reg_base;
  40. ret = 0;
  41. OUT:
  42. return ret;
  43. }
  44. static __u32 wb_get_reg_block_num(struct wb_submodule *p_wb)
  45. {
  46. if (p_wb)
  47. return p_wb->reg_blk_num;
  48. return 0;
  49. }
  50. static __s32 wb_get_reg_block(struct wb_submodule *p_wb,
  51. struct g2d_reg_block **blks)
  52. {
  53. __s32 i = 0, ret = -1;
  54. if (p_wb) {
  55. for (i = 0; i < p_wb->reg_blk_num; ++i)
  56. blks[i] = p_wb->reg_blks + i;
  57. ret = 0;
  58. }
  59. return ret;
  60. }
  61. static struct g2d_mixer_write_back_reg *wb_get_reg(struct wb_submodule *p_wb)
  62. {
  63. #if G2D_MIXER_RCQ_USED == 1
  64. return (struct g2d_mixer_write_back_reg *)(p_wb->reg_blks
  65. ->vir_addr);
  66. #else
  67. return (struct g2d_mixer_write_back_reg *)(p_wb->reg_blks
  68. ->reg_addr);
  69. #endif
  70. return NULL;
  71. }
  72. static void wb_set_block_dirty(struct wb_submodule *p_wb, __u32 blk_id, __u32 dirty)
  73. {
  74. #if G2D_MIXER_RCQ_USED == 1
  75. if (p_wb && p_wb->reg_blks->rcq_hd)
  76. p_wb->reg_blks->rcq_hd->dirty.bits.dirty = dirty;
  77. else
  78. G2D_ERR_MSG("Null pointer!\n");
  79. #else
  80. if (p_wb)
  81. p_wb->reg_blks->dirty = dirty;
  82. else
  83. G2D_ERR_MSG("Null pointer!\n");
  84. #endif
  85. }
  86. __s32 g2d_wb_set(struct wb_submodule *p_wb, g2d_image_enh *p_image)
  87. {
  88. struct g2d_mixer_write_back_reg *p_reg = NULL;
  89. __u64 addr0, addr1, addr2;
  90. __u32 ycnt, ucnt, vcnt;
  91. __u32 pitch0, pitch1, pitch2;
  92. __u32 ch, cw, cy, cx;
  93. __s32 ret = -1;
  94. if (p_wb && p_image) {
  95. p_reg = p_wb->get_reg(p_wb);
  96. if (!p_reg)
  97. goto OUT;
  98. p_reg->wb_attr.bits.fmt = p_image->format;
  99. p_reg->data_size.bits.height =
  100. (!p_image->clip_rect.h) ? 0 : p_image->clip_rect.h - 1;
  101. p_reg->data_size.bits.width =
  102. (!p_image->clip_rect.w) ? 0 : p_image->clip_rect.w - 1;
  103. if ((p_image->format >= G2D_FORMAT_YUV422UVC_V1U1V0U0) &&
  104. (p_image->format <= G2D_FORMAT_YUV422_PLANAR)) {
  105. cw = p_image->width >> 1;
  106. ch = p_image->height;
  107. cx = p_image->clip_rect.x >> 1;
  108. cy = p_image->clip_rect.y;
  109. } else if ((p_image->format >= G2D_FORMAT_YUV420UVC_V1U1V0U0) &&
  110. (p_image->format <= G2D_FORMAT_YUV420_PLANAR)) {
  111. cw = p_image->width >> 1;
  112. ch = p_image->height >> 1;
  113. cx = p_image->clip_rect.x >> 1;
  114. cy = p_image->clip_rect.y >> 1;
  115. } else if ((p_image->format >= G2D_FORMAT_YUV411UVC_V1U1V0U0) &&
  116. (p_image->format <= G2D_FORMAT_YUV411_PLANAR)) {
  117. cw = p_image->width >> 2;
  118. ch = p_image->height;
  119. cx = p_image->clip_rect.x >> 2;
  120. cy = p_image->clip_rect.y;
  121. } else {
  122. cw = 0;
  123. ch = 0;
  124. cx = 0;
  125. cy = 0;
  126. }
  127. g2d_byte_cal(p_image->format, &ycnt, &ucnt, &vcnt);
  128. pitch0 = cal_align(ycnt * p_image->width, p_image->align[0]);
  129. p_reg->pitch0 = pitch0;
  130. pitch1 = cal_align(ucnt * cw, p_image->align[1]);
  131. p_reg->pitch1 = pitch1;
  132. pitch2 = cal_align(vcnt * cw, p_image->align[2]);
  133. p_reg->pitch2 = pitch2;
  134. addr0 = p_image->laddr[0] + ((__u64)p_image->haddr[0] << 32) +
  135. pitch0 * p_image->clip_rect.y +
  136. ycnt * p_image->clip_rect.x;
  137. p_reg->laddr0 = addr0 & 0xffffffff;
  138. p_reg->haddr0 = (addr0 >> 32) & 0xff;
  139. addr1 = p_image->laddr[1] + ((__u64)p_image->haddr[1] << 32) +
  140. pitch1 * cy + ucnt * cx;
  141. p_reg->laddr1 = addr1 & 0xffffffff;
  142. p_reg->haddr1 = (addr1 >> 32) & 0xff;
  143. addr2 = p_image->laddr[2] + ((__u64)p_image->haddr[2] << 32) +
  144. pitch2 * cy + vcnt * cx;
  145. p_reg->laddr2 = addr2 & 0xffffffff;
  146. p_reg->haddr2 = (addr1 >> 32) & 0xff;
  147. p_wb->set_block_dirty(p_wb, 0, 1);
  148. }
  149. OUT:
  150. return ret;
  151. }
  152. static __u32 wb_get_rcq_mem_size(struct wb_submodule *p_wb)
  153. {
  154. return G2D_RCQ_BYTE_ALIGN(sizeof(struct g2d_mixer_write_back_reg));
  155. }
  156. static __s32 wb_destory(struct wb_submodule *p_wb)
  157. {
  158. __s32 ret = -1;
  159. if (p_wb) {
  160. free(p_wb->reg_blks);
  161. p_wb->reg_blks = NULL;
  162. free(p_wb->reg_info);
  163. p_wb->reg_info = NULL;
  164. ret = 0;
  165. free(p_wb);
  166. }
  167. return ret;
  168. }
  169. struct wb_submodule *g2d_wb_submodule_setup(struct g2d_mixer_frame *p_frame)
  170. {
  171. struct wb_submodule *p_wb = NULL;
  172. p_wb = hal_malloc(sizeof(struct wb_submodule));
  173. if (!p_wb) {
  174. G2D_ERR_MSG("malloc wb submodule fail!\n");
  175. return NULL;
  176. }
  177. memset(p_wb, 0, sizeof(struct wb_submodule));
  178. p_wb->rcq_setup = wb_rcq_setup;
  179. p_wb->reg_blk_num = 1;
  180. p_wb->get_reg_block_num = wb_get_reg_block_num;
  181. p_wb->get_reg_block = wb_get_reg_block;
  182. p_wb->get_reg = wb_get_reg;
  183. p_wb->set_block_dirty = wb_set_block_dirty;
  184. p_wb->get_rcq_mem_size = wb_get_rcq_mem_size;
  185. p_wb->destory = wb_destory;
  186. p_wb->reg_blks =
  187. hal_malloc(sizeof(struct g2d_reg_block) * p_wb->reg_blk_num);
  188. p_wb->reg_info =
  189. hal_malloc(sizeof(struct g2d_reg_mem_info));
  190. if (!p_wb->reg_blks || !p_wb->reg_info) {
  191. G2D_ERR_MSG("Kmalloc wb reg info fail!\n");
  192. goto FREE_WB;
  193. }
  194. memset(p_wb->reg_blks, 0, sizeof(struct g2d_reg_block) * p_wb->reg_blk_num);
  195. memset(p_wb->reg_info, 0, sizeof(struct g2d_reg_mem_info));
  196. return p_wb;
  197. FREE_WB:
  198. free(p_wb->reg_blks);
  199. free(p_wb->reg_info);
  200. free(p_wb);
  201. return NULL;
  202. }