From patchwork Thu Dec 17 08:39:43 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 7871221 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id CF6B19F32E for ; Thu, 17 Dec 2015 08:43:06 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 91004202EC for ; Thu, 17 Dec 2015 08:43:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 37885203F7 for ; Thu, 17 Dec 2015 08:43:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933146AbbLQIkp (ORCPT ); Thu, 17 Dec 2015 03:40:45 -0500 Received: from galahad.ideasonboard.com ([185.26.127.97]:44652 "EHLO galahad.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753194AbbLQIko (ORCPT ); Thu, 17 Dec 2015 03:40:44 -0500 Received: from avalon.ideasonboard.com (unknown [207.140.26.138]) by galahad.ideasonboard.com (Postfix) with ESMTPSA id 1D26120397; Thu, 17 Dec 2015 09:40:40 +0100 (CET) From: Laurent Pinchart To: linux-media@vger.kernel.org Cc: linux-sh@vger.kernel.org Subject: [PATCH/RFC 05/48] v4l: vsp1: Store the display list manager in the WPF Date: Thu, 17 Dec 2015 10:39:43 +0200 Message-Id: <1450341626-6695-6-git-send-email-laurent.pinchart+renesas@ideasonboard.com> X-Mailer: git-send-email 2.4.10 In-Reply-To: <1450341626-6695-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com> References: <1450341626-6695-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com> Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Each WPF can process display lists independently, move the manager to the WPF to reflect that and prepare for display list support for non-DRM pipelines. Signed-off-by: Laurent Pinchart --- drivers/media/platform/vsp1/vsp1_dl.c | 37 ++++++++++++++++++++++++++----- drivers/media/platform/vsp1/vsp1_dl.h | 26 ++++------------------ drivers/media/platform/vsp1/vsp1_drm.c | 19 +++++++--------- drivers/media/platform/vsp1/vsp1_drm.h | 9 +------- drivers/media/platform/vsp1/vsp1_entity.c | 2 ++ drivers/media/platform/vsp1/vsp1_entity.h | 2 ++ drivers/media/platform/vsp1/vsp1_rwpf.h | 3 +++ drivers/media/platform/vsp1/vsp1_wpf.c | 18 +++++++++++++++ 8 files changed, 70 insertions(+), 46 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c index 5f49f52e22f2..32661daac7b0 100644 --- a/drivers/media/platform/vsp1/vsp1_dl.c +++ b/drivers/media/platform/vsp1/vsp1_dl.c @@ -48,6 +48,25 @@ struct vsp1_dl_list { int reg_count; }; +/** + * struct vsp1_dl_manager - Display List manager + * @vsp1: the VSP1 device + * @lock: protects the active, queued and pending lists + * @free: array of all free display lists + * @active: list currently being processed (loaded) by hardware + * @queued: list queued to the hardware (written to the DL registers) + * @pending: list waiting to be queued to the hardware + */ +struct vsp1_dl_manager { + struct vsp1_device *vsp1; + + spinlock_t lock; + struct list_head free; + struct vsp1_dl_list *active; + struct vsp1_dl_list *queued; + struct vsp1_dl_list *pending; +}; + /* ----------------------------------------------------------------------------- * Display List Transaction Management */ @@ -257,11 +276,16 @@ void vsp1_dlm_reset(struct vsp1_dl_manager *dlm) dlm->pending = NULL; } -int vsp1_dlm_init(struct vsp1_device *vsp1, struct vsp1_dl_manager *dlm, - unsigned int prealloc) +struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1, + unsigned int prealloc) { + struct vsp1_dl_manager *dlm; unsigned int i; + dlm = devm_kzalloc(vsp1->dev, sizeof(*dlm), GFP_KERNEL); + if (!dlm) + return NULL; + dlm->vsp1 = vsp1; spin_lock_init(&dlm->lock); @@ -272,18 +296,21 @@ int vsp1_dlm_init(struct vsp1_device *vsp1, struct vsp1_dl_manager *dlm, dl = vsp1_dl_list_alloc(dlm); if (!dl) - return -ENOMEM; + return NULL; list_add_tail(&dl->list, &dlm->free); } - return 0; + return dlm; } -void vsp1_dlm_cleanup(struct vsp1_dl_manager *dlm) +void vsp1_dlm_destroy(struct vsp1_dl_manager *dlm) { struct vsp1_dl_list *dl, *next; + if (!dlm) + return; + list_for_each_entry_safe(dl, next, &dlm->free, list) { list_del(&dl->list); vsp1_dl_list_free(dl); diff --git a/drivers/media/platform/vsp1/vsp1_dl.h b/drivers/media/platform/vsp1/vsp1_dl.h index caa6a85f6825..46f7ae337374 100644 --- a/drivers/media/platform/vsp1/vsp1_dl.h +++ b/drivers/media/platform/vsp1/vsp1_dl.h @@ -17,31 +17,13 @@ struct vsp1_device; struct vsp1_dl_list; - -/** - * struct vsp1_dl_manager - Display List manager - * @vsp1: the VSP1 device - * @lock: protects the active, queued and pending lists - * @free: array of all free display lists - * @active: list currently being processed (loaded) by hardware - * @queued: list queued to the hardware (written to the DL registers) - * @pending: list waiting to be queued to the hardware - */ -struct vsp1_dl_manager { - struct vsp1_device *vsp1; - - spinlock_t lock; - struct list_head free; - struct vsp1_dl_list *active; - struct vsp1_dl_list *queued; - struct vsp1_dl_list *pending; -}; +struct vsp1_dl_manager; void vsp1_dlm_setup(struct vsp1_device *vsp1); -int vsp1_dlm_init(struct vsp1_device *vsp1, struct vsp1_dl_manager *dlm, - unsigned int prealloc); -void vsp1_dlm_cleanup(struct vsp1_dl_manager *dlm); +struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1, + unsigned int prealloc); +void vsp1_dlm_destroy(struct vsp1_dl_manager *dlm); void vsp1_dlm_reset(struct vsp1_dl_manager *dlm); void vsp1_dlm_irq_display_start(struct vsp1_dl_manager *dlm); void vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm); diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c index bc275bb38352..b3df694569e7 100644 --- a/drivers/media/platform/vsp1/vsp1_drm.c +++ b/drivers/media/platform/vsp1/vsp1_drm.c @@ -31,11 +31,14 @@ * Interrupt Handling */ -void vsp1_drm_frame_end(struct vsp1_pipeline *pipe) +void vsp1_drm_display_start(struct vsp1_device *vsp1) { - struct vsp1_device *vsp1 = pipe->output->entity.vsp1; + vsp1_dlm_irq_display_start(vsp1->drm->pipe.output->dlm); +} - vsp1_dlm_irq_frame_end(&vsp1->drm->dlm); +void vsp1_drm_frame_end(struct vsp1_pipeline *pipe) +{ + vsp1_dlm_irq_frame_end(pipe->output->dlm); } /* ----------------------------------------------------------------------------- @@ -101,7 +104,7 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int width, pipe->num_inputs = 0; - vsp1_dlm_reset(&vsp1->drm->dlm); + vsp1_dlm_reset(pipe->output->dlm); vsp1_device_put(vsp1); dev_dbg(vsp1->dev, "%s: pipeline disabled\n", __func__); @@ -228,7 +231,7 @@ void vsp1_du_atomic_begin(struct device *dev) spin_unlock_irqrestore(&pipe->irqlock, flags); /* Prepare the display list. */ - pipe->dl = vsp1_dl_list_get(&vsp1->drm->dlm); + pipe->dl = vsp1_dl_list_get(pipe->output->dlm); } EXPORT_SYMBOL_GPL(vsp1_du_atomic_begin); @@ -555,16 +558,11 @@ int vsp1_drm_init(struct vsp1_device *vsp1) { struct vsp1_pipeline *pipe; unsigned int i; - int ret; vsp1->drm = devm_kzalloc(vsp1->dev, sizeof(*vsp1->drm), GFP_KERNEL); if (!vsp1->drm) return -ENOMEM; - ret = vsp1_dlm_init(vsp1, &vsp1->drm->dlm, 4); - if (ret < 0) - return ret; - pipe = &vsp1->drm->pipe; vsp1_pipeline_init(pipe); @@ -590,5 +588,4 @@ int vsp1_drm_init(struct vsp1_device *vsp1) void vsp1_drm_cleanup(struct vsp1_device *vsp1) { - vsp1_dlm_cleanup(&vsp1->drm->dlm); } diff --git a/drivers/media/platform/vsp1/vsp1_drm.h b/drivers/media/platform/vsp1/vsp1_drm.h index 5ef32cff9601..1acf6048841b 100644 --- a/drivers/media/platform/vsp1/vsp1_drm.h +++ b/drivers/media/platform/vsp1/vsp1_drm.h @@ -13,7 +13,6 @@ #ifndef __VSP1_DRM_H__ #define __VSP1_DRM_H__ -#include "vsp1_dl.h" #include "vsp1_pipe.h" /** @@ -21,22 +20,16 @@ * @pipe: the VSP1 pipeline used for display * @num_inputs: number of active pipeline inputs at the beginning of an update * @update: the pipeline configuration has been updated - * @dlm: display list manager used for DRM operation */ struct vsp1_drm { struct vsp1_pipeline pipe; unsigned int num_inputs; bool update; - struct vsp1_dl_manager dlm; }; int vsp1_drm_init(struct vsp1_device *vsp1); void vsp1_drm_cleanup(struct vsp1_device *vsp1); int vsp1_drm_create_links(struct vsp1_device *vsp1); - -static inline void vsp1_drm_display_start(struct vsp1_device *vsp1) -{ - vsp1_dlm_irq_display_start(&vsp1->drm->dlm); -} +void vsp1_drm_display_start(struct vsp1_device *vsp1); #endif /* __VSP1_DRM_H__ */ diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c index 0d1163eb3362..c005d374c254 100644 --- a/drivers/media/platform/vsp1/vsp1_entity.c +++ b/drivers/media/platform/vsp1/vsp1_entity.c @@ -244,6 +244,8 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity, void vsp1_entity_destroy(struct vsp1_entity *entity) { + if (entity->destroy) + entity->destroy(entity); if (entity->subdev.ctrl_handler) v4l2_ctrl_handler_free(entity->subdev.ctrl_handler); media_entity_cleanup(&entity->subdev.entity); diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h index 311d5b64c9a5..259880e524fe 100644 --- a/drivers/media/platform/vsp1/vsp1_entity.h +++ b/drivers/media/platform/vsp1/vsp1_entity.h @@ -56,6 +56,8 @@ struct vsp1_route { struct vsp1_entity { struct vsp1_device *vsp1; + void (*destroy)(struct vsp1_entity *); + enum vsp1_entity_type type; unsigned int index; const struct vsp1_route *route; diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h index 8e8235682ada..d04df39b2737 100644 --- a/drivers/media/platform/vsp1/vsp1_rwpf.h +++ b/drivers/media/platform/vsp1/vsp1_rwpf.h @@ -24,6 +24,7 @@ #define RWPF_PAD_SOURCE 1 struct v4l2_ctrl; +struct vsp1_dl_manager; struct vsp1_rwpf; struct vsp1_video; @@ -60,6 +61,8 @@ struct vsp1_rwpf { unsigned int offsets[2]; dma_addr_t buf_addr[3]; + + struct vsp1_dl_manager *dlm; }; static inline struct vsp1_rwpf *to_rwpf(struct v4l2_subdev *subdev) diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c index c78d4af50fcf..6afc9c8d9adc 100644 --- a/drivers/media/platform/vsp1/vsp1_wpf.c +++ b/drivers/media/platform/vsp1/vsp1_wpf.c @@ -16,6 +16,7 @@ #include #include "vsp1.h" +#include "vsp1_dl.h" #include "vsp1_rwpf.h" #include "vsp1_video.h" @@ -218,6 +219,13 @@ static const struct vsp1_rwpf_operations wpf_vdev_ops = { * Initialization and Cleanup */ +static void vsp1_wpf_destroy(struct vsp1_entity *entity) +{ + struct vsp1_rwpf *wpf = container_of(entity, struct vsp1_rwpf, entity); + + vsp1_dlm_destroy(wpf->dlm); +} + struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index) { struct v4l2_subdev *subdev; @@ -233,6 +241,7 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index) wpf->max_width = WPF_MAX_WIDTH; wpf->max_height = WPF_MAX_HEIGHT; + wpf->entity.destroy = vsp1_wpf_destroy; wpf->entity.type = VSP1_ENTITY_WPF; wpf->entity.index = index; @@ -240,6 +249,15 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index) if (ret < 0) return ERR_PTR(ret); + /* Initialize the display list manager if the WPF is used for display */ + if ((vsp1->info->features & VSP1_HAS_LIF) && index == 0) { + wpf->dlm = vsp1_dlm_create(vsp1, 4); + if (!wpf->dlm) { + ret = -ENOMEM; + goto error; + } + } + /* Initialize the V4L2 subdev. */ subdev = &wpf->entity.subdev; v4l2_subdev_init(subdev, &wpf_ops);