dwe_devcore.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /****************************************************************************
  2. *
  3. * The MIT License (MIT)
  4. *
  5. * Copyright (c) 2020 VeriSilicon Holdings Co., Ltd.
  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) 2020 VeriSilicon Holdings Co., Ltd.
  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;
  43. *
  44. *****************************************************************************
  45. *
  46. * Note: This software is released under dual MIT and GPL licenses. A
  47. * recipient may use this file under the terms of either the MIT license or
  48. * GPL License. If you wish to use only one license not the other, you can
  49. * indicate your decision by deleting one of the above license notices in your
  50. * version of this file.
  51. *
  52. *****************************************************************************/
  53. #include "dwe_driver.h"
  54. #include "dwe_ioctl.h"
  55. LIST_HEAD(devcore_list);
  56. static DEFINE_SPINLOCK(devcore_list_lock);
  57. long dwe_devcore_ioctl(struct dwe_device *dwe, unsigned int cmd, void *args)
  58. {
  59. struct dwe_ic_dev *dev = &dwe->core->ic_dev;
  60. int which;
  61. long ret = 0;
  62. switch (cmd) {
  63. case DWEIOC_RESET:
  64. break;
  65. case DWEIOC_S_PARAMS:
  66. which = dev->which[dwe->id]; /*just set the current one*/
  67. viv_check_retval(copy_from_user(&dev->info[dwe->id][which],
  68. args, sizeof(dev->info[dwe->id][which])));
  69. break;
  70. case DWEIOC_START:
  71. if (dwe->state & STATE_DRIVER_STARTED)
  72. break;
  73. mutex_lock(&dwe->core->mutex);
  74. if (dwe->core->state == 0) {
  75. ret = dwe_priv_ioctl(&dwe->core->ic_dev,
  76. DWEIOC_RESET, NULL);
  77. ret |= dwe_priv_ioctl(&dwe->core->ic_dev, cmd, args);
  78. }
  79. dwe->core->state++;
  80. mutex_unlock(&dwe->core->mutex);
  81. dwe->state |= STATE_DRIVER_STARTED;
  82. break;
  83. case DWEIOC_STOP:
  84. if (!(dwe->state & STATE_DRIVER_STARTED))
  85. break;
  86. dwe->state &= ~STATE_DRIVER_STARTED;
  87. mutex_lock(&dwe->core->mutex);
  88. dwe->core->state--;
  89. if (dwe->core->state == 0)
  90. ret = dwe_priv_ioctl(&dwe->core->ic_dev, cmd, args);
  91. mutex_unlock(&dwe->core->mutex);
  92. break;
  93. case DWEIOC_SET_LUT: {
  94. struct lut_info info;
  95. viv_check_retval(copy_from_user(&info, args, sizeof(info)));
  96. if (info.port < MAX_CFG_NUM)
  97. dev->dist_map[dwe->id][info.port] = info.addr;
  98. else
  99. pr_err("map num exceeds the max cfg num.\n");
  100. break;
  101. }
  102. case VIDIOC_QUERYCAP: {
  103. struct v4l2_capability *cap = (struct v4l2_capability *)args;
  104. strcpy((char *)cap->driver, "viv_dewarp100");
  105. cap->bus_info[0] = (__u8)dwe->id;
  106. break;
  107. }
  108. default:
  109. return dwe_priv_ioctl(&dwe->core->ic_dev, cmd, args);
  110. }
  111. return ret;
  112. }
  113. static int dwe_core_match(struct dwe_devcore *core, struct resource *res)
  114. {
  115. return core && res && core->start == res->start &&
  116. core->end == res->end;
  117. }
  118. static int dwe_core_get_index(struct dwe_ic_dev *dev, struct vb2_dc_buf *buf)
  119. {
  120. struct dwe_devcore *core =
  121. container_of(dev, struct dwe_devcore, ic_dev);
  122. int i;
  123. for (i = 0; i < MAX_DWE_NUM; ++i)
  124. if (core->src_pads[i] == buf->pad)
  125. return i;
  126. return -1;
  127. }
  128. struct dwe_devcore *dwe_devcore_init(struct dwe_device *dwe,
  129. struct resource *res)
  130. {
  131. struct dwe_devcore *core, *found = NULL;
  132. unsigned long flags;
  133. int rc;
  134. spin_lock_irqsave(&devcore_list_lock, flags);
  135. if (!list_empty(&devcore_list)) {
  136. list_for_each_entry(core, &devcore_list, entry) {
  137. if (core->match && core->match(core, res)) {
  138. found = core;
  139. break;
  140. }
  141. }
  142. }
  143. spin_unlock_irqrestore(&devcore_list_lock, flags);
  144. if (found) {
  145. found->src_pads[dwe->id] = &dwe->pads[DWE_PAD_SINK];
  146. found->ic_dev.src_bctx[dwe->id] = &dwe->bctx[DWE_PAD_SOURCE];
  147. found->ic_dev.state[dwe->id] = &dwe->state;
  148. refcount_inc(&found->refcount);
  149. return found;
  150. }
  151. core = kzalloc(sizeof(struct dwe_devcore), GFP_KERNEL);
  152. if (!core)
  153. return NULL;
  154. core->ic_dev.base = devm_ioremap_resource(dwe->sd.dev, res);
  155. if (IS_ERR(core->ic_dev.base)) {
  156. pr_err("failed to get ioremap resource.\n");
  157. goto end;
  158. }
  159. core->start = res->start;
  160. core->end = res->end;
  161. #ifdef DWE_REG_RESET
  162. core->ic_dev.reset = ioremap(DWE_REG_RESET, 4);
  163. #endif
  164. pr_debug("dwe ioremap addr: %llx\n", (u64)core->ic_dev.base);
  165. vvbuf_ctx_init(&core->bctx[DWE_PAD_SINK]);
  166. core->ic_dev.sink_bctx = &core->bctx[DWE_PAD_SINK];
  167. core->irq = dwe->irq;
  168. pr_debug("request_irq num:%d, rc:%d\n", dwe->irq, rc);
  169. spin_lock_init(&core->ic_dev.irqlock);
  170. core->match = dwe_core_match;
  171. core->src_pads[dwe->id] = &dwe->pads[DWE_PAD_SINK];
  172. core->ic_dev.src_bctx[dwe->id] = &dwe->bctx[DWE_PAD_SOURCE];
  173. core->ic_dev.state[dwe->id] = &dwe->state;
  174. core->ic_dev.get_index = dwe_core_get_index;
  175. mutex_init(&core->mutex);
  176. refcount_set(&core->refcount, 1);
  177. spin_lock_irqsave(&devcore_list_lock, flags);
  178. list_add_tail(&core->entry, &devcore_list);
  179. spin_unlock_irqrestore(&devcore_list_lock, flags);
  180. return core;
  181. end:
  182. kfree(core);
  183. return NULL;
  184. }
  185. void dwe_devcore_deinit(struct dwe_device *dwe)
  186. {
  187. struct dwe_devcore *core = dwe->core;
  188. unsigned long flags;
  189. if (!core)
  190. return;
  191. if (refcount_dec_and_test(&core->refcount)) {
  192. spin_lock_irqsave(&devcore_list_lock, flags);
  193. list_del(&core->entry);
  194. spin_unlock_irqrestore(&devcore_list_lock, flags);
  195. vvbuf_ctx_deinit(&core->bctx[DWE_PAD_SINK]);
  196. #ifdef DWE_REG_RESET
  197. iounmap(core->ic_dev.reset);
  198. #endif
  199. mutex_destroy(&core->mutex);
  200. kfree(core);
  201. }
  202. }