diff options
author | Stanimir Varbanov <stanimir.varbanov@linaro.org> | 2017-06-15 19:31:45 +0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@s-opensource.com> | 2017-06-20 14:53:39 +0300 |
commit | af2c3834c8ca7cc65d15592ac671933df8848115 (patch) | |
tree | 3b1d6b57628a2b5014601dcf688df63d3c2751f6 /drivers/media/platform/qcom/venus/firmware.c | |
parent | 097748eb6478607ba73089c9e7b3775bbb01466c (diff) | |
download | linux-af2c3834c8ca7cc65d15592ac671933df8848115.tar.xz |
[media] media: venus: adding core part and helper functions
* core.c has implemented the platform driver methods, file
operations and v4l2 registration.
* helpers.c has implemented common helper functions for:
- buffer management
- vb2_ops and functions for format propagation,
- functions for allocating and freeing buffers for
internal usage. The buffer parameters describing internal
buffers depends on current format, resolution and codec.
- functions for calculation of current load of the
hardware. Depending on the count of instances and
resolutions it selects the best clock rate for the video
core.
* firmware loader
Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Diffstat (limited to 'drivers/media/platform/qcom/venus/firmware.c')
-rw-r--r-- | drivers/media/platform/qcom/venus/firmware.c | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/drivers/media/platform/qcom/venus/firmware.c b/drivers/media/platform/qcom/venus/firmware.c new file mode 100644 index 000000000000..365e64010920 --- /dev/null +++ b/drivers/media/platform/qcom/venus/firmware.c @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2017 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + * + */ + +#include <linux/dma-mapping.h> +#include <linux/firmware.h> +#include <linux/kernel.h> +#include <linux/of.h> +#include <linux/of_reserved_mem.h> +#include <linux/slab.h> +#include <linux/qcom_scm.h> +#include <linux/soc/qcom/mdt_loader.h> + +#include "firmware.h" + +#define VENUS_FIRMWARE_NAME "venus.mdt" +#define VENUS_PAS_ID 9 +#define VENUS_FW_MEM_SIZE SZ_8M + +static void device_release_dummy(struct device *dev) +{ + of_reserved_mem_device_release(dev); +} + +int venus_boot(struct device *parent, struct device *fw_dev) +{ + const struct firmware *mdt; + phys_addr_t mem_phys; + ssize_t fw_size; + size_t mem_size; + void *mem_va; + int ret; + + if (!qcom_scm_is_available()) + return -EPROBE_DEFER; + + fw_dev->parent = parent; + fw_dev->release = device_release_dummy; + + ret = dev_set_name(fw_dev, "%s:%s", dev_name(parent), "firmware"); + if (ret) + return ret; + + ret = device_register(fw_dev); + if (ret < 0) + return ret; + + ret = of_reserved_mem_device_init_by_idx(fw_dev, parent->of_node, 0); + if (ret) + goto err_unreg_device; + + mem_size = VENUS_FW_MEM_SIZE; + + mem_va = dmam_alloc_coherent(fw_dev, mem_size, &mem_phys, GFP_KERNEL); + if (!mem_va) { + ret = -ENOMEM; + goto err_unreg_device; + } + + ret = request_firmware(&mdt, VENUS_FIRMWARE_NAME, fw_dev); + if (ret < 0) + goto err_unreg_device; + + fw_size = qcom_mdt_get_size(mdt); + if (fw_size < 0) { + ret = fw_size; + release_firmware(mdt); + goto err_unreg_device; + } + + ret = qcom_mdt_load(fw_dev, mdt, VENUS_FIRMWARE_NAME, VENUS_PAS_ID, + mem_va, mem_phys, mem_size); + + release_firmware(mdt); + + if (ret) + goto err_unreg_device; + + ret = qcom_scm_pas_auth_and_reset(VENUS_PAS_ID); + if (ret) + goto err_unreg_device; + + return 0; + +err_unreg_device: + device_unregister(fw_dev); + return ret; +} + +int venus_shutdown(struct device *fw_dev) +{ + int ret; + + ret = qcom_scm_pas_shutdown(VENUS_PAS_ID); + device_unregister(fw_dev); + memset(fw_dev, 0, sizeof(*fw_dev)); + + return ret; +} |