123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- /****************************************************************************
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2020 VeriSilicon Holdings Co., Ltd.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- *****************************************************************************
- *
- * The GPL License (GPL)
- *
- * Copyright (c) 2020 VeriSilicon Holdings Co., Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program;
- *
- *****************************************************************************
- *
- * Note: This software is released under dual MIT and GPL licenses. A
- * recipient may use this file under the terms of either the MIT license or
- * GPL License. If you wish to use only one license not the other, you can
- * indicate your decision by deleting one of the above license notices in your
- * version of this file.
- *
- *****************************************************************************/
- #include "dwe_driver.h"
- #include "dwe_ioctl.h"
- LIST_HEAD(devcore_list);
- static DEFINE_SPINLOCK(devcore_list_lock);
- long dwe_devcore_ioctl(struct dwe_device *dwe, unsigned int cmd, void *args)
- {
- struct dwe_ic_dev *dev = &dwe->core->ic_dev;
- int which;
- long ret = 0;
- switch (cmd) {
- case DWEIOC_RESET:
- break;
- case DWEIOC_S_PARAMS:
- which = dev->which[dwe->id]; /*just set the current one*/
- viv_check_retval(copy_from_user(&dev->info[dwe->id][which],
- args, sizeof(dev->info[dwe->id][which])));
- break;
- case DWEIOC_START:
- if (dwe->state & STATE_DRIVER_STARTED)
- break;
- mutex_lock(&dwe->core->mutex);
- if (dwe->core->state == 0) {
- ret = dwe_priv_ioctl(&dwe->core->ic_dev,
- DWEIOC_RESET, NULL);
- ret |= dwe_priv_ioctl(&dwe->core->ic_dev, cmd, args);
- }
- dwe->core->state++;
- mutex_unlock(&dwe->core->mutex);
- dwe->state |= STATE_DRIVER_STARTED;
- break;
- case DWEIOC_STOP:
- if (!(dwe->state & STATE_DRIVER_STARTED))
- break;
- dwe->state &= ~STATE_DRIVER_STARTED;
- mutex_lock(&dwe->core->mutex);
- dwe->core->state--;
- if (dwe->core->state == 0)
- ret = dwe_priv_ioctl(&dwe->core->ic_dev, cmd, args);
- mutex_unlock(&dwe->core->mutex);
- break;
- case DWEIOC_SET_LUT: {
- struct lut_info info;
- viv_check_retval(copy_from_user(&info, args, sizeof(info)));
- if (info.port < MAX_CFG_NUM)
- dev->dist_map[dwe->id][info.port] = info.addr;
- else
- pr_err("map num exceeds the max cfg num.\n");
- break;
- }
- case VIDIOC_QUERYCAP: {
- struct v4l2_capability *cap = (struct v4l2_capability *)args;
- strcpy((char *)cap->driver, "viv_dewarp100");
- cap->bus_info[0] = (__u8)dwe->id;
- break;
- }
- default:
- return dwe_priv_ioctl(&dwe->core->ic_dev, cmd, args);
- }
- return ret;
- }
- static int dwe_core_match(struct dwe_devcore *core, struct resource *res)
- {
- return core && res && core->start == res->start &&
- core->end == res->end;
- }
- static int dwe_core_get_index(struct dwe_ic_dev *dev, struct vb2_dc_buf *buf)
- {
- struct dwe_devcore *core =
- container_of(dev, struct dwe_devcore, ic_dev);
- int i;
- for (i = 0; i < MAX_DWE_NUM; ++i)
- if (core->src_pads[i] == buf->pad)
- return i;
- return -1;
- }
- struct dwe_devcore *dwe_devcore_init(struct dwe_device *dwe,
- struct resource *res)
- {
- struct dwe_devcore *core, *found = NULL;
- unsigned long flags;
- int rc;
- spin_lock_irqsave(&devcore_list_lock, flags);
- if (!list_empty(&devcore_list)) {
- list_for_each_entry(core, &devcore_list, entry) {
- if (core->match && core->match(core, res)) {
- found = core;
- break;
- }
- }
- }
- spin_unlock_irqrestore(&devcore_list_lock, flags);
- if (found) {
- found->src_pads[dwe->id] = &dwe->pads[DWE_PAD_SINK];
- found->ic_dev.src_bctx[dwe->id] = &dwe->bctx[DWE_PAD_SOURCE];
- found->ic_dev.state[dwe->id] = &dwe->state;
- refcount_inc(&found->refcount);
- return found;
- }
- core = kzalloc(sizeof(struct dwe_devcore), GFP_KERNEL);
- if (!core)
- return NULL;
- core->ic_dev.base = devm_ioremap_resource(dwe->sd.dev, res);
- if (IS_ERR(core->ic_dev.base)) {
- pr_err("failed to get ioremap resource.\n");
- goto end;
- }
- core->start = res->start;
- core->end = res->end;
- #ifdef DWE_REG_RESET
- core->ic_dev.reset = ioremap(DWE_REG_RESET, 4);
- #endif
- pr_debug("dwe ioremap addr: %llx\n", (u64)core->ic_dev.base);
- vvbuf_ctx_init(&core->bctx[DWE_PAD_SINK]);
- core->ic_dev.sink_bctx = &core->bctx[DWE_PAD_SINK];
- core->irq = dwe->irq;
- pr_debug("request_irq num:%d, rc:%d\n", dwe->irq, rc);
- spin_lock_init(&core->ic_dev.irqlock);
- core->match = dwe_core_match;
- core->src_pads[dwe->id] = &dwe->pads[DWE_PAD_SINK];
- core->ic_dev.src_bctx[dwe->id] = &dwe->bctx[DWE_PAD_SOURCE];
- core->ic_dev.state[dwe->id] = &dwe->state;
- core->ic_dev.get_index = dwe_core_get_index;
- mutex_init(&core->mutex);
- refcount_set(&core->refcount, 1);
- spin_lock_irqsave(&devcore_list_lock, flags);
- list_add_tail(&core->entry, &devcore_list);
- spin_unlock_irqrestore(&devcore_list_lock, flags);
- return core;
- end:
- kfree(core);
- return NULL;
- }
- void dwe_devcore_deinit(struct dwe_device *dwe)
- {
- struct dwe_devcore *core = dwe->core;
- unsigned long flags;
- if (!core)
- return;
- if (refcount_dec_and_test(&core->refcount)) {
- spin_lock_irqsave(&devcore_list_lock, flags);
- list_del(&core->entry);
- spin_unlock_irqrestore(&devcore_list_lock, flags);
- vvbuf_ctx_deinit(&core->bctx[DWE_PAD_SINK]);
- #ifdef DWE_REG_RESET
- iounmap(core->ic_dev.reset);
- #endif
- mutex_destroy(&core->mutex);
- kfree(core);
- }
- }
|