[PATCHv9 9/9] drm: tegra: Add gr2d device
Add client driver for 2D device, and IOCTLs to pass work to host1x channel for 2D. Also adds functions that can be called to access sync points from DRM. Signed-off-by: Arto Merilainen Signed-off-by: Terje Bergstrom --- drivers/gpu/host1x/Makefile|1 + drivers/gpu/host1x/dev.c |7 + drivers/gpu/host1x/drm/Kconfig |9 ++ drivers/gpu/host1x/drm/drm.c | 212 - drivers/gpu/host1x/drm/drm.h | 27 +++- drivers/gpu/host1x/drm/gr2d.c | 339 drivers/gpu/host1x/host1x.h|4 +- include/uapi/drm/Kbuild|1 + include/uapi/drm/tegra_drm.h | 136 9 files changed, 733 insertions(+), 3 deletions(-) create mode 100644 drivers/gpu/host1x/drm/gr2d.c create mode 100644 include/uapi/drm/tegra_drm.h diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile index 3768dbc..3b037b6 100644 --- a/drivers/gpu/host1x/Makefile +++ b/drivers/gpu/host1x/Makefile @@ -16,4 +16,5 @@ ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o host1x-$(CONFIG_DRM_TEGRA) += drm/gem.o +host1x-$(CONFIG_DRM_TEGRA) += drm/gr2d.o obj-$(CONFIG_TEGRA_HOST1X) += host1x.o diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c index 8ce9889..28e28a2 100644 --- a/drivers/gpu/host1x/dev.c +++ b/drivers/gpu/host1x/dev.c @@ -209,11 +209,17 @@ static int __init tegra_host1x_init(void) err = platform_driver_register(_hdmi_driver); if (err < 0) goto unregister_dc; + + err = platform_driver_register(_gr2d_driver); + if (err < 0) + goto unregister_hdmi; #endif return 0; #ifdef CONFIG_DRM_TEGRA +unregister_hdmi: + platform_driver_unregister(_hdmi_driver); unregister_dc: platform_driver_unregister(_dc_driver); unregister_host1x: @@ -226,6 +232,7 @@ module_init(tegra_host1x_init); static void __exit tegra_host1x_exit(void) { #ifdef CONFIG_DRM_TEGRA + platform_driver_unregister(_gr2d_driver); platform_driver_unregister(_hdmi_driver); platform_driver_unregister(_dc_driver); #endif diff --git a/drivers/gpu/host1x/drm/Kconfig b/drivers/gpu/host1x/drm/Kconfig index f743540..6e3f567 100644 --- a/drivers/gpu/host1x/drm/Kconfig +++ b/drivers/gpu/host1x/drm/Kconfig @@ -13,6 +13,15 @@ config DRM_TEGRA if DRM_TEGRA +config DRM_TEGRA_STAGING + bool "Enable HOST1X interface" + depends on STAGING + default n + help + Say yes if HOST1X should be available for userspace DRM users. + + If unsure, choose N. + config DRM_TEGRA_DEBUG bool "NVIDIA Tegra DRM debug support" help diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c index c4e45c1..2b561c9 100644 --- a/drivers/gpu/host1x/drm/drm.c +++ b/drivers/gpu/host1x/drm/drm.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 Avionic Design GmbH - * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved. + * Copyright (C) 2012-2013 NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -14,6 +14,9 @@ #include #include +#include +#include + #include "host1x_client.h" #include "dev.h" #include "drm.h" @@ -81,8 +84,10 @@ static int host1x_parse_dt(struct host1x_drm *host1x) static const char * const compat[] = { "nvidia,tegra20-dc", "nvidia,tegra20-hdmi", + "nvidia,tegra20-gr2d", "nvidia,tegra30-dc", "nvidia,tegra30-hdmi", + "nvidia,tegra30-gr2d", }; unsigned int i; int err; @@ -277,9 +282,24 @@ static int tegra_drm_unload(struct drm_device *drm) static int tegra_drm_open(struct drm_device *drm, struct drm_file *filp) { + struct host1x_drm_file *fpriv; + + fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL); + if (!fpriv) + return -ENOMEM; + + INIT_LIST_HEAD(>contexts); + filp->driver_priv = fpriv; + return 0; } +static void host1x_drm_context_free(struct host1x_drm_context *context) +{ + context->client->ops->close_channel(context); + kfree(context); +} + static void tegra_drm_lastclose(struct drm_device *drm) { struct host1x_drm *host1x = drm->dev_private; @@ -287,7 +307,190 @@ static void tegra_drm_lastclose(struct drm_device *drm) tegra_fbdev_restore_mode(host1x->fbdev); } +#ifdef CONFIG_DRM_TEGRA_STAGING +static bool host1x_drm_file_owns_context(struct host1x_drm_file *file, +struct host1x_drm_context *context) +{ + struct host1x_drm_context *ctx; + + list_for_each_entry(ctx, >contexts, list) + if (ctx == context) + return true; + + return
[PATCHv9 9/9] drm: tegra: Add gr2d device
Add client driver for 2D device, and IOCTLs to pass work to host1x channel for 2D. Also adds functions that can be called to access sync points from DRM. Signed-off-by: Arto Merilainen amerilai...@nvidia.com Signed-off-by: Terje Bergstrom tbergst...@nvidia.com --- drivers/gpu/host1x/Makefile|1 + drivers/gpu/host1x/dev.c |7 + drivers/gpu/host1x/drm/Kconfig |9 ++ drivers/gpu/host1x/drm/drm.c | 212 - drivers/gpu/host1x/drm/drm.h | 27 +++- drivers/gpu/host1x/drm/gr2d.c | 339 drivers/gpu/host1x/host1x.h|4 +- include/uapi/drm/Kbuild|1 + include/uapi/drm/tegra_drm.h | 136 9 files changed, 733 insertions(+), 3 deletions(-) create mode 100644 drivers/gpu/host1x/drm/gr2d.c create mode 100644 include/uapi/drm/tegra_drm.h diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile index 3768dbc..3b037b6 100644 --- a/drivers/gpu/host1x/Makefile +++ b/drivers/gpu/host1x/Makefile @@ -16,4 +16,5 @@ ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o host1x-$(CONFIG_DRM_TEGRA) += drm/gem.o +host1x-$(CONFIG_DRM_TEGRA) += drm/gr2d.o obj-$(CONFIG_TEGRA_HOST1X) += host1x.o diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c index 8ce9889..28e28a2 100644 --- a/drivers/gpu/host1x/dev.c +++ b/drivers/gpu/host1x/dev.c @@ -209,11 +209,17 @@ static int __init tegra_host1x_init(void) err = platform_driver_register(tegra_hdmi_driver); if (err 0) goto unregister_dc; + + err = platform_driver_register(tegra_gr2d_driver); + if (err 0) + goto unregister_hdmi; #endif return 0; #ifdef CONFIG_DRM_TEGRA +unregister_hdmi: + platform_driver_unregister(tegra_hdmi_driver); unregister_dc: platform_driver_unregister(tegra_dc_driver); unregister_host1x: @@ -226,6 +232,7 @@ module_init(tegra_host1x_init); static void __exit tegra_host1x_exit(void) { #ifdef CONFIG_DRM_TEGRA + platform_driver_unregister(tegra_gr2d_driver); platform_driver_unregister(tegra_hdmi_driver); platform_driver_unregister(tegra_dc_driver); #endif diff --git a/drivers/gpu/host1x/drm/Kconfig b/drivers/gpu/host1x/drm/Kconfig index f743540..6e3f567 100644 --- a/drivers/gpu/host1x/drm/Kconfig +++ b/drivers/gpu/host1x/drm/Kconfig @@ -13,6 +13,15 @@ config DRM_TEGRA if DRM_TEGRA +config DRM_TEGRA_STAGING + bool Enable HOST1X interface + depends on STAGING + default n + help + Say yes if HOST1X should be available for userspace DRM users. + + If unsure, choose N. + config DRM_TEGRA_DEBUG bool NVIDIA Tegra DRM debug support help diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c index c4e45c1..2b561c9 100644 --- a/drivers/gpu/host1x/drm/drm.c +++ b/drivers/gpu/host1x/drm/drm.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 Avionic Design GmbH - * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved. + * Copyright (C) 2012-2013 NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -14,6 +14,9 @@ #include linux/dma-mapping.h #include asm/dma-iommu.h +#include drm/drm.h +#include drm/drmP.h + #include host1x_client.h #include dev.h #include drm.h @@ -81,8 +84,10 @@ static int host1x_parse_dt(struct host1x_drm *host1x) static const char * const compat[] = { nvidia,tegra20-dc, nvidia,tegra20-hdmi, + nvidia,tegra20-gr2d, nvidia,tegra30-dc, nvidia,tegra30-hdmi, + nvidia,tegra30-gr2d, }; unsigned int i; int err; @@ -277,9 +282,24 @@ static int tegra_drm_unload(struct drm_device *drm) static int tegra_drm_open(struct drm_device *drm, struct drm_file *filp) { + struct host1x_drm_file *fpriv; + + fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL); + if (!fpriv) + return -ENOMEM; + + INIT_LIST_HEAD(fpriv-contexts); + filp-driver_priv = fpriv; + return 0; } +static void host1x_drm_context_free(struct host1x_drm_context *context) +{ + context-client-ops-close_channel(context); + kfree(context); +} + static void tegra_drm_lastclose(struct drm_device *drm) { struct host1x_drm *host1x = drm-dev_private; @@ -287,7 +307,190 @@ static void tegra_drm_lastclose(struct drm_device *drm) tegra_fbdev_restore_mode(host1x-fbdev); } +#ifdef CONFIG_DRM_TEGRA_STAGING +static bool host1x_drm_file_owns_context(struct host1x_drm_file *file, +struct host1x_drm_context *context) +{ + struct host1x_drm_context *ctx; + +