mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
msm: vidc: wfd: Add WFD support for msm8974
Adds three new subdevices: - Encoder subdevice to interface with new venus driver o Renamed enc-subdev.c to enc-mfc-subdev.c which only compiles for targets using the Samsung MFC core. - MDP subdevice to interface with new MDSS driver o Renamed mdp-subdev.c to mdp-4-subdev.c used for targets using MDP4. - MDP subdevice for debugging purposes - Introduce a Kconfig file to properly choose between subdevices according to target Change-Id: I125b39cfdeb1fbb4adf7c15d0c4452146764f985 Signed-off-by: Deva Ramasubramanian <dramasub@codeaurora.org> Signed-off-by: Amara Venkata Mastan Manoj Kumar <manojavm@codeaurora.org>
This commit is contained in:
parent
e64f038561
commit
e0f91c62fa
14 changed files with 1627 additions and 46 deletions
|
@ -171,6 +171,11 @@ CONFIG_VIDEOBUF2_MSM_MEM=y
|
|||
# CONFIG_RADIO_ADAPTERS is not set
|
||||
CONFIG_V4L_PLATFORM_DRIVERS=y
|
||||
CONFIG_MSM_CAMERA_V4L2=y
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
CONFIG_MSM_WFD=y
|
||||
CONFIG_OV2720=y
|
||||
>>>>>>> 1efb995... msm: vidc: wfd: Add WFD support for msm8974
|
||||
CONFIG_MSM_CAMERA_SENSOR=y
|
||||
CONFIG_MSM_ACTUATOR=y
|
||||
CONFIG_MSM_CAM_IRQ_ROUTER=n
|
||||
|
|
|
@ -1262,3 +1262,4 @@ config VIDEO_MX2_EMMAPRP
|
|||
endif # V4L_MEM2MEM_DRIVERS
|
||||
|
||||
source "drivers/media/video/msm_vidc/Kconfig"
|
||||
source "drivers/media/video/msm_wfd/Kconfig"
|
||||
|
|
|
@ -215,7 +215,7 @@ obj-y += davinci/
|
|||
obj-$(CONFIG_MSM_CAMERA) += msm/
|
||||
obj-$(CONFIG_ARCH_OMAP) += omap/
|
||||
obj-$(CONFIG_MSM_VIDC_V4L2) += msm_vidc/
|
||||
obj-$(CONFIG_FB_MSM_WRITEBACK_MSM_PANEL) += msm_wfd/
|
||||
obj-$(CONFIG_MSM_WFD) += msm_wfd/
|
||||
|
||||
ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
|
||||
ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
|
||||
|
|
6
drivers/media/video/msm_wfd/Kconfig
Normal file
6
drivers/media/video/msm_wfd/Kconfig
Normal file
|
@ -0,0 +1,6 @@
|
|||
menuconfig MSM_WFD
|
||||
bool "Qualcomm MSM Wifi Display Driver"
|
||||
depends on (MSM_VIDC_1080P || MSM_VIDC_V4L2)
|
||||
---help---
|
||||
Enables the Wifi Display driver.
|
||||
|
|
@ -1,5 +1,14 @@
|
|||
obj-y += mdp-subdev.o
|
||||
obj-y += enc-subdev.o
|
||||
obj-y += vsg-subdev.o
|
||||
obj-y += wfd-ioctl.o
|
||||
obj-y += wfd-util.o
|
||||
ifeq ($(CONFIG_MSM_WFD),y)
|
||||
obj-y += wfd-ioctl.o
|
||||
obj-y += wfd-util.o
|
||||
obj-y += vsg-subdev.o
|
||||
ifeq ($(CONFIG_FB_MSM_WRITEBACK_MSM_PANEL),y)
|
||||
obj-y += mdp-4-subdev.o
|
||||
else ifeq ($(CONFIG_FB_MSM_MDSS_WRITEBACK),y)
|
||||
obj-y += mdp-5-subdev.o
|
||||
else
|
||||
obj-y += mdp-dummy-subdev.o
|
||||
endif
|
||||
obj-$(CONFIG_MSM_VIDC_1080P) += enc-mfc-subdev.o
|
||||
obj-$(CONFIG_MSM_VIDC_V4L2) += enc-venus-subdev.o
|
||||
endif
|
||||
|
|
|
@ -227,7 +227,7 @@ static void venc_cb(u32 event, u32 status, void *info, u32 size, void *handle,
|
|||
BUFFER_TYPE_OUTPUT, pmem_fd,
|
||||
kvaddr, buffer_index, &ion_handle);
|
||||
else
|
||||
WFD_MSG_ERR("Got an output buffer that we "
|
||||
WFD_MSG_ERR("Got an output buffer that we " \
|
||||
"couldn't recognize!\n");
|
||||
|
||||
if (msm_ion_do_cache_op(client_ctx->user_ion_client,
|
||||
|
@ -547,8 +547,8 @@ static long venc_set_codec_level(struct video_client_ctx *client_ctx,
|
|||
|
||||
if (vcd_property_level.level < VCD_LEVEL_MPEG4_0
|
||||
|| vcd_property_level.level > VCD_LEVEL_MPEG4_X) {
|
||||
WFD_MSG_ERR("Level (%d) out of range"
|
||||
"for codec (%d)\n", level, codec);
|
||||
WFD_MSG_ERR("Level (%d) out of range for codec (%d)\n",
|
||||
level, codec);
|
||||
|
||||
rc = -EINVAL;
|
||||
goto err;
|
||||
|
@ -558,8 +558,8 @@ static long venc_set_codec_level(struct video_client_ctx *client_ctx,
|
|||
|
||||
if (vcd_property_level.level < VCD_LEVEL_H264_1
|
||||
|| vcd_property_level.level > VCD_LEVEL_H264_5p1) {
|
||||
WFD_MSG_ERR("Level (%d) out of range"
|
||||
"for codec (%d)\n", level, codec);
|
||||
WFD_MSG_ERR("Level (%d) out of range for codec (%d)\n",
|
||||
level, codec);
|
||||
|
||||
rc = -EINVAL;
|
||||
goto err;
|
||||
|
@ -678,9 +678,9 @@ static long venc_set_codec_profile(struct video_client_ctx *client_ctx,
|
|||
vcd_property_profile.profile = VCD_PROFILE_MPEG4_ASP;
|
||||
break;
|
||||
default:
|
||||
WFD_MSG_ERR("Profile %d not supported,"
|
||||
"defaulting to simple (%d)",
|
||||
profile, VCD_PROFILE_MPEG4_SP);
|
||||
WFD_MSG_ERR("Profile %d not supported, defaulting " \
|
||||
"to simple (%d)", profile,
|
||||
VCD_PROFILE_MPEG4_SP);
|
||||
vcd_property_profile.profile = VCD_PROFILE_MPEG4_SP;
|
||||
break;
|
||||
}
|
||||
|
@ -697,17 +697,16 @@ static long venc_set_codec_profile(struct video_client_ctx *client_ctx,
|
|||
vcd_property_profile.profile = VCD_PROFILE_H264_HIGH;
|
||||
break;
|
||||
default:
|
||||
WFD_MSG_ERR("Profile %d not supported,"
|
||||
"defaulting to baseline (%d)",
|
||||
profile, VCD_PROFILE_H264_BASELINE);
|
||||
WFD_MSG_ERR("Profile %d not supported, defaulting " \
|
||||
"to baseline (%d)", profile,
|
||||
VCD_PROFILE_H264_BASELINE);
|
||||
vcd_property_profile.profile =
|
||||
VCD_PROFILE_H264_BASELINE;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
WFD_MSG_ERR("Codec (%d) not supported,"
|
||||
"not setting profile (%d)",
|
||||
codec, profile);
|
||||
WFD_MSG_ERR("Codec (%d) not supported, not "\
|
||||
"setting profile (%d)", codec, profile);
|
||||
rc = -ENOTSUPP;
|
||||
goto err_set_profile;
|
||||
}
|
|
@ -14,7 +14,8 @@
|
|||
#ifndef _WFD_ENC_SUBDEV_
|
||||
#define _WFD_ENC_SUBDEV_
|
||||
|
||||
#include <linux/ion.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/msm_ion.h>
|
||||
#include <media/v4l2-subdev.h>
|
||||
#include <media/videobuf2-core.h>
|
||||
#define VENC_MAGIC_IOCTL 'V'
|
||||
|
@ -29,6 +30,7 @@ struct mem_region {
|
|||
u32 cookie;
|
||||
struct ion_handle *ion_handle;
|
||||
};
|
||||
|
||||
struct bufreq {
|
||||
u32 count;
|
||||
u32 height;
|
||||
|
@ -44,13 +46,27 @@ struct venc_buf_info {
|
|||
struct venc_msg_ops {
|
||||
void *cookie;
|
||||
void *cbdata;
|
||||
int secure;
|
||||
bool secure;
|
||||
void (*op_buffer_done)(void *cookie, u32 status,
|
||||
struct vb2_buffer *buf);
|
||||
void (*ip_buffer_done)(void *cookie, u32 status,
|
||||
struct mem_region *mregion);
|
||||
};
|
||||
|
||||
static inline bool mem_region_equals(struct mem_region *a,
|
||||
struct mem_region *b)
|
||||
{
|
||||
if (a == b)
|
||||
return true;
|
||||
else if (a->fd || b->fd)
|
||||
return (a->fd == b->fd) &&
|
||||
(a->offset == b->offset);
|
||||
else if (a->kvaddr || b->kvaddr)
|
||||
return a->kvaddr == b->kvaddr;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
#define OPEN _IOR('V', 1, void *)
|
||||
#define CLOSE _IO('V', 2)
|
||||
#define ENCODE_START _IO('V', 3)
|
||||
|
|
1139
drivers/media/video/msm_wfd/enc-venus-subdev.c
Normal file
1139
drivers/media/video/msm_wfd/enc-venus-subdev.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -19,6 +19,8 @@ struct mdp_instance {
|
|||
struct fb_info *mdp;
|
||||
u32 height;
|
||||
u32 width;
|
||||
bool secure;
|
||||
bool uses_iommu_split_domain;
|
||||
};
|
||||
|
||||
int mdp_init(struct v4l2_subdev *sd, u32 val)
|
||||
|
@ -29,34 +31,42 @@ int mdp_open(struct v4l2_subdev *sd, void *arg)
|
|||
{
|
||||
struct mdp_instance *inst = kzalloc(sizeof(struct mdp_instance),
|
||||
GFP_KERNEL);
|
||||
void **cookie = (void **)arg;
|
||||
struct mdp_msg_ops *mops = arg;
|
||||
int rc = 0;
|
||||
struct fb_info *fbi = NULL;
|
||||
|
||||
if (!inst) {
|
||||
WFD_MSG_ERR("Out of memory\n");
|
||||
return -ENOMEM;
|
||||
rc = -ENOMEM;
|
||||
goto mdp_open_fail;
|
||||
} else if (!mops) {
|
||||
WFD_MSG_ERR("Invalid arguments\n");
|
||||
rc = -EINVAL;
|
||||
goto mdp_open_fail;
|
||||
}
|
||||
|
||||
fbi = msm_fb_get_writeback_fb();
|
||||
if (!fbi) {
|
||||
WFD_MSG_ERR("Failed to acquire mdp instance\n");
|
||||
rc = -ENODEV;
|
||||
goto exit;
|
||||
goto mdp_open_fail;
|
||||
}
|
||||
|
||||
/*Tell HDMI daemon to open fb2*/
|
||||
rc = kobject_uevent(&fbi->dev->kobj, KOBJ_ADD);
|
||||
if (rc) {
|
||||
WFD_MSG_ERR("Failed add to kobj");
|
||||
goto exit;
|
||||
goto mdp_open_fail;
|
||||
}
|
||||
|
||||
msm_fb_writeback_init(fbi);
|
||||
inst->mdp = fbi;
|
||||
*cookie = inst;
|
||||
inst->secure = mops->secure;
|
||||
inst->uses_iommu_split_domain = mops->iommu_split_domain;
|
||||
|
||||
mops->cookie = inst;
|
||||
return rc;
|
||||
exit:
|
||||
mdp_open_fail:
|
||||
kfree(inst);
|
||||
return rc;
|
||||
}
|
||||
|
@ -134,8 +144,8 @@ int mdp_q_buffer(struct v4l2_subdev *sd, void *arg)
|
|||
fbdata.flags = 0;
|
||||
fbdata.priv = (uint32_t)binfo->cookie;
|
||||
|
||||
WFD_MSG_INFO("queue buffer to mdp with offset = %u,"
|
||||
"fd = %u, priv = %p, iova = %p\n",
|
||||
WFD_MSG_INFO("queue buffer to mdp with offset = %u, fd = %u, "\
|
||||
"priv = %p, iova = %p\n",
|
||||
fbdata.offset, fbdata.memory_id,
|
||||
(void *)fbdata.priv, (void *)fbdata.iova);
|
||||
rc = msm_fb_writeback_queue_buffer(inst->mdp, &fbdata);
|
||||
|
@ -179,6 +189,7 @@ int mdp_set_prop(struct v4l2_subdev *sd, void *arg)
|
|||
inst->width = prop->width;
|
||||
return 0;
|
||||
}
|
||||
|
||||
long mdp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
{
|
||||
int rc = 0;
|
229
drivers/media/video/msm_wfd/mdp-5-subdev.c
Normal file
229
drivers/media/video/msm_wfd/mdp-5-subdev.c
Normal file
|
@ -0,0 +1,229 @@
|
|||
/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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/msm_mdp.h>
|
||||
#include <mach/iommu_domains.h>
|
||||
#include <media/videobuf2-core.h>
|
||||
#include "enc-subdev.h"
|
||||
#include "mdp-subdev.h"
|
||||
#include "wfd-util.h"
|
||||
|
||||
|
||||
struct mdp_instance {
|
||||
struct fb_info *mdp;
|
||||
u32 height;
|
||||
u32 width;
|
||||
bool secure;
|
||||
};
|
||||
|
||||
int mdp_init(struct v4l2_subdev *sd, u32 val)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mdp_open(struct v4l2_subdev *sd, void *arg)
|
||||
{
|
||||
struct mdp_instance *inst = kzalloc(sizeof(struct mdp_instance),
|
||||
GFP_KERNEL);
|
||||
struct mdp_msg_ops *mops = arg;
|
||||
int rc = 0;
|
||||
struct fb_info *fbi = NULL;
|
||||
|
||||
if (!inst) {
|
||||
WFD_MSG_ERR("Out of memory\n");
|
||||
rc = -ENOMEM;
|
||||
goto mdp_open_fail;
|
||||
} else if (!mops) {
|
||||
WFD_MSG_ERR("Invalid arguments\n");
|
||||
rc = -EINVAL;
|
||||
goto mdp_open_fail;
|
||||
}
|
||||
|
||||
fbi = msm_fb_get_writeback_fb();
|
||||
if (!fbi) {
|
||||
WFD_MSG_ERR("Failed to acquire mdp instance\n");
|
||||
rc = -ENODEV;
|
||||
goto mdp_open_fail;
|
||||
}
|
||||
|
||||
/*Tell HDMI daemon to open fb2*/
|
||||
rc = kobject_uevent(&fbi->dev->kobj, KOBJ_ADD);
|
||||
if (rc)
|
||||
WFD_MSG_ERR("Failed add to kobj");
|
||||
|
||||
msm_fb_writeback_init(fbi);
|
||||
inst->mdp = fbi;
|
||||
inst->secure = mops->secure;
|
||||
|
||||
mops->cookie = inst;
|
||||
return rc;
|
||||
mdp_open_fail:
|
||||
kfree(inst);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int mdp_start(struct v4l2_subdev *sd, void *arg)
|
||||
{
|
||||
struct mdp_instance *inst = arg;
|
||||
int rc = 0;
|
||||
struct fb_info *fbi = NULL;
|
||||
if (inst) {
|
||||
rc = msm_fb_writeback_start(inst->mdp);
|
||||
if (rc) {
|
||||
WFD_MSG_ERR("Failed to start MDP mode\n");
|
||||
goto exit;
|
||||
}
|
||||
fbi = msm_fb_get_writeback_fb();
|
||||
if (!fbi) {
|
||||
WFD_MSG_ERR("Failed to acquire mdp instance\n");
|
||||
rc = -ENODEV;
|
||||
goto exit;
|
||||
}
|
||||
rc = kobject_uevent(&fbi->dev->kobj, KOBJ_ONLINE);
|
||||
if (rc)
|
||||
WFD_MSG_ERR("Failed to send ONLINE event\n");
|
||||
}
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int mdp_stop(struct v4l2_subdev *sd, void *arg)
|
||||
{
|
||||
struct mdp_instance *inst = arg;
|
||||
int rc = 0;
|
||||
struct fb_info *fbi = NULL;
|
||||
if (inst) {
|
||||
rc = msm_fb_writeback_stop(inst->mdp);
|
||||
if (rc) {
|
||||
WFD_MSG_ERR("Failed to stop writeback mode\n");
|
||||
return rc;
|
||||
}
|
||||
fbi = (struct fb_info *)inst->mdp;
|
||||
rc = kobject_uevent(&fbi->dev->kobj, KOBJ_OFFLINE);
|
||||
if (rc) {
|
||||
WFD_MSG_ERR("Failed to send offline event\n");
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int mdp_close(struct v4l2_subdev *sd, void *arg)
|
||||
{
|
||||
struct mdp_instance *inst = arg;
|
||||
struct fb_info *fbi = NULL;
|
||||
if (inst) {
|
||||
fbi = (struct fb_info *)inst->mdp;
|
||||
msm_fb_writeback_terminate(fbi);
|
||||
kfree(inst);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int mdp_q_buffer(struct v4l2_subdev *sd, void *arg)
|
||||
{
|
||||
int rc = 0;
|
||||
struct mdp_buf_info *binfo = arg;
|
||||
struct msmfb_data fbdata;
|
||||
struct mdp_instance *inst;
|
||||
if (!binfo || !binfo->inst || !binfo->cookie) {
|
||||
WFD_MSG_ERR("Invalid argument\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
inst = binfo->inst;
|
||||
fbdata.offset = binfo->offset;
|
||||
fbdata.memory_id = binfo->fd;
|
||||
fbdata.iova = binfo->paddr;
|
||||
fbdata.id = 0;
|
||||
fbdata.flags = 0;
|
||||
fbdata.priv = (uint32_t)binfo->cookie;
|
||||
|
||||
WFD_MSG_DBG("queue buffer to mdp with offset = %u, fd = %u, "\
|
||||
"priv = %p, iova = %p\n",
|
||||
fbdata.offset, fbdata.memory_id,
|
||||
(void *)fbdata.priv, (void *)fbdata.iova);
|
||||
rc = msm_fb_writeback_queue_buffer(inst->mdp, &fbdata);
|
||||
|
||||
if (rc)
|
||||
WFD_MSG_ERR("Failed to queue buffer\n");
|
||||
return rc;
|
||||
}
|
||||
int mdp_dq_buffer(struct v4l2_subdev *sd, void *arg)
|
||||
{
|
||||
int rc = 0;
|
||||
struct mdp_buf_info *obuf = arg;
|
||||
struct msmfb_data fbdata;
|
||||
struct mdp_instance *inst;
|
||||
if (!arg) {
|
||||
WFD_MSG_ERR("Invalid argument\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
inst = obuf->inst;
|
||||
fbdata.flags = MSMFB_WRITEBACK_DEQUEUE_BLOCKING;
|
||||
rc = msm_fb_writeback_dequeue_buffer(inst->mdp, &fbdata);
|
||||
if (rc) {
|
||||
WFD_MSG_ERR("Failed to dequeue buffer\n");
|
||||
return rc;
|
||||
}
|
||||
WFD_MSG_DBG("dequeue buf from mdp with priv = %u\n",
|
||||
fbdata.priv);
|
||||
obuf->cookie = (void *)fbdata.priv;
|
||||
return rc;
|
||||
}
|
||||
int mdp_set_prop(struct v4l2_subdev *sd, void *arg)
|
||||
{
|
||||
struct mdp_prop *prop = (struct mdp_prop *)arg;
|
||||
struct mdp_instance *inst = prop->inst;
|
||||
if (!prop || !inst) {
|
||||
WFD_MSG_ERR("Invalid arguments\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
inst->height = prop->height;
|
||||
inst->width = prop->width;
|
||||
return 0;
|
||||
}
|
||||
|
||||
long mdp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
{
|
||||
int rc = 0;
|
||||
if (!sd) {
|
||||
WFD_MSG_ERR("Invalid arguments\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
switch (cmd) {
|
||||
case MDP_Q_BUFFER:
|
||||
rc = mdp_q_buffer(sd, arg);
|
||||
break;
|
||||
case MDP_DQ_BUFFER:
|
||||
rc = mdp_dq_buffer(sd, arg);
|
||||
break;
|
||||
case MDP_OPEN:
|
||||
rc = mdp_open(sd, arg);
|
||||
break;
|
||||
case MDP_START:
|
||||
rc = mdp_start(sd, arg);
|
||||
break;
|
||||
case MDP_STOP:
|
||||
rc = mdp_stop(sd, arg);
|
||||
break;
|
||||
case MDP_SET_PROP:
|
||||
rc = mdp_set_prop(sd, arg);
|
||||
break;
|
||||
case MDP_CLOSE:
|
||||
rc = mdp_close(sd, arg);
|
||||
break;
|
||||
default:
|
||||
WFD_MSG_ERR("IOCTL: %u not supported\n", cmd);
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
}
|
162
drivers/media/video/msm_wfd/mdp-dummy-subdev.c
Normal file
162
drivers/media/video/msm_wfd/mdp-dummy-subdev.c
Normal file
|
@ -0,0 +1,162 @@
|
|||
/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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/list.h>
|
||||
#include <linux/msm_mdp.h>
|
||||
#include <media/videobuf2-core.h>
|
||||
|
||||
#include "mdp-subdev.h"
|
||||
#include "wfd-util.h"
|
||||
|
||||
struct mdp_buf_queue {
|
||||
struct mdp_buf_info mdp_buf_info;
|
||||
struct list_head node;
|
||||
};
|
||||
|
||||
struct mdp_instance {
|
||||
struct mdp_buf_queue mdp_bufs;
|
||||
struct mutex mutex;
|
||||
};
|
||||
|
||||
int mdp_init(struct v4l2_subdev *sd, u32 val)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int mdp_open(struct v4l2_subdev *sd, void *arg)
|
||||
{
|
||||
struct mdp_instance *inst = kzalloc(sizeof(struct mdp_instance),
|
||||
GFP_KERNEL);
|
||||
void **cookie = (void **)arg;
|
||||
int rc = 0;
|
||||
|
||||
if (!inst) {
|
||||
WFD_MSG_ERR("Out of memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&inst->mdp_bufs.node);
|
||||
mutex_init(&inst->mutex);
|
||||
*cookie = inst;
|
||||
return rc;
|
||||
}
|
||||
|
||||
int mdp_start(struct v4l2_subdev *sd, void *arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int mdp_stop(struct v4l2_subdev *sd, void *arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int mdp_close(struct v4l2_subdev *sd, void *arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int mdp_q_buffer(struct v4l2_subdev *sd, void *arg)
|
||||
{
|
||||
static int foo;
|
||||
int rc = 0;
|
||||
struct mdp_buf_info *binfo = arg;
|
||||
struct mdp_instance *inst = NULL;
|
||||
|
||||
if (!binfo || !binfo->inst || !binfo->cookie) {
|
||||
WFD_MSG_ERR("Invalid argument\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
inst = binfo->inst;
|
||||
if (binfo->kvaddr) {
|
||||
struct mdp_buf_queue *new_entry = kzalloc(sizeof(*new_entry),
|
||||
GFP_KERNEL);
|
||||
memset((void *)binfo->kvaddr, foo++, 1024);
|
||||
new_entry->mdp_buf_info = *binfo;
|
||||
mutex_lock(&inst->mutex);
|
||||
list_add_tail(&new_entry->node, &inst->mdp_bufs.node);
|
||||
mutex_unlock(&inst->mutex);
|
||||
WFD_MSG_DBG("Queue %p with cookie %p\n",
|
||||
(void *)binfo->paddr, (void *)binfo->cookie);
|
||||
} else {
|
||||
rc = -EINVAL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
int mdp_dq_buffer(struct v4l2_subdev *sd, void *arg)
|
||||
{
|
||||
struct mdp_buf_info *binfo = arg;
|
||||
struct mdp_buf_queue *head = NULL;
|
||||
struct mdp_instance *inst = NULL;
|
||||
|
||||
inst = binfo->inst;
|
||||
|
||||
while (head == NULL) {
|
||||
mutex_lock(&inst->mutex);
|
||||
if (!list_empty(&inst->mdp_bufs.node))
|
||||
head = list_first_entry(&inst->mdp_bufs.node,
|
||||
struct mdp_buf_queue, node);
|
||||
mutex_unlock(&inst->mutex);
|
||||
}
|
||||
|
||||
if (head == NULL)
|
||||
return -ENOBUFS;
|
||||
|
||||
mutex_lock(&inst->mutex);
|
||||
list_del(&head->node);
|
||||
mutex_unlock(&inst->mutex);
|
||||
|
||||
*binfo = head->mdp_buf_info;
|
||||
WFD_MSG_DBG("Dequeue %p with cookie %p\n",
|
||||
(void *)binfo->paddr, (void *)binfo->cookie);
|
||||
return 0;
|
||||
|
||||
}
|
||||
int mdp_set_prop(struct v4l2_subdev *sd, void *arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
long mdp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
{
|
||||
int rc = 0;
|
||||
if (!sd) {
|
||||
WFD_MSG_ERR("Invalid arguments\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
switch (cmd) {
|
||||
case MDP_Q_BUFFER:
|
||||
rc = mdp_q_buffer(sd, arg);
|
||||
break;
|
||||
case MDP_DQ_BUFFER:
|
||||
rc = mdp_dq_buffer(sd, arg);
|
||||
break;
|
||||
case MDP_OPEN:
|
||||
rc = mdp_open(sd, arg);
|
||||
break;
|
||||
case MDP_START:
|
||||
rc = mdp_start(sd, arg);
|
||||
break;
|
||||
case MDP_STOP:
|
||||
rc = mdp_stop(sd, arg);
|
||||
break;
|
||||
case MDP_SET_PROP:
|
||||
rc = mdp_set_prop(sd, arg);
|
||||
break;
|
||||
case MDP_CLOSE:
|
||||
rc = mdp_close(sd, arg);
|
||||
break;
|
||||
default:
|
||||
WFD_MSG_ERR("IOCTL: %u not supported\n", cmd);
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
}
|
|
@ -34,6 +34,12 @@ struct mdp_prop {
|
|||
u32 width;
|
||||
};
|
||||
|
||||
struct mdp_msg_ops {
|
||||
void *cookie;
|
||||
bool secure;
|
||||
bool iommu_split_domain;
|
||||
};
|
||||
|
||||
static inline bool mdp_buf_info_equals(struct mdp_buf_info *a,
|
||||
struct mdp_buf_info *b)
|
||||
{
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/list.h>
|
||||
|
@ -40,8 +39,8 @@
|
|||
#define WFD_NUM_DEVICES 2
|
||||
#define WFD_DEVICE_NUMBER_BASE 38
|
||||
#define WFD_DEVICE_SECURE (WFD_DEVICE_NUMBER_BASE + 1)
|
||||
#define DEFAULT_WFD_WIDTH 640
|
||||
#define DEFAULT_WFD_HEIGHT 480
|
||||
#define DEFAULT_WFD_WIDTH 1280
|
||||
#define DEFAULT_WFD_HEIGHT 720
|
||||
#define VENC_INPUT_BUFFERS 4
|
||||
|
||||
struct wfd_device {
|
||||
|
@ -882,7 +881,7 @@ static int wfd_register_out_buf(struct wfd_inst *inst,
|
|||
list_add_tail(&minfo_entry->list, &inst->minfo_list);
|
||||
spin_unlock_irqrestore(&inst->inst_lock, flags);
|
||||
} else
|
||||
WFD_MSG_INFO("Buffer already registered\n");
|
||||
WFD_MSG_DBG("Buffer already registered\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -968,7 +967,7 @@ static int wfdioc_dqbuf(struct file *filp, void *fh,
|
|||
struct wfd_inst *inst = filp->private_data;
|
||||
int rc;
|
||||
|
||||
WFD_MSG_INFO("Waiting to dequeue buffer\n");
|
||||
WFD_MSG_DBG("Waiting to dequeue buffer\n");
|
||||
rc = vb2_dqbuf(&inst->vid_bufq, b, 0);
|
||||
|
||||
if (rc)
|
||||
|
@ -1304,6 +1303,7 @@ static int wfd_open(struct file *filp)
|
|||
struct wfd_inst *inst = NULL;
|
||||
struct wfd_device *wfd_dev = NULL;
|
||||
struct venc_msg_ops enc_mops;
|
||||
struct mdp_msg_ops mdp_mops;
|
||||
struct vsg_msg_ops vsg_mops;
|
||||
|
||||
WFD_MSG_DBG("wfd_open: E\n");
|
||||
|
@ -1337,12 +1337,15 @@ static int wfd_open(struct file *filp)
|
|||
|
||||
wfd_stats_init(&inst->stats, MINOR(filp->f_dentry->d_inode->i_rdev));
|
||||
|
||||
mdp_mops.secure = wfd_dev->secure_device;
|
||||
mdp_mops.iommu_split_domain = wfd_dev->mdp_iommu_split_domain;
|
||||
rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl, MDP_OPEN,
|
||||
(void *)&inst->mdp_inst);
|
||||
(void *)&mdp_mops);
|
||||
if (rc) {
|
||||
WFD_MSG_ERR("Failed to open mdp subdevice: %d\n", rc);
|
||||
goto err_mdp_open;
|
||||
}
|
||||
inst->mdp_inst = mdp_mops.cookie;
|
||||
|
||||
rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core, load_fw);
|
||||
if (rc) {
|
||||
|
|
|
@ -21,16 +21,11 @@
|
|||
/*#define DEBUG_WFD*/
|
||||
|
||||
#define WFD_TAG "wfd: "
|
||||
#ifdef DEBUG_WFD
|
||||
#define WFD_MSG_INFO(fmt...) pr_info(WFD_TAG fmt)
|
||||
#define WFD_MSG_WARN(fmt...) pr_warning(WFD_TAG fmt)
|
||||
#else
|
||||
#define WFD_MSG_INFO(fmt...)
|
||||
#define WFD_MSG_WARN(fmt...)
|
||||
#endif
|
||||
#define WFD_MSG_ERR(fmt...) pr_err(KERN_ERR WFD_TAG fmt)
|
||||
#define WFD_MSG_CRIT(fmt...) pr_crit(KERN_CRIT WFD_TAG fmt)
|
||||
#define WFD_MSG_DBG(fmt...) pr_debug(WFD_TAG fmt)
|
||||
#define WFD_MSG_INFO(fmt...) pr_info(WFD_TAG fmt)
|
||||
#define WFD_MSG_WARN(fmt...) pr_warning(WFD_TAG fmt)
|
||||
#define WFD_MSG_ERR(fmt...) pr_err(KERN_ERR WFD_TAG fmt)
|
||||
#define WFD_MSG_CRIT(fmt...) pr_crit(KERN_CRIT WFD_TAG fmt)
|
||||
#define WFD_MSG_DBG(fmt...) pr_debug(WFD_TAG fmt)
|
||||
|
||||
|
||||
struct wfd_stats_encode_sample {
|
||||
|
|
Loading…
Reference in a new issue