From e1512ee08f00c17918093e75be4a3fa297bcaf9b Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 30 May 2016 19:53:16 +0200 Subject: drm/arcpgu: Use lockless gem BO free callback No dev->struct_mutex anywhere to be seen. Cc: Alexey Brodkin Cc: Carlos Palminha Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1464630800-30786-25-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/arc/arcpgu_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/arc') diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c index 76e187a5bde0..bc53ebb83f75 100644 --- a/drivers/gpu/drm/arc/arcpgu_drv.c +++ b/drivers/gpu/drm/arc/arcpgu_drv.c @@ -207,7 +207,7 @@ static struct drm_driver arcpgu_drm_driver = { .get_vblank_counter = drm_vblank_no_hw_counter, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - .gem_free_object = drm_gem_cma_free_object, + .gem_free_object_unlocked = drm_gem_cma_free_object, .gem_vm_ops = &drm_gem_cma_vm_ops, .gem_prime_export = drm_gem_prime_export, .gem_prime_import = drm_gem_prime_import, -- cgit v1.2.3 From 1b47aaf9a93a69a61f8cc5219fd9c758b8588a59 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Thu, 2 Jun 2016 00:06:35 +0200 Subject: drm/fence: add fence to drm_pending_event Now a drm_pending_event can either send a real drm_event or signal a fence, or both. It allow us to signal via fences when the buffer is displayed on the screen. Which in turn means that the previous buffer is not in use anymore and can be freed or sent back to another driver for processing. v2: Comments from Daniel Vetter - call fence_signal in drm_send_event_locked() - remove unneeded !e->event check v3: Remove drm_pending_event->destroy to fix a leak when e->file_priv is not set. Reviewed-by: Sean Paul Signed-off-by: Gustavo Padovan (v2) [danvet: fix one e->destroy in arcpgu due to rebasing.] Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1464818821-5736-13-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/arc/arcpgu_drv.c | 2 +- drivers/gpu/drm/drm_atomic.c | 19 +++++++++++++------ drivers/gpu/drm/drm_fops.c | 16 +++++++++------- drivers/gpu/drm/nouveau/nouveau_usif.c | 1 - drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 2 +- include/drm/drmP.h | 3 ++- 6 files changed, 26 insertions(+), 17 deletions(-) (limited to 'drivers/gpu/drm/arc') diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c index 76e187a5bde0..69b5be0f9fb8 100644 --- a/drivers/gpu/drm/arc/arcpgu_drv.c +++ b/drivers/gpu/drm/arc/arcpgu_drv.c @@ -92,7 +92,7 @@ static void arcpgu_preclose(struct drm_device *drm, struct drm_file *file) if (e->base.file_priv != file) continue; list_del(&e->base.link); - e->base.destroy(&e->base); + kfree(&e->base); } spin_unlock_irqrestore(&drm->event_lock, flags); } diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 674b2e490aa9..1db198df3014 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1412,7 +1412,8 @@ EXPORT_SYMBOL(drm_atomic_nonblocking_commit); */ static struct drm_pending_vblank_event *create_vblank_event( - struct drm_device *dev, struct drm_file *file_priv, uint64_t user_data) + struct drm_device *dev, struct drm_file *file_priv, + struct fence *fence, uint64_t user_data) { struct drm_pending_vblank_event *e = NULL; int ret; @@ -1425,12 +1426,17 @@ static struct drm_pending_vblank_event *create_vblank_event( e->event.base.length = sizeof(e->event); e->event.user_data = user_data; - ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base); - if (ret) { - kfree(e); - return NULL; + if (file_priv) { + ret = drm_event_reserve_init(dev, file_priv, &e->base, + &e->event.base); + if (ret) { + kfree(e); + return NULL; + } } + e->base.fence = fence; + return e; } @@ -1670,7 +1676,8 @@ retry: for_each_crtc_in_state(state, crtc, crtc_state, i) { struct drm_pending_vblank_event *e; - e = create_vblank_event(dev, file_priv, arg->user_data); + e = create_vblank_event(dev, file_priv, NULL, + arg->user_data); if (!e) { ret = -ENOMEM; goto out; diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 7af7f8bcb355..efa980a54c75 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -368,7 +368,7 @@ static void drm_events_release(struct drm_file *file_priv) /* Remove unconsumed events */ list_for_each_entry_safe(e, et, &file_priv->event_list, link) { list_del(&e->link); - e->destroy(e); + kfree(e); } spin_unlock_irqrestore(&dev->event_lock, flags); @@ -636,7 +636,7 @@ put_back_event: } ret += length; - e->destroy(e); + kfree(e); } } mutex_unlock(&file_priv->event_read_lock); @@ -713,9 +713,6 @@ int drm_event_reserve_init_locked(struct drm_device *dev, list_add(&p->pending_link, &file_priv->pending_event_list); p->file_priv = file_priv; - /* we *could* pass this in as arg, but everyone uses kfree: */ - p->destroy = (void (*) (struct drm_pending_event *)) kfree; - return 0; } EXPORT_SYMBOL(drm_event_reserve_init_locked); @@ -778,7 +775,7 @@ void drm_event_cancel_free(struct drm_device *dev, list_del(&p->pending_link); } spin_unlock_irqrestore(&dev->event_lock, flags); - p->destroy(p); + kfree(p); } EXPORT_SYMBOL(drm_event_cancel_free); @@ -800,8 +797,13 @@ void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e) { assert_spin_locked(&dev->event_lock); + if (e->fence) { + fence_signal(e->fence); + fence_put(e->fence); + } + if (!e->file_priv) { - e->destroy(e); + kfree(e); return; } diff --git a/drivers/gpu/drm/nouveau/nouveau_usif.c b/drivers/gpu/drm/nouveau/nouveau_usif.c index 675e9e077a95..08f9c6fa0f7f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_usif.c +++ b/drivers/gpu/drm/nouveau/nouveau_usif.c @@ -212,7 +212,6 @@ usif_notify_get(struct drm_file *f, void *data, u32 size, void *argv, u32 argc) ntfy->p->base.event = &ntfy->p->e.base; ntfy->p->base.file_priv = f; ntfy->p->base.pid = current->pid; - ntfy->p->base.destroy =(void(*)(struct drm_pending_event *))kfree; ntfy->p->e.base.type = DRM_NOUVEAU_EVENT_NVIF; ntfy->p->e.base.length = sizeof(ntfy->p->e.base) + ntfy->reply; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 1c4d5b5a70a2..5567fb43e674 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -889,7 +889,7 @@ static void vop_crtc_cancel_pending_vblank(struct drm_crtc *crtc, if (e && e->base.file_priv == file_priv) { vop->event = NULL; - e->base.destroy(&e->base); + kfree(&e->base); file_priv->event_space += sizeof(e->event); } spin_unlock_irqrestore(&drm->event_lock, flags); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 00518289105f..9e5eefd6f733 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -57,6 +57,7 @@ #include #include #include +#include #include #include @@ -283,12 +284,12 @@ struct drm_ioctl_desc { /* Event queued up for userspace to read */ struct drm_pending_event { struct drm_event *event; + struct fence *fence; struct list_head link; struct list_head pending_link; struct drm_file *file_priv; pid_t pid; /* pid of requester, no guarantee it's valid by the time we deliver the event, for tracing only */ - void (*destroy)(struct drm_pending_event *event); }; /* initial implementaton using a linked list - todo hashtab */ -- cgit v1.2.3 From ed4f885657fe7e9bfec3d86a2b426da1e0d0c5de Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 8 Jun 2016 14:18:54 +0200 Subject: drm/arc: Nuke event_list This is just used for cleanup in preclose, and with the reworked event handling code this is now done properly by the core. Nuke it! But it also shows that arc totally fails at sending out drm events for flips. Next patch will hack that up. v2: Rebase it! Cc: Carlos Palminha Cc: Alexey Brodkin Cc: linux-snps-arc@lists.infradead.org Reviewed-by: Maarten Lankhorst Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1465388359-8070-2-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/arc/arcpgu.h | 1 - drivers/gpu/drm/arc/arcpgu_crtc.c | 4 ---- drivers/gpu/drm/arc/arcpgu_drv.c | 19 ------------------- 3 files changed, 24 deletions(-) (limited to 'drivers/gpu/drm/arc') diff --git a/drivers/gpu/drm/arc/arcpgu.h b/drivers/gpu/drm/arc/arcpgu.h index 86574b698a78..8c01a25d279a 100644 --- a/drivers/gpu/drm/arc/arcpgu.h +++ b/drivers/gpu/drm/arc/arcpgu.h @@ -22,7 +22,6 @@ struct arcpgu_drm_private { struct clk *clk; struct drm_fbdev_cma *fbdev; struct drm_framebuffer *fb; - struct list_head event_list; struct drm_crtc crtc; struct drm_plane *plane; }; diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c index 92f8beff8e60..d5ca0c280e68 100644 --- a/drivers/gpu/drm/arc/arcpgu_crtc.c +++ b/drivers/gpu/drm/arc/arcpgu_crtc.c @@ -155,10 +155,6 @@ static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc, event->pipe = drm_crtc_index(crtc); WARN_ON(drm_crtc_vblank_get(crtc) != 0); - - spin_lock_irqsave(&crtc->dev->event_lock, flags); - list_add_tail(&event->base.link, &arcpgu->event_list); - spin_unlock_irqrestore(&crtc->dev->event_lock, flags); } } diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c index 7675bbc70133..d407fd79a400 100644 --- a/drivers/gpu/drm/arc/arcpgu_drv.c +++ b/drivers/gpu/drm/arc/arcpgu_drv.c @@ -81,22 +81,6 @@ static const struct file_operations arcpgu_drm_ops = { .mmap = arcpgu_gem_mmap, }; -static void arcpgu_preclose(struct drm_device *drm, struct drm_file *file) -{ - struct arcpgu_drm_private *arcpgu = drm->dev_private; - struct drm_pending_vblank_event *e, *t; - unsigned long flags; - - spin_lock_irqsave(&drm->event_lock, flags); - list_for_each_entry_safe(e, t, &arcpgu->event_list, base.link) { - if (e->base.file_priv != file) - continue; - list_del(&e->base.link); - kfree(&e->base); - } - spin_unlock_irqrestore(&drm->event_lock, flags); -} - static void arcpgu_lastclose(struct drm_device *drm) { struct arcpgu_drm_private *arcpgu = drm->dev_private; @@ -122,8 +106,6 @@ static int arcpgu_load(struct drm_device *drm) if (IS_ERR(arcpgu->clk)) return PTR_ERR(arcpgu->clk); - INIT_LIST_HEAD(&arcpgu->event_list); - arcpgu_setup_mode_config(drm); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -192,7 +174,6 @@ int arcpgu_unload(struct drm_device *drm) static struct drm_driver arcpgu_drm_driver = { .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_ATOMIC, - .preclose = arcpgu_preclose, .lastclose = arcpgu_lastclose, .name = "drm-arcpgu", .desc = "ARC PGU Controller", -- cgit v1.2.3 From 84d9a4a28801fddb88dc61487089ed0ae2ccef78 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 8 Jun 2016 14:18:55 +0200 Subject: drm/arc: Actually bother with handling atomic events. The drm core has a nice ready-made helper for exactly the simple case where it should fire on the next vblank. Note that arming the vblank event in _begin is probably too early, and might easily result in the vblank firing too early, before the new set of planes are actually disabled. But that's kinda a minor issue compared to just outright hanging userspace. v2: Be more robust and either arm, when the CRTC is on, or just send the event out right away. v3: Just unconditionally send out the event directly, for safety - arcpgu doesn't even have vblank support ... Cc: Carlos Palminha Cc: Alexey Brodkin Cc: linux-snps-arc@lists.infradead.org Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1465388359-8070-3-git-send-email-daniel.vetter@ffwll.ch Link: http://patchwork.freedesktop.org/patch/msgid/1465388359-8070-4-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/arc/arcpgu_crtc.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm/arc') diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c index d5ca0c280e68..ee0a61c2861b 100644 --- a/drivers/gpu/drm/arc/arcpgu_crtc.c +++ b/drivers/gpu/drm/arc/arcpgu_crtc.c @@ -145,16 +145,14 @@ static int arc_pgu_crtc_atomic_check(struct drm_crtc *crtc, static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_crtc_state *state) { - struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc); - unsigned long flags; - - if (crtc->state->event) { - struct drm_pending_vblank_event *event = crtc->state->event; + struct drm_pending_vblank_event *event = crtc->state->event; + if (event) { crtc->state->event = NULL; - event->pipe = drm_crtc_index(crtc); - WARN_ON(drm_crtc_vblank_get(crtc) != 0); + spin_lock_irq(&crtc->dev->event_lock); + drm_crtc_send_vblank_event(crtc, event); + spin_unlock_irq(&crtc->dev->event_lock); } } -- cgit v1.2.3 From 17b58b2398419fd32994254aadf0b26257429e52 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 8 Jun 2016 14:19:03 +0200 Subject: drm/arc: Implement nonblocking commit correctly Committing with block it is not. Thanks to the fixed up vblank event handling we can just use the helper support for nonblocking commits now. Cc: Carlos Palminha Cc: Alexey Brodkin Cc: linux-snps-arc@lists.infradead.org Reviewed-by: Maarten Lankhorst Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1465388359-8070-11-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/arc/arcpgu_drv.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers/gpu/drm/arc') diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c index d407fd79a400..a92e533531c3 100644 --- a/drivers/gpu/drm/arc/arcpgu_drv.c +++ b/drivers/gpu/drm/arc/arcpgu_drv.c @@ -32,17 +32,11 @@ static void arcpgu_fb_output_poll_changed(struct drm_device *dev) drm_fbdev_cma_hotplug_event(arcpgu->fbdev); } -static int arcpgu_atomic_commit(struct drm_device *dev, - struct drm_atomic_state *state, bool async) -{ - return drm_atomic_helper_commit(dev, state, false); -} - static struct drm_mode_config_funcs arcpgu_drm_modecfg_funcs = { .fb_create = drm_fb_cma_create, .output_poll_changed = arcpgu_fb_output_poll_changed, .atomic_check = drm_atomic_helper_check, - .atomic_commit = arcpgu_atomic_commit, + .atomic_commit = drm_atomic_helper_commit, }; static void arcpgu_setup_mode_config(struct drm_device *drm) -- cgit v1.2.3 From da5b9d6b09ab4096d946e108007a6e75d77231c9 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Tue, 7 Jun 2016 13:47:57 +0200 Subject: drm: arc: Rely on the default ->best_encoder() behavior We have a 1:1 relationship between connectors and encoders and the driver is relying on the atomic helpers: we can drop the custom ->best_encoder(), and let the core call drm_atomic_helper_best_encoder() for us. Signed-off-by: Boris Brezillon Acked-by: Alexey Brodkin Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1465300095-16971-3-git-send-email-boris.brezillon@free-electrons.com --- drivers/gpu/drm/arc/arcpgu_hdmi.c | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'drivers/gpu/drm/arc') diff --git a/drivers/gpu/drm/arc/arcpgu_hdmi.c b/drivers/gpu/drm/arc/arcpgu_hdmi.c index 08b6baeb320d..b7a8b2ac4055 100644 --- a/drivers/gpu/drm/arc/arcpgu_hdmi.c +++ b/drivers/gpu/drm/arc/arcpgu_hdmi.c @@ -46,23 +46,6 @@ static int arcpgu_drm_connector_get_modes(struct drm_connector *connector) return sfuncs->get_modes(&slave->base, connector); } -struct drm_encoder * -arcpgu_drm_connector_best_encoder(struct drm_connector *connector) -{ - struct drm_encoder_slave *slave; - struct arcpgu_drm_connector *con = - container_of(connector, struct arcpgu_drm_connector, connector); - - slave = con->encoder_slave; - if (slave == NULL) { - dev_err(connector->dev->dev, - "connector_best_encoder: cannot find slave encoder for connector\n"); - return NULL; - } - - return &slave->base; -} - static enum drm_connector_status arcpgu_drm_connector_detect(struct drm_connector *connector, bool force) { @@ -97,7 +80,6 @@ static void arcpgu_drm_connector_destroy(struct drm_connector *connector) static const struct drm_connector_helper_funcs arcpgu_drm_connector_helper_funcs = { .get_modes = arcpgu_drm_connector_get_modes, - .best_encoder = arcpgu_drm_connector_best_encoder, }; static const struct drm_connector_funcs arcpgu_drm_connector_funcs = { -- cgit v1.2.3 From a189d28e5edea70f20995547ddc84c79b2f76c03 Mon Sep 17 00:00:00 2001 From: Ruud Derwig Date: Mon, 6 Jun 2016 10:47:46 +0300 Subject: drm/arcpgu: Make ARC PGU usable on simulation platforms In case of simulation there's no real encoder/transmitter device because in the model's virtual LCD we're rendering whatever appears in frame-buffer memory. Signed-off-by: Ruud Derwig Signed-off-by: Alexey Brodkin Acked-by: Daniel Vetter --- drivers/gpu/drm/arc/Makefile | 2 +- drivers/gpu/drm/arc/arcpgu.h | 1 + drivers/gpu/drm/arc/arcpgu_drv.c | 15 ++--- drivers/gpu/drm/arc/arcpgu_sim.c | 128 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 138 insertions(+), 8 deletions(-) create mode 100644 drivers/gpu/drm/arc/arcpgu_sim.c (limited to 'drivers/gpu/drm/arc') diff --git a/drivers/gpu/drm/arc/Makefile b/drivers/gpu/drm/arc/Makefile index d48fda70f857..73de56a0139a 100644 --- a/drivers/gpu/drm/arc/Makefile +++ b/drivers/gpu/drm/arc/Makefile @@ -1,2 +1,2 @@ -arcpgu-y := arcpgu_crtc.o arcpgu_hdmi.o arcpgu_drv.o +arcpgu-y := arcpgu_crtc.o arcpgu_hdmi.o arcpgu_sim.o arcpgu_drv.o obj-$(CONFIG_DRM_ARCPGU) += arcpgu.o diff --git a/drivers/gpu/drm/arc/arcpgu.h b/drivers/gpu/drm/arc/arcpgu.h index 86574b698a78..329ac7570911 100644 --- a/drivers/gpu/drm/arc/arcpgu.h +++ b/drivers/gpu/drm/arc/arcpgu.h @@ -43,6 +43,7 @@ static inline u32 arc_pgu_read(struct arcpgu_drm_private *arcpgu, int arc_pgu_setup_crtc(struct drm_device *dev); int arcpgu_drm_hdmi_init(struct drm_device *drm, struct device_node *np); +int arcpgu_drm_sim_init(struct drm_device *drm, struct device_node *np); struct drm_fbdev_cma *arcpgu_fbdev_cma_init(struct drm_device *dev, unsigned int preferred_bpp, unsigned int num_crtc, unsigned int max_conn_count); diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c index 7675bbc70133..07c1bdeca489 100644 --- a/drivers/gpu/drm/arc/arcpgu_drv.c +++ b/drivers/gpu/drm/arc/arcpgu_drv.c @@ -149,15 +149,16 @@ static int arcpgu_load(struct drm_device *drm) /* find the encoder node and initialize it */ encoder_node = of_parse_phandle(drm->dev->of_node, "encoder-slave", 0); - if (!encoder_node) { - dev_err(drm->dev, "failed to get an encoder slave node\n"); - return -ENODEV; + if (encoder_node) { + ret = arcpgu_drm_hdmi_init(drm, encoder_node); + if (ret < 0) + return ret; + } else { + ret = arcpgu_drm_sim_init(drm, 0); + if (ret < 0) + return ret; } - ret = arcpgu_drm_hdmi_init(drm, encoder_node); - if (ret < 0) - return ret; - drm_mode_config_reset(drm); drm_kms_helper_poll_init(drm); diff --git a/drivers/gpu/drm/arc/arcpgu_sim.c b/drivers/gpu/drm/arc/arcpgu_sim.c new file mode 100644 index 000000000000..2bf06d71556a --- /dev/null +++ b/drivers/gpu/drm/arc/arcpgu_sim.c @@ -0,0 +1,128 @@ +/* + * ARC PGU DRM driver. + * + * Copyright (C) 2016 Synopsys, Inc. (www.synopsys.com) + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include + +#include "arcpgu.h" + +#define XRES_DEF 640 +#define YRES_DEF 480 + +#define XRES_MAX 8192 +#define YRES_MAX 8192 + + +struct arcpgu_drm_connector { + struct drm_connector connector; + struct drm_encoder_slave *encoder_slave; +}; + +static int arcpgu_drm_connector_get_modes(struct drm_connector *connector) +{ + int count; + + count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX); + drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF); + return count; +} + +static enum drm_connector_status +arcpgu_drm_connector_detect(struct drm_connector *connector, bool force) +{ + return connector_status_connected; +} + +static void arcpgu_drm_connector_destroy(struct drm_connector *connector) +{ + drm_connector_unregister(connector); + drm_connector_cleanup(connector); +} + +static const struct drm_connector_helper_funcs +arcpgu_drm_connector_helper_funcs = { + .get_modes = arcpgu_drm_connector_get_modes, +}; + +static const struct drm_connector_funcs arcpgu_drm_connector_funcs = { + .dpms = drm_helper_connector_dpms, + .reset = drm_atomic_helper_connector_reset, + .detect = arcpgu_drm_connector_detect, + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = arcpgu_drm_connector_destroy, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, +}; + +static struct drm_encoder_funcs arcpgu_drm_encoder_funcs = { + .destroy = drm_encoder_cleanup, +}; + +int arcpgu_drm_sim_init(struct drm_device *drm, struct device_node *np) +{ + struct arcpgu_drm_connector *arcpgu_connector; + struct drm_encoder_slave *encoder; + struct drm_connector *connector; + int ret; + + encoder = devm_kzalloc(drm->dev, sizeof(*encoder), GFP_KERNEL); + if (encoder == NULL) + return -ENOMEM; + + encoder->base.possible_crtcs = 1; + encoder->base.possible_clones = 0; + + ret = drm_encoder_init(drm, &encoder->base, &arcpgu_drm_encoder_funcs, + DRM_MODE_ENCODER_VIRTUAL, NULL); + if (ret) + return ret; + + arcpgu_connector = devm_kzalloc(drm->dev, sizeof(*arcpgu_connector), + GFP_KERNEL); + if (!arcpgu_connector) { + ret = -ENOMEM; + goto error_encoder_cleanup; + } + + connector = &arcpgu_connector->connector; + drm_connector_helper_add(connector, &arcpgu_drm_connector_helper_funcs); + + ret = drm_connector_init(drm, connector, &arcpgu_drm_connector_funcs, + DRM_MODE_CONNECTOR_VIRTUAL); + if (ret < 0) { + dev_err(drm->dev, "failed to initialize drm connector\n"); + goto error_encoder_cleanup; + } + + ret = drm_mode_connector_attach_encoder(connector, &encoder->base); + if (ret < 0) { + dev_err(drm->dev, "could not attach connector to encoder\n"); + drm_connector_unregister(connector); + goto error_connector_cleanup; + } + + arcpgu_connector->encoder_slave = encoder; + + return 0; + +error_connector_cleanup: + drm_connector_cleanup(connector); + +error_encoder_cleanup: + drm_encoder_cleanup(&encoder->base); + return ret; +} -- cgit v1.2.3 From e01d9e5415f2770e341754fa40ca20e069772521 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 17 Jun 2016 09:25:18 +0100 Subject: drm/arc: Remove redundant calls to drm_connector_register_all() Up to now, the recommendation was for drivers to call drm_dev_register() followed by drm_connector_register_all(). Now that drm_connector_register() is safe against multiple invocations, we can move drm_connector_register_all() to drm_dev_register() and not suffer from any backwards compatibility issues with drivers not following the more rigorous init ordering. Signed-off-by: Chris Wilson Cc: Daniel Vetter Cc: Alexey Brodkin Cc: David Airlie Cc: dri-devel@lists.freedesktop.org Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1466151923-1572-3-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/arc/arcpgu_drv.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers/gpu/drm/arc') diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c index 381c5fcbf903..ccbdadb108dc 100644 --- a/drivers/gpu/drm/arc/arcpgu_drv.c +++ b/drivers/gpu/drm/arc/arcpgu_drv.c @@ -211,15 +211,8 @@ static int arcpgu_probe(struct platform_device *pdev) if (ret) goto err_unload; - ret = drm_connector_register_all(drm); - if (ret) - goto err_unregister; - return 0; -err_unregister: - drm_dev_unregister(drm); - err_unload: arcpgu_unload(drm); @@ -233,7 +226,6 @@ static int arcpgu_remove(struct platform_device *pdev) { struct drm_device *drm = platform_get_drvdata(pdev); - drm_connector_unregister_all(drm); drm_dev_unregister(drm); arcpgu_unload(drm); drm_dev_unref(drm); -- cgit v1.2.3 From 8e7446c36ffd43a19c8ca928899e835c527b615e Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Fri, 15 Jul 2016 11:17:05 +0800 Subject: gpu: drm: arcpgu_drv: add missing of_node_put after calling of_parse_phandle of_node_put needs to be called when the device node which is got from of_parse_phandle has finished using. Cc: Alexey Brodkin Signed-off-by: Peter Chen Signed-off-by: Sean Paul --- drivers/gpu/drm/arc/arcpgu_drv.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/arc') diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c index ccbdadb108dc..0226ec0667dd 100644 --- a/drivers/gpu/drm/arc/arcpgu_drv.c +++ b/drivers/gpu/drm/arc/arcpgu_drv.c @@ -127,6 +127,7 @@ static int arcpgu_load(struct drm_device *drm) encoder_node = of_parse_phandle(drm->dev->of_node, "encoder-slave", 0); if (encoder_node) { ret = arcpgu_drm_hdmi_init(drm, encoder_node); + of_node_put(encoder_node); if (ret < 0) return ret; } else { -- cgit v1.2.3 From f15a8e9a14196bad904d040e7b587bdf76ad35ed Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Fri, 15 Jul 2016 21:52:40 +0200 Subject: drm/arcpgu: Delete an unnecessary check before drm_fbdev_cma_hotplug_event() The drm_fbdev_cma_hotplug_event() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/dd9a16b1-234c-6776-e6d9-943a8457334e@users.sourceforge.net --- drivers/gpu/drm/arc/arcpgu_drv.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/gpu/drm/arc') diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c index 0226ec0667dd..20a5f2cd0d8b 100644 --- a/drivers/gpu/drm/arc/arcpgu_drv.c +++ b/drivers/gpu/drm/arc/arcpgu_drv.c @@ -28,8 +28,7 @@ static void arcpgu_fb_output_poll_changed(struct drm_device *dev) { struct arcpgu_drm_private *arcpgu = dev->dev_private; - if (arcpgu->fbdev) - drm_fbdev_cma_hotplug_event(arcpgu->fbdev); + drm_fbdev_cma_hotplug_event(arcpgu->fbdev); } static struct drm_mode_config_funcs arcpgu_drm_modecfg_funcs = { -- cgit v1.2.3 From c89f813a013e324ee3dc7d0277d92b33977677c9 Mon Sep 17 00:00:00 2001 From: Tobias Jakobi Date: Fri, 15 Jul 2016 14:47:57 +0200 Subject: drm/arc: make fbdev support really optional Currently enabling ARC DRM support automatically pulls in fbdev dependency. However this dep is unnecessary since DRM core already handles this for us (DRM_FBDEV_EMULATION). Signed-off-by: Tobias Jakobi Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1468586897-32298-2-git-send-email-tjakobi@math.uni-bielefeld.de --- drivers/gpu/drm/arc/Kconfig | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu/drm/arc') diff --git a/drivers/gpu/drm/arc/Kconfig b/drivers/gpu/drm/arc/Kconfig index f9a13b658fea..f47d88ba4fa5 100644 --- a/drivers/gpu/drm/arc/Kconfig +++ b/drivers/gpu/drm/arc/Kconfig @@ -2,7 +2,6 @@ config DRM_ARCPGU tristate "ARC PGU" depends on DRM && OF select DRM_KMS_CMA_HELPER - select DRM_KMS_FB_HELPER select DRM_KMS_HELPER help Choose this option if you have an ARC PGU controller. -- cgit v1.2.3 From ee29a9eaff92298412904669371037cb202b89b3 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 19 Jul 2016 12:04:05 +0000 Subject: drm/arc: Fix some sparse warnings Fixes the following sparse warnings: drivers/gpu/drm/arc/arcpgu_drv.c:52:5: warning: symbol 'arcpgu_gem_mmap' was not declared. Should it be static? drivers/gpu/drm/arc/arcpgu_drv.c:134:48: warning: Using plain integer as NULL pointer drivers/gpu/drm/arc/arcpgu_drv.c:155:5: warning: symbol 'arcpgu_unload' was not declared. Should it be static? Signed-off-by: Wei Yongjun Signed-off-by: Sean Paul --- drivers/gpu/drm/arc/arcpgu_drv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/arc') diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c index 20a5f2cd0d8b..c501576f6679 100644 --- a/drivers/gpu/drm/arc/arcpgu_drv.c +++ b/drivers/gpu/drm/arc/arcpgu_drv.c @@ -48,7 +48,7 @@ static void arcpgu_setup_mode_config(struct drm_device *drm) drm->mode_config.funcs = &arcpgu_drm_modecfg_funcs; } -int arcpgu_gem_mmap(struct file *filp, struct vm_area_struct *vma) +static int arcpgu_gem_mmap(struct file *filp, struct vm_area_struct *vma) { int ret; @@ -130,7 +130,7 @@ static int arcpgu_load(struct drm_device *drm) if (ret < 0) return ret; } else { - ret = arcpgu_drm_sim_init(drm, 0); + ret = arcpgu_drm_sim_init(drm, NULL); if (ret < 0) return ret; } @@ -151,7 +151,7 @@ static int arcpgu_load(struct drm_device *drm) return 0; } -int arcpgu_unload(struct drm_device *drm) +static int arcpgu_unload(struct drm_device *drm) { struct arcpgu_drm_private *arcpgu = drm->dev_private; -- cgit v1.2.3 From 7725936e9c45e597f4dbd173af390ec7155225e0 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 19 Jul 2016 12:01:37 +0000 Subject: drm/arc: Remove redundant dev_err call in arcpgu_load() There is a error message within devm_ioremap_resource already, so remove the dev_err call to avoid redundant error message. Signed-off-by: Wei Yongjun Signed-off-by: Sean Paul --- drivers/gpu/drm/arc/arcpgu_drv.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/gpu/drm/arc') diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c index c501576f6679..6d4ff34737cb 100644 --- a/drivers/gpu/drm/arc/arcpgu_drv.c +++ b/drivers/gpu/drm/arc/arcpgu_drv.c @@ -103,10 +103,8 @@ static int arcpgu_load(struct drm_device *drm) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); arcpgu->regs = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(arcpgu->regs)) { - dev_err(drm->dev, "Could not remap IO mem\n"); + if (IS_ERR(arcpgu->regs)) return PTR_ERR(arcpgu->regs); - } dev_info(drm->dev, "arc_pgu ID: 0x%x\n", arc_pgu_read(arcpgu, ARCPGU_REG_ID)); -- cgit v1.2.3