Re: [PATCH 1/3] [media] v4l: tegra: Add NVIDIA Tegra VI driver
On 09/22/2015 04:47 AM, Thierry Reding wrote: On Mon, Sep 21, 2015 at 11:55:53AM -0700, Bryan Wu wrote: [...] +static int tegra_csi_s_stream(struct v4l2_subdev *subdev, int enable) +{ + struct tegra_csi_device *csi = to_csi(subdev); + struct tegra_channel *chan = subdev->host_priv; + enum tegra_csi_port_num port_num = (chan->port & 1) ? PORT_B : PORT_A; + struct tegra_csi_port *port = >ports[port_num]; + int ret; + + if (enable) { [...] + } else { + u32 val = pp_read(port, TEGRA_CSI_PIXEL_PARSER_STATUS); + dev_dbg(csi->dev, "TEGRA_CSI_PIXEL_PARSER_STATUS 0x%08x\n", val); + + val = cil_read(port, TEGRA_CSI_CIL_STATUS); + dev_dbg(csi->dev, "TEGRA_CSI_CIL_STATUS 0x%08x\n", val); + + val = cil_read(port, TEGRA_CSI_CILX_STATUS); + dev_dbg(csi->dev, "TEGRA_CSI_CILX_STATUS 0x%08x\n", val); + I was going to apply this and give it a spin, but then git am complained about trailing whitespace above... +#ifdef DEBUG + val = csi_read(csi, TEGRA_CSI_DEBUG_COUNTER_0); + dev_err(>dev, "TEGRA_CSI_DEBUG_COUNTER_0 0x%08x\n", val); +#endif + + pp_write(port, TEGRA_CSI_PIXEL_STREAM_PP_COMMAND, +(0xF << CSI_PP_START_MARKER_FRAME_MAX_OFFSET) | +CSI_PP_DISABLE); + + clk_disable_unprepare(csi->clk); + } + and here, ... +static int tegra_csi_probe(struct platform_device *pdev) +{ [...] + for (i = 0; i < TEGRA_CSI_PORTS_NUM; i++) { + /* Initialize the default format */ + csi->ports[i].format.code = TEGRA_VF_DEF; + csi->ports[i].format.field = V4L2_FIELD_NONE; + csi->ports[i].format.colorspace = V4L2_COLORSPACE_SRGB; + csi->ports[i].format.width = TEGRA_DEF_WIDTH; + csi->ports[i].format.height = TEGRA_DEF_HEIGHT; + + /* Initialize port register bases */ + csi->ports[i].pixel_parser = csi->iomem + +(i & 1) * TEGRA_CSI_PORT_OFFSET; + csi->ports[i].cil = csi->iomem + TEGRA_CSI_CIL_OFFSET + here and... + (i & 1) * TEGRA_CSI_PORT_OFFSET; + csi->ports[i].tpg = csi->iomem + TEGRA_CSI_TPG_OFFSET + here. Might be worth fixing those up if you'll respin anyway. Thierry Thanks for pointing out this, I will rerun the check-patch.pl and fix all those coding style errors. -Bryan --- This email message is for the sole use of the intended recipient(s) and may contain confidential information. Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message. --- -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 01/21] Revert "[media] media: media controller entity framework enhancements for ALSA"
This reverts commit ed64cf1e182fb30fe67652386c0880fcf3302f97. This patch is no longer necessary as the entity register callback is implemented at media_device level. Signed-off-by: Shuah Khan--- drivers/media/media-device.c | 7 --- include/media/media-entity.h | 4 2 files changed, 11 deletions(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 76590ba..c55ab50 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -428,8 +428,6 @@ EXPORT_SYMBOL_GPL(media_device_unregister); int __must_check media_device_register_entity(struct media_device *mdev, struct media_entity *entity) { - struct media_entity *eptr; - /* Warn if we apparently re-register an entity */ WARN_ON(entity->parent != NULL); entity->parent = mdev; @@ -442,11 +440,6 @@ int __must_check media_device_register_entity(struct media_device *mdev, list_add_tail(>list, >entities); spin_unlock(>lock); - media_device_for_each_entity(eptr, mdev) { - if (eptr != entity) - media_entity_call(eptr, register_notify); - } - return 0; } EXPORT_SYMBOL_GPL(media_device_register_entity); diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 0bc4c2f..0c003d8 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -46,7 +46,6 @@ struct media_pad { /** * struct media_entity_operations - Media entity operations - * @register_notifyNotify entity of newly registered entity * @link_setup:Notify the entity of link changes. The operation can * return an error, in which case link setup will be * cancelled. Optional. @@ -55,7 +54,6 @@ struct media_pad { * validates all links by calling this operation. Optional. */ struct media_entity_operations { - int (*register_notify)(struct media_entity *entity); int (*link_setup)(struct media_entity *entity, const struct media_pad *local, const struct media_pad *remote, u32 flags); @@ -103,8 +101,6 @@ struct media_entity { /* Sub-device specifications */ /* Nothing needed yet */ } info; - - void *private; /* private data for the entity */ }; static inline u32 media_entity_type(struct media_entity *entity) -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 07/21] media: Media Controller non-locking __media_entity_pipeline_start/stop()
Add non-locking __media_entity_pipeline_start/stop() interfaces to be called from code paths that hold the graph_mutex. For this change, the media_entity_pipeline_start() routine is renamed to __media_entity_pipeline_start() minus the graph_mutex lock and unlock. media_entity_pipeline_start() now calls the non-locking __media_entity_pipeline_start() holding the graph_lock. The stop interface, media_entity_pipeline_stop() routine is renamed to __media_entity_pipeline_stop() minus the graph_mutex lock and unlock. media_entity_pipeline_stop() now calls the non-locking __media_entity_pipeline_stop() holding the graph_lock. Signed-off-by: Shuah Khan--- drivers/media/media-entity.c | 45 ++-- include/media/media-entity.h | 3 +++ 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 03b3836..b87e773 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -210,6 +210,7 @@ EXPORT_SYMBOL_GPL(media_entity_graph_walk_next); /** * media_entity_pipeline_start - Mark a pipeline as streaming + * __media_entity_pipeline_start - Mark a pipeline as streaming * @entity: Starting entity * @pipe: Media pipeline to be assigned to all entities in the pipeline. * @@ -220,18 +221,17 @@ EXPORT_SYMBOL_GPL(media_entity_graph_walk_next); * Calls to this function can be nested, in which case the same number of * media_entity_pipeline_stop() calls will be required to stop streaming. The * pipeline pointer must be identical for all nested calls to - * media_entity_pipeline_start(). + * __media_entity_pipeline_start(). + * User is expected to hold the graph_mutex. If not user can call + * media_entity_pipeline_start() */ -__must_check int media_entity_pipeline_start(struct media_entity *entity, -struct media_pipeline *pipe) +__must_check int __media_entity_pipeline_start(struct media_entity *entity, + struct media_pipeline *pipe) { - struct media_device *mdev = entity->parent; struct media_entity_graph graph; struct media_entity *entity_err = entity; int ret; - mutex_lock(>graph_mutex); - media_entity_graph_walk_start(, entity); while ((entity = media_entity_graph_walk_next())) { @@ -303,8 +303,6 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, } } - mutex_unlock(>graph_mutex); - return 0; error: @@ -330,14 +328,25 @@ error: break; } - mutex_unlock(>graph_mutex); + return ret; +} +EXPORT_SYMBOL_GPL(__media_entity_pipeline_start); +__must_check int media_entity_pipeline_start(struct media_entity *entity, +struct media_pipeline *pipe) +{ + struct media_device *mdev = entity->parent; + int ret; + + mutex_lock(>graph_mutex); + ret = __media_entity_pipeline_start(entity, pipe); + mutex_unlock(>graph_mutex); return ret; } EXPORT_SYMBOL_GPL(media_entity_pipeline_start); /** - * media_entity_pipeline_stop - Mark a pipeline as not streaming + * __media_entity_pipeline_stop - Mark a pipeline as not streaming * @entity: Starting entity * * Mark all entities connected to a given entity through enabled links, either @@ -347,14 +356,13 @@ EXPORT_SYMBOL_GPL(media_entity_pipeline_start); * If multiple calls to media_entity_pipeline_start() have been made, the same * number of calls to this function are required to mark the pipeline as not * streaming. + * User is expected to hold the graph_mutex. If not user can call + * media_entity_pipeline_stop() */ -void media_entity_pipeline_stop(struct media_entity *entity) +void __media_entity_pipeline_stop(struct media_entity *entity) { - struct media_device *mdev = entity->parent; struct media_entity_graph graph; - mutex_lock(>graph_mutex); - media_entity_graph_walk_start(, entity); while ((entity = media_entity_graph_walk_next())) { @@ -366,6 +374,15 @@ void media_entity_pipeline_stop(struct media_entity *entity) } } +} +EXPORT_SYMBOL_GPL(__media_entity_pipeline_stop); + +void media_entity_pipeline_stop(struct media_entity *entity) +{ + struct media_device *mdev = entity->parent; + + mutex_lock(>graph_mutex); + __media_entity_pipeline_stop(entity); mutex_unlock(>graph_mutex); } EXPORT_SYMBOL_GPL(media_entity_pipeline_stop); diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 0c003d8..cc0bbd0 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -148,8 +148,11 @@ void media_entity_graph_walk_start(struct media_entity_graph *graph, struct media_entity *entity); struct media_entity *
Re: [Linux-kernel] Renesas Lager: Device Tree entries for VIN HDMI input, version 2
Hi Simon, On Thu, 13 Aug 2015, William Towle wrote: > (Obsoletes corresponding parts of "HDMI and Composite capture on > Lager...", published previously) > To follow: >[PATCH 1/3] ARM: shmobile: lager dts: Add entries for VIN HDMI input >[PATCH 2/3] media: adv7604: automatic "default-input" selection >[PATCH 3/3] ARM: shmobile: lager dts: specify default-input for I am wondering about the status of patch 2 of the series, is it queued-up anywhere? All of these are effectively new, although the first and third debuted in another thread. The patchwork link for the latter (at https://patchwork.linuxtv.org/patch/30707/) contains the discussion that led to the above being separated out. I am also wondering about the relationship between patch 2 and 3. Does 3 work without 2? Does 2 make 3 unnecessary? The device tree change in patch 3 is from Ian Molton's original submissions, and works regardless of whether patch 2 is alongside it or not. As far as the automatic port selection goes, patch 2 is related to the argument made in commit 7111cdd ("[media] media: adv7604: reduce support to first (digital) input") that since cable detect doesn't work for port B, the .max_port property for boards using an ADV7612 should be ADV76XX_PAD_HDMI_PORT_A and we can use this to configure port A as the default where there is not also an entry to specify it in the device tree. If support for port B were available [in future], no action would be taken where an ADV7612 is present and one would need to arrange for applications in userland to actively make a choice where the device tree does not have an appropriate value. In our particular case we don't differentiate between hardware with ADV7611/7612 in the test suite, and this necessitates having port selection available in the device tree. Laurent may wish to comment further; for earlier discussion, see https://patchwork.linuxtv.org/patch/30707/ Cheers, Wills. -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 20/21] media: media: dvb-frontend fix enable_source error legs
When enable_source finds the tuner busy, do dvb_generic_release(). In addition, when dvb_frontend_start() fails, call disable_source to release tuner. Signed-off-by: Shuah Khan--- drivers/media/dvb-core/dvb_frontend.c | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index c06dd61..67e30ae 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -2503,13 +2503,13 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) if (ret) { dev_err(fe->dvb->device, "Tuner is busy. Error %d\n", ret); - goto err1; + goto err2; } } #endif ret = dvb_frontend_start (fe); if (ret) - goto err2; + goto err3; /* empty event queue */ fepriv->events.eventr = fepriv->events.eventw = 0; @@ -2519,6 +2519,11 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) mutex_unlock (>mfe_lock); return ret; +err3: +#ifdef CONFIG_MEDIA_CONTROLLER_DVB + if (fe->dvb->mdev && fe->dvb->mdev->disable_source) + fe->dvb->mdev->disable_source(dvbdev->entity); +#endif err2: dvb_generic_release(inode, file); err1: -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 21/21] sound/usb: Update ALSA driver to use Managed Media Controller API
Change ALSA driver to use Managed ~media Managed Controller API to share tuner with DVB and V4L2 drivers that control AU0828 media device. Media device is created based on a newly added field value in the struct snd_usb_audio_quirk. Using this approach, the media controller API usage can be added for a specific device. In this patch, Media Controller API is enabled for AU0828 hw. snd_usb_create_quirk() will check this new field, if set will create a media device using media_device_get_devres() interface. media_device_get_devres() will allocate a new media device devres or return an existing one, if it finds one. During probe, media usb driver could have created the media device devres. It will then register the media device if it isn't already registered. Media device unregister is done from usb_audio_disconnect(). During probe, media usb driver could have created the media device devres. It will then register the media device if it isn't already registered. Media device unregister is done from usb_audio_disconnect(). New structure media_ctl is added to group the new fields to support media entity and links. This new structure is added to struct snd_usb_substream. A new entity_notify hook and a new ALSA capture media entity are registered from snd_usb_pcm_open() after setting up hardware information for the PCM device. When a new entity is registered, Media Controller API interface media_device_register_entity() invokes all registered entity_notify hooks for the media device. ALSA entity_notify hook parses all the entity list to find a link from decoder it ALSA entity. This indicates that the bridge driver created a link from decoder to ALSA capture entity. ALSA will attempt to enable the tuner to link the tuner to the decoder calling enable_source handler if one is provided by the bridge driver prior to starting Media pipeline from snd_usb_hw_params(). If enable_source returns with tuner busy condition, then snd_usb_hw_params() will fail with -EBUSY. Media pipeline is stopped from snd_usb_hw_free(). Signed-off-by: Shuah Khan--- sound/usb/Makefile | 15 +++- sound/usb/card.c | 5 ++ sound/usb/card.h | 1 + sound/usb/media.c| 178 +++ sound/usb/media.h| 51 ++ sound/usb/pcm.c | 29 ++-- sound/usb/quirks-table.h | 1 + sound/usb/quirks.c | 9 ++- sound/usb/stream.c | 2 + sound/usb/usbaudio.h | 1 + 10 files changed, 284 insertions(+), 8 deletions(-) create mode 100644 sound/usb/media.c create mode 100644 sound/usb/media.h diff --git a/sound/usb/Makefile b/sound/usb/Makefile index 2d2d122..665fdd9 100644 --- a/sound/usb/Makefile +++ b/sound/usb/Makefile @@ -2,6 +2,18 @@ # Makefile for ALSA # +# Media Controller +ifeq ($(CONFIG_MEDIA_CONTROLLER),y) + ifeq ($(CONFIG_MEDIA_SUPPORT),y) +KBUILD_CFLAGS += -DUSE_MEDIA_CONTROLLER + endif + ifeq ($(CONFIG_MEDIA_SUPPORT_MODULE),y) +ifeq ($(MODULE),y) + KBUILD_CFLAGS += -DUSE_MEDIA_CONTROLLER +endif + endif +endif + snd-usb-audio-objs := card.o \ clock.o \ endpoint.o \ @@ -13,7 +25,8 @@ snd-usb-audio-objs := card.o \ pcm.o \ proc.o \ quirks.o \ - stream.o + stream.o \ + media.o snd-usbmidi-lib-objs := midi.o diff --git a/sound/usb/card.c b/sound/usb/card.c index 1fab977..469d2bf 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -66,6 +66,7 @@ #include "format.h" #include "power.h" #include "stream.h" +#include "media.h" MODULE_AUTHOR("Takashi Iwai "); MODULE_DESCRIPTION("USB Audio"); @@ -619,6 +620,10 @@ static void usb_audio_disconnect(struct usb_interface *intf) list_for_each_entry(mixer, >mixer_list, list) { snd_usb_mixer_disconnect(mixer); } + /* Nice to check quirk && quirk->media_device +* need some special handlings. Doesn't look like +* we have access to quirk here */ + media_device_delete(intf); } chip->num_interfaces--; diff --git a/sound/usb/card.h b/sound/usb/card.h index ef580b4..235a85f 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h @@ -155,6 +155,7 @@ struct snd_usb_substream { } dsd_dop; bool trigger_tstamp_pending_update; /* trigger timestamp being updated from initial estimate */ + void *media_ctl; }; struct snd_usb_stream { diff --git a/sound/usb/media.c b/sound/usb/media.c new file mode 100644 index 000..97c3b2d --- /dev/null +++ b/sound/usb/media.c @@ -0,0 +1,178 @@ +/* + * media.c - Media Controller specific ALSA driver code + * + * Copyright (c) 2015 Shuah Khan + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + *
[PATCH v3 08/21] media: v4l-core add v4l_enable/disable_media_tuner() helper functions
Add a new interfaces to be used by v4l-core to invoke enable source and disable_source handlers in the media_device. The enable_source helper function invokes the enable_source handler to find tuner entity connected to the decoder and check is it is available or busy. If tuner is available, link is activated and pipeline is started. The disable_source helper function invokes the disable_source handler to deactivate and stop the pipeline. Signed-off-by: Shuah Khan--- drivers/media/v4l2-core/v4l2-dev.c | 27 +++ include/media/v4l2-dev.h | 4 2 files changed, 31 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 71a1b93..8e93c99 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -230,6 +230,33 @@ struct video_device *video_devdata(struct file *file) } EXPORT_SYMBOL(video_devdata); +int v4l_enable_media_tuner(struct video_device *vdev) +{ +#ifdef CONFIG_MEDIA_CONTROLLER + struct media_device *mdev = vdev->entity.parent; + int ret; + + if (!mdev || !mdev->enable_source) + return 0; + ret = mdev->enable_source(>entity, >pipe); + if (ret) + return -EBUSY; + return 0; +#endif /* CONFIG_MEDIA_CONTROLLER */ + return 0; +} +EXPORT_SYMBOL_GPL(v4l_enable_media_tuner); + +void v4l_disable_media_tuner(struct video_device *vdev) +{ +#ifdef CONFIG_MEDIA_CONTROLLER + struct media_device *mdev = vdev->entity.parent; + + if (mdev && mdev->disable_source) + mdev->disable_source(>entity); +#endif /* CONFIG_MEDIA_CONTROLLER */ +} +EXPORT_SYMBOL_GPL(v4l_disable_media_tuner); /* Priority handling */ diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index acbcd2f..8f1884f 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -86,6 +86,7 @@ struct video_device { #if defined(CONFIG_MEDIA_CONTROLLER) struct media_entity entity; + struct media_pipeline pipe; #endif /* device ops */ const struct v4l2_file_operations *fops; @@ -178,6 +179,9 @@ struct video_device * __must_check video_device_alloc(void); /* this release function frees the vdev pointer */ void video_device_release(struct video_device *vdev); +int v4l_enable_media_tuner(struct video_device *vdev); +void v4l_disable_media_tuner(struct video_device *vdev); + /* this release function does nothing, use when the video_device is a static global struct. Note that having a static video_device is a dubious construction at best. */ -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 14/21] media: dvb-frontend invoke enable/disable_source handlers
Checking for tuner availability from frontend thread start disrupts video stream. Change to check for tuner and start pipeline from frontend open instead and stop pipeline from frontend release. In addition, make a change to invoke enable_source and disable_source handlers to check for tuner availability. The enable_source handler finds tuner entity connected to the decoder and check is it is available or busy. If tuner is available, link is activated and pipeline is started. The disable_source handler to deactivate and stop the pipeline. dvb_enable_media_tuner() is removed as it is no longer necessary with dvb invoking enable_source and disable_source handlers. pipe_start_entity field is removed and pipe field is moved to dvb_frontend from dvb_frontend_private. Signed-off-by: Shuah Khan--- drivers/media/dvb-core/dvb_frontend.c | 135 -- drivers/media/dvb-core/dvb_frontend.h | 3 + 2 files changed, 18 insertions(+), 120 deletions(-) diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 842b9c8..c06dd61 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -132,11 +132,6 @@ struct dvb_frontend_private { int quality; unsigned int check_wrapped; enum dvbfe_search algo_status; - -#if defined(CONFIG_MEDIA_CONTROLLER_DVB) - struct media_pipeline pipe; - struct media_entity *pipe_start_entity; -#endif }; static void dvb_frontend_wakeup(struct dvb_frontend *fe); @@ -597,107 +592,12 @@ static void dvb_frontend_wakeup(struct dvb_frontend *fe) wake_up_interruptible(>wait_queue); } -/** - * dvb_enable_media_tuner() - tries to enable the DVB tuner - * - * @fe:struct dvb_frontend pointer - * - * This function ensures that just one media tuner is enabled for a given - * frontend. It has two different behaviors: - * - For trivial devices with just one tuner: - * it just enables the existing tuner->fe link - * - For devices with more than one tuner: - * It is up to the driver to implement the logic that will enable one tuner - * and disable the other ones. However, if more than one tuner is enabled for - * the same frontend, it will print an error message and return -EINVAL. - * - * At return, it will return the error code returned by media_entity_setup_link, - * or 0 if everything is OK, if no tuner is linked to the frontend or if the - * mdev is NULL. - */ -#ifdef CONFIG_MEDIA_CONTROLLER_DVB -static int dvb_enable_media_tuner(struct dvb_frontend *fe) -{ - struct dvb_frontend_private *fepriv = fe->frontend_priv; - struct dvb_adapter *adapter = fe->dvb; - struct media_device *mdev = adapter->mdev; - struct media_entity *entity, *source; - struct media_link *link, *found_link = NULL; - int i, ret, n_links = 0, active_links = 0; - - fepriv->pipe_start_entity = NULL; - - if (!mdev) - return 0; - - entity = fepriv->dvbdev->entity; - fepriv->pipe_start_entity = entity; - - for (i = 0; i < entity->num_links; i++) { - link = >links[i]; - if (link->sink->entity == entity) { - found_link = link; - n_links++; - if (link->flags & MEDIA_LNK_FL_ENABLED) - active_links++; - } - } - - if (!n_links || active_links == 1 || !found_link) - return 0; - - /* -* If a frontend has more than one tuner linked, it is up to the driver -* to select with one will be the active one, as the frontend core can't -* guess. If the driver doesn't do that, it is a bug. -*/ - if (n_links > 1 && active_links != 1) { - dev_err(fe->dvb->device, - "WARNING: there are %d active links among %d tuners. This is a driver's bug!\n", - active_links, n_links); - return -EINVAL; - } - - source = found_link->source->entity; - fepriv->pipe_start_entity = source; - for (i = 0; i < source->num_links; i++) { - struct media_entity *sink; - int flags = 0; - - link = >links[i]; - sink = link->sink->entity; - - if (sink == entity) - flags = MEDIA_LNK_FL_ENABLED; - - ret = media_entity_setup_link(link, flags); - if (ret) { - dev_err(fe->dvb->device, - "Couldn't change link %s->%s to %s. Error %d\n", - source->name, sink->name, - flags ? "enabled" : "disabled", - ret); - return ret; - } else - dev_dbg(fe->dvb->device, - "link %s->%s was
[PATCH v3 10/21] media: au8522 change to create MC pad for ALSA Audio Out
Add new pad for ALSA Audio Out to au8522_media_pads. Signed-off-by: Shuah Khan--- drivers/media/dvb-frontends/au8522.h | 1 + drivers/media/dvb-frontends/au8522_decoder.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/media/dvb-frontends/au8522.h b/drivers/media/dvb-frontends/au8522.h index 3c72f40..d7a997f 100644 --- a/drivers/media/dvb-frontends/au8522.h +++ b/drivers/media/dvb-frontends/au8522.h @@ -94,6 +94,7 @@ enum au8522_media_pads { AU8522_PAD_INPUT, AU8522_PAD_VID_OUT, AU8522_PAD_VBI_OUT, + AU8522_PAD_AUDIO_OUT, AU8522_NUM_PADS }; diff --git a/drivers/media/dvb-frontends/au8522_decoder.c b/drivers/media/dvb-frontends/au8522_decoder.c index 24990db..5fc9a39 100644 --- a/drivers/media/dvb-frontends/au8522_decoder.c +++ b/drivers/media/dvb-frontends/au8522_decoder.c @@ -775,6 +775,7 @@ static int au8522_probe(struct i2c_client *client, state->pads[AU8522_PAD_INPUT].flags = MEDIA_PAD_FL_SINK; state->pads[AU8522_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; state->pads[AU8522_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE; + state->pads[AU8522_PAD_AUDIO_OUT].flags = MEDIA_PAD_FL_SOURCE; sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_DECODER; ret = media_entity_init(>entity, ARRAY_SIZE(state->pads), -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 16/21] media: au0828 video change to use v4l_enable_media_tuner()
au0828 is changed to use v4l_enable_media_tuner() to check for tuner availability from vidioc_g_tuner(), and au0828_v4l2_close(), before changing tuner settings. If tuner isn't free, return busy condition from vidioc_g_tuner() and in au0828_v4l2_close() tuner is left untouched without powering down to save energy. Signed-off-by: Shuah Khan--- drivers/media/usb/au0828/au0828-video.c | 14 -- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index b63ae78..6680aeb 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -1005,8 +1005,12 @@ static int au0828_v4l2_close(struct file *filp) goto end; if (dev->users == 1) { - /* Save some power by putting tuner to sleep */ - v4l2_device_call_all(>v4l2_dev, 0, core, s_power, 0); + /* Save some power by putting tuner to sleep, if it is free */ + /* What happens when radio is using tuner?? */ + ret = v4l_enable_media_tuner(vdev); + if (ret == 0) + v4l2_device_call_all(>v4l2_dev, 0, core, +s_power, 0); dev->std_set_in_tuner_core = 0; /* When close the device, set the usb intf0 into alt0 to free @@ -1407,10 +1411,16 @@ static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) { struct au0828_dev *dev = video_drvdata(file); + struct video_device *vfd = video_devdata(file); + int ret; if (t->index != 0) return -EINVAL; + ret = v4l_enable_media_tuner(vfd); + if (ret) + return ret; + dprintk(1, "%s called std_set %d dev_state %d\n", __func__, dev->std_set_in_tuner_core, dev->dev_state); -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 19/21] media: au0828 implement enable_source and disable_source handlers
Implements enable_source and disable_source handlers for other drivers (v4l2-core, dvb-core, and ALSA) to use to check for tuner connected to the decoder and activate the link if tuner is free, and deactivate and free the tuner when it is no longer needed. Signed-off-by: Shuah Khan--- drivers/media/usb/au0828/au0828-core.c | 169 + drivers/media/usb/au0828/au0828.h | 2 + 2 files changed, 171 insertions(+) diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index fcff2e2..ce9d5d4 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -268,6 +268,164 @@ static void au0828_create_media_graph(struct media_entity *new, #endif } +static int au0828_enable_source(struct media_entity *entity, + struct media_pipeline *pipe) +{ +#ifdef CONFIG_MEDIA_CONTROLLER + struct media_entity *source; + struct media_entity *sink; + struct media_link *link, *found_link = NULL; + int i, ret = 0; + struct media_device *mdev = entity->parent; + struct au0828_dev *dev; + + if (!mdev) + return -ENODEV; + + /* for ALSA and Video entities, source is the decoder */ + mutex_lock(>graph_mutex); + + dev = mdev->source_priv; + if (!dev->tuner || !dev->decoder) { + ret = -ENODEV; + goto end; + } + + /* +* For ALSA and V4L2 entity, find the link to which decoder +* is the sink. Look for an active link between decoder and +* tuner, if one exists, nothing to do. If not, look for any +* active links between tuner and any other entity. If one +* exists, tuner is busy. If tuner is free, setup link and +* start pipeline from source (tuner). +* For DVB FE entity, the source for the link is the tuner. +* Check if tuner is available and setup link and start +* pipeline. + */ + if (entity->type != MEDIA_ENT_T_DEVNODE_DVB_FE) + sink = dev->decoder; + else + sink = entity; + + /* Is an active link between sink and tuner */ + if (dev->active_link) { + if (dev->active_link->sink->entity == sink && + dev->active_link->source->entity == dev->tuner) { + ret = 0; + goto end; + } else { + ret = -EBUSY; + goto end; + } + } + + for (i = 0; i < sink->num_links; i++) { + link = >links[i]; + /* Used to check just the sink, check source too - works?? */ + if (link->sink->entity == sink && + link->source->entity == dev->tuner) { + found_link = link; + break; + } + } + + if (!found_link) { + ret = -ENODEV; + goto end; + } + + source = found_link->source->entity; + for (i = 0; i < source->num_links; i++) { + struct media_entity *find_sink; + int flags = 0; + + link = >links[i]; + find_sink = link->sink->entity; + + if (find_sink == sink) + flags = MEDIA_LNK_FL_ENABLED; + + ret = __media_entity_setup_link(link, flags); + if (ret) { + pr_err( + "Change tuner link %s->%s to %s. Error %d\n", + source->name, find_sink->name, + flags ? "enabled" : "disabled", + ret); + goto end; + } + /* start pipeline */ + if (find_sink == sink) { + dev->active_link = link; + ret = __media_entity_pipeline_start(entity, pipe); + if (ret) { + pr_err("Start Pipeline: %s->%s Error %d\n", + source->name, entity->name, ret); + goto end; + } + /* save link owner to avoid audio deactivating + video owned link from disable_source and + vice versa */ + dev->active_link_owner = entity; + pr_info("Started Pipeline: %s->%s ret %d\n", + source->name, entity->name, ret); + } + } +end: + mutex_unlock(>graph_mutex); + return ret; +#endif + return 0; +} + +static void au0828_disable_source(struct media_entity *entity) +{ +#ifdef CONFIG_MEDIA_CONTROLLER + struct media_entity *sink; + int ret = 0; + struct media_device *mdev = entity->parent; +
[PATCH v3 09/21] media: Move au8522_media_pads enum to au8522.h from au8522_priv.h
Move the au8522_media_pads enum to au8522.h from au8522_priv.h. This will allow au0828-core to use these defines instead of hard-coding the pad values when it creates media graph linking decode pads to other entities. Signed-off-by: Shuah Khan--- drivers/media/dvb-frontends/au8522.h | 7 +++ drivers/media/dvb-frontends/au8522_priv.h | 8 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/media/dvb-frontends/au8522.h b/drivers/media/dvb-frontends/au8522.h index dde6158..3c72f40 100644 --- a/drivers/media/dvb-frontends/au8522.h +++ b/drivers/media/dvb-frontends/au8522.h @@ -90,4 +90,11 @@ enum au8522_audio_input { AU8522_AUDIO_SIF, }; +enum au8522_media_pads { + AU8522_PAD_INPUT, + AU8522_PAD_VID_OUT, + AU8522_PAD_VBI_OUT, + + AU8522_NUM_PADS +}; #endif /* __AU8522_H__ */ diff --git a/drivers/media/dvb-frontends/au8522_priv.h b/drivers/media/dvb-frontends/au8522_priv.h index d6209d9..4c2a6ed 100644 --- a/drivers/media/dvb-frontends/au8522_priv.h +++ b/drivers/media/dvb-frontends/au8522_priv.h @@ -39,14 +39,6 @@ #define AU8522_DIGITAL_MODE 1 #define AU8522_SUSPEND_MODE 2 -enum au8522_media_pads { - AU8522_PAD_INPUT, - AU8522_PAD_VID_OUT, - AU8522_PAD_VBI_OUT, - - AU8522_NUM_PADS -}; - struct au8522_state { struct i2c_client *c; struct i2c_adapter *i2c; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 15/21] media: au0828 video remove au0828_enable_analog_tuner()
au0828_enable_analog_tuner() is no longer needed with v4l2-core and au0828-video invoking enable_source and disable_source handlers. In addition, it is unnecessary to check for tuner availability in queue_setup() as v4l2-core handles the tuner availability checks. Signed-off-by: Shuah Khan--- drivers/media/usb/au0828/au0828-video.c | 62 - 1 file changed, 62 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 939b2ad..b63ae78 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -637,66 +637,6 @@ static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb) return rc; } -static int au0828_enable_analog_tuner(struct au0828_dev *dev) -{ -#ifdef CONFIG_MEDIA_CONTROLLER - struct media_device *mdev = dev->media_dev; - struct media_entity *entity, *source; - struct media_link *link, *found_link = NULL; - int i, ret, active_links = 0; - - if (!mdev || !dev->decoder) - return 0; - - /* -* This will find the tuner that is connected into the decoder. -* Technically, this is not 100% correct, as the device may be -* using an analog input instead of the tuner. However, as we can't -* do DVB streaming while the DMA engine is being used for V4L2, -* this should be enough for the actual needs. -*/ - for (i = 0; i < dev->decoder->num_links; i++) { - link = >decoder->links[i]; - if (link->sink->entity == dev->decoder) { - found_link = link; - if (link->flags & MEDIA_LNK_FL_ENABLED) - active_links++; - break; - } - } - - if (active_links == 1 || !found_link) - return 0; - - source = found_link->source->entity; - for (i = 0; i < source->num_links; i++) { - struct media_entity *sink; - int flags = 0; - - link = >links[i]; - sink = link->sink->entity; - - if (sink == entity) - flags = MEDIA_LNK_FL_ENABLED; - - ret = media_entity_setup_link(link, flags); - if (ret) { - pr_err( - "Couldn't change link %s->%s to %s. Error %d\n", - source->name, sink->name, - flags ? "enabled" : "disabled", - ret); - return ret; - } else - au0828_isocdbg( - "link %s->%s was %s\n", - source->name, sink->name, - flags ? "ENABLED" : "disabled"); - } -#endif - return 0; -} - static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, unsigned int *nbuffers, unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[]) @@ -712,8 +652,6 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, *nplanes = 1; sizes[0] = size; - au0828_enable_analog_tuner(dev); - return 0; } -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 03/21] media: Add ALSA Media Controller devnodes
Add ALSA Media Controller capture, playback, and mixer devnode defines. Signed-off-by: Shuah Khan--- include/uapi/linux/media.h | 5 + 1 file changed, 5 insertions(+) diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 4e816be..4a30ea3 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -49,12 +49,17 @@ struct media_device_info { #define MEDIA_ENT_T_DEVNODE(1 << MEDIA_ENT_TYPE_SHIFT) #define MEDIA_ENT_T_DEVNODE_V4L(MEDIA_ENT_T_DEVNODE + 1) #define MEDIA_ENT_T_DEVNODE_FB (MEDIA_ENT_T_DEVNODE + 2) +/* Legacy ALSA symbol. Keep it to avoid userspace compilation breakages */ #define MEDIA_ENT_T_DEVNODE_ALSA (MEDIA_ENT_T_DEVNODE + 3) #define MEDIA_ENT_T_DEVNODE_DVB_FE (MEDIA_ENT_T_DEVNODE + 4) #define MEDIA_ENT_T_DEVNODE_DVB_DEMUX (MEDIA_ENT_T_DEVNODE + 5) #define MEDIA_ENT_T_DEVNODE_DVB_DVR(MEDIA_ENT_T_DEVNODE + 6) #define MEDIA_ENT_T_DEVNODE_DVB_CA (MEDIA_ENT_T_DEVNODE + 7) #define MEDIA_ENT_T_DEVNODE_DVB_NET(MEDIA_ENT_T_DEVNODE + 8) +/* ALSA devnodes */ +#define MEDIA_ENT_T_DEVNODE_ALSA_CAPTURE (MEDIA_ENT_T_DEVNODE + 9) +#define MEDIA_ENT_T_DEVNODE_ALSA_PLAYBACK (MEDIA_ENT_T_DEVNODE + 10) +#define MEDIA_ENT_T_DEVNODE_ALSA_MIXER (MEDIA_ENT_T_DEVNODE + 11) /* Legacy symbol. Use it to avoid userspace compilation breakages */ #define MEDIA_ENT_T_DEVNODE_DVBMEDIA_ENT_T_DEVNODE_DVB_FE -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 12/21] media: au0828 fix au0828_create_media_graph() entity checks
au0828_create_media_graph() checks if entity.links is null or not to determine, if vbi_dev and vdev entities have been registered. Checking entity.parent field is right way, as parent field gets initialized when entity is registered. Fix it to check entity.parent field. Signed-off-by: Shuah Khan--- drivers/media/usb/au0828/au0828-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 276598b..0b8dc49 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -263,11 +263,11 @@ static void au0828_create_media_graph(struct au0828_dev *dev) if (tuner) media_entity_create_link(tuner, 0, decoder, 0, MEDIA_LNK_FL_ENABLED); - if (dev->vdev.entity.links) + if (dev->vdev.entity.parent) media_entity_create_link(decoder, AU8522_PAD_VID_OUT, >vdev.entity, 0, MEDIA_LNK_FL_ENABLED); - if (dev->vbi_dev.entity.links) + if (dev->vbi_dev.entity.parent) media_entity_create_link(decoder, AU8522_PAD_VBI_OUT, >vbi_dev.entity, 0, MEDIA_LNK_FL_ENABLED); -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 02/21] media: Media Controller register/unregister entity_notify API
Add new interfaces to register and unregister entity_notify hook to media device to allow drivers to take appropriate actions when as new entities get added to the shared media device.When a new entity is registered, all registered entity_notify hooks are invoked to allow drivers or modules that registered hook to take appropriate action. For example, ALSA driver registers an entity_notify hook to parse the list of registered entities to determine if decoder has been linked to ALSA entity. au0828 bridge driver registers an entity_notify hook to create media graph for the device. Signed-off-by: Shuah Khan--- drivers/media/media-device.c | 45 include/media/media-device.h | 23 ++ 2 files changed, 68 insertions(+) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index c55ab50..22565a8 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -381,6 +381,7 @@ int __must_check __media_device_register(struct media_device *mdev, mdev->entity_id = 1; INIT_LIST_HEAD(>entities); + INIT_LIST_HEAD(>entity_notify); spin_lock_init(>lock); mutex_init(>graph_mutex); @@ -411,9 +412,12 @@ void media_device_unregister(struct media_device *mdev) { struct media_entity *entity; struct media_entity *next; + struct media_entity_notify *notify, *nextp; list_for_each_entry_safe(entity, next, >entities, list) media_device_unregister_entity(entity); + list_for_each_entry_safe(notify, nextp, >entity_notify, list) + media_device_unregister_entity_notify(mdev, notify); device_remove_file(>devnode.dev, _attr_model); media_devnode_unregister(>devnode); @@ -421,6 +425,39 @@ void media_device_unregister(struct media_device *mdev) EXPORT_SYMBOL_GPL(media_device_unregister); /** + * media_device_register_entity_notify - Register a media entity notify + * callback with a media device. When a new entity is registered, all + * the registered media_entity_notify callbacks are invoked. + * @mdev: The media device + * @nptr: The media_entity_notify + */ +int __must_check media_device_register_entity_notify(struct media_device *mdev, + struct media_entity_notify *nptr) +{ + spin_lock(>lock); + list_add_tail(>list, >entity_notify); + spin_unlock(>lock); + return 0; +} +EXPORT_SYMBOL_GPL(media_device_register_entity_notify); + +/** + * media_device_unregister_entity_notify - Unregister a media entity notify + * callback with a media device. When a new entity is registered, all + * the registered media_entity_notify callbacks are invoked. + * @mdev: The media device + * @nptr: The media_entity_notify + */ +void media_device_unregister_entity_notify(struct media_device *mdev, + struct media_entity_notify *nptr) +{ + spin_lock(>lock); + list_del(>list); + spin_unlock(>lock); +} +EXPORT_SYMBOL_GPL(media_device_unregister_entity_notify); + +/** * media_device_register_entity - Register an entity with a media device * @mdev: The media device * @entity:The entity @@ -428,6 +465,8 @@ EXPORT_SYMBOL_GPL(media_device_unregister); int __must_check media_device_register_entity(struct media_device *mdev, struct media_entity *entity) { + struct media_entity_notify *notify, *next; + /* Warn if we apparently re-register an entity */ WARN_ON(entity->parent != NULL); entity->parent = mdev; @@ -440,6 +479,11 @@ int __must_check media_device_register_entity(struct media_device *mdev, list_add_tail(>list, >entities); spin_unlock(>lock); + /* invoke entity_notify callbacks */ + list_for_each_entry_safe(notify, next, >entity_notify, list) { + (notify)->notify(entity, notify->notify_data); + } + return 0; } EXPORT_SYMBOL_GPL(media_device_register_entity); @@ -462,6 +506,7 @@ void media_device_unregister_entity(struct media_entity *entity) list_del(>list); spin_unlock(>lock); entity->parent = NULL; + /* invoke entity_notify callbacks to handle entity removal?? */ } EXPORT_SYMBOL_GPL(media_device_unregister_entity); diff --git a/include/media/media-device.h b/include/media/media-device.h index a44f18f..a3854f6 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -32,6 +32,12 @@ struct device; +struct media_entity_notify { + struct list_head list; + void *notify_data; + void (*notify)(struct media_entity *entity, void *notify_data); +}; + /** * struct media_device - Media device * @dev: Parent device @@ -70,6 +76,8 @@ struct media_device { u32 entity_id; struct list_head entities; + /* notify callback
[PATCH v3 05/21] media: Media Controller fix to not let stream_count go negative
Add a range check to not let the stream_count become negative. Wthout this check, calls to stop pipeline when there is no active pipeline will result in stream_count < 0 condition and lock and preventing link state (activate/deactivate) changes. This will happen from error leg in start pipeline interface. Signed-off-by: Shuah Khan--- drivers/media/media-entity.c | 18 -- 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 4d8e01c..68d5ec2 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -315,9 +315,12 @@ error: media_entity_graph_walk_start(, entity_err); while ((entity_err = media_entity_graph_walk_next())) { - entity_err->stream_count--; - if (entity_err->stream_count == 0) - entity_err->pipe = NULL; + /* don't let the stream_count go negative */ + if (entity->stream_count > 0) { + entity_err->stream_count--; + if (entity_err->stream_count == 0) + entity_err->pipe = NULL; + } /* * We haven't increased stream_count further than this @@ -355,9 +358,12 @@ void media_entity_pipeline_stop(struct media_entity *entity) media_entity_graph_walk_start(, entity); while ((entity = media_entity_graph_walk_next())) { - entity->stream_count--; - if (entity->stream_count == 0) - entity->pipe = NULL; + /* don't let the stream_count go negative */ + if (entity->stream_count > 0) { + entity->stream_count--; + if (entity->stream_count == 0) + entity->pipe = NULL; + } } mutex_unlock(>graph_mutex); -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 06/21] media: Media Controller export non locking __media_entity_setup_link()
Export __media_entity_setup_link() to be used from code paths that hold the graph_mutex. Signed-off-by: Shuah Khan--- drivers/media/media-entity.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 68d5ec2..03b3836 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -612,6 +612,7 @@ int __media_entity_setup_link(struct media_link *link, u32 flags) return ret; } +EXPORT_SYMBOL_GPL(__media_entity_setup_link); int media_entity_setup_link(struct media_link *link, u32 flags) { -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 11/21] media: au0828 Use au8522_media_pads enum for pad defines
Change au0828-core to use au8522_media_pads enum defines instead of hard-coding the pad values when it creates media graph linking decode pads to other entities. Signed-off-by: Shuah Khan--- drivers/media/usb/au0828/au0828-core.c | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 0378a2c..276598b 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -20,6 +20,7 @@ */ #include "au0828.h" +#include "au8522.h" #include #include @@ -263,11 +264,13 @@ static void au0828_create_media_graph(struct au0828_dev *dev) media_entity_create_link(tuner, 0, decoder, 0, MEDIA_LNK_FL_ENABLED); if (dev->vdev.entity.links) - media_entity_create_link(decoder, 1, >vdev.entity, 0, -MEDIA_LNK_FL_ENABLED); + media_entity_create_link(decoder, AU8522_PAD_VID_OUT, +>vdev.entity, 0, +MEDIA_LNK_FL_ENABLED); if (dev->vbi_dev.entity.links) - media_entity_create_link(decoder, 2, >vbi_dev.entity, 0, -MEDIA_LNK_FL_ENABLED); + media_entity_create_link(decoder, AU8522_PAD_VBI_OUT, +>vbi_dev.entity, 0, +MEDIA_LNK_FL_ENABLED); #endif } -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 13/21] media: Change v4l-core to check for tuner availability
Change s_input, s_fmt, s_tuner, s_frequency, querystd, s_hw_freq_seek, and vb2_internal_streamon interfaces that alter the tuner configuration to check for tuner availability by calling v4l_enable_media_tuner(). If tuner isn't free, return -EBUSY. v4l_disable_media_tuner() is called from v4l2_fh_exit() to release the tuner. Signed-off-by: Shuah Khan--- drivers/media/v4l2-core/v4l2-fh.c| 1 + drivers/media/v4l2-core/v4l2-ioctl.c | 29 + drivers/media/v4l2-core/videobuf2-core.c | 3 +++ 3 files changed, 33 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-fh.c b/drivers/media/v4l2-core/v4l2-fh.c index c97067a..538db62 100644 --- a/drivers/media/v4l2-core/v4l2-fh.c +++ b/drivers/media/v4l2-core/v4l2-fh.c @@ -92,6 +92,7 @@ void v4l2_fh_exit(struct v4l2_fh *fh) { if (fh->vdev == NULL) return; + v4l_disable_media_tuner(fh->vdev); v4l2_event_unsubscribe_all(fh); fh->vdev = NULL; } diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 85de455..deffc1b 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1035,6 +1035,12 @@ static int v4l_querycap(const struct v4l2_ioctl_ops *ops, static int v4l_s_input(const struct v4l2_ioctl_ops *ops, struct file *file, void *fh, void *arg) { + struct video_device *vfd = video_devdata(file); + int ret; + + ret = v4l_enable_media_tuner(vfd); + if (ret) + return ret; return ops->vidioc_s_input(file, fh, *(unsigned int *)arg); } @@ -1433,6 +1439,9 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops, bool is_tx = vfd->vfl_dir != VFL_DIR_RX; int ret; + ret = v4l_enable_media_tuner(vfd); + if (ret) + return ret; v4l_sanitize_format(p); switch (p->type) { @@ -1612,7 +1621,11 @@ static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops, { struct video_device *vfd = video_devdata(file); struct v4l2_tuner *p = arg; + int ret; + ret = v4l_enable_media_tuner(vfd); + if (ret) + return ret; p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; return ops->vidioc_s_tuner(file, fh, p); @@ -1650,7 +1663,11 @@ static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops, struct video_device *vfd = video_devdata(file); const struct v4l2_frequency *p = arg; enum v4l2_tuner_type type; + int ret; + ret = v4l_enable_media_tuner(vfd); + if (ret) + return ret; if (vfd->vfl_type == VFL_TYPE_SDR) { if (p->type != V4L2_TUNER_ADC && p->type != V4L2_TUNER_RF) return -EINVAL; @@ -1705,7 +1722,11 @@ static int v4l_s_std(const struct v4l2_ioctl_ops *ops, { struct video_device *vfd = video_devdata(file); v4l2_std_id id = *(v4l2_std_id *)arg, norm; + int ret; + ret = v4l_enable_media_tuner(vfd); + if (ret) + return ret; norm = id & vfd->tvnorms; if (vfd->tvnorms && !norm) /* Check if std is supported */ return -EINVAL; @@ -1719,7 +1740,11 @@ static int v4l_querystd(const struct v4l2_ioctl_ops *ops, { struct video_device *vfd = video_devdata(file); v4l2_std_id *p = arg; + int ret; + ret = v4l_enable_media_tuner(vfd); + if (ret) + return ret; /* * If no signal is detected, then the driver should return * V4L2_STD_UNKNOWN. Otherwise it should return tvnorms with @@ -1738,7 +1763,11 @@ static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops, struct video_device *vfd = video_devdata(file); struct v4l2_hw_freq_seek *p = arg; enum v4l2_tuner_type type; + int ret; + ret = v4l_enable_media_tuner(vfd); + if (ret) + return ret; /* s_hw_freq_seek is not supported for SDR for now */ if (vfd->vfl_type == VFL_TYPE_SDR) return -EINVAL; diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index d835814..f7304d8 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -2251,6 +2251,9 @@ static int vb2_internal_streamon(struct vb2_queue *q, enum v4l2_buf_type type) * are available. */ if (q->queued_count >= q->min_buffers_needed) { + ret = v4l_enable_media_tuner(q->owner->vdev); + if (ret) + return ret; ret = vb2_start_streaming(q); if (ret) { __vb2_queue_cancel(q); -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message
[PATCH v3 17/21] media: au0828 change to use Managed Media Controller API
Change au0828 to use Managed Media Controller API to coordinate creating/deleting media device on parent usb device it shares with the snd-usb-audio driver. With this change, au0828 uses media_device_get_devres() to allocate a new media device devres or return an existing one, if it finds one. Signed-off-by: Shuah Khan--- drivers/media/usb/au0828/au0828-core.c | 45 +- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 0b8dc49..63e31e2 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -132,9 +132,9 @@ static void au0828_unregister_media_device(struct au0828_dev *dev) { #ifdef CONFIG_MEDIA_CONTROLLER - if (dev->media_dev) { + if (dev->media_dev && + media_devnode_is_registered(>media_dev->devnode)) { media_device_unregister(dev->media_dev); - kfree(dev->media_dev); dev->media_dev = NULL; } #endif @@ -204,31 +204,30 @@ static void au0828_media_device_register(struct au0828_dev *dev, struct media_device *mdev; int ret; - mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); + mdev = media_device_get_devres(>dev); if (!mdev) return; - mdev->dev = >dev; - - if (!dev->board.name) - strlcpy(mdev->model, "unknown au0828", sizeof(mdev->model)); - else - strlcpy(mdev->model, dev->board.name, sizeof(mdev->model)); - if (udev->serial) - strlcpy(mdev->serial, udev->serial, sizeof(mdev->serial)); - strcpy(mdev->bus_info, udev->devpath); - mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); - mdev->driver_version = LINUX_VERSION_CODE; - - ret = media_device_register(mdev); - if (ret) { - pr_err( - "Couldn't create a media device. Error: %d\n", - ret); - kfree(mdev); - return; + if (!media_devnode_is_registered(>devnode)) { + /* register media device */ + mdev->dev = >dev; + + if (udev->product) + strlcpy(mdev->model, udev->product, + sizeof(mdev->model)); + if (udev->serial) + strlcpy(mdev->serial, udev->serial, + sizeof(mdev->serial)); + strcpy(mdev->bus_info, udev->devpath); + mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); + ret = media_device_register(mdev); + if (ret) { + dev_err(>dev, + "Couldn't create a media device. Error: %d\n", + ret); + return; + } } - dev->media_dev = mdev; #endif } -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 04/21] media: Media Controller enable/disable source handler API
Add new fields to struct media_device to add enable_source, and disable_source handlers, and source_priv to stash driver private data that is need to run these handlers. The enable_source handler finds source entity for the passed in entity and check if it is available, and activate the link using __media_entity_setup_link() interface. Bridge driver is expected to implement and set these handlers and private data when media_device is registered or when bridge driver finds the media_device during probe. This is to enable the use-case to find tuner entity connected to the decoder entity and check if it is available, and activate it and start pipeline between the source and the entity. The disable_source handler deactivates the link and stops the pipeline. This handler can be invoked from the media core (v4l-core, dvb-core) as well as other drivers such as ALSA that control the media device. Signed-off-by: Shuah Khan--- include/media/media-device.h | 18 ++ 1 file changed, 18 insertions(+) diff --git a/include/media/media-device.h b/include/media/media-device.h index a3854f6..117c169 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -84,6 +84,24 @@ struct media_device { /* Serializes graph operations. */ struct mutex graph_mutex; + /* Handlers to find source entity for the sink entity and +* check if it is available, and activate the link using +* media_entity_setup_link() interface and start pipeline +* from the source to the entity. +* Bridge driver is expected to implement and set the +* handler when media_device is registered or when +* bridge driver finds the media_device during probe. +* Bridge driver sets source_priv with information +* necessary to run enable/disable source handlers. +* +* Use-case: find tuner entity connected to the decoder +* entity and check if it is available, and activate the +* using media_entity_setup_link() if it is available. + */ + void *source_priv; + int (*enable_source)(struct media_entity *entity, +struct media_pipeline *pipe); + void (*disable_source)(struct media_entity *entity); int (*link_notify)(struct media_link *link, u32 flags, unsigned int notification); }; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 18/21] media: au0828 change to register/unregister entity_notify hook
au0828 registers entity_notify hook to create media graph for the device. This handler runs whenvere a new entity gets added to the media device. It creates necessary links from video, vbi, and ALSA entities to decoder and links tuner and decoder entities. As this handler runs as entities get added, it has to maintain state on the links it already created. New fields are added to au0828_dev to keep this state information. entity_notify gets unregistered before media_device unregister. Signed-off-by: Shuah Khan--- drivers/media/usb/au0828/au0828-core.c | 118 + drivers/media/usb/au0828/au0828.h | 6 ++ 2 files changed, 81 insertions(+), 43 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 63e31e2..fcff2e2 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -134,6 +134,8 @@ static void au0828_unregister_media_device(struct au0828_dev *dev) #ifdef CONFIG_MEDIA_CONTROLLER if (dev->media_dev && media_devnode_is_registered(>media_dev->devnode)) { + media_device_unregister_entity_notify(dev->media_dev, + >entity_notify); media_device_unregister(dev->media_dev); dev->media_dev = NULL; } @@ -197,6 +199,75 @@ static void au0828_usb_disconnect(struct usb_interface *interface) au0828_usb_release(dev); } +static void au0828_create_media_graph(struct media_entity *new, + void *notify_data) +{ +#ifdef CONFIG_MEDIA_CONTROLLER + struct au0828_dev *dev = (struct au0828_dev *) notify_data; + struct media_device *mdev = dev->media_dev; + struct media_entity *entity, *tuner = NULL, *decoder = NULL; + struct media_entity *alsa_capture = NULL; + int ret; + + if (!mdev) + return; + + if (dev->tuner_linked && dev->vdev_linked && dev->vbi_linked && + dev->alsa_capture_linked) + return; + + media_device_for_each_entity(entity, mdev) { + switch (entity->type) { + case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: + tuner = entity; + break; + case MEDIA_ENT_T_V4L2_SUBDEV_DECODER: + decoder = entity; + break; + case MEDIA_ENT_T_DEVNODE_ALSA_CAPTURE: + alsa_capture = entity; + break; + } + } + + if (!decoder) + return; + + /* save tuner for using in enable_source disable_source handlers +* avoid graph walk in those handlers. Note that decoder is +* saved during v4l2_dev registration */ + + if (tuner && !dev->tuner_linked) { + dev->tuner = tuner; + ret = media_entity_create_link(tuner, 0, decoder, 0, + MEDIA_LNK_FL_ENABLED); + if (ret == 0) + dev->tuner_linked = 1; + } + if (dev->vdev.entity.parent && !dev->vdev_linked) { + ret = media_entity_create_link(decoder, AU8522_PAD_VID_OUT, + >vdev.entity, 0, + MEDIA_LNK_FL_ENABLED); + if (ret == 0) + dev->vdev_linked = 1; + } + if (dev->vbi_dev.entity.parent && !dev->vbi_linked) { + ret = media_entity_create_link(decoder, AU8522_PAD_VBI_OUT, + >vbi_dev.entity, 0, + MEDIA_LNK_FL_ENABLED); + if (ret == 0) + dev->vbi_linked = 1; + } + if (alsa_capture && !dev->alsa_capture_linked) { + ret = media_entity_create_link(decoder, AU8522_PAD_AUDIO_OUT, + alsa_capture, 0, + MEDIA_LNK_FL_ENABLED); + if (ret == 0) + dev->alsa_capture_linked = 1; + } +#endif +} + static void au0828_media_device_register(struct au0828_dev *dev, struct usb_device *udev) { @@ -227,52 +298,15 @@ static void au0828_media_device_register(struct au0828_dev *dev, ret); return; } + /* register entity_notify callback */ + dev->entity_notify.notify_data = (void *) dev; + dev->entity_notify.notify = au0828_create_media_graph; + media_device_register_entity_notify(mdev, >entity_notify); } dev->media_dev = mdev; #endif } - -static void au0828_create_media_graph(struct au0828_dev *dev) -{ -#ifdef CONFIG_MEDIA_CONTROLLER
[PATCH v3 00/21] Update ALSA, and au0828 drivers to use Managed Media Controller API
This patch series updates ALSA driver, and au0828 core driver to use Managed Media controller API to share tuner. Please note that Managed Media Controller API and DVB and V4L2 drivers updates to use Media Controller API have been added in a prior patch series. Media Controller API is enhanced with two new interfaces to register and unregister entity_notify hooks to allow drivers to take appropriate actions when as new entities get added to the shared media device. Tested exclusion between digital, analog, and audio to ensure when tuner has an active link to DVB FE, analog, and audio will detect and honor the tuner busy conditions and vice versa. Changes since v2: http://www.spinics.net/lists/linux-media/msg91926.html 1. An important change in this patch series is made to ALSA to check for resources and hold in snd_usb_hw_params(), and release from snd_usb_hw_free(). This change fixed the lockdep warnings seen when resources were held in TRIGGER_START and released from TRIGGER_STOP which could run in IRQ context. I acknowledge Clemens Ladisch for suggesting the correct places to hold/free resources to avoid IRQ path complications. 2. With the above change, the patch series is simpler without the need to change the graph_mutex into a spinlock. 3. I split the patches up differently for easy reviews - no code bloat from v2. 4. A second important change is now the Bridge driver (au0828) owns and drives the graph creation as well as enabling and disabling tuner. It also keeps state information to avoid graph walks in enable_source and disable_source handler. I acknowledge Hans Verkuil for his suggestions and ideas for this change. History: This patch series has been updated to address comments from 3 previous versions of this series. Links to v3 version for reference are: https://www.mail-archive.com/linux-media%40vger.kernel.org/msg89491.html https://www.mail-archive.com/linux-media@vger.kernel.org/msg89492.html https://www.mail-archive.com/linux-media%40vger.kernel.org/msg89493.html Shuah Khan (21): Revert "[media] media: media controller entity framework enhancements for ALSA" media: Media Controller register/unregister entity_notify API media: Add ALSA Media Controller devnodes media: Media Controller enable/disable source handler API media: Media Controller fix to not let stream_count go negative media: Media Controller export non locking __media_entity_setup_link() media: Media Controller non-locking __media_entity_pipeline_start/stop() media: v4l-core add v4l_enable/disable_media_tuner() helper functions media: Move au8522_media_pads enum to au8522.h from au8522_priv.h media: au8522 change to create MC pad for ALSA Audio Out media: au0828 Use au8522_media_pads enum for pad defines media: au0828 fix au0828_create_media_graph() entity checks media: Change v4l-core to check for tuner availability media: dvb-frontend invoke enable/disable_source handlers media: au0828 video remove au0828_enable_analog_tuner() media: au0828 video change to use v4l_enable_media_tuner() media: au0828 change to use Managed Media Controller API media: au0828 change to register/unregister entity_notify hook media: au0828 implement enable_source and disable_source handlers media: media: dvb-frontend fix enable_source error legs sound/usb: Update ALSA driver to use Managed Media Controller API drivers/media/dvb-core/dvb_frontend.c| 142 ++--- drivers/media/dvb-core/dvb_frontend.h| 3 + drivers/media/dvb-frontends/au8522.h | 8 + drivers/media/dvb-frontends/au8522_decoder.c | 1 + drivers/media/dvb-frontends/au8522_priv.h| 8 - drivers/media/media-device.c | 46 +++- drivers/media/media-entity.c | 64 -- drivers/media/usb/au0828/au0828-core.c | 305 ++- drivers/media/usb/au0828/au0828-video.c | 76 ++- drivers/media/usb/au0828/au0828.h| 8 + drivers/media/v4l2-core/v4l2-dev.c | 27 +++ drivers/media/v4l2-core/v4l2-fh.c| 1 + drivers/media/v4l2-core/v4l2-ioctl.c | 29 +++ drivers/media/v4l2-core/videobuf2-core.c | 3 + include/media/media-device.h | 41 include/media/media-entity.h | 7 +- include/media/v4l2-dev.h | 4 + include/uapi/linux/media.h | 5 + sound/usb/Makefile | 15 +- sound/usb/card.c | 5 + sound/usb/card.h | 1 + sound/usb/media.c| 178 sound/usb/media.h| 51 + sound/usb/pcm.c | 29 ++- sound/usb/quirks-table.h | 1 + sound/usb/quirks.c | 9 +- sound/usb/stream.c | 2 + sound/usb/usbaudio.h
Re: [RESEND PATCH] media: vb2: Fix vb2_dc_prepare do not correct sync data to device
Hi Tiffany, (Robin and Hans cc'd.) On Mon, Sep 21, 2015 at 08:26:11PM +0800, Tiffany Lin wrote: > vb2_dc_prepare use the number of SG entries dma_map_sg_attrs return. > But in dma_sync_sg_for_device, it use lengths of each SG entries > before dma_map_sg_attrs. dma_map_sg_attrs will concatenate > SGs until dma length > dma seg bundary. sgt->nents will less than > sgt->orig_nents. Using SG entries after dma_map_sg_attrs > in vb2_dc_prepare will make some SGs are not sync to device. > After add DMA_ATTR_SKIP_CPU_SYNC in vb2_dc_get_userptr to remove > sync data to device twice. Device randomly get incorrect data because > some SGs are not sync to device. Change to use number of SG entries > before dma_map_sg_attrs in vb2_dc_prepare to prevent this issue. > > Signed-off-by: Tiffany Lin> --- > drivers/media/v4l2-core/videobuf2-dma-contig.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c > b/drivers/media/v4l2-core/videobuf2-dma-contig.c > index 2397ceb..c5d00bd 100644 > --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c > +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c > @@ -100,7 +100,7 @@ static void vb2_dc_prepare(void *buf_priv) > if (!sgt || buf->db_attach) > return; > > - dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); > + dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->orig_nents, > buf->dma_dir); > } > > static void vb2_dc_finish(void *buf_priv) > @@ -112,7 +112,7 @@ static void vb2_dc_finish(void *buf_priv) > if (!sgt || buf->db_attach) > return; > > - dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); > + dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir); > } > > /*/ Acked-by: Sakari Ailus Could you post a similar patch for videobuf2-dma-sg as well, please? This should probably go to stable (since when?). videobuf-dma-sg appears to be broken, too, but the fix is more changes than one or two lines. -- Kind regards, Sakari Ailus e-mail: sakari.ai...@iki.fi XMPP: sai...@retiisi.org.uk -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH v5 5/8] media: videobuf2: Change queue_setup argument
On 09/22/2015 10:44 PM, Hans Verkuil wrote: Hi Junghak, On 22-09-15 15:30, Junghak Sung wrote: Replace struct v4l2_format * with vb2_format * to make queue_setup() for common use. struct vb2_format { unsigned inttype; unsigned intpixelformat; unsigned intwidth; unsigned intheight; unsigned intnum_planes; unsigned intbytesperline[VIDEO_MAX_PLANES]; unsigned intreq_sizes[VIDEO_MAX_PLANES]; }; Why would you need all the other fields besides req_sizes[]? Which drivers actually need those other fields? Drivers like exynos4-is/fimc-lite.c don't actually use anything but req_sizes if you read the code carefully. I suspect any driver that uses more than req_sizes is actually buggy or written carelessly. I wish you'd checked with me before making this struct... Be aware that I'm abroad (vacation/conferences) from tomorrow until October 10, so I won't be able to do in-depth reviews during that time (well, I'm able, but I don't want to!) Regards, Hans Hi Hans, I added the member of struct vb2_format, if the member is used by any device driver. These are the usecases for each field besides req_sizes[]. [platform/s3c-camif/camif-capture.c] pixelformat [platform/exynos4-is/fimc-capture.c] pixelformat, width, height [platform/exynos4-is/fimc-isp-video.c] pixelformat, width, height [platform/exynos4-is/fimc-lite.c] pixelformat, width, height [platform/soc_camera/mx3_camera.c] pixelformat, width, bytesperline, height [platform/soc_camera/rcar_vin.c] pixelformat, width, bytesperline, height [platform/soc_camera/sh_mobile_ceu_camera.c] pixelformat, width, bytesperline, height [platform/sh_veu.c] type, pixelformat, width, height, byteperline [platform/vivid/vivid-vid-cap.c] num_planes, pixelformat [platform/vivid/vivid-vid-out.c] num_planes [platform/vsp2/vsp1_video.c] width, height, pixelformat, byteperline, num_planes And I can not understand that fimc-lite.c do not actually use anything but req_sizes[]. In original source code, it seems that fimc_lite.c should use the other fields - pixelformat, width, height - if a user set the v4l2_format. Would you please explain a little bit more? Thank you for your review. Best regards, Junghak -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH v5 7/8] media: videobuf2: Prepare to divide videobuf2
On 09/22/2015 11:48 PM, Hans Verkuil wrote: Hi Junghak, This looks pretty good! I have a few small comments below, but overall it is much improved. On 22-09-15 15:30, Junghak Sung wrote: Prepare to divide videobuf2 - Separate vb2 trace events from v4l2 trace event. - Make wrapper functions that will move to v4l2-side - Make vb2_core_* functions that remain in vb2 core side - Rename internal functions as vb2_* Signed-off-by: Junghak SungSigned-off-by: Geunyoung Kim Acked-by: Seung-Woo Kim Acked-by: Inki Dae --- drivers/media/v4l2-core/Makefile |2 +- drivers/media/v4l2-core/v4l2-trace.c |8 +- drivers/media/v4l2-core/vb2-trace.c |9 + drivers/media/v4l2-core/videobuf2-core.c | 556 -- include/trace/events/v4l2.h | 28 +- include/trace/events/vb2.h | 65 6 files changed, 457 insertions(+), 211 deletions(-) create mode 100644 drivers/media/v4l2-core/vb2-trace.c create mode 100644 include/trace/events/vb2.h diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile index ad07401..1dc8bba 100644 --- a/drivers/media/v4l2-core/Makefile +++ b/drivers/media/v4l2-core/Makefile @@ -14,7 +14,7 @@ ifeq ($(CONFIG_OF),y) videodev-objs += v4l2-of.o endif ifeq ($(CONFIG_TRACEPOINTS),y) - videodev-objs += v4l2-trace.o + videodev-objs += vb2-trace.o v4l2-trace.o endif obj-$(CONFIG_VIDEO_V4L2) += videodev.o diff --git a/drivers/media/v4l2-core/v4l2-trace.c b/drivers/media/v4l2-core/v4l2-trace.c index 4004814..7416010 100644 --- a/drivers/media/v4l2-core/v4l2-trace.c +++ b/drivers/media/v4l2-core/v4l2-trace.c @@ -5,7 +5,7 @@ #define CREATE_TRACE_POINTS #include -EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_buf_done); -EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_buf_queue); -EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_dqbuf); -EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_qbuf); +EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_v4l2_buf_done); +EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_v4l2_buf_queue); +EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_v4l2_dqbuf); +EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_v4l2_qbuf); diff --git a/drivers/media/v4l2-core/vb2-trace.c b/drivers/media/v4l2-core/vb2-trace.c new file mode 100644 index 000..61e74f5 --- /dev/null +++ b/drivers/media/v4l2-core/vb2-trace.c @@ -0,0 +1,9 @@ +#include + +#define CREATE_TRACE_POINTS +#include + +EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_buf_done); +EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_buf_queue); +EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_dqbuf); +EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_qbuf); diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 32fa425..380536d 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -30,7 +30,7 @@ #include #include -#include +#include static int debug; module_param(debug, int, 0644); @@ -612,10 +612,10 @@ static int __verify_length(struct vb2_buffer *vb, const struct v4l2_buffer *b) } /** - * __buffer_in_use() - return true if the buffer is in use and + * vb2_buffer_in_use() - return true if the buffer is in use and * the queue cannot be freed (by the means of REQBUFS(0)) call */ -static bool __buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb) +static bool vb2_buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb) { unsigned int plane; for (plane = 0; plane < vb->num_planes; ++plane) { @@ -640,7 +640,7 @@ static bool __buffers_in_use(struct vb2_queue *q) { unsigned int buffer; for (buffer = 0; buffer < q->num_buffers; ++buffer) { - if (__buffer_in_use(q, q->bufs[buffer])) + if (vb2_buffer_in_use(q, q->bufs[buffer])) return true; } return false; @@ -650,8 +650,9 @@ static bool __buffers_in_use(struct vb2_queue *q) * __fill_v4l2_buffer() - fill in a struct v4l2_buffer with information to be * returned to userspace */ -static void __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) +static int __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb) Why use a void * here? Wouldn't a struct vb2_buffer pointer be better? That way it all remains type-safe. Ditto elsewhere in this patch, of course. I disagree with this idea, IMHO. This function is for filling struct v4l2_buffer with information to be returned to userspace. So, if the void pointer are replaced with struct vb2_buffer pointer, a additional function will be needed in order to translate the vb2_buffer to v4l2_buffer and the function should be duplicated with __fill_v4l2_buffer() by meaning of functionality. { + struct v4l2_buffer *b = pb; struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); struct vb2_queue *q = vb->vb2_queue; unsigned int plane; @@ -742,8 +743,28 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, struct
Re: [RFC PATCH v5 8/8] media: videobuf2: Move v4l2-specific stuff to videobuf2-v4l2
On 09/22/2015 11:58 PM, Hans Verkuil wrote: Hi Junghak, A few small comments... On 22-09-15 15:30, Junghak Sung wrote: Move v4l2-specific stuff from videobu2-core to videobuf2-v4l2 without doing any functional changes. I feel the introduction of v4l2_buf_ops falls under functional changes. Is it possible to do that change in a separate patch before this one? OK, I will move vb2_buf_ops changes to the patch before this one. Signed-off-by: Junghak SungSigned-off-by: Geunyoung Kim Acked-by: Seung-Woo Kim Acked-by: Inki Dae --- drivers/media/v4l2-core/videobuf2-core.c | 1872 +- drivers/media/v4l2-core/videobuf2-internal.h | 161 +++ drivers/media/v4l2-core/videobuf2-v4l2.c | 1678 +++ include/media/videobuf2-core.h | 118 +- include/media/videobuf2-dvb.h|8 +- include/media/videobuf2-v4l2.h | 96 ++ 6 files changed, 2009 insertions(+), 1924 deletions(-) create mode 100644 drivers/media/v4l2-core/videobuf2-internal.h diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c b/drivers/media/v4l2-core/videobuf2-v4l2.c index 2f2b738..8ca07bb 100644 --- a/drivers/media/v4l2-core/videobuf2-v4l2.c +++ b/drivers/media/v4l2-core/videobuf2-v4l2.c + +const struct vb2_buf_ops v4l2_buf_ops = { Shouldn't this be static? + .fill_user_buffer = __fill_v4l2_buffer, + .fill_vb2_buffer= __fill_vb2_buffer, + .set_timestamp = __set_timestamp, +}; Yes, it should be static. I'll fix it at next round. Thank you for your review. Regards, Junghak Regards, Hans -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] ARM64: add tegra-vi support in T210 device-tree
Following device tree support for Tegra VI now: - "vi" node which might have 6 ports/endpoints - in TPG mode, "vi" node don't need to define any ports/endpoints - ports/endpoints defines the link between VI and external sensors. Signed-off-by: Bryan Wu--- arch/arm64/boot/dts/nvidia/tegra210-p2571-e01.dts | 8 + arch/arm64/boot/dts/nvidia/tegra210.dtsi | 174 +- 2 files changed, 181 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2571-e01.dts b/arch/arm64/boot/dts/nvidia/tegra210-p2571-e01.dts index d4ee460..534ada52 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-p2571-e01.dts +++ b/arch/arm64/boot/dts/nvidia/tegra210-p2571-e01.dts @@ -7,6 +7,14 @@ model = "NVIDIA Tegra210 P2571 reference board (E.1)"; compatible = "nvidia,p2571-e01", "nvidia,tegra210"; + host1x@0,5000 { + vi@0,5408 { + status = "okay"; + + avdd-dsi-csi-supply = <_dsi_csi>; + }; + }; + pinmux: pinmux@0,78d4 { pinctrl-names = "boot"; pinctrl-0 = <_boot>; diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi index 1168bcd..3f6501f 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi @@ -109,9 +109,181 @@ vi@0,5408 { compatible = "nvidia,tegra210-vi"; - reg = <0x0 0x5408 0x0 0x0004>; + reg = <0x0 0x5408 0x0 0x800>; interrupts = ; status = "disabled"; + clocks = <_car TEGRA210_CLK_VI>, +<_car TEGRA210_CLK_CSI>, +<_car TEGRA210_CLK_PLL_C>; + clock-names = "vi", "csi", "parent"; + resets = <_car 20>; + reset-names = "vi"; + + power-domains = < TEGRA_POWERGATE_VENC>; + + iommus = < TEGRA_SWGROUP_VI>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + vi_in0: endpoint { + remote-endpoint = <_out0>; + }; + }; + port@1 { + reg = <1>; + + vi_in1: endpoint { + remote-endpoint = <_out1>; + }; + }; + port@2 { + reg = <2>; + + vi_in2: endpoint { + remote-endpoint = <_out2>; + }; + }; + port@3 { + reg = <3>; + + vi_in3: endpoint { + remote-endpoint = <_out3>; + }; + }; + port@4 { + reg = <4>; + + vi_in4: endpoint { + remote-endpoint = <_out4>; + }; + }; + port@5 { + reg = <5>; + + vi_in5: endpoint { + remote-endpoint = <_out5>; + }; + }; + + }; + }; + + csi@0,54080838 { + compatible = "nvidia,tegra210-csi"; + reg = <0x0 0x54080838 0x0 0x700>; + clocks = <_car TEGRA210_CLK_CILAB>; + clock-names = "cil"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + csi_in0: endpoint@0 { + reg = <0x0>; + }; +
[PATCH 0/3 RFC v3] media: platform: add NVIDIA Tegra VI driver
This patchset add and enable V4L2 driver for latest NVIDIA Tegra Video Input hardware controller. It's based on the staging/work branch of Thierry Reding Tegra upstream kernel github repo, which is based on 4.2-rc1. (https://github.com/thierryreding/linux/tree/staging/work) v4: - fix all the coding style issues - solve all the minor problems pointed out by Hans Verkuil v3: - rework on the locking code related to kthread - remove some dead code - other fixes v2: - allocate kthread for each channel instead of workqueue - create tegra-csi as a separated V4L2 subdevice - define all the register bits needed in this driver - add device tree binding document - update things according to Hans and Thierry's review. Bryan Wu (3): [media] v4l: tegra: Add NVIDIA Tegra VI driver ARM64: add tegra-vi support in T210 device-tree Documentation: DT bindings: add VI and CSI bindings .../bindings/gpu/nvidia,tegra20-host1x.txt | 211 +- arch/arm64/boot/dts/nvidia/tegra210-p2571-e01.dts | 8 + arch/arm64/boot/dts/nvidia/tegra210.dtsi | 174 - drivers/media/platform/Kconfig | 1 + drivers/media/platform/Makefile| 2 + drivers/media/platform/tegra/Kconfig | 10 + drivers/media/platform/tegra/Makefile | 3 + drivers/media/platform/tegra/tegra-channel.c | 802 + drivers/media/platform/tegra/tegra-core.c | 252 +++ drivers/media/platform/tegra/tegra-core.h | 162 + drivers/media/platform/tegra/tegra-csi.c | 566 +++ drivers/media/platform/tegra/tegra-vi.c| 581 +++ drivers/media/platform/tegra/tegra-vi.h| 213 ++ 13 files changed, 2978 insertions(+), 7 deletions(-) create mode 100644 drivers/media/platform/tegra/Kconfig create mode 100644 drivers/media/platform/tegra/Makefile create mode 100644 drivers/media/platform/tegra/tegra-channel.c create mode 100644 drivers/media/platform/tegra/tegra-core.c create mode 100644 drivers/media/platform/tegra/tegra-core.h create mode 100644 drivers/media/platform/tegra/tegra-csi.c create mode 100644 drivers/media/platform/tegra/tegra-vi.c create mode 100644 drivers/media/platform/tegra/tegra-vi.h -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/3] ARM64: add tegra-vi support in T210 device-tree
On 09/22/2015 05:17 AM, Thierry Reding wrote: Hi Bryan, This patchset really needs to be Cc'ed to linux-te...@vger.kernel.org, it's becoming impossible to track it otherwise. My bad, I copied and pasted old git send-email command line. On Mon, Sep 21, 2015 at 11:55:54AM -0700, Bryan Wu wrote: [...] diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi index 1168bcd..3f6501f 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi @@ -109,9 +109,181 @@ vi@0,5408 { compatible = "nvidia,tegra210-vi"; - reg = <0x0 0x5408 0x0 0x0004>; + reg = <0x0 0x5408 0x0 0x800>; This now no longer matches the address map in the TRM. That's because we split out the CSI parts from VI. interrupts = ; status = "disabled"; + clocks = <_car TEGRA210_CLK_VI>, +<_car TEGRA210_CLK_CSI>, +<_car TEGRA210_CLK_PLL_C>; + clock-names = "vi", "csi", "parent"; + resets = <_car 20>; + reset-names = "vi"; + + power-domains = < TEGRA_POWERGATE_VENC>; As an aside, this will currently prevent the driver from probing because the generic power domain code will return -EPROBE_DEFER if this property is encountered but the corresponding driver (for the PMC) hasn't registered any power domains yet. So until the PMC driver changes have been merged we can't add these power-domains properties. That's not something for you to worry about, though. I'll make sure to strip this out if it happens to get merged before the PMC driver changes and add it back it afterwards. OK, need I strip this out and provide a separated patch which waiting for the PMC changes merged? + + iommus = < TEGRA_SWGROUP_VI>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + vi_in0: endpoint { + remote-endpoint = <_out0>; + }; + }; + port@1 { + reg = <1>; + + vi_in1: endpoint { + remote-endpoint = <_out1>; + }; + }; + port@2 { + reg = <2>; + + vi_in2: endpoint { + remote-endpoint = <_out2>; + }; + }; + port@3 { + reg = <3>; + + vi_in3: endpoint { + remote-endpoint = <_out3>; + }; + }; + port@4 { + reg = <4>; + + vi_in4: endpoint { + remote-endpoint = <_out4>; + }; + }; + port@5 { + reg = <5>; + + vi_in5: endpoint { + remote-endpoint = <_out5>; + }; + }; + + }; + }; + + csi@0,54080838 { I think this and its siblings should be children of the vi node. They are within the same memory aperture according to the TRM and the fact that the VI needs to reference the "CSI" clock indicates that the coupling is tighter than this current DT layout makes it out to be. + compatible = "nvidia,tegra210-csi"; + reg = <0x0 0x54080838 0x0 0x700>; Some of the internal register documentation indicates that the register range actually starts at an offset of 0x800, it just so happens that we don't use any of the registers from 0x800 to 0x837. So I think this needs to be adapted. Right, in the driver we don't use those registers from 0x800 to 0x837. + clocks = <_car TEGRA210_CLK_CILAB>; + clock-names = "cil"; + + ports { + #address-cells = <1>; +
[PATCH 1/3] [media] v4l: tegra: Add NVIDIA Tegra VI driver
NVIDIA Tegra processor contains a powerful Video Input (VI) hardware controller which can support up to 6 MIPI CSI camera sensors. This patch adds a V4L2 media controller and capture driver to support Tegra VI hardware. It's verified with Tegra built-in test pattern generator. Signed-off-by: Bryan WuReviewed-by: Hans Verkuil --- drivers/media/platform/Kconfig | 1 + drivers/media/platform/Makefile | 2 + drivers/media/platform/tegra/Kconfig | 10 + drivers/media/platform/tegra/Makefile| 3 + drivers/media/platform/tegra/tegra-channel.c | 767 +++ drivers/media/platform/tegra/tegra-core.c| 254 + drivers/media/platform/tegra/tegra-core.h| 162 ++ drivers/media/platform/tegra/tegra-csi.c | 572 drivers/media/platform/tegra/tegra-vi.c | 583 drivers/media/platform/tegra/tegra-vi.h | 209 10 files changed, 2563 insertions(+) create mode 100644 drivers/media/platform/tegra/Kconfig create mode 100644 drivers/media/platform/tegra/Makefile create mode 100644 drivers/media/platform/tegra/tegra-channel.c create mode 100644 drivers/media/platform/tegra/tegra-core.c create mode 100644 drivers/media/platform/tegra/tegra-core.h create mode 100644 drivers/media/platform/tegra/tegra-csi.c create mode 100644 drivers/media/platform/tegra/tegra-vi.c create mode 100644 drivers/media/platform/tegra/tegra-vi.h diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index f6bed19..553867f 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -119,6 +119,7 @@ source "drivers/media/platform/exynos4-is/Kconfig" source "drivers/media/platform/s5p-tv/Kconfig" source "drivers/media/platform/am437x/Kconfig" source "drivers/media/platform/xilinx/Kconfig" +source "drivers/media/platform/tegra/Kconfig" endif # V4L_PLATFORM_DRIVERS diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index 114f9ab..426e0e4 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -52,4 +52,6 @@ obj-$(CONFIG_VIDEO_AM437X_VPFE) += am437x/ obj-$(CONFIG_VIDEO_XILINX) += xilinx/ +obj-$(CONFIG_VIDEO_TEGRA) += tegra/ + ccflags-y += -I$(srctree)/drivers/media/i2c diff --git a/drivers/media/platform/tegra/Kconfig b/drivers/media/platform/tegra/Kconfig new file mode 100644 index 000..54c0e7a --- /dev/null +++ b/drivers/media/platform/tegra/Kconfig @@ -0,0 +1,10 @@ +config VIDEO_TEGRA + tristate "NVIDIA Tegra Video Input Driver" + depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF + depends on TEGRA_HOST1X + select VIDEOBUF2_DMA_CONTIG + ---help--- + Driver for Video Input (VI) controller found on NVIDIA Tegra SoC. + + To compile this driver as a module, choose M here: the module will be + called tegra-video. diff --git a/drivers/media/platform/tegra/Makefile b/drivers/media/platform/tegra/Makefile new file mode 100644 index 000..18a1c16 --- /dev/null +++ b/drivers/media/platform/tegra/Makefile @@ -0,0 +1,3 @@ +tegra-video-objs += tegra-core.o tegra-csi.o tegra-vi.o tegra-channel.o + +obj-$(CONFIG_VIDEO_TEGRA) += tegra-video.o diff --git a/drivers/media/platform/tegra/tegra-channel.c b/drivers/media/platform/tegra/tegra-channel.c new file mode 100644 index 000..735bb40 --- /dev/null +++ b/drivers/media/platform/tegra/tegra-channel.c @@ -0,0 +1,767 @@ +/* + * NVIDIA Tegra Video Input Device + * + * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved. + * + * Author: Bryan Wu + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "tegra-vi.h" + +#define TEGRA_VI_SYNCPT_WAIT_TIMEOUT 200 + +/* VI registers */ +#define TEGRA_VI_CFG_VI_INCR_SYNCPT0x000 +#define VI_CFG_VI_INCR_SYNCPT_COND(x)(((x) & 0xff) << 8) +#define VI_CSI_PP_LINE_START(port) (4 + (port) * 4) +#define VI_CSI_PP_FRAME_START(port) (5 + (port) * 4) +#define VI_CSI_MW_REQ_DONE(port) (6 + (port) * 4) +#define VI_CSI_MW_ACK_DONE(port) (7 + (port) * 4) + +#define TEGRA_VI_CFG_VI_INCR_SYNCPT_CNTRL 0x004 +#define TEGRA_VI_CFG_VI_INCR_SYNCPT_ERROR 0x008 +#define TEGRA_VI_CFG_CTXSW 0x020 +#define TEGRA_VI_CFG_INTSTATUS 0x024 +#define
[PATCH 3/3] Documentation: DT bindings: add VI and CSI bindings
Signed-off-by: Bryan Wu--- .../bindings/gpu/nvidia,tegra20-host1x.txt | 211 - 1 file changed, 205 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt b/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt index 46d6ead..433cb52 100644 --- a/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt +++ b/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt @@ -40,10 +40,39 @@ of the following host1x client modules: - interrupts: The interrupt outputs from the controller. - clocks: Must contain one entry, for the module clock. See ../clocks/clock-bindings.txt for details. + - clock-names: Must include the following entries: +- vi + This MUST be the first entry. +- csi +- parent - resets: Must contain an entry for each entry in reset-names. See ../reset/reset.txt for details. - reset-names: Must include the following entries: - vi + - power-domains: The power domains settings. +See ../power/power_domain.txt + - iommus: The IOMMU settings. +See ../iommu/iommu.txt + - ports: several VI input ports which connecting CSI ports. Ports contain +several port and each port has one endpoint. +See ../graph.txt and ../media/video-interfaces.txt + - avdd-dsi-csi-supply: a regulator required by VI. + +- csi: camera serial interface + + Required properties: + - compatible: "nvidia,tegra-csi" + - reg: Physical base address and length of the controller's registers. + - interrupts: The interrupt outputs from the controller. + - clocks: Must contain one entry, for the module clock. +See ../clocks/clock-bindings.txt for details. + - clock-names: Must include the following entries: +- cil + This MUST be the first entry. + - ports: 2 ports presenting 2 channels of CSI. Each port has 2 endpoints: +one connects to sensor device tree node as input and the other one connects +to VI endpoint. +See ../graph.txt and ../media/video-interfaces.txt - epp: encoder pre-processor @@ -274,13 +303,183 @@ Example: reset-names = "mpe"; }; - vi { - compatible = "nvidia,tegra20-vi"; - reg = <0x5408 0x0004>; - interrupts = <0 69 0x04>; - clocks = <_car TEGRA20_CLK_VI>; - resets = <_car 100>; + vi@0,5408 { + compatible = "nvidia,tegra210-vi"; + reg = <0x0 0x5408 0x0 0x800>; + interrupts = ; + status = "disabled"; + clocks = <_car TEGRA210_CLK_VI>, +<_car TEGRA210_CLK_CSI>, +<_car TEGRA210_CLK_PLL_C>; + clock-names = "vi", "csi", "parent"; + resets = <_car 20>; reset-names = "vi"; + + power-domains = < TEGRA_POWERGATE_VENC>; + + iommus = < TEGRA_SWGROUP_VI>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + vi_in0: endpoint { + remote-endpoint = <_out0>; + }; + }; + port@1 { + reg = <1>; + + vi_in1: endpoint { + remote-endpoint = <_out1>; + }; + }; + port@2 { + reg = <2>; + + vi_in2: endpoint { + remote-endpoint = <_out2>; + }; + }; + port@3 { + reg = <3>; + + vi_in3: endpoint { + remote-endpoint = <_out3>; + }; + }; + port@4 { + reg = <4>; + + vi_in4: endpoint { + remote-endpoint = <_out4>; + }; + }; + port@5 { + reg = <5>; + + vi_in5: endpoint {
cron job: media_tree daily build: ERRORS
This message is generated daily by a cron job that builds media_tree for the kernels and architectures in the list below. Results of the daily build of media_tree: date: Wed Sep 23 04:00:14 CEST 2015 git branch: test git hash: 9ddf9071ea17b83954358b2dac42b34e5857a9af gcc version:i686-linux-gcc (GCC) 5.1.0 sparse version: v0.5.0-51-ga53cea2 smatch version: 0.4.1-3153-g7d56ab3 host hardware: x86_64 host os:4.0.0-3.slh.1-amd64 linux-git-arm-at91: OK linux-git-arm-davinci: OK linux-git-arm-exynos: OK linux-git-arm-mx: OK linux-git-arm-omap: OK linux-git-arm-omap1: OK linux-git-arm-pxa: OK linux-git-blackfin-bf561: OK linux-git-i686: OK linux-git-m32r: OK linux-git-mips: OK linux-git-powerpc64: OK linux-git-sh: OK linux-git-x86_64: OK linux-2.6.32.27-i686: OK linux-2.6.33.7-i686: OK linux-2.6.34.7-i686: OK linux-2.6.35.9-i686: OK linux-2.6.36.4-i686: OK linux-2.6.37.6-i686: OK linux-2.6.38.8-i686: OK linux-2.6.39.4-i686: OK linux-3.0.60-i686: OK linux-3.1.10-i686: OK linux-3.2.37-i686: OK linux-3.3.8-i686: OK linux-3.4.27-i686: OK linux-3.5.7-i686: OK linux-3.6.11-i686: OK linux-3.7.4-i686: OK linux-3.8-i686: OK linux-3.9.2-i686: OK linux-3.10.1-i686: ERRORS linux-3.11.1-i686: ERRORS linux-3.12.23-i686: ERRORS linux-3.13.11-i686: ERRORS linux-3.14.9-i686: ERRORS linux-3.15.2-i686: ERRORS linux-3.16.7-i686: ERRORS linux-3.17.8-i686: ERRORS linux-3.18.7-i686: ERRORS linux-3.19-i686: ERRORS linux-4.0-i686: OK linux-4.1.1-i686: OK linux-4.2-i686: OK linux-4.3-rc1-i686: OK linux-2.6.32.27-x86_64: OK linux-2.6.33.7-x86_64: OK linux-2.6.34.7-x86_64: OK linux-2.6.35.9-x86_64: OK linux-2.6.36.4-x86_64: OK linux-2.6.37.6-x86_64: OK linux-2.6.38.8-x86_64: OK linux-2.6.39.4-x86_64: OK linux-3.0.60-x86_64: OK linux-3.1.10-x86_64: OK linux-3.2.37-x86_64: OK linux-3.3.8-x86_64: OK linux-3.4.27-x86_64: OK linux-3.5.7-x86_64: OK linux-3.6.11-x86_64: OK linux-3.7.4-x86_64: OK linux-3.8-x86_64: OK linux-3.9.2-x86_64: OK linux-3.10.1-x86_64: ERRORS linux-3.11.1-x86_64: ERRORS linux-3.12.23-x86_64: ERRORS linux-3.13.11-x86_64: ERRORS linux-3.14.9-x86_64: ERRORS linux-3.15.2-x86_64: ERRORS linux-3.16.7-x86_64: ERRORS linux-3.17.8-x86_64: ERRORS linux-3.18.7-x86_64: ERRORS linux-3.19-x86_64: ERRORS linux-4.0-x86_64: OK linux-4.1.1-x86_64: OK linux-4.2-x86_64: OK linux-4.3-rc1-x86_64: OK apps: OK spec-git: OK sparse: WARNINGS smatch: ERRORS Detailed results are available here: http://www.xs4all.nl/~hverkuil/logs/Wednesday.log Full logs are available here: http://www.xs4all.nl/~hverkuil/logs/Wednesday.tar.bz2 The Media Infrastructure API from this daily build is here: http://www.xs4all.nl/~hverkuil/spec/media.html -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] [media] tvp5150: add support for asynchronous probing
On Mon, Sep 21, 2015 at 12:23 PM, Javier Martinez Canillaswrote: > Allow the subdevice to be probed asynchronously. > > Signed-off-by: Javier Martinez Canillas > Acked-by: Lad, Prabhakar Cheers, --Prabhakar Lad -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RESEND PATCH] media: vb2: Fix vb2_dc_prepare do not correct sync data to device
Hi Robin, On Tue, Sep 22, 2015 at 04:37:17PM +0100, Robin Murphy wrote: > Hi Hans, > > On 21/09/15 14:13, Hans Verkuil wrote: > >Hi Tiffany! > > > >On 21-09-15 14:26, Tiffany Lin wrote: > >>vb2_dc_prepare use the number of SG entries dma_map_sg_attrs return. > >>But in dma_sync_sg_for_device, it use lengths of each SG entries > >>before dma_map_sg_attrs. dma_map_sg_attrs will concatenate > >>SGs until dma length > dma seg bundary. sgt->nents will less than > >>sgt->orig_nents. Using SG entries after dma_map_sg_attrs > >>in vb2_dc_prepare will make some SGs are not sync to device. > >>After add DMA_ATTR_SKIP_CPU_SYNC in vb2_dc_get_userptr to remove > >>sync data to device twice. Device randomly get incorrect data because > >>some SGs are not sync to device. Change to use number of SG entries > >>before dma_map_sg_attrs in vb2_dc_prepare to prevent this issue. > >> > >>Signed-off-by: Tiffany Lin> >>--- > >> drivers/media/v4l2-core/videobuf2-dma-contig.c | 4 ++-- > >> 1 file changed, 2 insertions(+), 2 deletions(-) > >> > >>diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c > >>b/drivers/media/v4l2-core/videobuf2-dma-contig.c > >>index 2397ceb..c5d00bd 100644 > >>--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c > >>+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c > >>@@ -100,7 +100,7 @@ static void vb2_dc_prepare(void *buf_priv) > >>if (!sgt || buf->db_attach) > >>return; > >> > >>- dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); > >>+ dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->orig_nents, > >>buf->dma_dir); > >> } > >> > >> static void vb2_dc_finish(void *buf_priv) > >>@@ -112,7 +112,7 @@ static void vb2_dc_finish(void *buf_priv) > >>if (!sgt || buf->db_attach) > >>return; > >> > >>- dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); > >>+ dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir); > >> } > > > >I don't really understand it. I am assuming that this happens on an arm and > >that > >the dma_map_sg_attrs and dma_sync_sg_* functions used are arm_iommu_map_sg() > >and > >arm_iommu_sync_sg_* as implemented in arch/arm/mm/dma-mapping.c. > > > >Now, as I understand it (and my understanding may very well be flawed!) the > >map_sg > >function concatenates SG entries if possible, so it may return fewer > >entries. But > >the dma_sync_sg functions use those updated SG entries, so the full buffer > >should > >be covered by this. Using orig_nents will actually sync parts of the buffer > >twice! > >The first nents entries already cover the full buffer so any remaining > >entries up > >to orig_nents will just duplicate parts of the buffer. > > As Documentation/DMA-API.txt says, the parameters to dma_sync_sg_* must be > the same as those originally passed into dma_map_sg. The segments are only > merged *from the point of view of the device*: if I have a scatterlist of > two discontiguous 4K segments, I can remap them with an IOMMU so the device > sees them as a single 8K buffer, and tell it as such. If on the other hand I > want to do maintenance from the CPU side (i.e. any DMA API call), then those > DMA addresses mean nothing and I can only operate on the CPU addresses of > the underlying pages, which are still very much discontiguous in the linear > map; ergo I still need to iterate over the original entries. > > Whilst I can't claim much familiarity with v4l itself, from a brief look > over the existing code this patch does look to be doing the right thing. Thanks for the explanation. I wonder if this is the only place where we have this issue. :-I I think this might have been partly caused by the unfortunately named field (nents) in struct sg_table. I wrote a small patch for this (plus a fix for a few other things as well): >From 8928d76db4d45c2b4a16ff90de6695bc88e19779 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 22 Sep 2015 23:30:30 +0300 Subject: [PATCH 1/1] Documentation: DMA API: Be more explicit that nelems is always the same The nelems argument to the DMA API functions operating on scatterlists is always the same. The documentation used different argument names and the matter was not mentioned in Documentation/DMA-API-HOWTO.txt at all. Fix these. Signed-off-by: Sakari Ailus --- Documentation/DMA-API-HOWTO.txt | 5 + Documentation/DMA-API.txt | 9 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Documentation/DMA-API-HOWTO.txt b/Documentation/DMA-API-HOWTO.txt index 55b70b9..d69b3fc 100644 --- a/Documentation/DMA-API-HOWTO.txt +++ b/Documentation/DMA-API-HOWTO.txt @@ -681,6 +681,11 @@ or: as appropriate. +PLEASE NOTE: The 'nents' argument to dma_sync_sg_for_cpu() and + dma_sync_sg_for_device() must be the same passed to + dma_map_sg(). It is _NOT_ the count returned by + dma_map_sg(). + After
Re: [RFC 0/9] Unrestricted media entity ID range support
Hi Mauro, Mauro Carvalho Chehab wrote: Em Sun, 20 Sep 2015 10:26:09 +0300 Sakari Ailusescreveu: Hi Mauro, Mauro Carvalho Chehab wrote: Hi Sakari, On Fri, 11 Sep 2015 13:09:03 +0300 Sakari Ailus wrote: Hi all, This patchset adds an API for managing entity enumerations, i.e. storing a bit of information per entity. The entity ID is no longer limited to small integers (e.g. 31 or 63), but MEDIA_ENTITY_MAX_LOW_ID. The drivers are also converted to use that instead of a fixed number. If the number of entities in a real use case grows beyond the capabilities of the approach, the algorithm may be changed. But most importantly, the API is used to perform the same operation everywhere it's done. I'm sending this for review only, the code itself is untested. I haven't entirely made up my mind on the fourth patch. It could be dropped, as it uses the API for a somewhat different purpose. Sorry for not reviewing this earlier, but I'm traveling this week to China, and I was having some troubles with the Internet. Btw, I don't have my notebook here (just a chromebook without the media tree). So, please consider this as just a preliminary review. I won't be comment this series patch by patch, because it is really painful to do it while here with this Internet. Also, I want to discuss the patch series as a hole. From what we've agreed last week, we won't be using a separate ID range for the entity ID, but this patch series is actually adding it, and, IMHO, using a confusing nomenclature: instead of calling the entity ID range as "entity_id" at the media_device struct, you're now calling it "low_id". That sounds confusing to me. If you think we should keep a separate range for entities, calling it as "entity_id" is clearer. It's *not* the entity ID. It's a number used internally to keep track of the entities, and only used for this purpose, nothing else. If you look at the patch, the number of places where low_id is used is very limited. Individual drivers do not and must not access the low_id field. The underlying algorithm for keeping track of entities does not change, but that could be changed later on without affecting the users of the alrogithm. --- See patch 3. There are two main reasons for this: 1. No need to implement a new algorithm which would be less efficient but could cope in cases we do not have yet; this can be done later on, as patch 3 adds an API to access the information without making assumptions on the implementation. If this is an internal number used only by the graph traversal algorithm, then the implementation doesn't seem correct. I mean: such number should be generated internally when starting the graph traversal algorithm, and it would be better to store such graph-traversal internal algorithm data on a separate struct. In that case the number would become enumeration specific. I have no problem in that, but if a single entity specific number works for the purpose, I think that could be used as well. Using something else than a constant value per entity quickly will require memory allocation, and graph traversal is performance critical in many cases. 2. It does solve the problem. The graph object IDs of the entities can be large without adversely affecting the functionality of existing drivers. Right now, with just those 9 patches, it doesn't ;) I mean: if I apply your patches after the MC next gen ones and try to use the graph traversal, it will do the wrong thing for hybrid TV cards, as the number of entities there are more than 64. Ok, easy to fix after this series by just changing the value of MEDIA_ENTITY_MAX_LOW_ID, but this will only work while we don't implement dynamic support. Fair enough. Still, it didn't work before either: the graph traversal algorithm depends on entity ID not exceeding MEDIA_ENTITY_ENUM_MAX_ID (which this set renames). I still consider that a separate problem. Also, you said at the low_id comment that if an entity is unregistered and then re-registered, it would preserve the same I never claimed that, and the patchset does not implement that either. That's what I understood from this comment: Rename the macro as it no longer is a maximum ID that an entity can have, but a low ID which is used for internal purposes of enumeration. This is the maximum number of concurrent entities that may exist in a media device. If this is the "max number of concurrent entities", you need to reassign those numbers when entities are removed. If this is not what you're meaning, then fix the patch description to let it clearer. I guess then that "low ID" is actually an upper bound for that graph-traversal only control number. We should really not use the word "ID" here, as this is not an ID. it is just some index/control number that will be granted to be below some upper bound. Index sounds good to me, it's indeed clearer. I
Re: [RFC PATCH v5 0/8] Refactoring Videobuf2 for common use
Dear Hans, I tried to make a patch to fix the compile errors below. If you can not wait for next round, you can resolve the compile errors below with attached patch file. But, I'm not sure that this patch can resolve really ALL compile problems. So, if you don't mind and if you can, please, send me your .config file that I can test compile by using same config file with yours. Regards, Junghak On 09/23/2015 12:09 AM, Hans Verkuil wrote: Mauro asked if I could make a pull request for patches 1-4, but while compiling it I got these errors and warnings: In file included from /home/hans/work/build/media-git/include/linux/interrupt.h:5:0, from /home/hans/work/build/media-git/drivers/media/platform/davinci/vpif_display.c:18: /home/hans/work/build/media-git/drivers/media/platform/davinci/vpif_display.c: In function 'to_vpif_buffer': /home/hans/work/build/media-git/include/linux/kernel.h:811:48: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types] const typeof( ((type *)0)->member ) *__mptr = (ptr); \ ^ /home/hans/work/build/media-git/drivers/media/platform/davinci/vpif_display.c:58:9: note: in expansion of macro 'container_of' return container_of(vb, struct vpif_disp_buffer, vb); ^ /home/hans/work/build/media-git/drivers/media/platform/davinci/vpif_display.c: In function 'vpif_buffer_prepare': /home/hans/work/build/media-git/drivers/media/platform/davinci/vpif_display.c:80:4: error: 'struct vb2_buffer' has no member named 'field' vb->field = common->fmt.fmt.pix.field; ^ /home/hans/work/build/media-git/drivers/media/platform/davinci/vpif_display.c: In function 'vpif_start_streaming': /home/hans/work/build/media-git/drivers/media/platform/davinci/vpif_display.c:200:39: warning: passing argument 1 of 'vb2_dma_contig_plane_dma_addr' from incompatible pointer type [-Wincompatible-pointer-types] addr = vb2_dma_contig_plane_dma_addr(>cur_frm->vb, 0); ^ In file included from /home/hans/work/build/media-git/drivers/media/platform/davinci/vpif_display.h:20:0, from /home/hans/work/build/media-git/drivers/media/platform/davinci/vpif_display.c:26: /home/hans/work/build/media-git/include/media/videobuf2-dma-contig.h:20:1: note: expected 'struct vb2_buffer *' but argument is of type 'struct vb2_v4l2_buffer *' vb2_dma_contig_plane_dma_addr(struct vb2_buffer *vb, unsigned int plane_no) ^ /home/hans/work/build/media-git/drivers/media/platform/davinci/vpif_display.c: In function 'process_progressive_mode': /home/hans/work/build/media-git/drivers/media/platform/davinci/vpif_display.c:311:39: warning: passing argument 1 of 'vb2_dma_contig_plane_dma_addr' from incompatible pointer type [-Wincompatible-pointer-types] addr = vb2_dma_contig_plane_dma_addr(>next_frm->vb, 0); ^ In file included from /home/hans/work/build/media-git/drivers/media/platform/davinci/vpif_display.h:20:0, from /home/hans/work/build/media-git/drivers/media/platform/davinci/vpif_display.c:26: /home/hans/work/build/media-git/include/media/videobuf2-dma-contig.h:20:1: note: expected 'struct vb2_buffer *' but argument is of type 'struct vb2_v4l2_buffer *' vb2_dma_contig_plane_dma_addr(struct vb2_buffer *vb, unsigned int plane_no) ^ /home/hans/work/build/media-git/scripts/Makefile.build:264: recipe for target 'drivers/media/platform/davinci/vpif_display.o' failed In file included from /home/hans/work/build/media-git/drivers/media/pci/sta2x11/sta2x11_vip.c:29:0: /home/hans/work/build/media-git/drivers/media/pci/sta2x11/sta2x11_vip.c: In function 'to_vip_buffer': /home/hans/work/build/media-git/include/linux/kernel.h:811:48: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types] const typeof( ((type *)0)->member ) *__mptr = (ptr); \ ^ /home/hans/work/build/media-git/drivers/media/pci/sta2x11/sta2x11_vip.c:97:9: note: in expansion of macro 'container_of' return container_of(vb2, struct vip_buffer, vb); ^ Please fix! Thanks, Hans On 22-09-15 15:30, Junghak Sung wrote: Hello everybody, This is the 5th round for refactoring Videobuf2(a.k.a VB2). The purpose of this patch series is to separate existing VB2 framework into core part and V4L2 specific part. So that not only V4L2 but also other frameworks can use them to manage buffer and utilize queue. Why do we try to make the VB2 framework to be common? As you may know, current DVB framework uses ringbuffer mechanism to demux MPEG-2 TS data and pass it to userspace. However, this mechanism requires extra memory copy because DVB framework provides only read() system call for application - read() system call copies the kernel data to user-space buffer. So if we can use VB2 framework which supports streaming I/O and buffer sharing
Re: [RFC 0/9] Unrestricted media entity ID range support
Em Wed, 23 Sep 2015 00:56:05 +0300 Sakari Ailusescreveu: > Hi Mauro, > > Mauro Carvalho Chehab wrote: > > Em Sun, 20 Sep 2015 10:26:09 +0300 > > Sakari Ailus escreveu: > > > >> Hi Mauro, > >> > >> Mauro Carvalho Chehab wrote: > >>> Hi Sakari, > >>> > >>> On Fri, 11 Sep 2015 13:09:03 +0300 > >>> Sakari Ailus wrote: > >>> > Hi all, > > This patchset adds an API for managing entity enumerations, i.e. > storing a bit of information per entity. The entity ID is no longer > limited to small integers (e.g. 31 or 63), but > MEDIA_ENTITY_MAX_LOW_ID. The drivers are also converted to use that > instead of a fixed number. > > If the number of entities in a real use case grows beyond the > capabilities of the approach, the algorithm may be changed. But most > importantly, the API is used to perform the same operation everywhere > it's done. > > I'm sending this for review only, the code itself is untested. > > I haven't entirely made up my mind on the fourth patch. It could be > dropped, as it uses the API for a somewhat different purpose. > > >>> > >>> Sorry for not reviewing this earlier, but I'm traveling this week to > >>> China, and I was having some troubles with the Internet. Btw, I don't > >>> have my notebook here (just a chromebook without the media tree). > >>> So, please consider this as just a preliminary review. > >>> > >>> I won't be comment this series patch by patch, because it is really > >>> painful to do it while here with this Internet. > >>> > >>> Also, I want to discuss the patch series as a hole. > >>> > >>> From what we've agreed last week, we won't be using a separate ID > >>> range for the entity ID, but this patch series is actually adding > >>> it, and, IMHO, using a confusing nomenclature: instead of calling the > >>> entity ID range as "entity_id" at the media_device struct, you're > >>> now calling it "low_id". That sounds confusing to me. If you think > >>> we should keep a separate range for entities, calling it as > >>> "entity_id" is clearer. > >> > >> It's *not* the entity ID. It's a number used internally to keep track of > >> the entities, and only used for this purpose, nothing else. If you look > >> at the patch, the number of places where low_id is used is very limited. > >> Individual drivers do not and must not access the low_id field. > >> > >> The underlying algorithm for keeping track of entities does not change, > >> but that could be changed later on without affecting the users of the > >> alrogithm. --- See patch 3. > >> > >> There are two main reasons for this: > >> > >> 1. No need to implement a new algorithm which would be less efficient > >> but could cope in cases we do not have yet; this can be done later on, > >> as patch 3 adds an API to access the information without making > >> assumptions on the implementation. > > > > If this is an internal number used only by the graph traversal > > algorithm, then the implementation doesn't seem correct. I mean: > > such number should be generated internally when starting the > > graph traversal algorithm, and it would be better to store such > > graph-traversal internal algorithm data on a separate struct. > > In that case the number would become enumeration specific. I have no > problem in that, but if a single entity specific number works for the > purpose, I think that could be used as well. Using something else than a > constant value per entity quickly will require memory allocation, and > graph traversal is performance critical in many cases. I guess a single loop at graph traversal start would solve it. Yet, it means an extra O(n) to fill in the numbers, but the algorithm that fills such numbers will be at least O(n) either here or at the entity creation. Perhaps one solution would be to have a "dirty" flag that would be raised if a new entity would be created (and removed?). If dirty flag is raised, it would do the count at the beginning of the graph start. > > > >> 2. It does solve the problem. The graph object IDs of the entities can > >> be large without adversely affecting the functionality of existing drivers. > > > > Right now, with just those 9 patches, it doesn't ;) > > > > I mean: if I apply your patches after the MC next gen ones and try to use > > the > > graph traversal, it will do the wrong thing for hybrid TV cards, as the > > number > > of entities there are more than 64. Ok, easy to fix after this series by > > just changing the value of MEDIA_ENTITY_MAX_LOW_ID, but this will only > > work while we don't implement dynamic support. > > Fair enough. Still, it didn't work before either: the graph traversal > algorithm depends on entity ID not exceeding MEDIA_ENTITY_ENUM_MAX_ID > (which this set renames). Well, for existing drivers that use graph traversal, this number is not exceeded. > I still
[PATCH] [media] media-entity: Don't use var length arrays
The graph traversal algorithm currently uses two variable-length arrays that are dynamically allocated at the stack: drivers/media/media-entity.c:238:17: warning: Variable length array is used. drivers/media/media-entity.c:239:17: warning: Variable length array is used. Those are bad, specially if the number of pads for some entity would be bigger than a certain amount, as it would cause a Linux stack overflow. We could just replace entity->num_pads by a define in order to solve the above sparse warnings, but that would still prevent having entities with a big number of pads. So, let's do the right thing and use a kalloced var to store those ancillary bitmaps, e. g. put them at struct media_device, and use an arbitrary big number that will work for all currently known usecases. Signed-off-by: Mauro Carvalho Chehabdiff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 153a46469814..02842d875809 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -235,8 +235,6 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, media_entity_graph_walk_start(, entity); while ((entity = media_entity_graph_walk_next())) { - DECLARE_BITMAP(active, entity->num_pads); - DECLARE_BITMAP(has_no_links, entity->num_pads); unsigned int i; entity->stream_count++; @@ -250,8 +248,8 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, if (!entity->ops || !entity->ops->link_validate) continue; - bitmap_zero(active, entity->num_pads); - bitmap_fill(has_no_links, entity->num_pads); + bitmap_zero(mdev->active, entity->num_pads); + bitmap_fill(mdev->has_no_links, entity->num_pads); for (i = 0; i < entity->num_links; i++) { struct media_link *link = >links[i]; @@ -259,7 +257,7 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, ? link->sink : link->source; /* Mark that a pad is connected by a link. */ - bitmap_clear(has_no_links, pad->index, 1); + bitmap_clear(mdev->has_no_links, pad->index, 1); /* * Pads that either do not need to connect or @@ -268,7 +266,7 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, */ if (!(pad->flags & MEDIA_PAD_FL_MUST_CONNECT) || link->flags & MEDIA_LNK_FL_ENABLED) - bitmap_set(active, pad->index, 1); + bitmap_set(mdev->active, pad->index, 1); /* * Link validation will only take place for @@ -290,15 +288,16 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, } /* Either no links or validated links are fine. */ - bitmap_or(active, active, has_no_links, entity->num_pads); + bitmap_or(mdev->active, mdev->active, mdev->has_no_links, + entity->num_pads); - if (!bitmap_full(active, entity->num_pads)) { + if (!bitmap_full(mdev->active, entity->num_pads)) { ret = -EPIPE; dev_dbg(entity->parent->dev, "\"%s\":%u must be connected by an enabled link\n", entity->name, (unsigned)find_first_zero_bit( - active, entity->num_pads)); + mdev->active, entity->num_pads)); goto error; } } diff --git a/include/media/media-device.h b/include/media/media-device.h index 6e6db78f1ee2..1ac132af031b 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -32,6 +32,10 @@ struct device; +/* Maximum number of pads per entity */ + +#defineMEDIA_MAX_PADS 512 + /** * struct media_device - Media device * @dev: Parent device @@ -78,6 +82,11 @@ struct media_device { int (*link_notify)(struct media_link *link, u32 flags, unsigned int notification); + + /* private: ancillary bitmaps used by graph traversal algo */ + + DECLARE_BITMAP(active, MEDIA_MAX_PADS); + DECLARE_BITMAP(has_no_links, MEDIA_MAX_PADS); }; /* Supported link_notify @notification values. */ -- 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RESEND PATCH] media: vb2: Fix vb2_dc_prepare do not correct sync data to device
Hi Sakari, On Wed, Sep 23, 2015 at 4:37 AM, Sakari Ailuswrote: > Hi Robin, > > On Tue, Sep 22, 2015 at 04:37:17PM +0100, Robin Murphy wrote: >> Hi Hans, >> >> On 21/09/15 14:13, Hans Verkuil wrote: >> >Hi Tiffany! >> > >> >On 21-09-15 14:26, Tiffany Lin wrote: >> >>vb2_dc_prepare use the number of SG entries dma_map_sg_attrs return. >> >>But in dma_sync_sg_for_device, it use lengths of each SG entries >> >>before dma_map_sg_attrs. dma_map_sg_attrs will concatenate >> >>SGs until dma length > dma seg bundary. sgt->nents will less than >> >>sgt->orig_nents. Using SG entries after dma_map_sg_attrs >> >>in vb2_dc_prepare will make some SGs are not sync to device. >> >>After add DMA_ATTR_SKIP_CPU_SYNC in vb2_dc_get_userptr to remove >> >>sync data to device twice. Device randomly get incorrect data because >> >>some SGs are not sync to device. Change to use number of SG entries >> >>before dma_map_sg_attrs in vb2_dc_prepare to prevent this issue. >> >> >> >>Signed-off-by: Tiffany Lin >> >>--- >> >> drivers/media/v4l2-core/videobuf2-dma-contig.c | 4 ++-- >> >> 1 file changed, 2 insertions(+), 2 deletions(-) >> >> >> >>diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c >> >>b/drivers/media/v4l2-core/videobuf2-dma-contig.c >> >>index 2397ceb..c5d00bd 100644 >> >>--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c >> >>+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c >> >>@@ -100,7 +100,7 @@ static void vb2_dc_prepare(void *buf_priv) >> >>if (!sgt || buf->db_attach) >> >>return; >> >> >> >>- dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); >> >>+ dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->orig_nents, >> >>buf->dma_dir); >> >> } >> >> >> >> static void vb2_dc_finish(void *buf_priv) >> >>@@ -112,7 +112,7 @@ static void vb2_dc_finish(void *buf_priv) >> >>if (!sgt || buf->db_attach) >> >>return; >> >> >> >>- dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); >> >>+ dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir); >> >> } >> > >> >I don't really understand it. I am assuming that this happens on an arm and >> >that >> >the dma_map_sg_attrs and dma_sync_sg_* functions used are >> >arm_iommu_map_sg() and >> >arm_iommu_sync_sg_* as implemented in arch/arm/mm/dma-mapping.c. >> > >> >Now, as I understand it (and my understanding may very well be flawed!) the >> >map_sg >> >function concatenates SG entries if possible, so it may return fewer >> >entries. But >> >the dma_sync_sg functions use those updated SG entries, so the full buffer >> >should >> >be covered by this. Using orig_nents will actually sync parts of the buffer >> >twice! >> >The first nents entries already cover the full buffer so any remaining >> >entries up >> >to orig_nents will just duplicate parts of the buffer. >> >> As Documentation/DMA-API.txt says, the parameters to dma_sync_sg_* must be >> the same as those originally passed into dma_map_sg. The segments are only >> merged *from the point of view of the device*: if I have a scatterlist of >> two discontiguous 4K segments, I can remap them with an IOMMU so the device >> sees them as a single 8K buffer, and tell it as such. If on the other hand I >> want to do maintenance from the CPU side (i.e. any DMA API call), then those >> DMA addresses mean nothing and I can only operate on the CPU addresses of >> the underlying pages, which are still very much discontiguous in the linear >> map; ergo I still need to iterate over the original entries. >> >> Whilst I can't claim much familiarity with v4l itself, from a brief look >> over the existing code this patch does look to be doing the right thing. > > Thanks for the explanation. I wonder if this is the only place where we have > this issue. :-I > > I think this might have been partly caused by the unfortunately named field > (nents) in struct sg_table. I wrote a small patch for this (plus a fix for a > few other things as well): > > > From 8928d76db4d45c2b4a16ff90de6695bc88e19779 Mon Sep 17 00:00:00 2001 > From: Sakari Ailus > Date: Tue, 22 Sep 2015 23:30:30 +0300 > Subject: [PATCH 1/1] Documentation: DMA API: Be more explicit that nelems is > always the same > > The nelems argument to the DMA API functions operating on scatterlists is > always the same. The documentation used different argument names and the > matter was not mentioned in Documentation/DMA-API-HOWTO.txt at all. Fix > these. Thanks for this patch! I was very confused by this as well. Can you also fix the following incorrect comments in arch/arm/mm/dma-mapping.c : 1694 /** 1695 * arm_iommu_sync_sg_for_cpu 1696 * @dev: valid struct device pointer 1697 * @sg: list of buffers 1698 * @nents: number of buffers to map (returned from dma_map_sg) 1699 * @dir: DMA transfer direction (same as was passed to dma_map_sg) 1700 */ 1701 void arm_iommu_sync_sg_for_cpu(struct device *dev, struct
Re: [PATCH 1/3] [media] v4l: tegra: Add NVIDIA Tegra VI driver
Hi Bryan, Thanks for this v3 patch series. It looks very good now. I have a few comments, I think they are trivial to add and then I would just wait for the new MC code to be merged. I hope it will be soon, but it's a bit unpredictable. On 21-09-15 20:55, Bryan Wu wrote: > NVIDIA Tegra processor contains a powerful Video Input (VI) hardware > controller which can support up to 6 MIPI CSI camera sensors. > > This patch adds a V4L2 media controller and capture driver to support > Tegra VI hardware. It's verified with Tegra built-in test pattern > generator. > > Signed-off-by: Bryan Wu> Reviewed-by: Hans Verkuil > --- > drivers/media/platform/Kconfig | 1 + > drivers/media/platform/Makefile | 2 + > drivers/media/platform/tegra/Kconfig | 10 + > drivers/media/platform/tegra/Makefile| 3 + > drivers/media/platform/tegra/tegra-channel.c | 782 > +++ > drivers/media/platform/tegra/tegra-core.c| 252 + > drivers/media/platform/tegra/tegra-core.h| 162 ++ > drivers/media/platform/tegra/tegra-csi.c | 566 +++ > drivers/media/platform/tegra/tegra-vi.c | 581 > drivers/media/platform/tegra/tegra-vi.h | 209 +++ > 10 files changed, 2568 insertions(+) > create mode 100644 drivers/media/platform/tegra/Kconfig > create mode 100644 drivers/media/platform/tegra/Makefile > create mode 100644 drivers/media/platform/tegra/tegra-channel.c > create mode 100644 drivers/media/platform/tegra/tegra-core.c > create mode 100644 drivers/media/platform/tegra/tegra-core.h > create mode 100644 drivers/media/platform/tegra/tegra-csi.c > create mode 100644 drivers/media/platform/tegra/tegra-vi.c > create mode 100644 drivers/media/platform/tegra/tegra-vi.h > > diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig > index f6bed19..553867f 100644 > --- a/drivers/media/platform/Kconfig > +++ b/drivers/media/platform/Kconfig > @@ -119,6 +119,7 @@ source "drivers/media/platform/exynos4-is/Kconfig" > source "drivers/media/platform/s5p-tv/Kconfig" > source "drivers/media/platform/am437x/Kconfig" > source "drivers/media/platform/xilinx/Kconfig" > +source "drivers/media/platform/tegra/Kconfig" > > endif # V4L_PLATFORM_DRIVERS > > diff --git a/drivers/media/platform/tegra/tegra-channel.c > b/drivers/media/platform/tegra/tegra-channel.c > new file mode 100644 > index 000..37a7017 > --- /dev/null > +++ b/drivers/media/platform/tegra/tegra-channel.c > @@ -0,0 +1,782 @@ > +/* > + * NVIDIA Tegra Video Input Device > + * > + * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved. > + * > + * Author: Bryan Wu > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +#include "tegra-vi.h" > + > +#define TEGRA_VI_SYNCPT_WAIT_TIMEOUT 200 > + > +/* VI registers */ > +#define TEGRA_VI_CFG_VI_INCR_SYNCPT 0x000 > +#define VI_CFG_VI_INCR_SYNCPT_COND(x) (((x) & 0xff) > << 8) > +#define VI_CSI_PP_LINE_START(port) (4 + (port) * 4) > +#define VI_CSI_PP_FRAME_START(port)(5 + (port) * 4) > +#define VI_CSI_MW_REQ_DONE(port) (6 + (port) * 4) > +#define VI_CSI_MW_ACK_DONE(port) (7 + (port) * 4) > + > +#define TEGRA_VI_CFG_VI_INCR_SYNCPT_CNTRL0x004 > +#define TEGRA_VI_CFG_VI_INCR_SYNCPT_ERROR0x008 > +#define TEGRA_VI_CFG_CTXSW 0x020 > +#define TEGRA_VI_CFG_INTSTATUS 0x024 > +#define TEGRA_VI_CFG_PWM_CONTROL 0x038 > +#define TEGRA_VI_CFG_PWM_HIGH_PULSE 0x03c > +#define TEGRA_VI_CFG_PWM_LOW_PULSE 0x040 > +#define TEGRA_VI_CFG_PWM_SELECT_PULSE_A 0x044 > +#define TEGRA_VI_CFG_PWM_SELECT_PULSE_B 0x048 > +#define TEGRA_VI_CFG_PWM_SELECT_PULSE_C 0x04c > +#define TEGRA_VI_CFG_PWM_SELECT_PULSE_D 0x050 > +#define TEGRA_VI_CFG_VGP10x064 > +#define TEGRA_VI_CFG_VGP20x068 > +#define TEGRA_VI_CFG_VGP30x06c > +#define TEGRA_VI_CFG_VGP40x070 > +#define TEGRA_VI_CFG_VGP50x074 > +#define TEGRA_VI_CFG_VGP60x078 > +#define TEGRA_VI_CFG_INTERRUPT_MASK 0x08c > +#define
Re: [PATCH 00/38] Fixes related to incorrect usage of unsigned types
On 09/21/2015 03:42 PM, David Howells wrote: > Andrzej Hajdawrote: > >> Semantic patch finds comparisons of types: >> unsigned < 0 >> unsigned >= 0 >> The former is always false, the latter is always true. >> Such comparisons are useless, so theoretically they could be >> safely removed, but their presence quite often indicates bugs. > > Or someone has left them in because they don't matter and there's the > possibility that the type being tested might be or become signed under some > circumstances. If the comparison is useless, I'd expect the compiler to just > discard it - for such cases your patch is pointless. > > If I have, for example: > > unsigned x; > > if (x == 0 || x > 27) > give_a_range_error(); > > I will write this as: > > unsigned x; > > if (x <= 0 || x > 27) > give_a_range_error(); > > because it that gives a way to handle x being changed to signed at some point > in the future for no cost. In which case, your changing the <= to an == > "because the < part of the case is useless" is arguably wrong. This is why I have not checked for such cases - I have skipped checks of type unsigned <= 0 exactly for the reasons above. However I have left two other checks as they seems to me more suspicious - they are always true or false. But as Dmitry and Andrew pointed out Linus have quite strong opinion against removing range checks in such cases as he finds it clearer. I think it applies to patches 29-36. I am not sure about patches 26-28,37. Regards Andrzej > > David > -- > To unsubscribe from this list: send the line "unsubscribe linux-wireless" in > the body of a message to majordomo-u79uwxl29ty76z2rm5m...@public.gmane.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] [media] cx231xx: fix bulk transfer mode
The current cx231xx driver doesn't work with bulk transfer mode. This patch makes it possible to use bulk transfer mode. Signed-off-by: Terry Heo--- drivers/media/usb/cx231xx/cx231xx-core.c | 15 ++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c index a2fd49b..f497888 100644 --- a/drivers/media/usb/cx231xx/cx231xx-core.c +++ b/drivers/media/usb/cx231xx/cx231xx-core.c @@ -914,6 +914,7 @@ EXPORT_SYMBOL_GPL(cx231xx_uninit_isoc); */ void cx231xx_uninit_bulk(struct cx231xx *dev) { + struct cx231xx_dmaqueue *dma_q = >video_mode.vidq; struct urb *urb; int i; @@ -931,7 +932,7 @@ void cx231xx_uninit_bulk(struct cx231xx *dev) if (dev->video_mode.bulk_ctl.transfer_buffer[i]) { usb_free_coherent(dev->udev, urb->transfer_buffer_length, - dev->video_mode.isoc_ctl. + dev->video_mode.bulk_ctl. transfer_buffer[i], urb->transfer_dma); } @@ -943,10 +944,12 @@ void cx231xx_uninit_bulk(struct cx231xx *dev) kfree(dev->video_mode.bulk_ctl.urb); kfree(dev->video_mode.bulk_ctl.transfer_buffer); + kfree(dma_q->p_left_data); dev->video_mode.bulk_ctl.urb = NULL; dev->video_mode.bulk_ctl.transfer_buffer = NULL; dev->video_mode.bulk_ctl.num_bufs = 0; + dma_q->p_left_data = NULL; if (dev->mode_tv == 0) cx231xx_capture_start(dev, 0, Raw_Video); @@ -1196,6 +1199,16 @@ int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, sb_size, cx231xx_bulk_irq_callback, dma_q); } + /* clear halt */ + rc = usb_clear_halt(dev->udev, dev->video_mode.bulk_ctl.urb[0]->pipe); + if (rc < 0) { + dev_err(dev->dev, + "failed to clear USB bulk endpoint stall/halt condition (error=%i)\n", + rc); + cx231xx_uninit_bulk(dev); + return rc; + } + init_waitqueue_head(_q->wq); /* submit urbs and enables IRQ */ -- 2.6.0.rc0.131.gf624c3d -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[GIT PULL FOR v4.4] More fixes/enhancements
More fixes and enhancements. Note the v4l2-ctrls fix that has a CC to stable for 3.17 and up. Regards, Hans The following changes since commit 9ddf9071ea17b83954358b2dac42b34e5857a9af: Merge tag 'v4.3-rc1' into patchwork (2015-09-13 11:10:12 -0300) are available in the git repository at: git://linuxtv.org/hverkuil/media_tree.git for-v4.4c for you to fetch changes up to c8e88d026d67d33c427a9083a7762527a6b80d1c: media: v4l2-ctrls: Fix 64bit support in get_ctrl() (2015-09-22 10:23:37 +0200) Andrzej Pietrasiewicz (2): s5p-jpeg: add support for 5433 MAINTAINERS: add exynos jpeg codec maintainers Benoit Parrot (1): media: v4l2-ctrls: Fix 64bit support in get_ctrl() Hans Verkuil (1): cobalt: fix Kconfig dependency Javier Martinez Canillas (1): tvp5150: add support for asynchronous probing Joe Perches (1): s5p-mfc: Correct misuse of %0x Luis de Bethencourt (1): cx25821, cx88, tm6000: use SNDRV_DEFAULT_ENABLE_PNP Marek Szyprowski (1): s5p-jpeg: generalize clocks handling Documentation/devicetree/bindings/media/exynos-jpeg-codec.txt | 3 +- MAINTAINERS | 8 ++ drivers/media/i2c/tvp5150.c | 14 ++- drivers/media/pci/cobalt/Kconfig | 2 +- drivers/media/pci/cx25821/cx25821-alsa.c | 2 +- drivers/media/pci/cx88/cx88-alsa.c| 2 +- drivers/media/platform/s5p-jpeg/jpeg-core.c | 444 +- drivers/media/platform/s5p-jpeg/jpeg-core.h | 41 ++- drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c | 80 ++--- drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.h | 11 +- drivers/media/platform/s5p-jpeg/jpeg-regs.h | 85 +- drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c | 2 +- drivers/media/usb/tm6000/tm6000-alsa.c| 2 +- drivers/media/v4l2-core/v4l2-ctrls.c | 6 +- 14 files changed, 586 insertions(+), 116 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH v5 8/8] media: videobuf2: Move v4l2-specific stuff to videobuf2-v4l2
Move v4l2-specific stuff from videobu2-core to videobuf2-v4l2 without doing any functional changes. Signed-off-by: Junghak SungSigned-off-by: Geunyoung Kim Acked-by: Seung-Woo Kim Acked-by: Inki Dae --- drivers/media/v4l2-core/videobuf2-core.c | 1872 +- drivers/media/v4l2-core/videobuf2-internal.h | 161 +++ drivers/media/v4l2-core/videobuf2-v4l2.c | 1678 +++ include/media/videobuf2-core.h | 118 +- include/media/videobuf2-dvb.h|8 +- include/media/videobuf2-v4l2.h | 96 ++ 6 files changed, 2009 insertions(+), 1924 deletions(-) create mode 100644 drivers/media/v4l2-core/videobuf2-internal.h diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 380536d..6b4de9b 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -24,164 +24,15 @@ #include #include -#include -#include -#include -#include -#include +#include #include -static int debug; -module_param(debug, int, 0644); +#include "videobuf2-internal.h" -#define dprintk(level, fmt, arg...) \ - do { \ - if (debug >= level) \ - pr_info("vb2: %s: " fmt, __func__, ## arg); \ - } while (0) - -#ifdef CONFIG_VIDEO_ADV_DEBUG - -/* - * If advanced debugging is on, then count how often each op is called - * successfully, which can either be per-buffer or per-queue. - * - * This makes it easy to check that the 'init' and 'cleanup' - * (and variations thereof) stay balanced. - */ - -#define log_memop(vb, op) \ - dprintk(2, "call_memop(%p, %d, %s)%s\n",\ - (vb)->vb2_queue, (vb)->index, #op, \ - (vb)->vb2_queue->mem_ops->op ? "" : " (nop)") - -#define call_memop(vb, op, args...)\ -({ \ - struct vb2_queue *_q = (vb)->vb2_queue; \ - int err;\ - \ - log_memop(vb, op); \ - err = _q->mem_ops->op ? _q->mem_ops->op(args) : 0; \ - if (!err) \ - (vb)->cnt_mem_ ## op++; \ - err;\ -}) - -#define call_ptr_memop(vb, op, args...) \ -({ \ - struct vb2_queue *_q = (vb)->vb2_queue; \ - void *ptr; \ - \ - log_memop(vb, op); \ - ptr = _q->mem_ops->op ? _q->mem_ops->op(args) : NULL; \ - if (!IS_ERR_OR_NULL(ptr)) \ - (vb)->cnt_mem_ ## op++; \ - ptr;\ -}) - -#define call_void_memop(vb, op, args...) \ -({ \ - struct vb2_queue *_q = (vb)->vb2_queue; \ - \ - log_memop(vb, op); \ - if (_q->mem_ops->op)\ - _q->mem_ops->op(args); \ - (vb)->cnt_mem_ ## op++; \ -}) - -#define log_qop(q, op) \ - dprintk(2, "call_qop(%p, %s)%s\n", q, #op, \ - (q)->ops->op ? "" : " (nop)") - -#define call_qop(q, op, args...) \ -({ \ - int err;\ - \ - log_qop(q, op); \ - err = (q)->ops->op ? (q)->ops->op(args) : 0;\ - if (!err) \ - (q)->cnt_ ## op++;
[RFC PATCH v5 5/8] media: videobuf2: Change queue_setup argument
Replace struct v4l2_format * with vb2_format * to make queue_setup() for common use. struct vb2_format { unsigned inttype; unsigned intpixelformat; unsigned intwidth; unsigned intheight; unsigned intnum_planes; unsigned intbytesperline[VIDEO_MAX_PLANES]; unsigned intreq_sizes[VIDEO_MAX_PLANES]; }; And then, modify all device drivers related with this change. Signed-off-by: Junghak SungSigned-off-by: Geunyoung Kim Acked-by: Seung-Woo Kim Acked-by: Inki Dae --- drivers/input/touchscreen/sur40.c | 11 +- drivers/media/dvb-frontends/rtl2832_sdr.c |2 +- drivers/media/pci/cobalt/cobalt-v4l2.c |6 +- drivers/media/pci/cx23885/cx23885-417.c|2 +- drivers/media/pci/cx23885/cx23885-dvb.c|2 +- drivers/media/pci/cx23885/cx23885-vbi.c|2 +- drivers/media/pci/cx23885/cx23885-video.c |2 +- drivers/media/pci/cx25821/cx25821-video.c | 11 +- drivers/media/pci/cx88/cx88-blackbird.c|2 +- drivers/media/pci/cx88/cx88-dvb.c |2 +- drivers/media/pci/cx88/cx88-vbi.c |2 +- drivers/media/pci/cx88/cx88-video.c|2 +- drivers/media/pci/dt3155/dt3155.c |6 +- drivers/media/pci/netup_unidvb/netup_unidvb_core.c |2 +- drivers/media/pci/saa7134/saa7134-ts.c |2 +- drivers/media/pci/saa7134/saa7134-vbi.c|2 +- drivers/media/pci/saa7134/saa7134-video.c |2 +- drivers/media/pci/saa7134/saa7134.h|2 +- drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c |2 +- drivers/media/pci/solo6x10/solo6x10-v4l2.c |7 +- drivers/media/pci/sta2x11/sta2x11_vip.c|2 +- drivers/media/pci/tw68/tw68-video.c|9 +- drivers/media/platform/am437x/am437x-vpfe.c|6 +- drivers/media/platform/coda/coda-common.c |2 +- drivers/media/platform/davinci/vpbe_display.c |6 +- drivers/media/platform/davinci/vpif_capture.c |6 +- drivers/media/platform/exynos-gsc/gsc-m2m.c|2 +- drivers/media/platform/exynos4-is/fimc-capture.c | 12 +- drivers/media/platform/exynos4-is/fimc-isp-video.c | 12 +- drivers/media/platform/exynos4-is/fimc-lite.c | 12 +- drivers/media/platform/exynos4-is/fimc-m2m.c |2 +- drivers/media/platform/m2m-deinterlace.c |2 +- drivers/media/platform/marvell-ccic/mcam-core.c|6 +- drivers/media/platform/mx2_emmaprp.c |2 +- drivers/media/platform/omap3isp/ispvideo.c |2 +- drivers/media/platform/rcar_jpu.c |5 +- drivers/media/platform/s3c-camif/camif-capture.c | 12 +- drivers/media/platform/s5p-g2d/g2d.c |7 +- drivers/media/platform/s5p-jpeg/jpeg-core.c|2 +- drivers/media/platform/s5p-mfc/s5p_mfc_dec.c |2 +- drivers/media/platform/s5p-mfc/s5p_mfc_enc.c |2 +- drivers/media/platform/s5p-tv/mixer_video.c|2 +- drivers/media/platform/sh_veu.c| 51 +++-- drivers/media/platform/sh_vou.c| 11 +- drivers/media/platform/soc_camera/atmel-isi.c |2 +- drivers/media/platform/soc_camera/mx2_camera.c |2 +- drivers/media/platform/soc_camera/mx3_camera.c | 14 +-- drivers/media/platform/soc_camera/rcar_vin.c | 14 +-- .../platform/soc_camera/sh_mobile_ceu_camera.c | 14 +-- drivers/media/platform/sti/bdisp/bdisp-v4l2.c |6 +- drivers/media/platform/ti-vpe/vpe.c|2 +- drivers/media/platform/vim2m.c |6 +- drivers/media/platform/vivid/vivid-sdr-cap.c |7 +- drivers/media/platform/vivid/vivid-vbi-cap.c |2 +- drivers/media/platform/vivid/vivid-vbi-out.c |7 +- drivers/media/platform/vivid/vivid-vid-cap.c | 20 ++-- drivers/media/platform/vivid/vivid-vid-out.c | 21 ++-- drivers/media/platform/vsp1/vsp1_video.c | 115 +--- drivers/media/platform/xilinx/xilinx-dma.c |6 +- drivers/media/usb/airspy/airspy.c |2 +- drivers/media/usb/au0828/au0828-vbi.c | 10 +- drivers/media/usb/au0828/au0828-video.c|4 +- drivers/media/usb/em28xx/em28xx-vbi.c |9 +- drivers/media/usb/em28xx/em28xx-video.c|4 +- drivers/media/usb/go7007/go7007-v4l2.c |2 +- drivers/media/usb/hackrf/hackrf.c |2 +- drivers/media/usb/msi2500/msi2500.c|2 +- drivers/media/usb/pwc/pwc-if.c |2 +- drivers/media/usb/s2255/s2255drv.c |2 +-
[RFC PATCH v5 1/8] media: videobuf2: Replace videobuf2-core with videobuf2-v4l2
Make videobuf2-v4l2 as a wrapper of videobuf2-core for v4l2-use. And replace videobuf2-core.h with videobuf2-v4l2.h. This renaming change should be accompanied by the modifications of all device drivers that include videobuf2-core.h. It can be done with just running this shell script. replace() { str1=$1 str2=$2 dir=$3 for file in $(find $dir -name *.h -o -name *.c -o -name Makefile) do echo $file sed "s/$str1/$str2/g" $file > $file.out mv $file.out $file done } replace "videobuf2-core" "videobuf2-v4l2" "include/media/" replace "videobuf2-core" "videobuf2-v4l2" "drivers/media/" replace "videobuf2-core" "videobuf2-v4l2" "drivers/usb/gadget/" replace "videobuf2-core" "videobuf2-v4l2" "drivers/staging/media/" Signed-off-by: Junghak SungSigned-off-by: Geunyoung Kim Acked-by: Seung-Woo Kim Acked-by: Inki Dae --- drivers/media/pci/solo6x10/solo6x10.h |2 +- drivers/media/platform/coda/coda-bit.c |2 +- drivers/media/platform/coda/coda-common.c |2 +- drivers/media/platform/coda/coda.h |2 +- drivers/media/platform/coda/trace.h|2 +- drivers/media/platform/exynos-gsc/gsc-core.h |2 +- drivers/media/platform/exynos4-is/fimc-capture.c |2 +- drivers/media/platform/exynos4-is/fimc-core.c |2 +- drivers/media/platform/exynos4-is/fimc-core.h |2 +- drivers/media/platform/exynos4-is/fimc-is.h|2 +- drivers/media/platform/exynos4-is/fimc-isp-video.c |2 +- drivers/media/platform/exynos4-is/fimc-isp-video.h |2 +- drivers/media/platform/exynos4-is/fimc-isp.h |2 +- drivers/media/platform/exynos4-is/fimc-lite.c |2 +- drivers/media/platform/exynos4-is/fimc-lite.h |2 +- drivers/media/platform/exynos4-is/fimc-m2m.c |2 +- drivers/media/platform/marvell-ccic/mcam-core.h|2 +- drivers/media/platform/omap3isp/ispvideo.h |2 +- drivers/media/platform/rcar_jpu.c |2 +- drivers/media/platform/s3c-camif/camif-capture.c |2 +- drivers/media/platform/s3c-camif/camif-core.c |2 +- drivers/media/platform/s3c-camif/camif-core.h |2 +- drivers/media/platform/s5p-g2d/g2d.c |2 +- drivers/media/platform/s5p-jpeg/jpeg-core.c|2 +- drivers/media/platform/s5p-mfc/s5p_mfc.c |2 +- drivers/media/platform/s5p-mfc/s5p_mfc_common.h|2 +- drivers/media/platform/s5p-mfc/s5p_mfc_dec.c |2 +- drivers/media/platform/s5p-mfc/s5p_mfc_enc.c |2 +- drivers/media/platform/s5p-tv/mixer.h |2 +- drivers/media/platform/soc_camera/mx2_camera.c |2 +- drivers/media/platform/soc_camera/soc_camera.c |2 +- drivers/media/platform/ti-vpe/vpe.c|2 +- drivers/media/platform/vivid/vivid-core.h |2 +- drivers/media/platform/vsp1/vsp1_video.c |2 +- drivers/media/platform/vsp1/vsp1_video.h |2 +- drivers/media/platform/xilinx/xilinx-dma.c |2 +- drivers/media/platform/xilinx/xilinx-dma.h |2 +- drivers/media/usb/go7007/go7007-priv.h |2 +- drivers/media/usb/stk1160/stk1160.h|2 +- drivers/media/usb/usbtv/usbtv-video.c |2 +- drivers/media/usb/uvc/uvcvideo.h |2 +- drivers/media/v4l2-core/Makefile |2 +- drivers/media/v4l2-core/v4l2-ioctl.c |2 +- drivers/media/v4l2-core/v4l2-mem2mem.c |2 +- drivers/media/v4l2-core/v4l2-trace.c |2 +- drivers/media/v4l2-core/videobuf2-core.c | 10 +++ drivers/media/v4l2-core/videobuf2-dma-contig.c |2 +- drivers/media/v4l2-core/videobuf2-dma-sg.c |2 +- drivers/media/v4l2-core/videobuf2-memops.c |2 +- drivers/media/v4l2-core/videobuf2-v4l2.c | 31 drivers/media/v4l2-core/videobuf2-vmalloc.c|2 +- drivers/staging/media/omap4iss/iss_video.h |2 +- drivers/usb/gadget/function/uvc_queue.h|2 +- include/media/soc_camera.h |2 +- include/media/v4l2-mem2mem.h |2 +- include/media/videobuf2-core.h |2 +- include/media/videobuf2-dma-contig.h |2 +- include/media/videobuf2-dma-sg.h |2 +- include/media/videobuf2-memops.h |2 +- include/media/videobuf2-v4l2.h | 17 +++ include/media/videobuf2-vmalloc.h |2 +- 61 files changed, 111 insertions(+), 63 deletions(-) create mode 100644 drivers/media/v4l2-core/videobuf2-v4l2.c create mode 100644 include/media/videobuf2-v4l2.h diff --git a/drivers/media/pci/solo6x10/solo6x10.h
[RFC PATCH v5 6/8] media: videobuf2: Replace v4l2-specific data with vb2 data.
Simple changes that replace v4l2-specific data with vb2 data in videobuf2-core. enum v4l2_buf_type --> int enum v4l2_memory --> enum vb2_memory VIDEO_MAX_FRAME --> VB2_MAX_FRAME VIDEO_MAX_PLANES --> VB2_MAX_PLANES struct v4l2_fh *owner --> void *owner V4L2_TYPE_IS_MULTIPLANAR() --> is_multiplanar V4L2_TYPE_IS_OUTPUT() --> is_output Signed-off-by: Junghak SungSigned-off-by: Geunyoung Kim Acked-by: Seung-Woo Kim Acked-by: Inki Dae --- drivers/media/v4l2-core/videobuf2-core.c | 131 -- include/media/videobuf2-core.h | 37 ++--- include/media/videobuf2-v4l2.h |8 ++ include/trace/events/v4l2.h |5 +- 4 files changed, 108 insertions(+), 73 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index aeef76c..32fa425 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -193,7 +193,7 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb) { struct vb2_queue *q = vb->vb2_queue; enum dma_data_direction dma_dir = - V4L2_TYPE_IS_OUTPUT(q->type) ? DMA_TO_DEVICE : DMA_FROM_DEVICE; + q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE; void *mem_priv; int plane; @@ -347,7 +347,7 @@ static void __setup_offsets(struct vb2_queue *q, unsigned int n) * * Returns the number of buffers successfully allocated. */ -static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory, +static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory, unsigned int num_buffers, unsigned int num_planes) { unsigned int buffer; @@ -370,7 +370,7 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory, vb->memory = memory; /* Allocate video buffer memory for the MMAP type */ - if (memory == V4L2_MEMORY_MMAP) { + if (memory == VB2_MEMORY_MMAP) { ret = __vb2_buf_mem_alloc(vb); if (ret) { dprintk(1, "failed allocating memory for " @@ -397,7 +397,7 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory, } __setup_lengths(q, buffer); - if (memory == V4L2_MEMORY_MMAP) + if (memory == VB2_MEMORY_MMAP) __setup_offsets(q, buffer); dprintk(1, "allocated %d buffers, %d plane(s) each\n", @@ -421,9 +421,9 @@ static void __vb2_free_mem(struct vb2_queue *q, unsigned int buffers) continue; /* Free MMAP buffers or release USERPTR buffers */ - if (q->memory == V4L2_MEMORY_MMAP) + if (q->memory == VB2_MEMORY_MMAP) __vb2_buf_mem_free(vb); - else if (q->memory == V4L2_MEMORY_DMABUF) + else if (q->memory == VB2_MEMORY_DMABUF) __vb2_buf_dmabuf_put(vb); else __vb2_buf_userptr_put(vb); @@ -562,7 +562,7 @@ static int __verify_planes_array(struct vb2_buffer *vb, const struct v4l2_buffer return -EINVAL; } - if (b->length < vb->num_planes || b->length > VIDEO_MAX_PLANES) { + if (b->length < vb->num_planes || b->length > VB2_MAX_PLANES) { dprintk(1, "incorrect planes array length, " "expected %d, got %d\n", vb->num_planes, b->length); return -EINVAL; @@ -586,8 +586,8 @@ static int __verify_length(struct vb2_buffer *vb, const struct v4l2_buffer *b) if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) { for (plane = 0; plane < vb->num_planes; ++plane) { - length = (b->memory == V4L2_MEMORY_USERPTR || - b->memory == V4L2_MEMORY_DMABUF) + length = (b->memory == VB2_MEMORY_USERPTR || + b->memory == VB2_MEMORY_DMABUF) ? b->m.planes[plane].length : vb->planes[plane].length; bytesused = b->m.planes[plane].bytesused @@ -601,7 +601,7 @@ static int __verify_length(struct vb2_buffer *vb, const struct v4l2_buffer *b) return -EINVAL; } } else { - length = (b->memory == V4L2_MEMORY_USERPTR) + length = (b->memory == VB2_MEMORY_USERPTR) ? b->length : vb->planes[0].length; if (b->bytesused > length) @@ -670,7 +670,7 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) b->reserved2 = 0; b->reserved = 0; - if (V4L2_TYPE_IS_MULTIPLANAR(q->type)) { + if (q->is_multiplanar) {
[RFC PATCH v5 7/8] media: videobuf2: Prepare to divide videobuf2
Prepare to divide videobuf2 - Separate vb2 trace events from v4l2 trace event. - Make wrapper functions that will move to v4l2-side - Make vb2_core_* functions that remain in vb2 core side - Rename internal functions as vb2_* Signed-off-by: Junghak SungSigned-off-by: Geunyoung Kim Acked-by: Seung-Woo Kim Acked-by: Inki Dae --- drivers/media/v4l2-core/Makefile |2 +- drivers/media/v4l2-core/v4l2-trace.c |8 +- drivers/media/v4l2-core/vb2-trace.c |9 + drivers/media/v4l2-core/videobuf2-core.c | 556 -- include/trace/events/v4l2.h | 28 +- include/trace/events/vb2.h | 65 6 files changed, 457 insertions(+), 211 deletions(-) create mode 100644 drivers/media/v4l2-core/vb2-trace.c create mode 100644 include/trace/events/vb2.h diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile index ad07401..1dc8bba 100644 --- a/drivers/media/v4l2-core/Makefile +++ b/drivers/media/v4l2-core/Makefile @@ -14,7 +14,7 @@ ifeq ($(CONFIG_OF),y) videodev-objs += v4l2-of.o endif ifeq ($(CONFIG_TRACEPOINTS),y) - videodev-objs += v4l2-trace.o + videodev-objs += vb2-trace.o v4l2-trace.o endif obj-$(CONFIG_VIDEO_V4L2) += videodev.o diff --git a/drivers/media/v4l2-core/v4l2-trace.c b/drivers/media/v4l2-core/v4l2-trace.c index 4004814..7416010 100644 --- a/drivers/media/v4l2-core/v4l2-trace.c +++ b/drivers/media/v4l2-core/v4l2-trace.c @@ -5,7 +5,7 @@ #define CREATE_TRACE_POINTS #include -EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_buf_done); -EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_buf_queue); -EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_dqbuf); -EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_qbuf); +EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_v4l2_buf_done); +EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_v4l2_buf_queue); +EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_v4l2_dqbuf); +EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_v4l2_qbuf); diff --git a/drivers/media/v4l2-core/vb2-trace.c b/drivers/media/v4l2-core/vb2-trace.c new file mode 100644 index 000..61e74f5 --- /dev/null +++ b/drivers/media/v4l2-core/vb2-trace.c @@ -0,0 +1,9 @@ +#include + +#define CREATE_TRACE_POINTS +#include + +EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_buf_done); +EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_buf_queue); +EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_dqbuf); +EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_qbuf); diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 32fa425..380536d 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -30,7 +30,7 @@ #include #include -#include +#include static int debug; module_param(debug, int, 0644); @@ -612,10 +612,10 @@ static int __verify_length(struct vb2_buffer *vb, const struct v4l2_buffer *b) } /** - * __buffer_in_use() - return true if the buffer is in use and + * vb2_buffer_in_use() - return true if the buffer is in use and * the queue cannot be freed (by the means of REQBUFS(0)) call */ -static bool __buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb) +static bool vb2_buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb) { unsigned int plane; for (plane = 0; plane < vb->num_planes; ++plane) { @@ -640,7 +640,7 @@ static bool __buffers_in_use(struct vb2_queue *q) { unsigned int buffer; for (buffer = 0; buffer < q->num_buffers; ++buffer) { - if (__buffer_in_use(q, q->bufs[buffer])) + if (vb2_buffer_in_use(q, q->bufs[buffer])) return true; } return false; @@ -650,8 +650,9 @@ static bool __buffers_in_use(struct vb2_queue *q) * __fill_v4l2_buffer() - fill in a struct v4l2_buffer with information to be * returned to userspace */ -static void __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) +static int __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb) { + struct v4l2_buffer *b = pb; struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); struct vb2_queue *q = vb->vb2_queue; unsigned int plane; @@ -742,8 +743,28 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) break; } - if (__buffer_in_use(q, vb)) + if (vb2_buffer_in_use(q, vb)) b->flags |= V4L2_BUF_FLAG_MAPPED; + + return 0; +} + +/** + * vb2_core_querybuf() - query video buffer information + * @q: videobuf queue + * @index: id number of the buffer + * @pb:buffer struct passed from userspace + * + * Should be called from vidioc_querybuf ioctl handler in driver. + * The passed buffer should have been verified. + * This function fills the relevant information for the userspace. + * + * The return values from this function are intended to be directly returned + * from vidioc_querybuf handler in driver. + */ +static int vb2_core_querybuf(struct vb2_queue
Re: [RESEND PATCH] media: vb2: Fix vb2_dc_prepare do not correct sync data to device
Hi Sakari, On Tue, 2015-09-22 at 15:07 +0300, Sakari Ailus wrote: > Hi Tiffany, > > On Tue, Sep 22, 2015 at 06:19:25PM +0800, tiffany lin wrote: > > Hi Hans, > > > > On Mon, 2015-09-21 at 15:13 +0200, Hans Verkuil wrote: > > > Hi Tiffany! > > > > > > On 21-09-15 14:26, Tiffany Lin wrote: > > > > vb2_dc_prepare use the number of SG entries dma_map_sg_attrs return. > > > > But in dma_sync_sg_for_device, it use lengths of each SG entries > > > > before dma_map_sg_attrs. dma_map_sg_attrs will concatenate > > > > SGs until dma length > dma seg bundary. sgt->nents will less than > > > > sgt->orig_nents. Using SG entries after dma_map_sg_attrs > > > > in vb2_dc_prepare will make some SGs are not sync to device. > > > > After add DMA_ATTR_SKIP_CPU_SYNC in vb2_dc_get_userptr to remove > > > > sync data to device twice. Device randomly get incorrect data because > > > > some SGs are not sync to device. Change to use number of SG entries > > > > before dma_map_sg_attrs in vb2_dc_prepare to prevent this issue. > > > > > > > > Signed-off-by: Tiffany Lin> > > > --- > > > > drivers/media/v4l2-core/videobuf2-dma-contig.c | 4 ++-- > > > > 1 file changed, 2 insertions(+), 2 deletions(-) > > > > > > > > diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c > > > > b/drivers/media/v4l2-core/videobuf2-dma-contig.c > > > > index 2397ceb..c5d00bd 100644 > > > > --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c > > > > +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c > > > > @@ -100,7 +100,7 @@ static void vb2_dc_prepare(void *buf_priv) > > > > if (!sgt || buf->db_attach) > > > > return; > > > > > > > > - dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, > > > > buf->dma_dir); > > > > + dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->orig_nents, > > > > buf->dma_dir); > > > > } > > > > > > > > static void vb2_dc_finish(void *buf_priv) > > > > @@ -112,7 +112,7 @@ static void vb2_dc_finish(void *buf_priv) > > > > if (!sgt || buf->db_attach) > > > > return; > > > > > > > > - dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, > > > > buf->dma_dir); > > > > + dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->orig_nents, > > > > buf->dma_dir); > > > > } > > > > > > I don't really understand it. I am assuming that this happens on an arm > > > and that > > > the dma_map_sg_attrs and dma_sync_sg_* functions used are > > > arm_iommu_map_sg() and > > > arm_iommu_sync_sg_* as implemented in arch/arm/mm/dma-mapping.c. > > > > > > > We are using __iommu_* implemented in "arch/arm64/mm/dma-mapping.c" in > > review patch > > http://lists.linuxfoundation.org/pipermail/iommu/2015-July/013898.html > > Without patch "[media] vb2: use dma_map_sg_attrs to prevent unnecessary > > sync", vb2 will sync data to device twice. > > One is from "dma_map_sg" in "vb2_dc_get_userptr", the other is from > > "dma_sync_sg_for_device" in "vb2_dc_prepare". dma_map_sg use orig_nents, > > and dma_sync_sg_for_device use nents." > > > > We do not run in 32bits mode, but check "arm_dma_sync_sg_for_device" in > > "arch/arm/mm/dma-mapping.c", > > ops->sync_single_for_device(dev, sg_dma_address(s), s->length, dir); > > It looks like has same issue. > > > > > Now, as I understand it (and my understanding may very well be flawed!) > > > the map_sg > > > function concatenates SG entries if possible, so it may return fewer > > > entries. But > > > the dma_sync_sg functions use those updated SG entries, so the full > > > buffer should > > > be covered by this. Using orig_nents will actually sync parts of the > > > buffer twice! > > > The first nents entries already cover the full buffer so any remaining > > > entries up > > > to orig_nents will just duplicate parts of the buffer. > > > > > I found that in __iommu_sync_sg_for_device, it use sg->length , do not > > cover full buffer. > > By adding log in " __iommu_sync_sg_for_device" without patch "[media] > > vb2: use dma_map_sg_attrs to prevent unnecessary sync", we could see > > total synced size are different between called from dma_map_sg and > > dma_sync_sg_for_device. > > I had the same question Hans did, but I still fail to understand where in > the code things are going wrong the way you described at the moment --- > after dma_map_sg() there are nents entries in the scatterlist. But. > sg_dma_len() should be used instead of the length field to get the size of > the entry. If something is wrong, then it's this AFAICT. > > Could you try whether changing this fixes it? > Do you mean try to change to use sg_dma_len in __iommu_sync_sg_for_device? I tried to change using sg_dam_len() in __iommu_sync_sg_for_device for_each_sg(sgl, sg, nelems, i) { //__dma_map_area(sg_virt(sg), sg->length, dir); __dma_map_area(sg_virt(sg), sg_dma_len(sg), dir); } I still see the issue. Probably there are some other issue in iommu_dma_map_sg. The
Re: [RFC PATCH v5 5/8] media: videobuf2: Change queue_setup argument
Hi Junghak, On 22-09-15 15:30, Junghak Sung wrote: > Replace struct v4l2_format * with vb2_format * to make queue_setup() > for common use. > > struct vb2_format { > unsigned inttype; > unsigned intpixelformat; > unsigned intwidth; > unsigned intheight; > unsigned intnum_planes; > unsigned intbytesperline[VIDEO_MAX_PLANES]; > unsigned intreq_sizes[VIDEO_MAX_PLANES]; > }; Why would you need all the other fields besides req_sizes[]? Which drivers actually need those other fields? Drivers like exynos4-is/fimc-lite.c don't actually use anything but req_sizes if you read the code carefully. I suspect any driver that uses more than req_sizes is actually buggy or written carelessly. I wish you'd checked with me before making this struct... Be aware that I'm abroad (vacation/conferences) from tomorrow until October 10, so I won't be able to do in-depth reviews during that time (well, I'm able, but I don't want to!) Regards, Hans -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH v5 3/8] media: videobuf2: Restructure vb2_buffer (2/3)
Modify all device drivers related with previous change that restructures vb2_buffer for common use. Signed-off-by: Junghak SungSigned-off-by: Geunyoung Kim Acked-by: Seung-Woo Kim Acked-by: Inki Dae --- drivers/input/touchscreen/sur40.c | 17 drivers/media/dvb-frontends/rtl2832_sdr.c | 21 + drivers/media/pci/cobalt/cobalt-driver.h |6 ++- drivers/media/pci/cobalt/cobalt-irq.c |7 +-- drivers/media/pci/cobalt/cobalt-v4l2.c | 20 + drivers/media/pci/cx23885/cx23885-417.c| 11 +++-- drivers/media/pci/cx23885/cx23885-core.c | 24 +- drivers/media/pci/cx23885/cx23885-dvb.c|9 ++-- drivers/media/pci/cx23885/cx23885-vbi.c| 16 --- drivers/media/pci/cx23885/cx23885-video.c | 27 +++- drivers/media/pci/cx23885/cx23885.h|2 +- drivers/media/pci/cx25821/cx25821-video.c | 21 + drivers/media/pci/cx25821/cx25821.h|3 +- drivers/media/pci/cx88/cx88-blackbird.c| 13 +++--- drivers/media/pci/cx88/cx88-core.c |8 ++-- drivers/media/pci/cx88/cx88-dvb.c | 11 +++-- drivers/media/pci/cx88/cx88-mpeg.c | 14 +++--- drivers/media/pci/cx88/cx88-vbi.c | 17 +--- drivers/media/pci/cx88/cx88-video.c| 19 drivers/media/pci/cx88/cx88.h |2 +- drivers/media/pci/dt3155/dt3155.c | 17 drivers/media/pci/dt3155/dt3155.h |3 +- drivers/media/pci/netup_unidvb/netup_unidvb_core.c | 19 drivers/media/pci/saa7134/saa7134-core.c | 14 +++--- drivers/media/pci/saa7134/saa7134-ts.c | 14 +++--- drivers/media/pci/saa7134/saa7134-vbi.c| 10 +++-- drivers/media/pci/saa7134/saa7134-video.c | 21 + drivers/media/pci/saa7134/saa7134.h|2 +- drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c | 46 +++- drivers/media/pci/solo6x10/solo6x10-v4l2.c | 19 drivers/media/pci/solo6x10/solo6x10.h |2 +- drivers/media/pci/sta2x11/sta2x11_vip.c| 12 ++--- drivers/media/pci/tw68/tw68-video.c| 19 drivers/media/pci/tw68/tw68.h |3 +- drivers/media/usb/airspy/airspy.c | 24 +- drivers/media/usb/au0828/au0828-vbi.c |7 +-- drivers/media/usb/au0828/au0828-video.c| 45 ++- drivers/media/usb/au0828/au0828.h |3 +- drivers/media/usb/em28xx/em28xx-vbi.c |7 +-- drivers/media/usb/em28xx/em28xx-video.c| 34 +-- drivers/media/usb/em28xx/em28xx.h |3 +- drivers/media/usb/go7007/go7007-driver.c | 29 ++-- drivers/media/usb/go7007/go7007-priv.h |2 +- drivers/media/usb/go7007/go7007-v4l2.c | 20 + drivers/media/usb/hackrf/hackrf.c | 22 ++ drivers/media/usb/msi2500/msi2500.c| 17 +--- drivers/media/usb/pwc/pwc-if.c | 33 +- drivers/media/usb/pwc/pwc-uncompress.c |6 +-- drivers/media/usb/pwc/pwc.h|4 +- drivers/media/usb/s2255/s2255drv.c | 27 +++- drivers/media/usb/stk1160/stk1160-v4l.c| 15 --- drivers/media/usb/stk1160/stk1160-video.c | 12 ++--- drivers/media/usb/stk1160/stk1160.h|2 +- drivers/media/usb/usbtv/usbtv-video.c | 19 drivers/media/usb/usbtv/usbtv.h|3 +- drivers/media/usb/uvc/uvc_queue.c | 26 ++- drivers/media/usb/uvc/uvc_video.c | 20 - drivers/media/usb/uvc/uvcvideo.h |4 +- drivers/media/v4l2-core/v4l2-mem2mem.c |8 ++-- drivers/staging/media/davinci_vpfe/vpfe_video.c| 43 ++ drivers/staging/media/davinci_vpfe/vpfe_video.h|3 +- drivers/staging/media/omap4iss/iss_video.c | 23 +- drivers/staging/media/omap4iss/iss_video.h |4 +- drivers/usb/gadget/function/uvc_queue.c| 26 ++- drivers/usb/gadget/function/uvc_queue.h|2 +- include/media/davinci/vpbe_display.h |3 +- include/media/v4l2-mem2mem.h |9 ++-- include/trace/events/v4l2.h| 35 +++ 68 files changed, 575 insertions(+), 434 deletions(-) diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c index
[RFC PATCH v5 0/8] Refactoring Videobuf2 for common use
Hello everybody, This is the 5th round for refactoring Videobuf2(a.k.a VB2). The purpose of this patch series is to separate existing VB2 framework into core part and V4L2 specific part. So that not only V4L2 but also other frameworks can use them to manage buffer and utilize queue. Why do we try to make the VB2 framework to be common? As you may know, current DVB framework uses ringbuffer mechanism to demux MPEG-2 TS data and pass it to userspace. However, this mechanism requires extra memory copy because DVB framework provides only read() system call for application - read() system call copies the kernel data to user-space buffer. So if we can use VB2 framework which supports streaming I/O and buffer sharing mechanism, then we could enhance existing DVB framework by removing the extra memory copy - with VB2 framework, application can access the kernel data directly through mmap system call. We have a plan for this work as follows: 1. Separate existing VB2 framework into three parts - VB2 common, VB2-v4l2. Of course, this change will not affect other v4l2-based device drivers. This patch series corresponds to this step. 2. Add and implement new APIs for DVB streaming I/O. We can remove unnecessary memory copy between kernel-space and user-space by using these new APIs. However, we leaves legacy interfaces as-is for backward compatibility. This patch series is the first step for it. The previous version of this patch series can be found at belows. [1] RFC PATCH v1 - http://www.spinics.net/lists/linux-media/msg90688.html [2] RFC PATCH v2 - http://www.spinics.net/lists/linux-media/msg92130.html [3] RFC PATCH v3 - http://www.spinics.net/lists/linux-media/msg92953.html [4] RFC PATCH v4 - http://www.spinics.net/lists/linux-media/msg93421.html Changes since v4 1. Rebase on 4.3-rc1 Kernel 4.3-rc1 was released. So, this patch set is made based on that version. 2. Modify queue_setup() argument In previous patch set, struct v4l2_format, which is a parameter of queue_setup(), is abstracted by using void pointer. But, it is better way to pass the parameter with presise meaning than abstracting it. So, replace void * with struct vb2_format which is newly defined to contain the format information for common use. 3. Add a code to check if VB2_MAX_* match with VIDEO_MAX_* Add a check code to videobuf2-v4l2.c where the compiler compares VIDEO_MAX_FRAME and VB2_MAX_FRAME (and ditto for MAX_PLANES) and throws an #error if they do not match. 4. Change the commit order For easier review, the patch that just move things around without doing any functional change is moved to the last. All ideas above are from Hans and it seems to be better and right way. Changes since v3 1. Resolve build errors In previous patch set, the build errors prevented reviewers from applying the patch. So, in this patch, I tryed to fix the build errors but I hadn't the build test on all architectures except for x86 and ARM. 2. Modify descriptions for DocBook Descriptions not complying with the DocBook rule are modified, which was pointed out by Mauro. 3. Initialize reserved fields explicitly The reserved fields of v4l2_buffer are initialized by 0 explicitly when the vb2_buffer information is returned to userspace, which was pointed out by Hans. 4. Remove unnecessary type-cast According to Mauro's advice, the unnecessary type-cast are removed because it's better for the compiler - rather than human - to check those things. 5. Sperate the patch - not easy to review - into two patches In previous patch set, patch 5 was too difficult to review. So accoring to Hans' opinion, it separated the patch without any functional changes. Changes since v2 1. Remove v4l2 stuffs completely from vb2_buffer The v4l2 stuffs - v4l2_buf and v4l2_planes - are removed completely from struct vb2_buffer. New member variables - index, type, memory - are added to struct vb2_buffer, all of which can be used commonly. And bytesused, length, offset, userptr, fd, data_offset are added to struct vb2_plane for the same reason. So, we can manage video buffer by only using struct vb2_buffer. And, v4l2 stuffs - flags, field, timestamp, timecode, sequence - are defined as member variables of struct vb2_v4l2_buffer. 2. Create new header file for VB2 internal use videobuf2-internal.h is created, which is referred by videobuf2-core and videobuf2-v4l2. The header file contains dprintk() for debug, macro functions to invoke various callbacks, and vb2_core_* function prototypes referred by inside of videobuf2. 3. Remove buffer-specific callbacks as much as possible There were many callback functions to handle video buffer information in previous patch series. In this patch series, I try to remove these callbacks as much as possible without breaking the existing function flow. As a result, only four callbacks are remained - fill_user_buffer(), fill_vb2_buffer(), fill_vb2_timestamp() and is_last(). All ideas above are from Hans and it seems to be better and
[RFC PATCH v5 2/8] media: videobuf2: Restructure vb2_buffer (1/3)
Remove v4l2 stuff - v4l2_buf, v4l2_plane - from struct vb2_buffer. Add new member variables - bytesused, length, offset, userptr, fd, data_offset - to struct vb2_plane in order to cover all information of v4l2_plane. struct vb2_plane { unsigned intbytesused; unsigned intlength; union { unsigned intoffset; unsigned long userptr; int fd; } m; unsigned intdata_offset; } Replace v4l2_buf with new member variables - index, type, memory - which are common fields for buffer management. struct vb2_buffer { unsigned intindex; unsigned inttype; unsigned intmemory; unsigned intnum_planes; struct vb2_planeplanes[VIDEO_MAX_PLANES]; }; v4l2 specific fields - flags, field, timestamp, timecode, sequence - are moved to vb2_v4l2_buffer in videobuf2-v4l2.c struct vb2_v4l2_buffer { struct vb2_buffer vb2_buf; __u32 flags; __u32 field; struct timeval timestamp; struct v4l2_timecodetimecode; __u32 sequence; }; This patch includes only changes inside of the videobuf2. So, in practice, we need to fold this patch and following two patches when merging upstream, to avoid breaking git bisectability. Signed-off-by: Junghak SungSigned-off-by: Geunyoung Kim Acked-by: Seung-Woo Kim Acked-by: Inki Dae --- drivers/media/v4l2-core/videobuf2-core.c | 219 ++ include/media/videobuf2-core.h | 66 + include/media/videobuf2-v4l2.h | 28 3 files changed, 201 insertions(+), 112 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 9518ebd..8c456f7 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -53,7 +53,7 @@ module_param(debug, int, 0644); #define log_memop(vb, op) \ dprintk(2, "call_memop(%p, %d, %s)%s\n",\ - (vb)->vb2_queue, (vb)->v4l2_buf.index, #op, \ + (vb)->vb2_queue, (vb)->index, #op, \ (vb)->vb2_queue->mem_ops->op ? "" : " (nop)") #define call_memop(vb, op, args...)\ @@ -115,7 +115,7 @@ module_param(debug, int, 0644); #define log_vb_qop(vb, op, args...)\ dprintk(2, "call_vb_qop(%p, %d, %s)%s\n", \ - (vb)->vb2_queue, (vb)->v4l2_buf.index, #op, \ + (vb)->vb2_queue, (vb)->index, #op, \ (vb)->vb2_queue->ops->op ? "" : " (nop)") #define call_vb_qop(vb, op, args...) \ @@ -211,7 +211,7 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb) /* Associate allocator private data with this plane */ vb->planes[plane].mem_priv = mem_priv; - vb->v4l2_planes[plane].length = q->plane_sizes[plane]; + vb->planes[plane].length = q->plane_sizes[plane]; } return 0; @@ -235,8 +235,7 @@ static void __vb2_buf_mem_free(struct vb2_buffer *vb) for (plane = 0; plane < vb->num_planes; ++plane) { call_void_memop(vb, put, vb->planes[plane].mem_priv); vb->planes[plane].mem_priv = NULL; - dprintk(3, "freed plane %d of buffer %d\n", plane, - vb->v4l2_buf.index); + dprintk(3, "freed plane %d of buffer %d\n", plane, vb->index); } } @@ -269,7 +268,9 @@ static void __vb2_plane_dmabuf_put(struct vb2_buffer *vb, struct vb2_plane *p) call_void_memop(vb, detach_dmabuf, p->mem_priv); dma_buf_put(p->dbuf); - memset(p, 0, sizeof(*p)); + p->mem_priv = NULL; + p->dbuf = NULL; + p->dbuf_mapped = 0; } /** @@ -299,7 +300,7 @@ static void __setup_lengths(struct vb2_queue *q, unsigned int n) continue; for (plane = 0; plane < vb->num_planes; ++plane) - vb->v4l2_planes[plane].length = q->plane_sizes[plane]; + vb->planes[plane].length = q->plane_sizes[plane]; } } @@ -314,10 +315,10 @@ static void __setup_offsets(struct vb2_queue *q, unsigned int n) unsigned long off; if (q->num_buffers) { - struct v4l2_plane *p; + struct vb2_plane *p; vb = q->bufs[q->num_buffers - 1]; - p = >v4l2_planes[vb->num_planes - 1]; - off = PAGE_ALIGN(p->m.mem_offset +
Re: [Patch v2] media: v4l2-ctrls: Fix 64bit support in get_ctrl()
On Mon, Sep 21, 2015 at 11:03:21AM -0500, Benoit Parrot wrote: > When trying to use v4l2_ctrl_g_ctrl_int64() to retrieve a > V4L2_CTRL_TYPE_INTEGER64 type value the internal helper function > get_ctrl() would prematurely exits because for this control type > the 'is_int' flag is not set. This would result in v4l2_ctrl_g_ctrl_int64 > always returning 0. > Also v4l2_ctrl_g_ctrl_int64() is reading and returning the 32bit value > member instead of the 64bit version, so fixing that as well. > > This patch extend the condition check to allow V4L2_CTRL_TYPE_INTEGER64 > type to continue processing instead of exiting. > > Signed-off-by: Benoit ParrotThanks! Acked-by: Sakari Ailus -- Sakari Ailus e-mail: sakari.ai...@iki.fi XMPP: sai...@retiisi.org.uk -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3] [media] v4l: tegra: Add NVIDIA Tegra VI driver
On Mon, Sep 21, 2015 at 11:55:53AM -0700, Bryan Wu wrote: [...] > +static int tegra_csi_s_stream(struct v4l2_subdev *subdev, int enable) > +{ > + struct tegra_csi_device *csi = to_csi(subdev); > + struct tegra_channel *chan = subdev->host_priv; > + enum tegra_csi_port_num port_num = (chan->port & 1) ? PORT_B : PORT_A; > + struct tegra_csi_port *port = >ports[port_num]; > + int ret; > + > + if (enable) { [...] > + } else { > + u32 val = pp_read(port, TEGRA_CSI_PIXEL_PARSER_STATUS); > + dev_dbg(csi->dev, "TEGRA_CSI_PIXEL_PARSER_STATUS 0x%08x\n", > val); > + > + val = cil_read(port, TEGRA_CSI_CIL_STATUS); > + dev_dbg(csi->dev, "TEGRA_CSI_CIL_STATUS 0x%08x\n", val); > + > + val = cil_read(port, TEGRA_CSI_CILX_STATUS); > + dev_dbg(csi->dev, "TEGRA_CSI_CILX_STATUS 0x%08x\n", val); > + I was going to apply this and give it a spin, but then git am complained about trailing whitespace above... > +#ifdef DEBUG > + val = csi_read(csi, TEGRA_CSI_DEBUG_COUNTER_0); > + dev_err(>dev, "TEGRA_CSI_DEBUG_COUNTER_0 0x%08x\n", val); > +#endif > + > + pp_write(port, TEGRA_CSI_PIXEL_STREAM_PP_COMMAND, > + (0xF << CSI_PP_START_MARKER_FRAME_MAX_OFFSET) | > + CSI_PP_DISABLE); > + > + clk_disable_unprepare(csi->clk); > + } > + and here, ... > +static int tegra_csi_probe(struct platform_device *pdev) > +{ [...] > + for (i = 0; i < TEGRA_CSI_PORTS_NUM; i++) { > + /* Initialize the default format */ > + csi->ports[i].format.code = TEGRA_VF_DEF; > + csi->ports[i].format.field = V4L2_FIELD_NONE; > + csi->ports[i].format.colorspace = V4L2_COLORSPACE_SRGB; > + csi->ports[i].format.width = TEGRA_DEF_WIDTH; > + csi->ports[i].format.height = TEGRA_DEF_HEIGHT; > + > + /* Initialize port register bases */ > + csi->ports[i].pixel_parser = csi->iomem + > + (i & 1) * TEGRA_CSI_PORT_OFFSET; > + csi->ports[i].cil = csi->iomem + TEGRA_CSI_CIL_OFFSET + here and... > + (i & 1) * TEGRA_CSI_PORT_OFFSET; > + csi->ports[i].tpg = csi->iomem + TEGRA_CSI_TPG_OFFSET + here. Might be worth fixing those up if you'll respin anyway. Thierry signature.asc Description: PGP signature
Re: [PATCH 00/38] Fixes related to incorrect usage of unsigned types
On 09/22/2015 11:13 AM, Andrzej Hajda wrote: On 09/21/2015 03:42 PM, David Howells wrote: Andrzej Hajdawrote: Semantic patch finds comparisons of types: unsigned < 0 unsigned >= 0 The former is always false, the latter is always true. Such comparisons are useless, so theoretically they could be safely removed, but their presence quite often indicates bugs. Or someone has left them in because they don't matter and there's the possibility that the type being tested might be or become signed under some circumstances. If the comparison is useless, I'd expect the compiler to just discard it - for such cases your patch is pointless. If I have, for example: unsigned x; if (x == 0 || x > 27) give_a_range_error(); I will write this as: unsigned x; if (x <= 0 || x > 27) give_a_range_error(); because it that gives a way to handle x being changed to signed at some point in the future for no cost. In which case, your changing the <= to an == "because the < part of the case is useless" is arguably wrong. This is why I have not checked for such cases - I have skipped checks of type unsigned <= 0 exactly for the reasons above. However I have left two other checks as they seems to me more suspicious - they are always true or false. But as Dmitry and Andrew pointed out Linus have quite strong opinion against removing range checks in such cases as he finds it clearer. I think it applies to patches 29-36. I am not sure about patches 26-28,37. Dropped 30/38 and 31/38 from LED tree then. -- Best Regards, Jacek Anaszewski -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Driver private field for struct dmxdev_filter
Hello, I am working on a solution, where the dvb demuxer solution is partly based on LDVB demux framework. Due to some constraints posed by the lower layers of software stack, fops have been over-written. I have allocated driver private per filter structure which I want to use in conjuction with struct dmxdev_filter without modifying file->private_data. So, I would like to have a "void *priv" added to this structure. Thanks to share you view. Regards, Divneil -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RESEND PATCH] media: vb2: Fix vb2_dc_prepare do not correct sync data to device
Hi Hans, On Mon, 2015-09-21 at 15:13 +0200, Hans Verkuil wrote: > Hi Tiffany! > > On 21-09-15 14:26, Tiffany Lin wrote: > > vb2_dc_prepare use the number of SG entries dma_map_sg_attrs return. > > But in dma_sync_sg_for_device, it use lengths of each SG entries > > before dma_map_sg_attrs. dma_map_sg_attrs will concatenate > > SGs until dma length > dma seg bundary. sgt->nents will less than > > sgt->orig_nents. Using SG entries after dma_map_sg_attrs > > in vb2_dc_prepare will make some SGs are not sync to device. > > After add DMA_ATTR_SKIP_CPU_SYNC in vb2_dc_get_userptr to remove > > sync data to device twice. Device randomly get incorrect data because > > some SGs are not sync to device. Change to use number of SG entries > > before dma_map_sg_attrs in vb2_dc_prepare to prevent this issue. > > > > Signed-off-by: Tiffany Lin> > --- > > drivers/media/v4l2-core/videobuf2-dma-contig.c | 4 ++-- > > 1 file changed, 2 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c > > b/drivers/media/v4l2-core/videobuf2-dma-contig.c > > index 2397ceb..c5d00bd 100644 > > --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c > > +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c > > @@ -100,7 +100,7 @@ static void vb2_dc_prepare(void *buf_priv) > > if (!sgt || buf->db_attach) > > return; > > > > - dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); > > + dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->orig_nents, > > buf->dma_dir); > > } > > > > static void vb2_dc_finish(void *buf_priv) > > @@ -112,7 +112,7 @@ static void vb2_dc_finish(void *buf_priv) > > if (!sgt || buf->db_attach) > > return; > > > > - dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); > > + dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir); > > } > > I don't really understand it. I am assuming that this happens on an arm and > that > the dma_map_sg_attrs and dma_sync_sg_* functions used are arm_iommu_map_sg() > and > arm_iommu_sync_sg_* as implemented in arch/arm/mm/dma-mapping.c. > We are using __iommu_* implemented in "arch/arm64/mm/dma-mapping.c" in review patch http://lists.linuxfoundation.org/pipermail/iommu/2015-July/013898.html Without patch "[media] vb2: use dma_map_sg_attrs to prevent unnecessary sync", vb2 will sync data to device twice. One is from "dma_map_sg" in "vb2_dc_get_userptr", the other is from "dma_sync_sg_for_device" in "vb2_dc_prepare". dma_map_sg use orig_nents, and dma_sync_sg_for_device use nents." We do not run in 32bits mode, but check "arm_dma_sync_sg_for_device" in "arch/arm/mm/dma-mapping.c", ops->sync_single_for_device(dev, sg_dma_address(s), s->length, dir); It looks like has same issue. > Now, as I understand it (and my understanding may very well be flawed!) the > map_sg > function concatenates SG entries if possible, so it may return fewer entries. > But > the dma_sync_sg functions use those updated SG entries, so the full buffer > should > be covered by this. Using orig_nents will actually sync parts of the buffer > twice! > The first nents entries already cover the full buffer so any remaining > entries up > to orig_nents will just duplicate parts of the buffer. > I found that in __iommu_sync_sg_for_device, it use sg->length , do not cover full buffer. By adding log in " __iommu_sync_sg_for_device" without patch "[media] vb2: use dma_map_sg_attrs to prevent unnecessary sync", we could see total synced size are different between called from dma_map_sg and dma_sync_sg_for_device. __iommu_sync_sg_for_device called from dma_sync_sg_for_device got updated SG entries number but it use un-updated sg length. After using "DMA_ATTR_SKIP_CPU_SYNC" to skip sync in vb2_dc_get_userptr, we got some part of the buffer not sync. > So this patch makes no sense in the current code. > > If I understand your log text correctly this patch goes on top of Sakari > Ailus' vb2 > sync patch series. So if it wasn't needed before, but it is needed after his > patch > series, then the problem is in that patch series. > This patch goes on top of these two patchs https://www.mail-archive.com/linux-media%40vger.kernel.org/msg82143.html http://lists.linuxfoundation.org/pipermail/iommu/2015-July/013898.html > In any case, I need some help understanding this patch. > > And *if* this patch is correct, then the same thing should likely be done for > videobuf2-dma-sg.c. > Yes, if this patch correct, same thing should be done for videobuf2-dma-sg.c > Regards, > > Hans > > > > > /*/ > > -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH v5 0/8] Refactoring Videobuf2 for common use
Mauro asked if I could make a pull request for patches 1-4, but while compiling it I got these errors and warnings: In file included from /home/hans/work/build/media-git/include/linux/interrupt.h:5:0, from /home/hans/work/build/media-git/drivers/media/platform/davinci/vpif_display.c:18: /home/hans/work/build/media-git/drivers/media/platform/davinci/vpif_display.c: In function 'to_vpif_buffer': /home/hans/work/build/media-git/include/linux/kernel.h:811:48: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types] const typeof( ((type *)0)->member ) *__mptr = (ptr); \ ^ /home/hans/work/build/media-git/drivers/media/platform/davinci/vpif_display.c:58:9: note: in expansion of macro 'container_of' return container_of(vb, struct vpif_disp_buffer, vb); ^ /home/hans/work/build/media-git/drivers/media/platform/davinci/vpif_display.c: In function 'vpif_buffer_prepare': /home/hans/work/build/media-git/drivers/media/platform/davinci/vpif_display.c:80:4: error: 'struct vb2_buffer' has no member named 'field' vb->field = common->fmt.fmt.pix.field; ^ /home/hans/work/build/media-git/drivers/media/platform/davinci/vpif_display.c: In function 'vpif_start_streaming': /home/hans/work/build/media-git/drivers/media/platform/davinci/vpif_display.c:200:39: warning: passing argument 1 of 'vb2_dma_contig_plane_dma_addr' from incompatible pointer type [-Wincompatible-pointer-types] addr = vb2_dma_contig_plane_dma_addr(>cur_frm->vb, 0); ^ In file included from /home/hans/work/build/media-git/drivers/media/platform/davinci/vpif_display.h:20:0, from /home/hans/work/build/media-git/drivers/media/platform/davinci/vpif_display.c:26: /home/hans/work/build/media-git/include/media/videobuf2-dma-contig.h:20:1: note: expected 'struct vb2_buffer *' but argument is of type 'struct vb2_v4l2_buffer *' vb2_dma_contig_plane_dma_addr(struct vb2_buffer *vb, unsigned int plane_no) ^ /home/hans/work/build/media-git/drivers/media/platform/davinci/vpif_display.c: In function 'process_progressive_mode': /home/hans/work/build/media-git/drivers/media/platform/davinci/vpif_display.c:311:39: warning: passing argument 1 of 'vb2_dma_contig_plane_dma_addr' from incompatible pointer type [-Wincompatible-pointer-types] addr = vb2_dma_contig_plane_dma_addr(>next_frm->vb, 0); ^ In file included from /home/hans/work/build/media-git/drivers/media/platform/davinci/vpif_display.h:20:0, from /home/hans/work/build/media-git/drivers/media/platform/davinci/vpif_display.c:26: /home/hans/work/build/media-git/include/media/videobuf2-dma-contig.h:20:1: note: expected 'struct vb2_buffer *' but argument is of type 'struct vb2_v4l2_buffer *' vb2_dma_contig_plane_dma_addr(struct vb2_buffer *vb, unsigned int plane_no) ^ /home/hans/work/build/media-git/scripts/Makefile.build:264: recipe for target 'drivers/media/platform/davinci/vpif_display.o' failed In file included from /home/hans/work/build/media-git/drivers/media/pci/sta2x11/sta2x11_vip.c:29:0: /home/hans/work/build/media-git/drivers/media/pci/sta2x11/sta2x11_vip.c: In function 'to_vip_buffer': /home/hans/work/build/media-git/include/linux/kernel.h:811:48: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types] const typeof( ((type *)0)->member ) *__mptr = (ptr); \ ^ /home/hans/work/build/media-git/drivers/media/pci/sta2x11/sta2x11_vip.c:97:9: note: in expansion of macro 'container_of' return container_of(vb2, struct vip_buffer, vb); ^ Please fix! Thanks, Hans On 22-09-15 15:30, Junghak Sung wrote: > Hello everybody, > > This is the 5th round for refactoring Videobuf2(a.k.a VB2). > The purpose of this patch series is to separate existing VB2 framework > into core part and V4L2 specific part. So that not only V4L2 but also other > frameworks can use them to manage buffer and utilize queue. > > Why do we try to make the VB2 framework to be common? > > As you may know, current DVB framework uses ringbuffer mechanism to demux > MPEG-2 TS data and pass it to userspace. However, this mechanism requires > extra memory copy because DVB framework provides only read() system call for > application - read() system call copies the kernel data to user-space buffer. > So if we can use VB2 framework which supports streaming I/O and buffer > sharing mechanism, then we could enhance existing DVB framework by removing > the extra memory copy - with VB2 framework, application can access the kernel > data directly through mmap system call. > > We have a plan for this work as follows: > 1. Separate existing VB2 framework into three parts - VB2 common, VB2-v4l2. >Of course, this change will not affect other v4l2-based >device drivers. This patch series corresponds to this step. > >
Re: [RFC PATCH v5 6/8] media: videobuf2: Replace v4l2-specific data with vb2 data.
On 22-09-15 15:30, Junghak Sung wrote: > Simple changes that replace v4l2-specific data with vb2 data > in videobuf2-core. > > enum v4l2_buf_type --> int > enum v4l2_memory --> enum vb2_memory > VIDEO_MAX_FRAME --> VB2_MAX_FRAME > VIDEO_MAX_PLANES --> VB2_MAX_PLANES > struct v4l2_fh *owner --> void *owner > V4L2_TYPE_IS_MULTIPLANAR() --> is_multiplanar > V4L2_TYPE_IS_OUTPUT() --> is_output > > Signed-off-by: Junghak Sung> Signed-off-by: Geunyoung Kim > Acked-by: Seung-Woo Kim > Acked-by: Inki Dae Acked-by: Hans Verkuil Thanks! Hans -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC v2 4/4] vivid: add support for reduced frame rate in video capture
With this patch, vivid capture thread can now generate a video with frame rate reduced by a factor of 1000 / 1001. This option can be selected using a control Reduced Framerate from gui. Cc: Hans VerkuilSigned-off-by: Prashant Laddha --- drivers/media/platform/vivid/vivid-vid-cap.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c index ed0b878..74ba98f 100644 --- a/drivers/media/platform/vivid/vivid-vid-cap.c +++ b/drivers/media/platform/vivid/vivid-vid-cap.c @@ -401,6 +401,7 @@ void vivid_update_format_cap(struct vivid_dev *dev, bool keep_controls) { struct v4l2_bt_timings *bt = >dv_timings_cap.bt; unsigned size; + u64 pixelclock; switch (dev->input_type[dev->input]) { case WEBCAM: @@ -430,8 +431,15 @@ void vivid_update_format_cap(struct vivid_dev *dev, bool keep_controls) dev->src_rect.width = bt->width; dev->src_rect.height = bt->height; size = V4L2_DV_BT_FRAME_WIDTH(bt) * V4L2_DV_BT_FRAME_HEIGHT(bt); + if (dev->reduced_fps && can_reduce_fps(bt)) { + pixelclock = div_u64(bt->pixelclock * 1000, 1001); + bt->flags |= V4L2_DV_FL_REDUCED_FPS; + } else { + pixelclock = bt->pixelclock; + bt->flags &= ~V4L2_DV_FL_REDUCED_FPS; + } dev->timeperframe_vid_cap = (struct v4l2_fract) { - size / 100, (u32)bt->pixelclock / 100 + size / 100, (u32)pixelclock / 100 }; if (bt->interlaced) dev->field_cap = V4L2_FIELD_ALTERNATE; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC v2 3/4] vivid-capture: add control for reduced frame rate
A boolean control Reduced Framerate is added to vivid controls for controlling the reduced fps option for vivid capture from gui. Cc: Hans VerkuilSigned-off-by: Prashant Laddha --- drivers/media/platform/vivid/vivid-core.h | 1 + drivers/media/platform/vivid/vivid-ctrls.c | 15 +++ 2 files changed, 16 insertions(+) diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h index c72349c..4a2c8b7 100644 --- a/drivers/media/platform/vivid/vivid-core.h +++ b/drivers/media/platform/vivid/vivid-core.h @@ -263,6 +263,7 @@ struct vivid_dev { boolvflip; boolvbi_cap_interlaced; boolloop_video; + boolreduced_fps; /* Framebuffer */ unsigned long video_pbase; diff --git a/drivers/media/platform/vivid/vivid-ctrls.c b/drivers/media/platform/vivid/vivid-ctrls.c index 339c8b7..30d472a 100644 --- a/drivers/media/platform/vivid/vivid-ctrls.c +++ b/drivers/media/platform/vivid/vivid-ctrls.c @@ -78,6 +78,7 @@ #define VIVID_CID_TIME_WRAP(VIVID_CID_VIVID_BASE + 39) #define VIVID_CID_MAX_EDID_BLOCKS (VIVID_CID_VIVID_BASE + 40) #define VIVID_CID_PERCENTAGE_FILL (VIVID_CID_VIVID_BASE + 41) +#define VIVID_CID_REDUCED_FPS (VIVID_CID_VIVID_BASE + 42) #define VIVID_CID_STD_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 60) #define VIVID_CID_STANDARD (VIVID_CID_VIVID_BASE + 61) @@ -422,6 +423,10 @@ static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl) dev->sensor_vflip = ctrl->val; tpg_s_vflip(>tpg, dev->sensor_vflip ^ dev->vflip); break; + case VIVID_CID_REDUCED_FPS: + dev->reduced_fps = ctrl->val; + vivid_update_format_cap(dev, true); + break; case VIVID_CID_HAS_CROP_CAP: dev->has_crop_cap = ctrl->val; vivid_update_format_cap(dev, true); @@ -599,6 +604,15 @@ static const struct v4l2_ctrl_config vivid_ctrl_vflip = { .step = 1, }; +static const struct v4l2_ctrl_config vivid_ctrl_reduced_fps = { + .ops = _vid_cap_ctrl_ops, + .id = VIVID_CID_REDUCED_FPS, + .name = "Reduced Framerate", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .max = 1, + .step = 1, +}; + static const struct v4l2_ctrl_config vivid_ctrl_has_crop_cap = { .ops = _vid_cap_ctrl_ops, .id = VIVID_CID_HAS_CROP_CAP, @@ -1379,6 +1393,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, v4l2_ctrl_new_custom(hdl_vid_cap, _ctrl_vflip, NULL); v4l2_ctrl_new_custom(hdl_vid_cap, _ctrl_insert_sav, NULL); v4l2_ctrl_new_custom(hdl_vid_cap, _ctrl_insert_eav, NULL); + v4l2_ctrl_new_custom(hdl_vid_cap, _ctrl_reduced_fps, NULL); if (show_ccs_cap) { dev->ctrl_has_crop_cap = v4l2_ctrl_new_custom(hdl_vid_cap, _ctrl_has_crop_cap, NULL); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC v2 2/4] vivid: add support for reduced fps in video out
If reduced fps flag is set then check if other necessary conditions are true for the given bt timing. If yes, then reduce the frame rate. For vivid transmitter, timeperframe_vid_out controls the frame rate. Adjusting the timeperframe_vid_out by scaling down pixel clock by factor of 1000 / 1001. Cc: Hans VerkuilSigned-off-by: Prashant Laddha --- drivers/media/platform/vivid/vivid-vid-out.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/vivid/vivid-vid-out.c b/drivers/media/platform/vivid/vivid-vid-out.c index c404e27..e860347 100644 --- a/drivers/media/platform/vivid/vivid-vid-out.c +++ b/drivers/media/platform/vivid/vivid-vid-out.c @@ -220,6 +220,7 @@ void vivid_update_format_out(struct vivid_dev *dev) { struct v4l2_bt_timings *bt = >dv_timings_out.bt; unsigned size, p; + u64 pixelclock; switch (dev->output_type[dev->output]) { case SVID: @@ -241,8 +242,14 @@ void vivid_update_format_out(struct vivid_dev *dev) dev->sink_rect.width = bt->width; dev->sink_rect.height = bt->height; size = V4L2_DV_BT_FRAME_WIDTH(bt) * V4L2_DV_BT_FRAME_HEIGHT(bt); + + if (can_reduce_fps(bt) && (bt->flags & V4L2_DV_FL_REDUCED_FPS)) + pixelclock = div_u64(bt->pixelclock * 1000, 1001); + else + pixelclock = bt->pixelclock; + dev->timeperframe_vid_out = (struct v4l2_fract) { - size / 100, (u32)bt->pixelclock / 100 + size / 100, (u32)pixelclock / 100 }; if (bt->interlaced) dev->field_out = V4L2_FIELD_ALTERNATE; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH v5 8/8] media: videobuf2: Move v4l2-specific stuff to videobuf2-v4l2
Hi Junghak, A few small comments... On 22-09-15 15:30, Junghak Sung wrote: > Move v4l2-specific stuff from videobu2-core to videobuf2-v4l2 > without doing any functional changes. I feel the introduction of v4l2_buf_ops falls under functional changes. Is it possible to do that change in a separate patch before this one? > > Signed-off-by: Junghak Sung> Signed-off-by: Geunyoung Kim > Acked-by: Seung-Woo Kim > Acked-by: Inki Dae > --- > drivers/media/v4l2-core/videobuf2-core.c | 1872 > +- > drivers/media/v4l2-core/videobuf2-internal.h | 161 +++ > drivers/media/v4l2-core/videobuf2-v4l2.c | 1678 +++ > include/media/videobuf2-core.h | 118 +- > include/media/videobuf2-dvb.h|8 +- > include/media/videobuf2-v4l2.h | 96 ++ > 6 files changed, 2009 insertions(+), 1924 deletions(-) > create mode 100644 drivers/media/v4l2-core/videobuf2-internal.h > > diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c > b/drivers/media/v4l2-core/videobuf2-v4l2.c > index 2f2b738..8ca07bb 100644 > --- a/drivers/media/v4l2-core/videobuf2-v4l2.c > +++ b/drivers/media/v4l2-core/videobuf2-v4l2.c > + > +const struct vb2_buf_ops v4l2_buf_ops = { Shouldn't this be static? > + .fill_user_buffer = __fill_v4l2_buffer, > + .fill_vb2_buffer= __fill_vb2_buffer, > + .set_timestamp = __set_timestamp, > +}; Regards, Hans -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/3] Documentation: DT bindings: add VI and CSI bindings
On Mon, Sep 21, 2015 at 11:55:55AM -0700, Bryan Wu wrote: > Signed-off-by: Bryan Wu> --- > .../bindings/gpu/nvidia,tegra20-host1x.txt | 211 > - > 1 file changed, 205 insertions(+), 6 deletions(-) > > diff --git a/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt > b/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt [...] > + - ports: 2 ports presenting 2 channels of CSI. Each port has 2 endpoints: > +one connects to sensor device tree node as input and the other one > connects > +to VI endpoint. It looks to me like we'll only need the first of these endpoints. The connection to the VI is implied. Even more so if the CSI nodes are moved into the VI node as children (which I really think they should be). Thierry signature.asc Description: PGP signature
Re: [PATCH 2/3] ARM64: add tegra-vi support in T210 device-tree
Hi Bryan, This patchset really needs to be Cc'ed to linux-te...@vger.kernel.org, it's becoming impossible to track it otherwise. On Mon, Sep 21, 2015 at 11:55:54AM -0700, Bryan Wu wrote: [...] > diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi > b/arch/arm64/boot/dts/nvidia/tegra210.dtsi > index 1168bcd..3f6501f 100644 > --- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi > +++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi > @@ -109,9 +109,181 @@ > > vi@0,5408 { > compatible = "nvidia,tegra210-vi"; > - reg = <0x0 0x5408 0x0 0x0004>; > + reg = <0x0 0x5408 0x0 0x800>; This now no longer matches the address map in the TRM. > interrupts = ; > status = "disabled"; > + clocks = <_car TEGRA210_CLK_VI>, > + <_car TEGRA210_CLK_CSI>, > + <_car TEGRA210_CLK_PLL_C>; > + clock-names = "vi", "csi", "parent"; > + resets = <_car 20>; > + reset-names = "vi"; > + > + power-domains = < TEGRA_POWERGATE_VENC>; As an aside, this will currently prevent the driver from probing because the generic power domain code will return -EPROBE_DEFER if this property is encountered but the corresponding driver (for the PMC) hasn't registered any power domains yet. So until the PMC driver changes have been merged we can't add these power-domains properties. That's not something for you to worry about, though. I'll make sure to strip this out if it happens to get merged before the PMC driver changes and add it back it afterwards. > + > + iommus = < TEGRA_SWGROUP_VI>; > + > + ports { > + #address-cells = <1>; > + #size-cells = <0>; > + > + port@0 { > + reg = <0>; > + > + vi_in0: endpoint { > + remote-endpoint = <_out0>; > + }; > + }; > + port@1 { > + reg = <1>; > + > + vi_in1: endpoint { > + remote-endpoint = <_out1>; > + }; > + }; > + port@2 { > + reg = <2>; > + > + vi_in2: endpoint { > + remote-endpoint = <_out2>; > + }; > + }; > + port@3 { > + reg = <3>; > + > + vi_in3: endpoint { > + remote-endpoint = <_out3>; > + }; > + }; > + port@4 { > + reg = <4>; > + > + vi_in4: endpoint { > + remote-endpoint = <_out4>; > + }; > + }; > + port@5 { > + reg = <5>; > + > + vi_in5: endpoint { > + remote-endpoint = <_out5>; > + }; > + }; > + > + }; > + }; > + > + csi@0,54080838 { I think this and its siblings should be children of the vi node. They are within the same memory aperture according to the TRM and the fact that the VI needs to reference the "CSI" clock indicates that the coupling is tighter than this current DT layout makes it out to be. > + compatible = "nvidia,tegra210-csi"; > + reg = <0x0 0x54080838 0x0 0x700>; Some of the internal register documentation indicates that the register range actually starts at an offset of 0x800, it just so happens that we don't use any of the registers from 0x800 to 0x837. So I think this needs to be adapted. > + clocks = <_car TEGRA210_CLK_CILAB>; > + clock-names = "cil"; > + > + ports { > + #address-cells = <1>; > + #size-cells = <0>; > + > + port@0 { > + reg = <0>; > + #address-cells = <1>; > + #size-cells = <0>; > + csi_in0:
Re: [RESEND PATCH] media: vb2: Fix vb2_dc_prepare do not correct sync data to device
Hi Tiffany, On Tue, Sep 22, 2015 at 06:19:25PM +0800, tiffany lin wrote: > Hi Hans, > > On Mon, 2015-09-21 at 15:13 +0200, Hans Verkuil wrote: > > Hi Tiffany! > > > > On 21-09-15 14:26, Tiffany Lin wrote: > > > vb2_dc_prepare use the number of SG entries dma_map_sg_attrs return. > > > But in dma_sync_sg_for_device, it use lengths of each SG entries > > > before dma_map_sg_attrs. dma_map_sg_attrs will concatenate > > > SGs until dma length > dma seg bundary. sgt->nents will less than > > > sgt->orig_nents. Using SG entries after dma_map_sg_attrs > > > in vb2_dc_prepare will make some SGs are not sync to device. > > > After add DMA_ATTR_SKIP_CPU_SYNC in vb2_dc_get_userptr to remove > > > sync data to device twice. Device randomly get incorrect data because > > > some SGs are not sync to device. Change to use number of SG entries > > > before dma_map_sg_attrs in vb2_dc_prepare to prevent this issue. > > > > > > Signed-off-by: Tiffany Lin> > > --- > > > drivers/media/v4l2-core/videobuf2-dma-contig.c | 4 ++-- > > > 1 file changed, 2 insertions(+), 2 deletions(-) > > > > > > diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c > > > b/drivers/media/v4l2-core/videobuf2-dma-contig.c > > > index 2397ceb..c5d00bd 100644 > > > --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c > > > +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c > > > @@ -100,7 +100,7 @@ static void vb2_dc_prepare(void *buf_priv) > > > if (!sgt || buf->db_attach) > > > return; > > > > > > - dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); > > > + dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->orig_nents, > > > buf->dma_dir); > > > } > > > > > > static void vb2_dc_finish(void *buf_priv) > > > @@ -112,7 +112,7 @@ static void vb2_dc_finish(void *buf_priv) > > > if (!sgt || buf->db_attach) > > > return; > > > > > > - dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); > > > + dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir); > > > } > > > > I don't really understand it. I am assuming that this happens on an arm and > > that > > the dma_map_sg_attrs and dma_sync_sg_* functions used are > > arm_iommu_map_sg() and > > arm_iommu_sync_sg_* as implemented in arch/arm/mm/dma-mapping.c. > > > > We are using __iommu_* implemented in "arch/arm64/mm/dma-mapping.c" in > review patch > http://lists.linuxfoundation.org/pipermail/iommu/2015-July/013898.html > Without patch "[media] vb2: use dma_map_sg_attrs to prevent unnecessary > sync", vb2 will sync data to device twice. > One is from "dma_map_sg" in "vb2_dc_get_userptr", the other is from > "dma_sync_sg_for_device" in "vb2_dc_prepare". dma_map_sg use orig_nents, > and dma_sync_sg_for_device use nents." > > We do not run in 32bits mode, but check "arm_dma_sync_sg_for_device" in > "arch/arm/mm/dma-mapping.c", > ops->sync_single_for_device(dev, sg_dma_address(s), s->length, dir); > It looks like has same issue. > > > Now, as I understand it (and my understanding may very well be flawed!) the > > map_sg > > function concatenates SG entries if possible, so it may return fewer > > entries. But > > the dma_sync_sg functions use those updated SG entries, so the full buffer > > should > > be covered by this. Using orig_nents will actually sync parts of the buffer > > twice! > > The first nents entries already cover the full buffer so any remaining > > entries up > > to orig_nents will just duplicate parts of the buffer. > > > I found that in __iommu_sync_sg_for_device, it use sg->length , do not > cover full buffer. > By adding log in " __iommu_sync_sg_for_device" without patch "[media] > vb2: use dma_map_sg_attrs to prevent unnecessary sync", we could see > total synced size are different between called from dma_map_sg and > dma_sync_sg_for_device. I had the same question Hans did, but I still fail to understand where in the code things are going wrong the way you described at the moment --- after dma_map_sg() there are nents entries in the scatterlist. But. sg_dma_len() should be used instead of the length field to get the size of the entry. If something is wrong, then it's this AFAICT. Could you try whether changing this fixes it? > __iommu_sync_sg_for_device called from dma_sync_sg_for_device got > updated SG entries number but it use un-updated sg length. > After using "DMA_ATTR_SKIP_CPU_SYNC" to skip sync in vb2_dc_get_userptr, > we got some part of the buffer not sync. > > > So this patch makes no sense in the current code. > > > > If I understand your log text correctly this patch goes on top of Sakari > > Ailus' vb2 > > sync patch series. So if it wasn't needed before, but it is needed after > > his patch > > series, then the problem is in that patch series. > > > This patch goes on top of these two patchs > https://www.mail-archive.com/linux-media%40vger.kernel.org/msg82143.html This patch has been merged long time ago. >
Re: [RFC 0/9] Unrestricted media entity ID range support
Em Sun, 20 Sep 2015 10:26:09 +0300 Sakari Ailusescreveu: > Hi Mauro, > > Mauro Carvalho Chehab wrote: > > Hi Sakari, > > > > On Fri, 11 Sep 2015 13:09:03 +0300 > > Sakari Ailus wrote: > > > >> Hi all, > >> > >> This patchset adds an API for managing entity enumerations, i.e. > >> storing a bit of information per entity. The entity ID is no longer > >> limited to small integers (e.g. 31 or 63), but > >> MEDIA_ENTITY_MAX_LOW_ID. The drivers are also converted to use that > >> instead of a fixed number. > >> > >> If the number of entities in a real use case grows beyond the > >> capabilities of the approach, the algorithm may be changed. But most > >> importantly, the API is used to perform the same operation everywhere > >> it's done. > >> > >> I'm sending this for review only, the code itself is untested. > >> > >> I haven't entirely made up my mind on the fourth patch. It could be > >> dropped, as it uses the API for a somewhat different purpose. > >> > > > > Sorry for not reviewing this earlier, but I'm traveling this week to > > China, and I was having some troubles with the Internet. Btw, I don't > > have my notebook here (just a chromebook without the media tree). > > So, please consider this as just a preliminary review. > > > > I won't be comment this series patch by patch, because it is really > > painful to do it while here with this Internet. > > > > Also, I want to discuss the patch series as a hole. > > > > From what we've agreed last week, we won't be using a separate ID > > range for the entity ID, but this patch series is actually adding > > it, and, IMHO, using a confusing nomenclature: instead of calling the > > entity ID range as "entity_id" at the media_device struct, you're > > now calling it "low_id". That sounds confusing to me. If you think > > we should keep a separate range for entities, calling it as > > "entity_id" is clearer. > > It's *not* the entity ID. It's a number used internally to keep track of > the entities, and only used for this purpose, nothing else. If you look > at the patch, the number of places where low_id is used is very limited. > Individual drivers do not and must not access the low_id field. > > The underlying algorithm for keeping track of entities does not change, > but that could be changed later on without affecting the users of the > alrogithm. --- See patch 3. > > There are two main reasons for this: > > 1. No need to implement a new algorithm which would be less efficient > but could cope in cases we do not have yet; this can be done later on, > as patch 3 adds an API to access the information without making > assumptions on the implementation. If this is an internal number used only by the graph traversal algorithm, then the implementation doesn't seem correct. I mean: such number should be generated internally when starting the graph traversal algorithm, and it would be better to store such graph-traversal internal algorithm data on a separate struct. > 2. It does solve the problem. The graph object IDs of the entities can > be large without adversely affecting the functionality of existing drivers. Right now, with just those 9 patches, it doesn't ;) I mean: if I apply your patches after the MC next gen ones and try to use the graph traversal, it will do the wrong thing for hybrid TV cards, as the number of entities there are more than 64. Ok, easy to fix after this series by just changing the value of MEDIA_ENTITY_MAX_LOW_ID, but this will only work while we don't implement dynamic support. > > > > Also, you said at the low_id comment that if an entity is > > unregistered and then re-registered, it would preserve the same > > I never claimed that, and the patchset does not implement that either. That's what I understood from this comment: Rename the macro as it no longer is a maximum ID that an entity can have, but a low ID which is used for internal purposes of enumeration. This is the maximum number of concurrent entities that may exist in a media device. If this is the "max number of concurrent entities", you need to reassign those numbers when entities are removed. If this is not what you're meaning, then fix the patch description to let it clearer. I guess then that "low ID" is actually an upper bound for that graph-traversal only control number. We should really not use the word "ID" here, as this is not an ID. it is just some index/control number that will be granted to be below some upper bound. > If an entity is unregistered and registered again, from the MC point of > view it is not the same entity. We do not keep track of entities that > are not registered with MC, do we? > > > entity ID. That doesn't seem easy to implement, as we would need > > to track those previously-used ID. On the other hand, if we just > > re-use a previously released ID for some other entity, this can > > be a problem, as userspace may
Re: [PATCH 3/3] Documentation: DT bindings: add VI and CSI bindings
On Mon, Sep 21, 2015 at 11:55:55AM -0700, Bryan Wu wrote: > Signed-off-by: Bryan Wu> --- > .../bindings/gpu/nvidia,tegra20-host1x.txt | 211 > - > 1 file changed, 205 insertions(+), 6 deletions(-) Also you probably want to include devicet...@vger.kernel.org on the binding patch to give people the chance to review. Thierry signature.asc Description: PGP signature
[RFC v2 1/4] v4l2-dv-timings: add condition checks for reduced fps
Added a helper function to check necessary conditions required for reduced fps. The reduced fps is supported for CVT and CEA861 timings. CVT supports reduced fps only if reduced blanking v2 (indicated by vsync = 8) is true. Whereas CEA861 supports reduced fps if V4L2_DV_FL_CAN_REDUCE_FPS flag is true. Cc: Hans VerkuilSigned-off-by: Prashant Laddha --- drivers/media/v4l2-core/v4l2-dv-timings.c | 5 + include/media/v4l2-dv-timings.h | 21 + 2 files changed, 26 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c index 6a83d61..d8e62f6 100644 --- a/drivers/media/v4l2-core/v4l2-dv-timings.c +++ b/drivers/media/v4l2-core/v4l2-dv-timings.c @@ -210,7 +210,12 @@ bool v4l2_find_dv_timings_cap(struct v4l2_dv_timings *t, fnc, fnc_handle) && v4l2_match_dv_timings(t, v4l2_dv_timings_presets + i, pclock_delta)) { + u32 flags = t->bt.flags & V4L2_DV_FL_REDUCED_FPS; + *t = v4l2_dv_timings_presets[i]; + if (can_reduce_fps(>bt)) + t->bt.flags |= flags; + return true; } } diff --git a/include/media/v4l2-dv-timings.h b/include/media/v4l2-dv-timings.h index b6130b5..49c2328 100644 --- a/include/media/v4l2-dv-timings.h +++ b/include/media/v4l2-dv-timings.h @@ -183,4 +183,25 @@ bool v4l2_detect_gtf(unsigned frame_height, unsigned hfreq, unsigned vsync, */ struct v4l2_fract v4l2_calc_aspect_ratio(u8 hor_landscape, u8 vert_portrait); +/* + * reduce_fps - check if conditions for reduced fps are true. + * bt - v4l2 timing structure + * For different timings reduced fps is allowed if following conditions + * are met - + * For CVT timings: if reduced blanking v2 (vsync == 8) is true. + * For CEA861 timings: if V4L2_DV_FL_CAN_REDUCE_FPS flag is true. + */ +static inline bool can_reduce_fps(struct v4l2_bt_timings *bt) +{ + if ((bt->standards & V4L2_DV_BT_STD_CVT) && (bt->vsync == 8)) + return true; + + if ((bt->standards & V4L2_DV_BT_STD_CEA861) && + (bt->flags & V4L2_DV_FL_CAN_REDUCE_FPS)) + return true; + + return false; +} + + #endif -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC v2 0/4] vivid: reduced fps support
Hi, Please find RFC v2 for adding reduced fps support in vivid video transmit and receive. Changes since v1: 1. Added helper function to check if all necessary conditions for reduced fps are met. 2. This function can now common for vivid-vid-out and vivid-vid-cap 3. Same helper function can also be used by v4l2-dv-timings before setting the flag for reduced fps. 4. Incorporated other review comments. Also split patches into smaller and well separated changes. Please review and share your comments. Regards, Prashant Prashant Laddha (4): v4l2-dv-timings: add condition checks for reduced fps vivid: add support for reduced fps in video out vivid-capture: add control for reduced frame rate vivid: add support for reduced frame rate in video capture drivers/media/platform/vivid/vivid-core.h| 1 + drivers/media/platform/vivid/vivid-ctrls.c | 15 +++ drivers/media/platform/vivid/vivid-vid-cap.c | 10 +- drivers/media/platform/vivid/vivid-vid-out.c | 9 - drivers/media/v4l2-core/v4l2-dv-timings.c| 5 + include/media/v4l2-dv-timings.h | 21 + 6 files changed, 59 insertions(+), 2 deletions(-) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH v5 7/8] media: videobuf2: Prepare to divide videobuf2
Hi Junghak, This looks pretty good! I have a few small comments below, but overall it is much improved. On 22-09-15 15:30, Junghak Sung wrote: > Prepare to divide videobuf2 > - Separate vb2 trace events from v4l2 trace event. > - Make wrapper functions that will move to v4l2-side > - Make vb2_core_* functions that remain in vb2 core side > - Rename internal functions as vb2_* > > Signed-off-by: Junghak Sung> Signed-off-by: Geunyoung Kim > Acked-by: Seung-Woo Kim > Acked-by: Inki Dae > --- > drivers/media/v4l2-core/Makefile |2 +- > drivers/media/v4l2-core/v4l2-trace.c |8 +- > drivers/media/v4l2-core/vb2-trace.c |9 + > drivers/media/v4l2-core/videobuf2-core.c | 556 > -- > include/trace/events/v4l2.h | 28 +- > include/trace/events/vb2.h | 65 > 6 files changed, 457 insertions(+), 211 deletions(-) > create mode 100644 drivers/media/v4l2-core/vb2-trace.c > create mode 100644 include/trace/events/vb2.h > > diff --git a/drivers/media/v4l2-core/Makefile > b/drivers/media/v4l2-core/Makefile > index ad07401..1dc8bba 100644 > --- a/drivers/media/v4l2-core/Makefile > +++ b/drivers/media/v4l2-core/Makefile > @@ -14,7 +14,7 @@ ifeq ($(CONFIG_OF),y) >videodev-objs += v4l2-of.o > endif > ifeq ($(CONFIG_TRACEPOINTS),y) > - videodev-objs += v4l2-trace.o > + videodev-objs += vb2-trace.o v4l2-trace.o > endif > > obj-$(CONFIG_VIDEO_V4L2) += videodev.o > diff --git a/drivers/media/v4l2-core/v4l2-trace.c > b/drivers/media/v4l2-core/v4l2-trace.c > index 4004814..7416010 100644 > --- a/drivers/media/v4l2-core/v4l2-trace.c > +++ b/drivers/media/v4l2-core/v4l2-trace.c > @@ -5,7 +5,7 @@ > #define CREATE_TRACE_POINTS > #include > > -EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_buf_done); > -EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_buf_queue); > -EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_dqbuf); > -EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_qbuf); > +EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_v4l2_buf_done); > +EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_v4l2_buf_queue); > +EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_v4l2_dqbuf); > +EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_v4l2_qbuf); > diff --git a/drivers/media/v4l2-core/vb2-trace.c > b/drivers/media/v4l2-core/vb2-trace.c > new file mode 100644 > index 000..61e74f5 > --- /dev/null > +++ b/drivers/media/v4l2-core/vb2-trace.c > @@ -0,0 +1,9 @@ > +#include > + > +#define CREATE_TRACE_POINTS > +#include > + > +EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_buf_done); > +EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_buf_queue); > +EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_dqbuf); > +EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_qbuf); > diff --git a/drivers/media/v4l2-core/videobuf2-core.c > b/drivers/media/v4l2-core/videobuf2-core.c > index 32fa425..380536d 100644 > --- a/drivers/media/v4l2-core/videobuf2-core.c > +++ b/drivers/media/v4l2-core/videobuf2-core.c > @@ -30,7 +30,7 @@ > #include > #include > > -#include > +#include > > static int debug; > module_param(debug, int, 0644); > @@ -612,10 +612,10 @@ static int __verify_length(struct vb2_buffer *vb, const > struct v4l2_buffer *b) > } > > /** > - * __buffer_in_use() - return true if the buffer is in use and > + * vb2_buffer_in_use() - return true if the buffer is in use and > * the queue cannot be freed (by the means of REQBUFS(0)) call > */ > -static bool __buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb) > +static bool vb2_buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb) > { > unsigned int plane; > for (plane = 0; plane < vb->num_planes; ++plane) { > @@ -640,7 +640,7 @@ static bool __buffers_in_use(struct vb2_queue *q) > { > unsigned int buffer; > for (buffer = 0; buffer < q->num_buffers; ++buffer) { > - if (__buffer_in_use(q, q->bufs[buffer])) > + if (vb2_buffer_in_use(q, q->bufs[buffer])) > return true; > } > return false; > @@ -650,8 +650,9 @@ static bool __buffers_in_use(struct vb2_queue *q) > * __fill_v4l2_buffer() - fill in a struct v4l2_buffer with information to be > * returned to userspace > */ > -static void __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) > +static int __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb) Why use a void * here? Wouldn't a struct vb2_buffer pointer be better? That way it all remains type-safe. Ditto elsewhere in this patch, of course. > { > + struct v4l2_buffer *b = pb; > struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); > struct vb2_queue *q = vb->vb2_queue; > unsigned int plane; > @@ -742,8 +743,28 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, > struct v4l2_buffer *b) > break; > } > > - if (__buffer_in_use(q, vb)) > + if (vb2_buffer_in_use(q, vb)) > b->flags |= V4L2_BUF_FLAG_MAPPED; > + > + return 0; > +} > + > +/** > + * vb2_core_querybuf() - query
Re: [RESEND PATCH] media: vb2: Fix vb2_dc_prepare do not correct sync data to device
Hi Hans, On 21/09/15 14:13, Hans Verkuil wrote: Hi Tiffany! On 21-09-15 14:26, Tiffany Lin wrote: vb2_dc_prepare use the number of SG entries dma_map_sg_attrs return. But in dma_sync_sg_for_device, it use lengths of each SG entries before dma_map_sg_attrs. dma_map_sg_attrs will concatenate SGs until dma length > dma seg bundary. sgt->nents will less than sgt->orig_nents. Using SG entries after dma_map_sg_attrs in vb2_dc_prepare will make some SGs are not sync to device. After add DMA_ATTR_SKIP_CPU_SYNC in vb2_dc_get_userptr to remove sync data to device twice. Device randomly get incorrect data because some SGs are not sync to device. Change to use number of SG entries before dma_map_sg_attrs in vb2_dc_prepare to prevent this issue. Signed-off-by: Tiffany Lin--- drivers/media/v4l2-core/videobuf2-dma-contig.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 2397ceb..c5d00bd 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -100,7 +100,7 @@ static void vb2_dc_prepare(void *buf_priv) if (!sgt || buf->db_attach) return; - dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); + dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir); } static void vb2_dc_finish(void *buf_priv) @@ -112,7 +112,7 @@ static void vb2_dc_finish(void *buf_priv) if (!sgt || buf->db_attach) return; - dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); + dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir); } I don't really understand it. I am assuming that this happens on an arm and that the dma_map_sg_attrs and dma_sync_sg_* functions used are arm_iommu_map_sg() and arm_iommu_sync_sg_* as implemented in arch/arm/mm/dma-mapping.c. Now, as I understand it (and my understanding may very well be flawed!) the map_sg function concatenates SG entries if possible, so it may return fewer entries. But the dma_sync_sg functions use those updated SG entries, so the full buffer should be covered by this. Using orig_nents will actually sync parts of the buffer twice! The first nents entries already cover the full buffer so any remaining entries up to orig_nents will just duplicate parts of the buffer. As Documentation/DMA-API.txt says, the parameters to dma_sync_sg_* must be the same as those originally passed into dma_map_sg. The segments are only merged *from the point of view of the device*: if I have a scatterlist of two discontiguous 4K segments, I can remap them with an IOMMU so the device sees them as a single 8K buffer, and tell it as such. If on the other hand I want to do maintenance from the CPU side (i.e. any DMA API call), then those DMA addresses mean nothing and I can only operate on the CPU addresses of the underlying pages, which are still very much discontiguous in the linear map; ergo I still need to iterate over the original entries. Whilst I can't claim much familiarity with v4l itself, from a brief look over the existing code this patch does look to be doing the right thing. Robin. -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html