[PATCH 10/10] drm/exynos: added virtual display driver.

2012-03-13 Thread Inki Dae
this driver would be used for wireless display. virtual display
driver has independent crtc, encoder and connector and to use
this driver, user application should send edid data to this driver
from wireless display.

Signed-off-by: Inki Dae 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/Kconfig|6 +
 drivers/gpu/drm/exynos/Makefile   |1 +
 drivers/gpu/drm/exynos/exynos_drm_connector.c |4 +
 drivers/gpu/drm/exynos/exynos_drm_drv.c   |   18 +
 drivers/gpu/drm/exynos/exynos_drm_drv.h   |7 +-
 drivers/gpu/drm/exynos/exynos_drm_encoder.c   |1 +
 drivers/gpu/drm/exynos/exynos_drm_vidi.c  |  677 +
 drivers/gpu/drm/exynos/exynos_drm_vidi.h  |   36 ++
 include/drm/exynos_drm.h  |   20 +
 9 files changed, 768 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_vidi.c
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_vidi.h

diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 8493fe9..76aed3a 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -22,6 +22,12 @@ config DRM_EXYNOS_HDMI
help
  Choose this option if you want to use Exynos HDMI for DRM.

+config DRM_EXYNOS_VIDI
+   bool "Samsung DRM Virtual Display"
+   depends on DRM_EXYNOS
+   help
+ Choose this option if you want to use Samsung VIDI for DRM.
+
 config DRM_EXYNOS_G2D
bool "Exynos DRM G2D"
depends on DRM_EXYNOS
diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
index d6c1a3c..8ee8fb4 100644
--- a/drivers/gpu/drm/exynos/Makefile
+++ b/drivers/gpu/drm/exynos/Makefile
@@ -12,6 +12,7 @@ exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD)   += exynos_drm_fimd.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI)+= exynos_hdmi.o exynos_mixer.o \
   exynos_ddc.o exynos_hdmiphy.o \
   exynos_drm_hdmi.o
+exynosdrm-$(CONFIG_DRM_EXYNOS_VIDI)+= exynos_drm_vidi.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_G2D) += exynos_drm_g2d.o

 obj-$(CONFIG_DRM_EXYNOS)   += exynosdrm.o
diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c 
b/drivers/gpu/drm/exynos/exynos_drm_connector.c
index 33893a9..bf791fa 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_connector.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c
@@ -315,6 +315,10 @@ struct drm_connector *exynos_drm_connector_create(struct 
drm_device *dev,
connector->interlace_allowed = true;
connector->polled = DRM_CONNECTOR_POLL_HPD;
break;
+   case EXYNOS_DISPLAY_TYPE_VIDI:
+   type = DRM_MODE_CONNECTOR_VIRTUAL;
+   connector->polled = DRM_CONNECTOR_POLL_HPD;
+   break;
default:
type = DRM_MODE_CONNECTOR_Unknown;
break;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c 
b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 2b72c5d..76524f4 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -39,6 +39,7 @@
 #include "exynos_drm_gem.h"
 #include "exynos_drm_g2d.h"
 #include "exynos_drm_plane.h"
+#include "exynos_drm_vidi.h"

 #define DRIVER_NAME"exynos"
 #define DRIVER_DESC"Samsung SoC DRM"
@@ -217,6 +218,8 @@ static struct drm_ioctl_desc exynos_ioctls[] = {
exynos_drm_gem_mmap_ioctl, DRM_UNLOCKED | DRM_AUTH),
DRM_IOCTL_DEF_DRV(EXYNOS_PLANE_SET_ZPOS, exynos_plane_set_zpos_ioctl,
DRM_UNLOCKED | DRM_AUTH),
+   DRM_IOCTL_DEF_DRV(EXYNOS_VIDI_CONNECTION,
+   vidi_connection_ioctl, DRM_UNLOCKED | DRM_AUTH),

DRM_IOCTL_DEF_DRV(EXYNOS_G2D_GET_VER,
exynos_g2d_get_ver_ioctl, DRM_UNLOCKED | DRM_AUTH),
@@ -314,6 +317,12 @@ static int __init exynos_drm_init(void)
goto out_common_hdmi;
 #endif

+#ifdef CONFIG_DRM_EXYNOS_VIDI
+   ret = platform_driver_register(&vidi_driver);
+   if (ret < 0)
+   goto out_vidi;
+#endif
+
 #ifdef CONFIG_DRM_EXYNOS_G2D
ret = platform_driver_register(&g2d_driver);
if (ret < 0)
@@ -332,6 +341,11 @@ out:
 out_g2d:
 #endif

+#ifdef CONFIG_DRM_EXYNOS_VIDI
+   platform_driver_unregister(&vidi_driver);
+out_vidi:
+#endif
+
 #ifdef CONFIG_DRM_EXYNOS_HDMI
platform_driver_unregister(&exynos_drm_common_hdmi_driver);
 out_common_hdmi:
@@ -358,6 +372,10 @@ static void __exit exynos_drm_exit(void)
platform_driver_unregister(&g2d_driver);
 #endif

+#ifdef CONFIG_DRM_EXYNOS_VIDI
+   platform_driver_unregister(&vidi_driver);
+#endif
+
 #ifdef CONFIG_DRM_EXYNOS_HDMI
platform_driver_unregister(&exynos_drm_common_hdmi_driver);
platform_driver_unregister(&mixer_driver);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h 
b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index d7b50e5..943853a 100644

[PATCH 09/10] drm/exynos: add G2D driver

2012-03-13 Thread Inki Dae
From: Joonyoung Shim 

G2D is a 2D graphic accelerator that supports Bit Block Transfer. This
G2D driver is exynos drm specific and supports only exynos4x12 series.
user application fills command set in cmdlist and once dma start request
these cmdlists are parsed and performed by dma.

This adds below three exynos specific ioctl and one event for G2D.
 - DRM_EXYNOS_G2D_GET_VER
 - DRM_EXYNOS_G2D_SET_CMDLIST
 - DRM_EXYNOS_G2D_EXEC
 - DRM_EXYNOS_G2D_EVENT

Signed-off-by: Joonyoung Shim 
Signed-off-by: Inki Dae 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/Kconfig  |6 +
 drivers/gpu/drm/exynos/Makefile |1 +
 drivers/gpu/drm/exynos/exynos_drm_drv.c |   31 ++
 drivers/gpu/drm/exynos/exynos_drm_drv.h |   11 +
 drivers/gpu/drm/exynos/exynos_drm_g2d.c |  864 +++
 drivers/gpu/drm/exynos/exynos_drm_g2d.h |   36 ++
 include/drm/exynos_drm.h|   56 ++
 7 files changed, 1005 insertions(+), 0 deletions(-)
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_g2d.c
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_g2d.h

diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 9a9850a..8493fe9 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -21,3 +21,9 @@ config DRM_EXYNOS_HDMI
depends on DRM_EXYNOS && !VIDEO_SAMSUNG_S5P_TV
help
  Choose this option if you want to use Exynos HDMI for DRM.
+
+config DRM_EXYNOS_G2D
+   bool "Exynos DRM G2D"
+   depends on DRM_EXYNOS
+   help
+ Choose this option if you want to use Exynos G2D for DRM.
diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
index 5331fa3..d6c1a3c 100644
--- a/drivers/gpu/drm/exynos/Makefile
+++ b/drivers/gpu/drm/exynos/Makefile
@@ -12,5 +12,6 @@ exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD)   += exynos_drm_fimd.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI)+= exynos_hdmi.o exynos_mixer.o \
   exynos_ddc.o exynos_hdmiphy.o \
   exynos_drm_hdmi.o
+exynosdrm-$(CONFIG_DRM_EXYNOS_G2D) += exynos_drm_g2d.o

 obj-$(CONFIG_DRM_EXYNOS)   += exynosdrm.o
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c 
b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index b4e265f..2b72c5d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -37,6 +37,7 @@
 #include "exynos_drm_fbdev.h"
 #include "exynos_drm_fb.h"
 #include "exynos_drm_gem.h"
+#include "exynos_drm_g2d.h"
 #include "exynos_drm_plane.h"

 #define DRIVER_NAME"exynos"
@@ -146,8 +147,16 @@ static int exynos_drm_unload(struct drm_device *dev)

 static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
 {
+   struct drm_exynos_file_private *file_priv;
+
DRM_DEBUG_DRIVER("%s\n", __FILE__);

+   file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
+   if (!file_priv)
+   return -ENOMEM;
+
+   file->driver_priv = file_priv;
+
return exynos_drm_subdrv_open(dev, file);
 }

@@ -208,6 +217,13 @@ static struct drm_ioctl_desc exynos_ioctls[] = {
exynos_drm_gem_mmap_ioctl, DRM_UNLOCKED | DRM_AUTH),
DRM_IOCTL_DEF_DRV(EXYNOS_PLANE_SET_ZPOS, exynos_plane_set_zpos_ioctl,
DRM_UNLOCKED | DRM_AUTH),
+
+   DRM_IOCTL_DEF_DRV(EXYNOS_G2D_GET_VER,
+   exynos_g2d_get_ver_ioctl, DRM_UNLOCKED | DRM_AUTH),
+   DRM_IOCTL_DEF_DRV(EXYNOS_G2D_SET_CMDLIST,
+   exynos_g2d_set_cmdlist_ioctl, DRM_UNLOCKED | DRM_AUTH),
+   DRM_IOCTL_DEF_DRV(EXYNOS_G2D_EXEC,
+   exynos_g2d_exec_ioctl, DRM_UNLOCKED | DRM_AUTH),
 };

 static const struct file_operations exynos_drm_driver_fops = {
@@ -298,6 +314,12 @@ static int __init exynos_drm_init(void)
goto out_common_hdmi;
 #endif

+#ifdef CONFIG_DRM_EXYNOS_G2D
+   ret = platform_driver_register(&g2d_driver);
+   if (ret < 0)
+   goto out_g2d;
+#endif
+
ret = platform_driver_register(&exynos_drm_platform_driver);
if (ret < 0)
goto out;
@@ -305,6 +327,11 @@ static int __init exynos_drm_init(void)
return 0;

 out:
+#ifdef CONFIG_DRM_EXYNOS_G2D
+   platform_driver_unregister(&g2d_driver);
+out_g2d:
+#endif
+
 #ifdef CONFIG_DRM_EXYNOS_HDMI
platform_driver_unregister(&exynos_drm_common_hdmi_driver);
 out_common_hdmi:
@@ -327,6 +354,10 @@ static void __exit exynos_drm_exit(void)

platform_driver_unregister(&exynos_drm_platform_driver);

+#ifdef CONFIG_DRM_EXYNOS_G2D
+   platform_driver_unregister(&g2d_driver);
+#endif
+
 #ifdef CONFIG_DRM_EXYNOS_HDMI
platform_driver_unregister(&exynos_drm_common_hdmi_driver);
platform_driver_unregister(&mixer_driver);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h 
b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index b26c2f4..d7b50e5 100644
--- a/drivers/gpu/dr

[PATCH 08/10] drm/exynos: add is_local member in exynos_drm_subdrv struct

2012-03-13 Thread Inki Dae
From: Joonyoung Shim 

The is_local member indicates unused subdrv such connector and encoder
so doesn't make resources for them.

Signed-off-by: Joonyoung Shim 
Signed-off-by: Inki Dae 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_drm_core.c |3 +++
 drivers/gpu/drm/exynos/exynos_drm_drv.h  |2 ++
 2 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c 
b/drivers/gpu/drm/exynos/exynos_drm_core.c
index 4e29c71..411832e 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_core.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_core.c
@@ -59,6 +59,9 @@ static int exynos_drm_subdrv_probe(struct drm_device *dev,
return ret;
}

+   if (subdrv->is_local)
+   return 0;
+
/* create and initialize a encoder for this sub driver. */
encoder = exynos_drm_encoder_create(dev, &subdrv->manager,
(1 << MAX_CRTC) - 1);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h 
b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index a412454..b26c2f4 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -225,6 +225,7 @@ struct exynos_drm_private {
  * @list: sub driver has its own list object to register to exynos drm driver.
  * @drm_dev: pointer to drm_device and this pointer would be set
  * when sub driver calls exynos_drm_subdrv_register().
+ * @is_local: appear encoder and connector disrelated device.
  * @probe: this callback would be called by exynos drm driver after
  * subdrv is registered to it.
  * @remove: this callback is used to release resources created
@@ -239,6 +240,7 @@ struct exynos_drm_private {
 struct exynos_drm_subdrv {
struct list_head list;
struct drm_device *drm_dev;
+   bool is_local;

int (*probe)(struct drm_device *drm_dev, struct device *dev);
void (*remove)(struct drm_device *dev);
-- 
1.7.4.1



[PATCH 07/10] drm/exynos: add subdrv open/close functions

2012-03-13 Thread Inki Dae
From: Joonyoung Shim 

Some subdrv need open and close functions call when open and close drm.

Signed-off-by: Joonyoung Shim 
Signed-off-by: Inki Dae 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_drm_core.c |   35 ++
 drivers/gpu/drm/exynos/exynos_drm_drv.c  |   10 
 drivers/gpu/drm/exynos/exynos_drm_drv.h  |9 +++
 3 files changed, 54 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c 
b/drivers/gpu/drm/exynos/exynos_drm_core.c
index 937b059..4e29c71 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_core.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_core.c
@@ -175,3 +175,38 @@ int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv 
*subdrv)
return 0;
 }
 EXPORT_SYMBOL_GPL(exynos_drm_subdrv_unregister);
+
+int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file)
+{
+   struct exynos_drm_subdrv *subdrv;
+   int ret;
+
+   list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
+   if (subdrv->open) {
+   ret = subdrv->open(dev, subdrv->manager.dev, file);
+   if (ret)
+   goto err;
+   }
+   }
+
+   return 0;
+
+err:
+   list_for_each_entry_reverse(subdrv, &subdrv->list, list) {
+   if (subdrv->close)
+   subdrv->close(dev, subdrv->manager.dev, file);
+   }
+   return ret;
+}
+EXPORT_SYMBOL_GPL(exynos_drm_subdrv_open);
+
+void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file)
+{
+   struct exynos_drm_subdrv *subdrv;
+
+   list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
+   if (subdrv->close)
+   subdrv->close(dev, subdrv->manager.dev, file);
+   }
+}
+EXPORT_SYMBOL_GPL(exynos_drm_subdrv_close);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c 
b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index a2f8fae..b4e265f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -144,6 +144,13 @@ static int exynos_drm_unload(struct drm_device *dev)
return 0;
 }

+static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
+{
+   DRM_DEBUG_DRIVER("%s\n", __FILE__);
+
+   return exynos_drm_subdrv_open(dev, file);
+}
+
 static void exynos_drm_preclose(struct drm_device *dev,
struct drm_file *file)
 {
@@ -163,6 +170,8 @@ static void exynos_drm_preclose(struct drm_device *dev,
}
}
spin_unlock_irqrestore(&dev->event_lock, flags);
+
+   exynos_drm_subdrv_close(dev, file);
 }

 static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
@@ -216,6 +225,7 @@ static struct drm_driver exynos_drm_driver = {
  DRIVER_MODESET | DRIVER_GEM,
.load   = exynos_drm_load,
.unload = exynos_drm_unload,
+   .open   = exynos_drm_open,
.preclose   = exynos_drm_preclose,
.lastclose  = exynos_drm_lastclose,
.postclose  = exynos_drm_postclose,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h 
b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index f8bac0e..a412454 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -229,6 +229,8 @@ struct exynos_drm_private {
  * subdrv is registered to it.
  * @remove: this callback is used to release resources created
  * by probe callback.
+ * @open: this would be called with drm device file open.
+ * @close: this would be called with drm device file close.
  * @manager: subdrv has its own manager to control a hardware appropriately
  * and we can access a hardware drawing on this manager.
  * @encoder: encoder object owned by this sub driver.
@@ -240,6 +242,10 @@ struct exynos_drm_subdrv {

int (*probe)(struct drm_device *drm_dev, struct device *dev);
void (*remove)(struct drm_device *dev);
+   int (*open)(struct drm_device *drm_dev, struct device *dev,
+   struct drm_file *file);
+   void (*close)(struct drm_device *drm_dev, struct device *dev,
+   struct drm_file *file);

struct exynos_drm_manager manager;
struct drm_encoder *encoder;
@@ -269,6 +275,9 @@ int exynos_drm_subdrv_register(struct exynos_drm_subdrv 
*drm_subdrv);
 /* this function removes subdrv list from exynos drm driver */
 int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv *drm_subdrv);

+int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file);
+void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file);
+
 extern struct platform_driver fimd_driver;
 extern struct platform_driver hdmi_driver;
 extern struct platform_driver mixer_driver;
-- 
1.7.4.1



[PATCH 06/10] drm/exynos: remove module of exynos drm subdrv

2012-03-13 Thread Inki Dae
From: Joonyoung Shim 

The exynos drm driver has several subdrv. They each can be module but it
causes unfixed probe order of exynodr drm driver and each subdrv. It
also needs some weird codes such as exynos_drm_fbdev_reinit and
exynos_drm_mode_group_reinit. This patch can remove weird codes and
clear codes through we doesn't modularity each subdrv.

Also this removes unnecessary codes related module.

Signed-off-by: Joonyoung Shim 
Signed-off-by: Inki Dae 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/Kconfig|8 +--
 drivers/gpu/drm/exynos/Makefile   |   10 ++-
 drivers/gpu/drm/exynos/exynos_ddc.c   |1 -
 drivers/gpu/drm/exynos/exynos_drm_buf.c   |4 -
 drivers/gpu/drm/exynos/exynos_drm_connector.c |6 --
 drivers/gpu/drm/exynos/exynos_drm_core.c  |  112 ++---
 drivers/gpu/drm/exynos/exynos_drm_crtc.c  |6 --
 drivers/gpu/drm/exynos/exynos_drm_drv.c   |   52 +++-
 drivers/gpu/drm/exynos/exynos_drm_drv.h   |   12 ++--
 drivers/gpu/drm/exynos/exynos_drm_encoder.c   |6 --
 drivers/gpu/drm/exynos/exynos_drm_fb.c|6 --
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c |   86 ---
 drivers/gpu/drm/exynos/exynos_drm_fimd.c  |   20 +
 drivers/gpu/drm/exynos/exynos_drm_gem.c   |4 -
 drivers/gpu/drm/exynos/exynos_drm_hdmi.c  |   87 +--
 drivers/gpu/drm/exynos/exynos_hdmi.c  |9 --
 drivers/gpu/drm/exynos/exynos_mixer.c |7 --
 17 files changed, 77 insertions(+), 359 deletions(-)

diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index b9e5266..9a9850a 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -1,7 +1,6 @@
 config DRM_EXYNOS
tristate "DRM Support for Samsung SoC EXYNOS Series"
depends on DRM && PLAT_SAMSUNG
-   default n
select DRM_KMS_HELPER
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
@@ -12,16 +11,13 @@ config DRM_EXYNOS
  If M is selected the module will be called exynosdrm.

 config DRM_EXYNOS_FIMD
-   tristate "Exynos DRM FIMD"
+   bool "Exynos DRM FIMD"
depends on DRM_EXYNOS && !FB_S3C
-   default n
help
  Choose this option if you want to use Exynos FIMD for DRM.
- If M is selected, the module will be called exynos_drm_fimd

 config DRM_EXYNOS_HDMI
-   tristate "Exynos DRM HDMI"
+   bool "Exynos DRM HDMI"
depends on DRM_EXYNOS && !VIDEO_SAMSUNG_S5P_TV
help
  Choose this option if you want to use Exynos HDMI for DRM.
- If M is selected, the module will be called exynos_drm_hdmi
diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
index 395e69c..5331fa3 100644
--- a/drivers/gpu/drm/exynos/Makefile
+++ b/drivers/gpu/drm/exynos/Makefile
@@ -8,7 +8,9 @@ exynosdrm-y := exynos_drm_drv.o exynos_drm_encoder.o 
exynos_drm_connector.o \
exynos_drm_buf.o exynos_drm_gem.o exynos_drm_core.o \
exynos_drm_plane.o

-obj-$(CONFIG_DRM_EXYNOS) += exynosdrm.o
-obj-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o
-obj-$(CONFIG_DRM_EXYNOS_HDMI) += exynos_hdmi.o exynos_mixer.o exynos_ddc.o \
-exynos_hdmiphy.o exynos_drm_hdmi.o
+exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD)+= exynos_drm_fimd.o
+exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI)+= exynos_hdmi.o exynos_mixer.o \
+  exynos_ddc.o exynos_hdmiphy.o \
+  exynos_drm_hdmi.o
+
+obj-$(CONFIG_DRM_EXYNOS)   += exynosdrm.o
diff --git a/drivers/gpu/drm/exynos/exynos_ddc.c 
b/drivers/gpu/drm/exynos/exynos_ddc.c
index 84b614f..7e1051d 100644
--- a/drivers/gpu/drm/exynos/exynos_ddc.c
+++ b/drivers/gpu/drm/exynos/exynos_ddc.c
@@ -55,4 +55,3 @@ struct i2c_driver ddc_driver = {
.remove = __devexit_p(s5p_ddc_remove),
.command= NULL,
 };
-EXPORT_SYMBOL(ddc_driver);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c 
b/drivers/gpu/drm/exynos/exynos_drm_buf.c
index 554f674..0fb5ceb 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_buf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c
@@ -211,7 +211,3 @@ void exynos_drm_buf_destroy(struct drm_device *dev,
kfree(buffer);
buffer = NULL;
 }
-
-MODULE_AUTHOR("Inki Dae ");
-MODULE_DESCRIPTION("Samsung SoC DRM Buffer Management Module");
-MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c 
b/drivers/gpu/drm/exynos/exynos_drm_connector.c
index 303af60..33893a9 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_connector.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c
@@ -348,9 +348,3 @@ err_connector:
kfree(exynos_connector);
return NULL;
 }
-
-MODULE_AUTHOR("Inki Dae ");
-MODULE_AUTHOR("Joonyoung Shim ");
-MODULE_AUTHOR("Seung-Woo Kim ");
-MODULE_DESCRIPTION("Samsung SoC DRM Connector Driver"

[PATCH 05/10] drm/exynos: release pending pageflip events when closed

2012-03-13 Thread Inki Dae
From: Joonyoung Shim 

We should release pending pageflip events when closed. If not, they will
be dangling events.

Signed-off-by: Joonyoung Shim 
Signed-off-by: Inki Dae 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_drm_drv.c |   14 ++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c 
b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 09cc13f..aaa1b40 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -147,8 +147,22 @@ static int exynos_drm_unload(struct drm_device *dev)
 static void exynos_drm_preclose(struct drm_device *dev,
struct drm_file *file)
 {
+   struct exynos_drm_private *private = dev->dev_private;
+   struct drm_pending_vblank_event *e, *t;
+   unsigned long flags;
+
DRM_DEBUG_DRIVER("%s\n", __FILE__);

+   /* release events of current file */
+   spin_lock_irqsave(&dev->event_lock, flags);
+   list_for_each_entry_safe(e, t, &private->pageflip_event_list,
+   base.link) {
+   if (e->base.file_priv == file) {
+   list_del(&e->base.link);
+   e->base.destroy(&e->base);
+   }
+   }
+   spin_unlock_irqrestore(&dev->event_lock, flags);
 }

 static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
-- 
1.7.4.1



[PATCH 04/10] drm/exynos: added new funtion to get/put dma address.

2012-03-13 Thread Inki Dae
this function would be used for drm based 2d acceleration driver
to get/put dma address through gem handle.
when exynos_drm_get_dma_address is called reference count of
gem object would be increased not to be released by gem close and
when exynos_drm_put_dma_address is called the reference count of
this gem object would be decreased to be released.

Signed-off-by: Inki Dae 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c |   58 +++
 drivers/gpu/drm/exynos/exynos_drm_gem.h |   18 +
 2 files changed, 76 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 36d081d..ddcb7e3 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -377,6 +377,64 @@ int exynos_drm_gem_create_ioctl(struct drm_device *dev, 
void *data,
return 0;
 }

+void *exynos_drm_gem_get_dma_addr(struct drm_device *dev,
+   unsigned int gem_handle,
+   struct drm_file *file_priv)
+{
+   struct exynos_drm_gem_obj *exynos_gem_obj;
+   struct drm_gem_object *obj;
+
+   obj = drm_gem_object_lookup(dev, file_priv, gem_handle);
+   if (!obj) {
+   DRM_ERROR("failed to lookup gem object.\n");
+   return ERR_PTR(-EINVAL);
+   }
+
+   exynos_gem_obj = to_exynos_gem_obj(obj);
+
+   if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) {
+   DRM_DEBUG_KMS("not support NONCONTIG type.\n");
+   drm_gem_object_unreference_unlocked(obj);
+
+   /* TODO */
+   return ERR_PTR(-EINVAL);
+   }
+
+   return &exynos_gem_obj->buffer->dma_addr;
+}
+
+void exynos_drm_gem_put_dma_addr(struct drm_device *dev,
+   unsigned int gem_handle,
+   struct drm_file *file_priv)
+{
+   struct exynos_drm_gem_obj *exynos_gem_obj;
+   struct drm_gem_object *obj;
+
+   obj = drm_gem_object_lookup(dev, file_priv, gem_handle);
+   if (!obj) {
+   DRM_ERROR("failed to lookup gem object.\n");
+   return;
+   }
+
+   exynos_gem_obj = to_exynos_gem_obj(obj);
+
+   if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) {
+   DRM_DEBUG_KMS("not support NONCONTIG type.\n");
+   drm_gem_object_unreference_unlocked(obj);
+
+   /* TODO */
+   return;
+   }
+
+   drm_gem_object_unreference_unlocked(obj);
+
+   /*
+* decrease obj->refcount one more time because we has already
+* increased it at exynos_drm_gem_get_dma_addr().
+*/
+   drm_gem_object_unreference_unlocked(obj);
+}
+
 int exynos_drm_gem_map_offset_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
 {
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h 
b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index 096267d..e40fbad 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -88,6 +88,24 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct 
drm_device *dev,
 int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);

+/*
+ * get dma address from gem handle and this function could be used for
+ * other drivers such as 2d/3d acceleration drivers.
+ * with this function call, gem object reference count would be increased.
+ */
+void *exynos_drm_gem_get_dma_addr(struct drm_device *dev,
+   unsigned int gem_handle,
+   struct drm_file *file_priv);
+
+/*
+ * put dma address from gem handle and this function could be used for
+ * other drivers such as 2d/3d acceleration drivers.
+ * with this function call, gem object reference count would be decreased.
+ */
+void exynos_drm_gem_put_dma_addr(struct drm_device *dev,
+   unsigned int gem_handle,
+   struct drm_file *file_priv);
+
 /* get buffer offset to map to user space. */
 int exynos_drm_gem_map_offset_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-- 
1.7.4.1



[PATCH 03/10] drm/exynos: added buffer allocation type.

2012-03-13 Thread Inki Dae
with this patch, we can allocate physically continuous or non-continuous
memory and also it creates scatterlist for iommu support so allocated
memory region can be mapped to iommu page table using scatterlist.

Signed-off-by: Inki Dae 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_drm_buf.c   |  148 +--
 drivers/gpu/drm/exynos/exynos_drm_buf.h   |4 +-
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c |4 +-
 drivers/gpu/drm/exynos/exynos_drm_gem.c   |  284 ++---
 drivers/gpu/drm/exynos/exynos_drm_gem.h   |   11 +-
 include/drm/exynos_drm.h  |6 +
 6 files changed, 407 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c 
b/drivers/gpu/drm/exynos/exynos_drm_buf.c
index 3cf785c..554f674 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_buf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c
@@ -25,45 +25,151 @@

 #include "drmP.h"
 #include "drm.h"
+#include "exynos_drm.h"

 #include "exynos_drm_drv.h"
 #include "exynos_drm_gem.h"
 #include "exynos_drm_buf.h"

 static int lowlevel_buffer_allocate(struct drm_device *dev,
-   struct exynos_drm_gem_buf *buffer)
+   unsigned int flags, struct exynos_drm_gem_buf *buf)
 {
+   int ret = 0;
+
DRM_DEBUG_KMS("%s\n", __FILE__);

-   buffer->kvaddr = dma_alloc_writecombine(dev->dev, buffer->size,
-   &buffer->dma_addr, GFP_KERNEL);
-   if (!buffer->kvaddr) {
-   DRM_ERROR("failed to allocate buffer.\n");
-   return -ENOMEM;
+   /*
+* allocate only physically continuous memory and
+* non-continuous memory would be allocated by exynos
+* gem framework.
+*/
+   if (!(flags & EXYNOS_BO_NONCONTIG)) {
+   dma_addr_t start_addr, end_addr;
+   unsigned int npages, page_size, i = 0;
+   struct scatterlist *sgl;
+
+   if (buf->dma_addr) {
+   DRM_DEBUG_KMS("already allocated.\n");
+   return -EINVAL;
+   }
+
+   /*
+* according to desired size, it sets page size
+* for performance with using iommu so physically
+* continuous memory could be mapped to iommu in
+* multiple page size.
+*/
+   if (buf->size >= SZ_1M) {
+   npages = (buf->size >> SECTION_SHIFT) + 1;
+   page_size = SECTION_SIZE;
+   } else if (buf->size >= SZ_64K) {
+   npages = (buf->size >> 16) + 1;
+   page_size = SZ_64K;
+   } else {
+   npages = (buf->size >> PAGE_SHIFT) + 1;
+   page_size = PAGE_SIZE;
+   }
+
+   buf->sgt = kzalloc(sizeof(struct sg_table), GFP_KERNEL);
+   if (!buf->sgt) {
+   DRM_ERROR("failed to allocate sg table.\n");
+   return -ENOMEM;
+   }
+
+   ret = sg_alloc_table(buf->sgt, npages, GFP_KERNEL);
+   if (ret < 0) {
+   DRM_ERROR("failed to initialize sg table.\n");
+   kfree(buf->sgt);
+   buf->sgt = NULL;
+   return -ENOMEM;
+   }
+
+   buf->kvaddr = dma_alloc_writecombine(dev->dev, buf->size,
+   &buf->dma_addr, GFP_KERNEL);
+   if (!buf->kvaddr) {
+   DRM_ERROR("failed to allocate buffer.\n");
+   ret = -ENOMEM;
+   goto err1;
+   }
+
+   start_addr = buf->dma_addr;
+   end_addr = buf->dma_addr + buf->size;
+
+   buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL);
+   if (!buf->pages) {
+   DRM_ERROR("failed to allocate pages.\n");
+   ret = -ENOMEM;
+   goto err2;
+   }
+
+   sgl = buf->sgt->sgl;
+
+   while (i < npages) {
+   buf->pages[i] = phys_to_page(start_addr);
+   sg_set_page(sgl, buf->pages[i], page_size, 0);
+   sg_dma_address(sgl) = start_addr;
+   start_addr += page_size;
+   if (end_addr - start_addr < page_size)
+   break;
+   sgl = sg_next(sgl);
+   i++;
+   }
+
+   buf->pages[i] = phys_to_page(start_addr);
+
+   sgl = sg_next(sgl);
+   sg_set_page(sgl, buf->pages[i+1], end_addr - start_addr, 0);
}

DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n",
-   (unsigned long)buffer->kvaddr,
-   (unsigned long)buffer->dma_addr,
-   buffer->si

[PATCH 02/10] drm/exynos: added mode_fixup feature and code clean.

2012-03-13 Thread Inki Dae
this patch adds mode_fixup feature for hdmi module that
specific driver changes current mode to driver desired mode
properly.

Signed-off-by: Inki Dae 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_drm_connector.c |   25 +++-
 drivers/gpu/drm/exynos/exynos_drm_crtc.c  |6 ++-
 drivers/gpu/drm/exynos/exynos_drm_drv.h   |8 +++
 drivers/gpu/drm/exynos/exynos_drm_encoder.c   |   17 -
 drivers/gpu/drm/exynos/exynos_drm_hdmi.c  |   28 +
 drivers/gpu/drm/exynos/exynos_drm_hdmi.h  |5 ++
 drivers/gpu/drm/exynos/exynos_hdmi.c  |   81 ++--
 7 files changed, 157 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c 
b/drivers/gpu/drm/exynos/exynos_drm_connector.c
index 99d5527..303af60 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_connector.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c
@@ -225,6 +225,29 @@ static struct drm_connector_helper_funcs 
exynos_connector_helper_funcs = {
.best_encoder   = exynos_drm_best_encoder,
 };

+static int exynos_drm_connector_fill_modes(struct drm_connector *connector,
+   unsigned int max_width, unsigned int max_height)
+{
+   struct exynos_drm_connector *exynos_connector =
+   to_exynos_connector(connector);
+   struct exynos_drm_manager *manager = exynos_connector->manager;
+   struct exynos_drm_manager_ops *ops = manager->ops;
+   unsigned int width, height;
+
+   width = max_width;
+   height = max_height;
+
+   /*
+* if specific driver want to find desired_mode using maxmum
+* resolution then get max width and height from that driver.
+*/
+   if (ops && ops->get_max_resol)
+   ops->get_max_resol(manager->dev, &width, &height);
+
+   return drm_helper_probe_single_connector_modes(connector, width,
+   height);
+}
+
 /* get detection status of display device. */
 static enum drm_connector_status
 exynos_drm_connector_detect(struct drm_connector *connector, bool force)
@@ -262,7 +285,7 @@ static void exynos_drm_connector_destroy(struct 
drm_connector *connector)

 static struct drm_connector_funcs exynos_connector_funcs = {
.dpms   = drm_helper_connector_dpms,
-   .fill_modes = drm_helper_probe_single_connector_modes,
+   .fill_modes = exynos_drm_connector_fill_modes,
.detect = exynos_drm_connector_detect,
.destroy= exynos_drm_connector_destroy,
 };
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c 
b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index de81883..2d9a0e6 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -249,7 +249,11 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct 
drm_display_mode *mode,
 {
DRM_DEBUG_KMS("%s\n", __FILE__);

-   mode = adjusted_mode;
+   /*
+* copy the mode data adjusted by mode_fixup() into crtc->mode
+* so that hardware can be seet to proper mode.
+*/
+   memcpy(&crtc->mode, adjusted_mode, sizeof(*adjusted_mode));

return exynos_drm_crtc_update(crtc);
 }
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h 
b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 13540de..4115a9f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -155,8 +155,10 @@ struct exynos_drm_display_ops {
  *
  * @dpms: control device power.
  * @apply: set timing, vblank and overlay data to registers.
+ * @mode_fixup: fix mode data comparing to hw specific display mode.
  * @mode_set: convert drm_display_mode to hw specific display mode and
  *   would be called by encoder->mode_set().
+ * @get_max_resol: get maximum resolution to specific hardware.
  * @commit: set current hw specific display mode to hw.
  * @enable_vblank: specific driver callback for enabling vblank interrupt.
  * @disable_vblank: specific driver callback for disabling vblank interrupt.
@@ -164,7 +166,13 @@ struct exynos_drm_display_ops {
 struct exynos_drm_manager_ops {
void (*dpms)(struct device *subdrv_dev, int mode);
void (*apply)(struct device *subdrv_dev);
+   void (*mode_fixup)(struct device *subdrv_dev,
+   struct drm_connector *connector,
+   struct drm_display_mode *mode,
+   struct drm_display_mode *adjusted_mode);
void (*mode_set)(struct device *subdrv_dev, void *mode);
+   void (*get_max_resol)(struct device *subdrv_dev, unsigned int *width,
+   unsigned int *height);
void (*commit)(struct device *subdrv_dev);
int (*enable_vblank)(struct device *subdrv_dev);
void (*disable_vblank)(struct device *subdrv_dev);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c 
b/drivers

[PATCH 01/10] drm/exynos: add HDMI version 1.4 support

2012-03-13 Thread Inki Dae
Later Exynos series from Exynos4X12 support HDMI version 1.4. We will
distinguish to use which version via platform data.

Signed-off-by: Joonyoung Shim 
Signed-off-by: Inki Dae 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_hdmi.c | 1152 +++---
 drivers/gpu/drm/exynos/exynos_hdmi.h |   10 +-
 drivers/gpu/drm/exynos/regs-hdmi.h   |  306 --
 include/drm/exynos_drm.h |2 +
 4 files changed, 1325 insertions(+), 145 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 3429d3f..1cfe86e 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -43,42 +43,43 @@
 #define HDMI_OVERLAY_NUMBER3
 #define get_hdmi_context(dev)  platform_get_drvdata(to_platform_device(dev))

-static const u8 hdmiphy_conf27[32] = {
+/* HDMI Version 1.3 */
+static const u8 hdmiphy_v13_conf27[32] = {
0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
 };

-static const u8 hdmiphy_conf27_027[32] = {
+static const u8 hdmiphy_v13_conf27_027[32] = {
0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
 };

-static const u8 hdmiphy_conf74_175[32] = {
+static const u8 hdmiphy_v13_conf74_175[32] = {
0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
 };

-static const u8 hdmiphy_conf74_25[32] = {
+static const u8 hdmiphy_v13_conf74_25[32] = {
0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
 };

-static const u8 hdmiphy_conf148_5[32] = {
+static const u8 hdmiphy_v13_conf148_5[32] = {
0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
 };

-struct hdmi_tg_regs {
+struct hdmi_v13_tg_regs {
u8 cmd;
u8 h_fsz_l;
u8 h_fsz_h;
@@ -110,7 +111,7 @@ struct hdmi_tg_regs {
u8 field_bot_hdmi_h;
 };

-struct hdmi_core_regs {
+struct hdmi_v13_core_regs {
u8 h_blank[2];
u8 v_blank[3];
u8 h_v_line[3];
@@ -123,12 +124,21 @@ struct hdmi_core_regs {
u8 v_sync_gen3[3];
 };

-struct hdmi_preset_conf {
-   struct hdmi_core_regs core;
-   struct hdmi_tg_regs tg;
+struct hdmi_v13_preset_conf {
+   struct hdmi_v13_core_regs core;
+   struct hdmi_v13_tg_regs tg;
+};
+
+struct hdmi_v13_conf {
+   int width;
+   int height;
+   int vrefresh;
+   bool interlace;
+   const u8 *hdmiphy_data;
+   const struct hdmi_v13_preset_conf *conf;
 };

-static const struct hdmi_preset_conf hdmi_conf_480p = {
+static const struct hdmi_v13_preset_conf hdmi_v13_conf_480p = {
.core = {
.h_blank = {0x8a, 0x00},
.v_blank = {0x0d, 0x6a, 0x01},
@@ -154,7 +164,7 @@ static const struct hdmi_preset_conf hdmi_conf_480p = {
},
 };

-static const struct hdmi_preset_conf hdmi_conf_720p60 = {
+static const struct hdmi_v13_preset_conf hdmi_v13_conf_720p60 = {
.core = {
.h_blank = {0x72, 0x01},
.v_blank = {0xee, 0xf2, 0x00},
@@ -182,7 +192,7 @@ static const struct hdmi_preset_conf hdmi_conf_720p60 = {
},
 };

-static const struct hdmi_preset_conf hdmi_conf_1080i50 = {
+static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i50 = {
.core = {
.h_blank = {0xd0, 0x02},
.v_blank = {0x32, 0xB2, 0x00},
@@ -210,7 +220,7 @@ static const struct hdmi_preset_conf hdmi_conf_1080i50 = {
},
 };

-static const struct hdmi_preset_conf hdmi_conf_1080p50 = {
+static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p50 = {
.core = {
.h_blank = {0xd0, 0x02},
.v_blank = {0x65, 0x6c, 0x01},
@@ -238,7 +248,7 @@ static const struct hdmi_preset_conf hdmi_conf_1080p50 = {
},
 };

-static const struct hdmi_preset_conf hdmi_conf_1080i60 = {
+static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i60 = {
.core = {
.h_blank = {0x18, 0x01},
.v_blank = {0x32, 0xB2, 0x00},
@@ -266,7 +276,7 @@ static const struct hdmi_preset_conf hdmi_conf_1080i60 = {
},
 };

-static const struct hdmi_preset_conf hdmi_conf_1080p60 = {
+static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p60

[PATCH 00/10] updated exynos-drm-next

2012-03-13 Thread Inki Dae
Hi, Dave and all.

this patch set includes the following features.
- add HDMI version 1.4 support.
- add mode_fixup feature.
  . hdmi module would change current mode to driver desired mode properly.
- add buffer alloction type.
  . we can allocate physically continuous or non-continuous
memory and also it creates scatterlist for iommu support so allocated
memory region can be mapped to iommu page table using scatterlist.
- add dma address get/put interface.
  . this function would be used for drm based 2d acceleration driver
to get/put dma address through gem handle.
when exynos_drm_get_dma_address is called reference count of
gem object would be increased not to be released by gem close and
when exynos_drm_put_dma_address is called the reference count of
this gem object would be decreased to be released.
- add virtual display driver.
  . this driver would be used for wireless display.
- add direct rendering based 2d graphics acceleration module.
  . exynos SoC chip has fimg2d named 2d graphics accelerator and this driver
supports only exynos4x12 series.


this patch set is based on git repository below:
git://git.infradead.org/users/kmpark/linux-samsung exynos-drm-fixes
commit-id: f6d69d1e77509d71c29f2a7b119214b8fdf86ae2

and exynos-drm-fixes is based on git repository below:
git://people.freedesktop.org/~airlied/linux.git drm-fixes
commit-id: 38aa4a568ba4c3ccba83e862a01e3e60e3b811ee

P.S.
drm-next doesn't reflect updated latest codes of mainline so this patch set
should be merged to drm-next after latest mainline codes are merged to
drm-next. now is just for review and if latest codes are merged to drm-next
then I will merge this patch set to exynos-drm-next for git pull request.

Thanks.

Inki Dae (5):
  drm/exynos: add HDMI version 1.4 support
  drm/exynos: added mode_fixup feature and code clean.
  drm/exynos: added buffer allocation type.
  drm/exynos: added new funtion to get/put dma address.
  drm/exynos: added virtual display driver.

Joonyoung Shim (5):
  drm/exynos: release pending pageflip events when closed
  drm/exynos: remove module of exynos drm subdrv
  drm/exynos: add subdrv open/close functions
  drm/exynos: add is_local member in exynos_drm_subdrv struct
  drm/exynos: add G2D driver

 drivers/gpu/drm/exynos/Kconfig|   20 +-
 drivers/gpu/drm/exynos/Makefile   |   12 +-
 drivers/gpu/drm/exynos/exynos_ddc.c   |1 -
 drivers/gpu/drm/exynos/exynos_drm_buf.c   |  152 +++-
 drivers/gpu/drm/exynos/exynos_drm_buf.h   |4 +-
 drivers/gpu/drm/exynos/exynos_drm_connector.c |   35 +-
 drivers/gpu/drm/exynos/exynos_drm_core.c  |  140 +--
 drivers/gpu/drm/exynos/exynos_drm_crtc.c  |   12 +-
 drivers/gpu/drm/exynos/exynos_drm_drv.c   |  125 +++-
 drivers/gpu/drm/exynos/exynos_drm_drv.h   |   49 +-
 drivers/gpu/drm/exynos/exynos_drm_encoder.c   |   24 +-
 drivers/gpu/drm/exynos/exynos_drm_fb.c|6 -
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c |   90 +--
 drivers/gpu/drm/exynos/exynos_drm_fimd.c  |   20 +-
 drivers/gpu/drm/exynos/exynos_drm_g2d.c   |  864 +
 drivers/gpu/drm/exynos/exynos_drm_g2d.h   |   36 +
 drivers/gpu/drm/exynos/exynos_drm_gem.c   |  346 +++-
 drivers/gpu/drm/exynos/exynos_drm_gem.h   |   29 +-
 drivers/gpu/drm/exynos/exynos_drm_hdmi.c  |  115 +--
 drivers/gpu/drm/exynos/exynos_drm_hdmi.h  |5 +
 drivers/gpu/drm/exynos/exynos_drm_vidi.c  |  677 ++
 drivers/gpu/drm/exynos/exynos_drm_vidi.h  |   36 +
 drivers/gpu/drm/exynos/exynos_hdmi.c  | 1234 ++---
 drivers/gpu/drm/exynos/exynos_hdmi.h  |   10 +-
 drivers/gpu/drm/exynos/exynos_mixer.c |7 -
 drivers/gpu/drm/exynos/regs-hdmi.h|  306 ++-
 include/drm/exynos_drm.h  |   84 ++
 27 files changed, 3879 insertions(+), 560 deletions(-)
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_g2d.c
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_g2d.h
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_vidi.c
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_vidi.h

-- 
1.7.4.1



[Bug 47289] New: SIGSEGV at r300_state.c:1066

2012-03-13 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=47289

 Bug #: 47289
   Summary: SIGSEGV at r300_state.c:1066
Classification: Unclassified
   Product: Mesa
   Version: 7.11
  Platform: x86-64 (AMD64)
OS/Version: FreeBSD
Status: NEW
  Severity: critical
  Priority: medium
 Component: Drivers/DRI/r300
AssignedTo: dri-devel at lists.freedesktop.org
ReportedBy: rfg-freedesktop at tristatelogic.com


I have been using a program called "gthumb" for some time now, and it
has worked well for me.

Recently, I upgraded some of my hardware.  Specifically, I bought a new
monitor and a nice "X600" (Radeon) card to hang that off of.  Since then,
gthumb crashes consistantly, shortly after startup.  (I'm on FreeBSD 8.2,
by the way.)

I made some modest efforts to try to find out what was going on, but frankly,
this graphics stuff is pretty much all greek to me.  I did however rebuild
and re-install both gthumb and dri with debugging info so that I could at
least get a stack trace from the coredump file.

So here is some (gdb) context for the SIGSEGV crash of gthumb:

#0  0x000805453233 in r300UpdateWindow (ctx=0x80534a000)
at r300_state.c:1066
1066GLfloat sx = v[MAT_SX];
[New Thread 8052041c0 (LWP 100247)]
(gdb) where
#0  0x000805453233 in r300UpdateWindow (ctx=0x80534a000)
at r300_state.c:1066
#1  0x000805456a83 in r300ResetHwState (r300=0x8052f8000)
at r300_state.c:2195
#2  0x0008054588ec in r300InitState (r300=0x8052f8000) at r300_state.c:2750
#3  0x0008054451fd in r300CreateContext (glVisual=0x805308700, 
driContextPriv=0x80524d220, sharedContextPrivate=0x0) at r300_context.c:382
#4  0x00080543b5bf in radeonCreateContext (glVisual=0x805308700, 
driContextPriv=0x80524d220, sharedContextPriv=0x0) at radeon_screen.c:1143
#5  0x000805435793 in driCreateNewContext (psp=0x80524e480, 
config=0x805308700, render_type=32788, shared=0x0, hwContext=3, 
data=0x80524d1f0) at ../common/dri_util.c:587
#6  0x000802f2d70f in driCreateContext () from /usr/local/lib/libGL.so.1
#7  0x000802f08320 in CreateContext () from /usr/local/lib/libGL.so.1
#8  0x000802f086dc in glXCreateNewContext () from /usr/local/lib/libGL.so.1
#9  0x000800a61255 in cogl_pango_glyph_cache_new ()
   from /usr/local/lib/libclutter-glx-1.0.so.0
#10 0x0008009ebfdb in clutter_feature_available ()
   from /usr/local/lib/libclutter-glx-1.0.so.0
#11 0x0008009f6045 in clutter_get_option_group_without_init ()
   from /usr/local/lib/libclutter-glx-1.0.so.0
#12 0x0008009f626f in clutter_init ()
   from /usr/local/lib/libclutter-glx-1.0.so.0
#13 0x004c3b59 in main (argc=1, argv=0x7fffe300) at main.c:561
(gdb) print v
$1 = (const GLfloat *) 0x8
(gdb) print *$1
Cannot access memory at address 0x8
(gdb) 


I did some grepping around and found that MAT_SX is #defined to the value 0.
Thus, the gdb command "print v[0]" or equivalently "print *v" should give a
clearer picture of what is causing the problem, and as you can see, indeed
it does.  The process virtual space at 0x8 is apparently not mapped
in.  Thus, the attempt to fetch the contents of v[MAT_SX] quite reasonably
results in a SIGSEGV and a coredump.

After getting this far, I read the page:

   http://dri.freedesktop.org/wiki/DriTroubleshooting

and checked everything I could that was listed there and all seems to be
well.  The radeon.ko module does seem to be loaded into the kernel, and the
folliowing line does exist in my /var/log/Xorg.0.log file:

(II) RADEON(0): Direct rendering enabled

Additionally, after doing "setenv LIBGL_DEBUG verbose" and re-running
gthumb, most everything seems to be OK, however it is apparent that
there are a couple of (optional?) DRI configuration files that simply
are not present.  (Do I need to have one or both of these?)

% gthumb .
libGL: XF86DRIGetClientDriverName: 5.3.0 r300 (screen 0)
libGL: OpenDriver: trying /usr/local/lib/dri/r300_dri.so
drmOpenDevice: node name is /dev/dri/card0
drmOpenDevice: open result is 6, (OK)
drmOpenByBusid: Searching for BusID pci::02:00.0
drmOpenDevice: node name is /dev/dri/card0
drmOpenDevice: open result is 6, (OK)
drmOpenByBusid: drmOpenMinor returns 6
drmOpenByBusid: drmGetBusid reports pci::02:00.0
libGL error: 
Can't open configuration file /etc/drirc: No such file or directory.
libGL error: 
Can't open configuration file /usr/home/rfg/.drirc: No such file or directory.
Segmentation fault (core dumped)


So anyway, long story short, I could use some help here.  I'd kinda like
to be able to run gthumb again, you know, without it crashing right off
the bat.

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.


[Bug 42923] New: External monitor on display port has no sync with radeon driver

2012-03-13 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=42923

   Summary: External monitor on display port has no sync with
radeon driver
   Product: Drivers
   Version: 2.5
Kernel Version: 3.3.0
  Platform: All
OS/Version: Linux
  Tree: Mainline
Status: NEW
  Severity: normal
  Priority: P1
 Component: Video(DRI - non Intel)
AssignedTo: drivers_video-dri at kernel-bugs.osdl.org
ReportedBy: bghome at gmail.com
Regression: No


Description and steps to reproduce can be found here:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/952486

Actual Results: An empty screen on external monitor complaining about input
timing.
Expected Results: GNOME desktop should have shown on external monitor.
Build Date & Platform: Build 2012-03-09 on Ubuntu 12.04

-- 
Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are watching the assignee of the bug.


[Bug 46713] HDMI audio played back at a wrong rate

2012-03-13 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=46713

--- Comment #17 from Rafa? Mi?ecki  2012-03-13 12:05:38 
PDT ---
If you wish, you can try switching to radeon and:
1) Start playback
2) Make sure speed is still wrong
3) Execute: "avivotool regset 0x05b0 0x000ea600"
4) Execute: "avivotool regset 0x05bc 0x0072"

Does it help?

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.


[Bug 46713] HDMI audio played back at a wrong rate

2012-03-13 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=46713

--- Comment #16 from Rafa? Mi?ecki  2012-03-13 12:04:19 
PDT ---
Tvrtko: thanks a lot for your effort and dumps coming from fglrx.

What I can say now: it seems fglrx is using the same registers
(EVERGREEN_AUDIO_PLL1_MUL and EVERGREEN_AUDIO_PLL1_DIV) for your card.

However:
1) radeon uses 480'000 for MUL
2) fglrx uses 960'000 for MUL

On the other hand fglrx uses 0x72 instead of 0x71 for EVERGREEN_AUDIO_PLL1_UNK.
Maybe that 0x2 is some DIV? Maybe it tells GPU to take 960'000 and divide it by
2?

I've to investigate meaning of the register, but you gave me a track to follow,
thanks a lot for your effors! I'll take a look on that after my vacations (next
week).

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.


[korg]help: How to submit a kernel driver on kernel.org.

2012-03-13 Thread Aaron.Chen 陈俊杰
Hi Ilija,

Thank you for your reply. We will check the coding style next time.

I don't know about the license thing. Is there any different license for 
choosing?

Regards
Aaron

--
???: Ilija Hadzic [mailto:ihadzic at research.bell-labs.com] 
: 2012?3?10? 0:30
???: Aaron.Chen ???
??: Paul Menzel; Alex Deucher; dri-devel at lists.freedesktop.org; caesar.qiu 
???
??: Re: ??: [korg]help: How to submit a kernel driver on kernel.org.


A couple of non-technical things. First, I think you are sending the patch 
to the wrong list. dri-devel is for drivers that go under drivers/gpu/drm. 
Your driver is apparently fbdev driver and thus belongs to 
linux-fbdev at vger.kernel.org list (see the Maintainers file)

Second, your patch generates about 9000 coding style errors when you run 
through ./scripts/checkpatch.pl script available in the Linux kernel tree. 
You need to clean up. See also Documentation/CodingStyle. Also, you must 
break up the patch into smaller self-contained units that logically make 
sense. Nobody can review 17000 lines of code in one shot.

Last, but probably the most important. All your files have the proprietary 
license in the comment overhead. You (actually your company lawyers) have 
to decide which license you are releasing this dirver under and make sure 
it is compatible with Linux kernel (i.e. GPL) and you have to state that 
in each file that is being added.

-- Ilija


On Fri, 9 Mar 2012, [utf-8] Aaron.Chen  ~Y~H~J~] wrote:

> Hi Paul&Alex,
>
> Thank you very much for your great help.
>
> Here is the first patch.
>
> Regards
> Aaron
>
> --
> ???: Paul Menzel [mailto:paulepanter at users.sourceforge.net]
> : 2012?3?6? 22:38
> ???: Alex Deucher
> ??: Aaron.Chen ???; caesar.qiu ???; dri-devel at lists.freedesktop.org
> ??: Re: [korg]help: How to submit a kernel driver on kernel.org.
>
> Dear Aaron,
>
>
> Am Dienstag, den 06.03.2012, 08:47 -0500 schrieb Alex Deucher:
>> On Mon, Mar 5, 2012 at 11:13 PM, Aaron.Chen  ??? wrote:
>
>>> Thank you very much for your guide. It's a great help for me.
>>>
>>> But I still have a little problem with the patch thing. I'm not familiar 
>>> with the git.
>>> 1.Shall I need to do the clone and get the source location and target 
>>> directory first?
>>> 2.Where is the source location and target directory?
>>> 3.Our driver has pass the customer's test from kernel version 2.6.5 to 
>>> 3.0.0, So what shall I do to submit a driver cover all these kernel version.
>
> you can only get new features included upstream in the latest Linux kernel. 
> So earliest version would be 3.4. You have to maintain you own repository for 
> earlier version. But backporting should be not so much trouble if you have it 
> included upstream.
>
>>> 4.or just email you the source code and tell you the changes?
>>>
>>> I'm looking forward your re-guide. Thank you so much.
>>
>> Your best bet it to clone Linus' git tree and then apply your patches:
>>
>> 1. clone Linus' git tree:
>> git clone
>> git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
>
> you can do this in between.
>
>cd linux
>git config --global user.name "??? (Aaron Chen)"
>git config --global user.email aaron.chen at siliconmotion.com
>
>> 2.a) apply your first patch
>>b)  if you patch adds new files to the source tree, add them:
>> git add path/to/files/file.c
>> git add path/to/files/file.h
>> etc.  if the patch only modifies patches that are already
>> in the tree, you do not need to add them.
>>c) when the patch is applied commit it:
>>git commit -a -s
>>d) when you run the commit command you will be prompted to
>> enter a commit message.  The commit message has the following format:
>>
>> subsystem: patch description
>>
>> description of what the patch does.
>>
>> Signed-off-by: Your name 
>>
>> E.g.,
>>
>> fb: add initial code for video 5000 graphics
>>
>> This adds the initial support for the video 5000 graphics adapter.  It
>> supports vga and lcd connectors.
>>
>> Signed-off-by: Joe Developer 
>>
>> e) repeat steps a-d for all of your patches 3. generate patches:
>> git format-patch -n
>>
>> where n is the number of patches you committed.  E.g., if your driver
>> consists of 5 patches:
>> git format-patch -5
>>
>> 4. Send the patches to the list.
>
> Aaron, Git is nowadays documented pretty well. So just use
>
>git help command
>
> (like `git help commit`) to read the manual. Additionally you can just search 
> for it using your favorite search engine. Interesting reads should be 
> [1][2][3].
>
>
> Thanks,
>
> Paul
>
>
> [1] http://schacon.github.com/git/user-manual.html#cleaning-up-history
> [2] http://git-scm.com/documentation
> [3] http://progit.org/book/
>


[PATCH] omap2+: add drm device

2012-03-13 Thread Rob Clark
From: Andy Gross 

Register OMAP DRM/KMS platform device, and reserve a CMA region for
the device to use for buffer allocation.  DMM is split into a
separate device using hwmod.

Signed-off-by: Andy Gross 
Signed-off-by: Rob Clark 
---
 arch/arm/mach-omap2/Makefile  |4 ++
 arch/arm/mach-omap2/drm.c |   83 +
 arch/arm/plat-omap/common.c   |3 +-
 arch/arm/plat-omap/include/plat/drm.h |   64 +
 4 files changed, 153 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-omap2/drm.c
 create mode 100644 arch/arm/plat-omap/include/plat/drm.h

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index bd76394..9e6065b 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -189,6 +189,10 @@ ifneq ($(CONFIG_TIDSPBRIDGE),)
 obj-y  += dsp.o
 endif

+ifneq ($(CONFIG_DRM_OMAP),)
+obj-y  += drm.o
+endif
+
 # Specific board support
 obj-$(CONFIG_MACH_OMAP_GENERIC)+= board-generic.o
 obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o
diff --git a/arch/arm/mach-omap2/drm.c b/arch/arm/mach-omap2/drm.c
new file mode 100644
index 000..779ae02
--- /dev/null
+++ b/arch/arm/mach-omap2/drm.c
@@ -0,0 +1,83 @@
+/*
+ * DRM/KMS device registration for TI OMAP platforms
+ *
+ * Copyright (C) 2012 Texas Instruments
+ * Author: Rob Clark 
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#ifdef CONFIG_CMA
+#  include 
+#endif
+
+#include 
+#include 
+
+#include 
+
+#if defined(CONFIG_DRM_OMAP) || (CONFIG_DRM_OMAP_MODULE)
+
+static struct omap_drm_platform_data omapdrm_platdata;
+
+static struct platform_device omap_drm_device = {
+   .dev = {
+   .coherent_dma_mask = DMA_BIT_MASK(32),
+   .platform_data = &omapdrm_platdata,
+   },
+   .name = "omapdrm",
+   .id = 0,
+};
+
+static int __init omap_init_drm(void)
+{
+   struct omap_hwmod *oh = NULL;
+   struct platform_device *pdev;
+
+   /* lookup and populate the DMM information, if present - OMAP4+ */
+   oh = omap_hwmod_lookup("dmm");
+
+   if (oh) {
+   pdev = omap_device_build(oh->name, -1, oh, NULL, 0, NULL, 0,
+   false);
+   WARN(IS_ERR(pdev), "Could not build omap_device for %s\n",
+   oh->name);
+   }
+
+   return platform_device_register(&omap_drm_device);
+
+}
+
+arch_initcall(omap_init_drm);
+
+void omapdrm_reserve_vram(void)
+{
+#ifdef CONFIG_CMA
+   /*
+* Create private 32MiB contiguous memory area for omapdrm.0 device
+* TODO revisit size.. if uc/wc buffers are allocated from CMA pages
+* then the amount of memory we need goes up..
+*/
+   dma_declare_contiguous(&omap_drm_device.dev, 32 * SZ_1M, 0, 0);
+#else
+#  warning "CMA is not enabled, there may be limitations about scanout buffer 
allocations on OMAP3 and earlier"
+#endif
+}
+
+#endif
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index 4de7d1e..e027cc7 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -21,10 +21,10 @@
 #include 
 #include 
 #include 
+#include 

 #include 

-
 #define NO_LENGTH_CHECK 0x

 struct omap_board_config_kernel *omap_board_config __initdata;
@@ -65,6 +65,7 @@ const void *__init omap_get_var_config(u16 tag, size_t *len)

 void __init omap_reserve(void)
 {
+   omapdrm_reserve_vram();
omapfb_reserve_sdram_memblock();
omap_vram_reserve_sdram_memblock();
omap_dsp_reserve_sdram_memblock();
diff --git a/arch/arm/plat-omap/include/plat/drm.h 
b/arch/arm/plat-omap/include/plat/drm.h
new file mode 100644
index 000..df9bc41
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/drm.h
@@ -0,0 +1,64 @@
+/*
+ * DRM/KMS device registration for TI OMAP platforms
+ *
+ * Copyright (C) 2012 Texas Instruments
+ * Author: Rob Clark 
+ *
+ * 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

[PATCH] drm/i915: no-lvds quirk on MSI DC500

2012-03-13 Thread Anisse Astier
Any opinion on this quirk ?

On Wed,  7 Mar 2012 18:36:35 +0100, Anisse Astier  wrote :

> This hardware doesn't have an LVDS, it's a desktop box. Fix incorrect
> LVDS detection.
> 
> Cc: stable at kernel.org
> Signed-off-by: Anisse Astier 
> ---
>  drivers/gpu/drm/i915/intel_lvds.c |8 
>  1 files changed, 8 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_lvds.c 
> b/drivers/gpu/drm/i915/intel_lvds.c
> index b103c3b..2dee11e 100644
> --- a/drivers/gpu/drm/i915/intel_lvds.c
> +++ b/drivers/gpu/drm/i915/intel_lvds.c
> @@ -739,6 +739,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
>   DMI_MATCH(DMI_BOARD_NAME, "AT5NM10T-I"),
>   },
>   },
> + {
> + .callback = intel_no_lvds_dmi_callback,
> + .ident = "MSI Wind Box DC500",
> + .matches = {
> + DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL 
> CO., LTD"),
> + DMI_MATCH(DMI_BOARD_NAME, "MS-7469"),
> + },
> + },
>  
>   { } /* terminating entry */
>  };


Re: [PATCH -next] vgaarb.h: fix build warnings

2012-03-13 Thread Randy Dunlap
On 01/30/2012 11:43 AM, Randy Dunlap wrote:

This patch is still needed in linux-next of 20120313.


> From: Randy Dunlap 
> 
> Fix build warnings by providing a struct stub since no fields of
> the struct are used:
> 
> include/linux/vgaarb.h:66:9: warning: 'struct pci_dev' declared inside 
> parameter list
> include/linux/vgaarb.h:66:9: warning: its scope is only this definition or 
> declaration, which is probably not what you want
> include/linux/vgaarb.h:99:34: warning: 'struct pci_dev' declared inside 
> parameter list
> include/linux/vgaarb.h:109:6: warning: 'struct pci_dev' declared inside 
> parameter list
> include/linux/vgaarb.h:121:8: warning: 'struct pci_dev' declared inside 
> parameter list
> include/linux/vgaarb.h:140:37: warning: 'struct pci_dev' declared inside 
> parameter list
> 
> Signed-off-by: Randy Dunlap 
> Cc:   David Airlie 
> Cc:   dri-devel@lists.freedesktop.org
> ---
>  include/linux/vgaarb.h |2 ++
>  1 file changed, 2 insertions(+)
> 
> --- linux-next-20120130.orig/include/linux/vgaarb.h
> +++ linux-next-20120130/include/linux/vgaarb.h
> @@ -47,6 +47,8 @@
>   */
>  #define VGA_DEFAULT_DEVICE (NULL)
>  
> +struct pci_dev;
> +
>  /* For use by clients */
>  
>  /**
> 



-- 
~Randy
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 47289] New: SIGSEGV at r300_state.c:1066

2012-03-13 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=47289

 Bug #: 47289
   Summary: SIGSEGV at r300_state.c:1066
Classification: Unclassified
   Product: Mesa
   Version: 7.11
  Platform: x86-64 (AMD64)
OS/Version: FreeBSD
Status: NEW
  Severity: critical
  Priority: medium
 Component: Drivers/DRI/r300
AssignedTo: dri-devel@lists.freedesktop.org
ReportedBy: rfg-freedesk...@tristatelogic.com


I have been using a program called "gthumb" for some time now, and it
has worked well for me.

Recently, I upgraded some of my hardware.  Specifically, I bought a new
monitor and a nice "X600" (Radeon) card to hang that off of.  Since then,
gthumb crashes consistantly, shortly after startup.  (I'm on FreeBSD 8.2,
by the way.)

I made some modest efforts to try to find out what was going on, but frankly,
this graphics stuff is pretty much all greek to me.  I did however rebuild
and re-install both gthumb and dri with debugging info so that I could at
least get a stack trace from the coredump file.

So here is some (gdb) context for the SIGSEGV crash of gthumb:

#0  0x000805453233 in r300UpdateWindow (ctx=0x80534a000)
at r300_state.c:1066
1066GLfloat sx = v[MAT_SX];
[New Thread 8052041c0 (LWP 100247)]
(gdb) where
#0  0x000805453233 in r300UpdateWindow (ctx=0x80534a000)
at r300_state.c:1066
#1  0x000805456a83 in r300ResetHwState (r300=0x8052f8000)
at r300_state.c:2195
#2  0x0008054588ec in r300InitState (r300=0x8052f8000) at r300_state.c:2750
#3  0x0008054451fd in r300CreateContext (glVisual=0x805308700, 
driContextPriv=0x80524d220, sharedContextPrivate=0x0) at r300_context.c:382
#4  0x00080543b5bf in radeonCreateContext (glVisual=0x805308700, 
driContextPriv=0x80524d220, sharedContextPriv=0x0) at radeon_screen.c:1143
#5  0x000805435793 in driCreateNewContext (psp=0x80524e480, 
config=0x805308700, render_type=32788, shared=0x0, hwContext=3, 
data=0x80524d1f0) at ../common/dri_util.c:587
#6  0x000802f2d70f in driCreateContext () from /usr/local/lib/libGL.so.1
#7  0x000802f08320 in CreateContext () from /usr/local/lib/libGL.so.1
#8  0x000802f086dc in glXCreateNewContext () from /usr/local/lib/libGL.so.1
#9  0x000800a61255 in cogl_pango_glyph_cache_new ()
   from /usr/local/lib/libclutter-glx-1.0.so.0
#10 0x0008009ebfdb in clutter_feature_available ()
   from /usr/local/lib/libclutter-glx-1.0.so.0
#11 0x0008009f6045 in clutter_get_option_group_without_init ()
   from /usr/local/lib/libclutter-glx-1.0.so.0
#12 0x0008009f626f in clutter_init ()
   from /usr/local/lib/libclutter-glx-1.0.so.0
#13 0x004c3b59 in main (argc=1, argv=0x7fffe300) at main.c:561
(gdb) print v
$1 = (const GLfloat *) 0x8
(gdb) print *$1
Cannot access memory at address 0x8
(gdb) 


I did some grepping around and found that MAT_SX is #defined to the value 0.
Thus, the gdb command "print v[0]" or equivalently "print *v" should give a
clearer picture of what is causing the problem, and as you can see, indeed
it does.  The process virtual space at 0x8 is apparently not mapped
in.  Thus, the attempt to fetch the contents of v[MAT_SX] quite reasonably
results in a SIGSEGV and a coredump.

After getting this far, I read the page:

   http://dri.freedesktop.org/wiki/DriTroubleshooting

and checked everything I could that was listed there and all seems to be
well.  The radeon.ko module does seem to be loaded into the kernel, and the
folliowing line does exist in my /var/log/Xorg.0.log file:

(II) RADEON(0): Direct rendering enabled

Additionally, after doing "setenv LIBGL_DEBUG verbose" and re-running
gthumb, most everything seems to be OK, however it is apparent that
there are a couple of (optional?) DRI configuration files that simply
are not present.  (Do I need to have one or both of these?)

% gthumb .
libGL: XF86DRIGetClientDriverName: 5.3.0 r300 (screen 0)
libGL: OpenDriver: trying /usr/local/lib/dri/r300_dri.so
drmOpenDevice: node name is /dev/dri/card0
drmOpenDevice: open result is 6, (OK)
drmOpenByBusid: Searching for BusID pci::02:00.0
drmOpenDevice: node name is /dev/dri/card0
drmOpenDevice: open result is 6, (OK)
drmOpenByBusid: drmOpenMinor returns 6
drmOpenByBusid: drmGetBusid reports pci::02:00.0
libGL error: 
Can't open configuration file /etc/drirc: No such file or directory.
libGL error: 
Can't open configuration file /usr/home/rfg/.drirc: No such file or directory.
Segmentation fault (core dumped)


So anyway, long story short, I could use some help here.  I'd kinda like
to be able to run gthumb again, you know, without it crashing right off
the bat.

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.
___
dri-devel mailing list
dri-devel@lists.freedeskto

[PATCH -next] vgaarb.h: fix build warnings

2012-03-13 Thread Randy Dunlap
On 01/30/2012 11:43 AM, Randy Dunlap wrote:

This patch is still needed in linux-next of 20120313.


> From: Randy Dunlap 
> 
> Fix build warnings by providing a struct stub since no fields of
> the struct are used:
> 
> include/linux/vgaarb.h:66:9: warning: 'struct pci_dev' declared inside 
> parameter list
> include/linux/vgaarb.h:66:9: warning: its scope is only this definition or 
> declaration, which is probably not what you want
> include/linux/vgaarb.h:99:34: warning: 'struct pci_dev' declared inside 
> parameter list
> include/linux/vgaarb.h:109:6: warning: 'struct pci_dev' declared inside 
> parameter list
> include/linux/vgaarb.h:121:8: warning: 'struct pci_dev' declared inside 
> parameter list
> include/linux/vgaarb.h:140:37: warning: 'struct pci_dev' declared inside 
> parameter list
> 
> Signed-off-by: Randy Dunlap 
> Cc:   David Airlie 
> Cc:   dri-devel at lists.freedesktop.org
> ---
>  include/linux/vgaarb.h |2 ++
>  1 file changed, 2 insertions(+)
> 
> --- linux-next-20120130.orig/include/linux/vgaarb.h
> +++ linux-next-20120130/include/linux/vgaarb.h
> @@ -47,6 +47,8 @@
>   */
>  #define VGA_DEFAULT_DEVICE (NULL)
>  
> +struct pci_dev;
> +
>  /* For use by clients */
>  
>  /**
> 



-- 
~Randy


[Bug 42920] Radeon with KMS and UMA works only up to 128MB

2012-03-13 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=42920





--- Comment #3 from Alex Deucher   2012-03-13 
14:13:34 ---
radeontool is for older chips.  The register is at a different location on
them.  Note I said radeonreg rather than radeontool, but either will work as
long as you specify the proper offset (0x5428).

-- 
Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are watching the assignee of the bug.


[Bug 42920] Radeon with KMS and UMA works only up to 128MB

2012-03-13 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=42920





--- Comment #2 from j.fikar at gmail.com  2012-03-13 13:55:08 ---
for 128MB it shows this:

./radeontool regmatch 0x5428
0x5428  0x0800 (134217728)

but

./radeontool regs | grep MEMSIZE
RADEON_CONFIG_MEMSIZE   


is this it? I'll add values for 256MB later.

-- 
Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are watching the assignee of the bug.


[PATCH] omap2+: add drm device

2012-03-13 Thread Rob Clark
From: Andy Gross 

Register OMAP DRM/KMS platform device, and reserve a CMA region for
the device to use for buffer allocation.  DMM is split into a
separate device using hwmod.

Signed-off-by: Andy Gross 
Signed-off-by: Rob Clark 
---
 arch/arm/mach-omap2/Makefile  |4 ++
 arch/arm/mach-omap2/drm.c |   83 +
 arch/arm/plat-omap/common.c   |3 +-
 arch/arm/plat-omap/include/plat/drm.h |   64 +
 4 files changed, 153 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-omap2/drm.c
 create mode 100644 arch/arm/plat-omap/include/plat/drm.h

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index bd76394..9e6065b 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -189,6 +189,10 @@ ifneq ($(CONFIG_TIDSPBRIDGE),)
 obj-y  += dsp.o
 endif
 
+ifneq ($(CONFIG_DRM_OMAP),)
+obj-y  += drm.o
+endif
+
 # Specific board support
 obj-$(CONFIG_MACH_OMAP_GENERIC)+= board-generic.o
 obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o
diff --git a/arch/arm/mach-omap2/drm.c b/arch/arm/mach-omap2/drm.c
new file mode 100644
index 000..779ae02
--- /dev/null
+++ b/arch/arm/mach-omap2/drm.c
@@ -0,0 +1,83 @@
+/*
+ * DRM/KMS device registration for TI OMAP platforms
+ *
+ * Copyright (C) 2012 Texas Instruments
+ * Author: Rob Clark 
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#ifdef CONFIG_CMA
+#  include 
+#endif
+
+#include 
+#include 
+
+#include 
+
+#if defined(CONFIG_DRM_OMAP) || (CONFIG_DRM_OMAP_MODULE)
+
+static struct omap_drm_platform_data omapdrm_platdata;
+
+static struct platform_device omap_drm_device = {
+   .dev = {
+   .coherent_dma_mask = DMA_BIT_MASK(32),
+   .platform_data = &omapdrm_platdata,
+   },
+   .name = "omapdrm",
+   .id = 0,
+};
+
+static int __init omap_init_drm(void)
+{
+   struct omap_hwmod *oh = NULL;
+   struct platform_device *pdev;
+
+   /* lookup and populate the DMM information, if present - OMAP4+ */
+   oh = omap_hwmod_lookup("dmm");
+
+   if (oh) {
+   pdev = omap_device_build(oh->name, -1, oh, NULL, 0, NULL, 0,
+   false);
+   WARN(IS_ERR(pdev), "Could not build omap_device for %s\n",
+   oh->name);
+   }
+
+   return platform_device_register(&omap_drm_device);
+
+}
+
+arch_initcall(omap_init_drm);
+
+void omapdrm_reserve_vram(void)
+{
+#ifdef CONFIG_CMA
+   /*
+* Create private 32MiB contiguous memory area for omapdrm.0 device
+* TODO revisit size.. if uc/wc buffers are allocated from CMA pages
+* then the amount of memory we need goes up..
+*/
+   dma_declare_contiguous(&omap_drm_device.dev, 32 * SZ_1M, 0, 0);
+#else
+#  warning "CMA is not enabled, there may be limitations about scanout buffer 
allocations on OMAP3 and earlier"
+#endif
+}
+
+#endif
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index 4de7d1e..e027cc7 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -21,10 +21,10 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
-
 #define NO_LENGTH_CHECK 0x
 
 struct omap_board_config_kernel *omap_board_config __initdata;
@@ -65,6 +65,7 @@ const void *__init omap_get_var_config(u16 tag, size_t *len)
 
 void __init omap_reserve(void)
 {
+   omapdrm_reserve_vram();
omapfb_reserve_sdram_memblock();
omap_vram_reserve_sdram_memblock();
omap_dsp_reserve_sdram_memblock();
diff --git a/arch/arm/plat-omap/include/plat/drm.h 
b/arch/arm/plat-omap/include/plat/drm.h
new file mode 100644
index 000..df9bc41
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/drm.h
@@ -0,0 +1,64 @@
+/*
+ * DRM/KMS device registration for TI OMAP platforms
+ *
+ * Copyright (C) 2012 Texas Instruments
+ * Author: Rob Clark 
+ *
+ * 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 war

[Bug 42920] Radeon with KMS and UMA works only up to 128MB

2012-03-13 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=42920


Alex Deucher  changed:

   What|Removed |Added

 CC||alexdeucher at gmail.com




--- Comment #1 from Alex Deucher   2012-03-13 
13:34:13 ---
Looks like the bios sets up the vram size wrong for values > 128 MB.  Can you
print the value of the CONFIG_MEMSIZE register (0x5428) when you select various
vram sizes over 128 MB?  You can either use radeonreg
(http://cgit.freedesktop.org/~airlied/radeontool/):

radeonreg regmatch 0x5428

or the following patch:

diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 426cc65..6f02970 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -1204,6 +1204,7 @@ int r600_mc_init(struct radeon_device *rdev)
/* Setup GPU memory space */
rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
+   DRM_INFO("CONFIG_MEMSIZE: 0x%08x\n", RREG32(CONFIG_MEMSIZE));
rdev->mc.visible_vram_size = rdev->mc.aper_size;
r600_vram_gtt_location(rdev, &rdev->mc);

-- 
Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are watching the assignee of the bug.


[Bug 42920] New: Radeon with KMS and UMA works only up to 128MB

2012-03-13 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=42920

   Summary: Radeon with KMS and UMA works only up to 128MB
   Product: Drivers
   Version: 2.5
Kernel Version: 3.3-rc7
  Platform: All
OS/Version: Linux
  Tree: Mainline
Status: NEW
  Severity: normal
  Priority: P1
 Component: Video(DRI - non Intel)
AssignedTo: drivers_video-dri at kernel-bugs.osdl.org
ReportedBy: j.fikar at gmail.com
Regression: No


Hardware: Asus M4A88TD-M EVO with integrated Radeon HD 4250 (RS780)

Description: in bios I can choose UMA from 32MB up to 1024MB, but only values
up to 128MB work. Higher values lock the console in text mode before switching
to KMS. It also happens on older kernels with KMS (2.6.27), but the console is
not locked, the radeon module oopses and resolution stays VGA.

There is also option to locate UMA "above 4G" or "below 4G" in bios, it doesn't
matter. Also it has 128MB of sideport memory, this option doesn't matter
neither. (I have it off for now).

vramlimit parameter doesn't matter either.

System is x86_64, 16GB ECC DDR3 RAM.

lspci: 01:05.0 VGA compatible controller: Advanced Micro Devices [AMD] nee ATI
RS880 [Radeon HD 4250] (prog-if 00 [VGA controller])
Subsystem: ASUSTeK Computer Inc. M5A88-V EVO
Flags: bus master, fast devsel, latency 0, IRQ 18
Memory at f000 (32-bit, prefetchable) [size=128M]
I/O ports at d000 [size=256]
Memory at febe (32-bit, non-prefetchable) [size=64K]
Memory at fea0 (32-bit, non-prefetchable) [size=1M]
Expansion ROM at  [disabled]
Capabilities: [50] Power Management version 3
Capabilities: [a0] MSI: Enable- Count=1/1 Maskable- 64bit+
Kernel driver in use: radeon
Kernel modules: radeon

dmesg | grep -i -E "drm|radeon" on UMA=128MB; working:

[0.00] Kernel command line: root=/dev/md1
md=1,/dev/sda3,/dev/sdb3,/dev/sdc3,/dev/sdd3
rootflags=logbsize=256k,inode64,logbufs=8 mce=bootlog usbcore.autosuspend=1
radeon.benchmark=1 radeon.test=0 radeon.hw_i2c=0 zcache lockd.nlm_udpport=4001
lockd.nlm_tcpport=4001
[5.544881] [drm] Initialized drm 1.1.0 20060810
[5.644935] [drm] radeon defaulting to kernel modesetting.
[5.644937] [drm] radeon kernel modesetting enabled.
[5.644989] radeon :01:05.0: setting latency timer to 64
[5.645114] [drm] initializing kernel modesetting (RS880 0x1002:0x9715
0x1043:0x843E).
[5.645130] [drm] register mmio base: 0xFEBE
[5.645131] [drm] register mmio size: 65536
[5.645707] radeon :01:05.0: VRAM: 128M 0xC000 -
0xC7FF (128M used)
[5.645709] radeon :01:05.0: GTT: 512M 0xA000 -
0xBFFF
[5.649847] [drm] Detected VRAM RAM=128M, BAR=128M
[5.649850] [drm] RAM width 32bits DDR
[5.649943] [drm] radeon: 128M of VRAM memory ready
[5.649945] [drm] radeon: 512M of GTT memory ready.
[5.649958] [drm] Supports vblank timestamp caching Rev 1 (10.10.2010).
[5.649959] [drm] Driver supports precise vblank timestamp query.
[5.649976] [drm] radeon: irq initialized.
[5.649979] [drm] GART: num cpu pages 131072, num gpu pages 131072
[5.650514] [drm] radeon: ib pool ready.
[5.650588] [drm] Loading RS780 Microcode
[5.812474] [drm] PCIE GART of 512M enabled (table at 0xC004).
[5.812535] radeon :01:05.0: WB enabled
[5.812537] [drm] fence driver on ring 0 use gpu addr 0xac00 and cpu
addr 0x88040037ec00
[5.844636] [drm] ring test on 0 succeeded in 1 usecs
[5.844706] [drm] ib test on ring 0 succeeded in 0 usecs
[6.150041] [drm] radeon: blit 1024 bo moves of 1024 kB from 2 to 4 in 306
ms, throughput: 27408 Mb/s or 3426 MB/s
[6.455242] [drm] radeon: blit 1024 bo moves of 1024 kB from 4 to 2 in 305
ms, throughput: 27496 Mb/s or 3437 MB/s
[6.455574] [drm] Radeon Display Connectors
[6.455576] [drm] Connector 0:
[6.455577] [drm]   VGA
[6.455578] [drm]   DDC: 0x7e40 0x7e40 0x7e44 0x7e44 0x7e48 0x7e48 0x7e4c
0x7e4c
[6.455579] [drm]   Encoders:
[6.455580] [drm] CRT1: INTERNAL_KLDSCP_DAC1
[6.455581] [drm] Connector 1:
[6.455582] [drm]   HDMI-A
[6.455583] [drm]   HPD3
[6.455584] [drm]   DDC: 0x7e50 0x7e50 0x7e54 0x7e54 0x7e58 0x7e58 0x7e5c
0x7e5c
[6.455585] [drm]   Encoders:
[6.455586] [drm] DFP3: INTERNAL_KLDSCP_LVTMA
[6.455604] [drm] radeon: power management initialized
[6.528664] [drm] fb mappable at 0xF0142000
[6.528666] [drm] vram apper at 0xF000
[6.528667] [drm] size 3932160
[6.528668] [drm] fb depth is 24
[6.528669] [drm]pitch is 5120
[6.528727] fbcon: radeondrmfb (fb0) is primary device
[6.551936] fb0: radeondrmfb frame buffer device
[6.551937] drm: registered panic notifier
[6.551941] [drm] Initialized radeon 2.13.0 20080528 for :01:05.0 on
minor 0

dmesg | grep -i -E "drm|radeon"

[Bug 42923] New: External monitor on display port has no sync with radeon driver

2012-03-13 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=42923

   Summary: External monitor on display port has no sync with
radeon driver
   Product: Drivers
   Version: 2.5
Kernel Version: 3.3.0
  Platform: All
OS/Version: Linux
  Tree: Mainline
Status: NEW
  Severity: normal
  Priority: P1
 Component: Video(DRI - non Intel)
AssignedTo: drivers_video-...@kernel-bugs.osdl.org
ReportedBy: bgh...@gmail.com
Regression: No


Description and steps to reproduce can be found here:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/952486

Actual Results: An empty screen on external monitor complaining about input
timing.
Expected Results: GNOME desktop should have shown on external monitor.
Build Date & Platform: Build 2012-03-09 on Ubuntu 12.04

-- 
Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are watching the assignee of the bug.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 15/15] drm: Fix drm_mode_objecte_get() return values

2012-03-13 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Change drm_mode_object_get() to return -ENOMEM if idr_pre_get() fails,
and also handle -ENOSPC from idr_get_new_above().

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_crtc.c |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 12333ca..8f66a15 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -227,7 +227,7 @@ static int drm_mode_object_get(struct drm_device *dev,
do {
if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) {
DRM_ERROR("Ran out memory getting a mode number\n");
-   return -EINVAL;
+   return -ENOMEM;
}

mutex_lock(&dev->mode_config.idr_mutex);
@@ -236,6 +236,9 @@ static int drm_mode_object_get(struct drm_device *dev,
mutex_unlock(&dev->mode_config.idr_mutex);
} while (ret == -EAGAIN);

+   if (ret)
+   return ret;
+
obj->id = new_id;
obj->type = obj_type;
return 0;
-- 
1.7.3.4



[PATCH 14/15] drm: Add drm_mode_copy()

2012-03-13 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Add a helper function to copy a display mode. Use it in
drm_mode_duplicate() and nouveau mode_fixup hooks.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_modes.c|   28 +++-
 drivers/gpu/drm/nouveau/nv50_dac.c |7 ++-
 drivers/gpu/drm/nouveau/nv50_sor.c |7 ++-
 include/drm/drm_crtc.h |1 +
 4 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 7ff13bc..b7adb4a 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -714,6 +714,27 @@ EXPORT_SYMBOL(drm_mode_set_crtcinfo);


 /**
+ * drm_mode_copy - copy the mode
+ * @dst: mode to overwrite
+ * @src: mode to copy
+ *
+ * LOCKING:
+ * None.
+ *
+ * Copy an existing mode into another mode, preserving the object id
+ * of the destination mode.
+ */
+void drm_mode_copy(struct drm_display_mode *dst, const struct drm_display_mode 
*src)
+{
+   int id = dst->base.id;
+
+   *dst = *src;
+   dst->base.id = id;
+   INIT_LIST_HEAD(&dst->head);
+}
+EXPORT_SYMBOL(drm_mode_copy);
+
+/**
  * drm_mode_duplicate - allocate and duplicate an existing mode
  * @m: mode to duplicate
  *
@@ -727,16 +748,13 @@ struct drm_display_mode *drm_mode_duplicate(struct 
drm_device *dev,
const struct drm_display_mode *mode)
 {
struct drm_display_mode *nmode;
-   int new_id;

nmode = drm_mode_create(dev);
if (!nmode)
return NULL;

-   new_id = nmode->base.id;
-   *nmode = *mode;
-   nmode->base.id = new_id;
-   INIT_LIST_HEAD(&nmode->head);
+   drm_mode_copy(nmode, mode);
+
return nmode;
 }
 EXPORT_SYMBOL(drm_mode_duplicate);
diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c 
b/drivers/gpu/drm/nouveau/nv50_dac.c
index a0f2beb..55c5633 100644
--- a/drivers/gpu/drm/nouveau/nv50_dac.c
+++ b/drivers/gpu/drm/nouveau/nv50_dac.c
@@ -190,11 +190,8 @@ nv50_dac_mode_fixup(struct drm_encoder *encoder, struct 
drm_display_mode *mode,
}

if (connector->scaling_mode != DRM_MODE_SCALE_NONE &&
-connector->native_mode) {
-   int id = adjusted_mode->base.id;
-   *adjusted_mode = *connector->native_mode;
-   adjusted_mode->base.id = id;
-   }
+connector->native_mode)
+   drm_mode_copy(adjusted_mode, connector->native_mode);

return true;
 }
diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c 
b/drivers/gpu/drm/nouveau/nv50_sor.c
index c4423ba..1706964 100644
--- a/drivers/gpu/drm/nouveau/nv50_sor.c
+++ b/drivers/gpu/drm/nouveau/nv50_sor.c
@@ -162,11 +162,8 @@ nv50_sor_mode_fixup(struct drm_encoder *encoder, struct 
drm_display_mode *mode,
}

if (connector->scaling_mode != DRM_MODE_SCALE_NONE &&
-connector->native_mode) {
-   int id = adjusted_mode->base.id;
-   *adjusted_mode = *connector->native_mode;
-   adjusted_mode->base.id = id;
-   }
+connector->native_mode)
+   drm_mode_copy(adjusted_mode, connector->native_mode);

return true;
 }
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 53cb49a..9595c2c 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -855,6 +855,7 @@ extern struct edid *drm_get_edid(struct drm_connector 
*connector,
 extern int drm_add_edid_modes(struct drm_connector *connector, struct edid 
*edid);
 extern void drm_mode_probed_add(struct drm_connector *connector, struct 
drm_display_mode *mode);
 extern void drm_mode_remove(struct drm_connector *connector, struct 
drm_display_mode *mode);
+extern void drm_mode_copy(struct drm_display_mode *dst, const struct 
drm_display_mode *src);
 extern struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev,
   const struct 
drm_display_mode *mode);
 extern void drm_mode_debug_printmodeline(struct drm_display_mode *mode);
-- 
1.7.3.4



[PATCH 13/15] drm: Eliminate pointless goto

2012-03-13 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Use a do {} while() loop instead of a goto in drm_mode_object_get().

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_crtc.c |   20 ++--
 1 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index d2d9dc5..12333ca 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -224,17 +224,17 @@ static int drm_mode_object_get(struct drm_device *dev,
int new_id = 0;
int ret;

-again:
-   if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) {
-   DRM_ERROR("Ran out memory getting a mode number\n");
-   return -EINVAL;
-   }
+   do {
+   if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) {
+   DRM_ERROR("Ran out memory getting a mode number\n");
+   return -EINVAL;
+   }

-   mutex_lock(&dev->mode_config.idr_mutex);
-   ret = idr_get_new_above(&dev->mode_config.crtc_idr, obj, 1, &new_id);
-   mutex_unlock(&dev->mode_config.idr_mutex);
-   if (ret == -EAGAIN)
-   goto again;
+   mutex_lock(&dev->mode_config.idr_mutex);
+   ret = idr_get_new_above(&dev->mode_config.crtc_idr,
+   obj, 1, &new_id);
+   mutex_unlock(&dev->mode_config.idr_mutex);
+   } while (ret == -EAGAIN);

obj->id = new_id;
obj->type = obj_type;
-- 
1.7.3.4



[PATCH 12/15] drm: Use a flexible array member for blob property data

2012-03-13 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

The blob property data is always allocated immediately after the object
header. No need for the extra indirection when accessing it, just use
a flexible array member.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_crtc.c |1 -
 include/drm/drm_crtc.h |2 +-
 2 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index f5b098e..d2d9dc5 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2943,7 +2943,6 @@ static struct drm_property_blob 
*drm_property_create_blob(struct drm_device *dev
return NULL;
}

-   blob->data = (void *)((char *)blob + sizeof(struct drm_property_blob));
blob->length = length;

memcpy(blob->data, data, length);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 00f4007..53cb49a 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -257,7 +257,7 @@ struct drm_property_blob {
struct drm_mode_object base;
struct list_head head;
unsigned int length;
-   void *data;
+   unsigned char data[];
 };

 struct drm_property_enum {
-- 
1.7.3.4



[PATCH 11/15] drm: Handle drm_object_get() failures

2012-03-13 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Check drm_mode_object_get() return value everywhere.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_crtc.c|   95 -
 drivers/gpu/drm/drm_crtc_helper.c |2 +
 include/drm/drm_crtc.h|   22 
 3 files changed, 85 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index e36bd43..f5b098e 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -293,9 +293,8 @@ int drm_framebuffer_init(struct drm_device *dev, struct 
drm_framebuffer *fb,
int ret;

ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB);
-   if (ret) {
+   if (ret)
return ret;
-   }

fb->dev = dev;
fb->funcs = funcs;
@@ -365,19 +364,31 @@ EXPORT_SYMBOL(drm_framebuffer_cleanup);
  * Caller must hold mode config lock.
  *
  * Inits a new object created as base part of an driver crtc object.
+ *
+ * RETURNS:
+ * Zero on success, error code on failure.
  */
-void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
+int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
   const struct drm_crtc_funcs *funcs)
 {
+   int ret;
+
crtc->dev = dev;
crtc->funcs = funcs;

mutex_lock(&dev->mode_config.mutex);
-   drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
+
+   ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
+   if (ret)
+   goto out;

list_add_tail(&crtc->head, &dev->mode_config.crtc_list);
dev->mode_config.num_crtc++;
+
+ out:
mutex_unlock(&dev->mode_config.mutex);
+
+   return ret;
 }
 EXPORT_SYMBOL(drm_crtc_init);

@@ -453,17 +464,25 @@ EXPORT_SYMBOL(drm_mode_remove);
  *
  * Initialises a preallocated connector. Connectors should be
  * subclassed as part of driver connector objects.
+ *
+ * RETURNS:
+ * Zero on success, error code on failure.
  */
-void drm_connector_init(struct drm_device *dev,
-struct drm_connector *connector,
-const struct drm_connector_funcs *funcs,
-int connector_type)
+int drm_connector_init(struct drm_device *dev,
+  struct drm_connector *connector,
+  const struct drm_connector_funcs *funcs,
+  int connector_type)
 {
+   int ret;
+
mutex_lock(&dev->mode_config.mutex);

+   ret = drm_mode_object_get(dev, &connector->base, 
DRM_MODE_OBJECT_CONNECTOR);
+   if (ret)
+   goto out;
+
connector->dev = dev;
connector->funcs = funcs;
-   drm_mode_object_get(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR);
connector->connector_type = connector_type;
connector->connector_type_id =
++drm_connector_enum_list[connector_type].count; /* TODO */
@@ -483,7 +502,10 @@ void drm_connector_init(struct drm_device *dev,
drm_connector_attach_property(connector,
  dev->mode_config.dpms_property, 0);

+ out:
mutex_unlock(&dev->mode_config.mutex);
+
+   return ret;
 }
 EXPORT_SYMBOL(drm_connector_init);

@@ -518,23 +540,30 @@ void drm_connector_cleanup(struct drm_connector 
*connector)
 }
 EXPORT_SYMBOL(drm_connector_cleanup);

-void drm_encoder_init(struct drm_device *dev,
- struct drm_encoder *encoder,
- const struct drm_encoder_funcs *funcs,
- int encoder_type)
+int drm_encoder_init(struct drm_device *dev,
+struct drm_encoder *encoder,
+const struct drm_encoder_funcs *funcs,
+int encoder_type)
 {
+   int ret;
+
mutex_lock(&dev->mode_config.mutex);

+   ret = drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER);
+   if (ret)
+   goto out;
+
encoder->dev = dev;
-
-   drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER);
encoder->encoder_type = encoder_type;
encoder->funcs = funcs;

list_add_tail(&encoder->head, &dev->mode_config.encoder_list);
dev->mode_config.num_encoder++;

+ out:
mutex_unlock(&dev->mode_config.mutex);
+
+   return ret;
 }
 EXPORT_SYMBOL(drm_encoder_init);

@@ -555,18 +584,23 @@ int drm_plane_init(struct drm_device *dev, struct 
drm_plane *plane,
   const uint32_t *formats, uint32_t format_count,
   bool priv)
 {
+   int ret;
+
mutex_lock(&dev->mode_config.mutex);

+   ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
+   if (ret)
+   goto out;
+
plane->dev = dev;
-   drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
plane->funcs = funcs;
plane->format_types = kmalloc(sizeof(uint32_t) * format_count,
  GFP_KERNEL);
   

[PATCH 10/15] drm: Make drm_crtc_convert_{umode, to_umode} static and constify their params

2012-03-13 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

drm_crtc_convert_umode() and drm_crtc_convert_to_umode() are never
used outside drm_crtc.c, so make them static. Also make the input
mode structure const for both functions.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_crtc.c |8 
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 37d34ad..e36bd43 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1002,8 +1002,8 @@ EXPORT_SYMBOL(drm_mode_config_cleanup);
  * Convert a drm_display_mode into a drm_mode_modeinfo structure to return to
  * the user.
  */
-void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out,
-  struct drm_display_mode *in)
+static void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out,
+ const struct drm_display_mode *in)
 {
WARN(in->hdisplay > USHRT_MAX || in->hsync_start > USHRT_MAX ||
 in->hsync_end > USHRT_MAX || in->htotal > USHRT_MAX ||
@@ -1044,8 +1044,8 @@ void drm_crtc_convert_to_umode(struct drm_mode_modeinfo 
*out,
  * RETURNS:
  * Zero on success, errno on failure.
  */
-int drm_crtc_convert_umode(struct drm_display_mode *out,
-  struct drm_mode_modeinfo *in)
+static int drm_crtc_convert_umode(struct drm_display_mode *out,
+ const struct drm_mode_modeinfo *in)
 {
if (in->clock > INT_MAX || in->vrefresh > INT_MAX)
return -ERANGE;
-- 
1.7.3.4



[PATCH 09/15] drm: Fix drm_mode_attachmode_crtc()

2012-03-13 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Change drm_mode_attachmode_crtc() to take an "all or nothing" approach.
If an error is returned, there are no side effects visible.

Also change the function to always duplicate the mode passed in.

Also change the function to not give up when it finds the first
connector without and encoder.

A simpler approach would be to just remove the function completely as
it's unused currently.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_crtc.c |   38 +++---
 include/drm/drm_crtc.h |2 +-
 2 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 3f5c603..37d34ad 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2421,24 +2421,40 @@ static void drm_mode_attachmode(struct drm_device *dev,
 }

 int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc,
-struct drm_display_mode *mode)
+const struct drm_display_mode *mode)
 {
struct drm_connector *connector;
-   struct drm_display_mode *dup_mode;
-   int need_dup = 0;
+   int ret = 0;
+   struct drm_display_mode *dup_mode, *next;
+   LIST_HEAD(list);
+
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
if (!connector->encoder)
-   break;
+   continue;
if (connector->encoder->crtc == crtc) {
-   if (need_dup)
-   dup_mode = drm_mode_duplicate(dev, mode);
-   else
-   dup_mode = mode;
-   drm_mode_attachmode(dev, connector, dup_mode);
-   need_dup = 1;
+   dup_mode = drm_mode_duplicate(dev, mode);
+   if (!dup_mode) {
+   ret = -ENOMEM;
+   goto out;
+   }
+   list_add_tail(&dup_mode->head, &list);
}
}
-   return 0;
+
+   list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+   if (!connector->encoder)
+   continue;
+   if (connector->encoder->crtc == crtc)
+   list_move_tail(list.next, &connector->user_modes);
+   }
+
+   WARN_ON(!list_empty(&list));
+
+ out:
+   list_for_each_entry_safe(dup_mode, next, &list, head)
+   drm_mode_destroy(dev, dup_mode);
+
+   return ret;
 }
 EXPORT_SYMBOL(drm_mode_attachmode_crtc);

diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 31715bd..fe7ebc6 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -869,7 +869,7 @@ extern int drm_mode_height(struct drm_display_mode *mode);
 /* for us by fb module */
 extern int drm_mode_attachmode_crtc(struct drm_device *dev,
struct drm_crtc *crtc,
-   struct drm_display_mode *mode);
+   const struct drm_display_mode *mode);
 extern int drm_mode_detachmode_crtc(struct drm_device *dev, struct 
drm_display_mode *mode);

 extern struct drm_display_mode *drm_mode_create(struct drm_device *dev);
-- 
1.7.3.4



[PATCH 08/15] drm: Check CRTC viewport against framebuffer size

2012-03-13 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

Make sure the requested CRTC viewport fits inside the
framebuffer.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_crtc.c |   24 
 1 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 4d9e69c..3f5c603 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1835,6 +1835,18 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
}

drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
+
+   if (mode->hdisplay > fb->width ||
+   mode->vdisplay > fb->height ||
+   crtc_req->x > fb->width - mode->hdisplay ||
+   crtc_req->y > fb->height - mode->vdisplay) {
+   DRM_DEBUG_KMS("Invalid CRTC viewport %ux%u+%u+%u for fb 
size %ux%u.\n",
+ mode->hdisplay, mode->vdisplay,
+ crtc_req->x, crtc_req->y,
+ fb->width, fb->height);
+   ret = -ENOSPC;
+   goto out;
+   }
}

if (crtc_req->count_connectors == 0 && mode) {
@@ -3206,6 +3218,18 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
goto out;
fb = obj_to_fb(obj);

+   if (crtc->mode.hdisplay > fb->width ||
+   crtc->mode.vdisplay > fb->height ||
+   crtc->x > fb->width - crtc->mode.hdisplay ||
+   crtc->y > fb->height - crtc->mode.vdisplay) {
+   DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport 
%ux%u+%d+%d.\n",
+ fb->width, fb->height,
+ crtc->mode.hdisplay, crtc->mode.vdisplay,
+ crtc->x, crtc->y);
+   ret = -ENOSPC;
+   goto out;
+   }
+
if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
ret = -ENOMEM;
spin_lock_irqsave(&dev->event_lock, flags);
-- 
1.7.3.4



[PATCH 07/15] drm: Check user mode against overflows

2012-03-13 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

The internal mode representation drm_display_mode uses signed data
types. When converting the user mode to internal representation,
check that the unsigned values don't overflow the signed datatypes.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_crtc.c |   33 -
 1 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 9ccb92f..4d9e69c 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1040,10 +1040,16 @@ void drm_crtc_convert_to_umode(struct drm_mode_modeinfo 
*out,
  *
  * Convert a drm_mode_modeinfo into a drm_display_mode structure to return to
  * the caller.
+ *
+ * RETURNS:
+ * Zero on success, errno on failure.
  */
-void drm_crtc_convert_umode(struct drm_display_mode *out,
-   struct drm_mode_modeinfo *in)
+int drm_crtc_convert_umode(struct drm_display_mode *out,
+  struct drm_mode_modeinfo *in)
 {
+   if (in->clock > INT_MAX || in->vrefresh > INT_MAX)
+   return -ERANGE;
+
out->clock = in->clock;
out->hdisplay = in->hdisplay;
out->hsync_start = in->hsync_start;
@@ -1060,6 +1066,8 @@ void drm_crtc_convert_umode(struct drm_display_mode *out,
out->type = in->type;
strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
+
+   return 0;
 }

 /**
@@ -1820,7 +1828,12 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
goto out;
}

-   drm_crtc_convert_umode(mode, &crtc_req->mode);
+   ret = drm_crtc_convert_umode(mode, &crtc_req->mode);
+   if (ret) {
+   DRM_DEBUG_KMS("Invalid mode\n");
+   goto out;
+   }
+
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
}

@@ -2492,7 +2505,12 @@ int drm_mode_attachmode_ioctl(struct drm_device *dev,
goto out;
}

-   drm_crtc_convert_umode(mode, umode);
+   ret = drm_crtc_convert_umode(mode, umode);
+   if (ret) {
+   DRM_DEBUG_KMS("Invalid mode\n");
+   drm_mode_destroy(dev, mode);
+   goto out;
+   }

drm_mode_attachmode(dev, connector, mode);
 out:
@@ -2535,7 +2553,12 @@ int drm_mode_detachmode_ioctl(struct drm_device *dev,
}
connector = obj_to_connector(obj);

-   drm_crtc_convert_umode(&mode, umode);
+   ret = drm_crtc_convert_umode(&mode, umode);
+   if (ret) {
+   DRM_DEBUG_KMS("Invalid mode\n");
+   goto out;
+   }
+
ret = drm_mode_detachmode(dev, connector, &mode);
 out:
mutex_unlock(&dev->mode_config.mutex);
-- 
1.7.3.4



[PATCH 06/15] drm: Fix memory leak in drm_mode_setcrtc()

2012-03-13 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

The mode passed to the .set_config() hook was never freed. The drivers
will make a copy of the mode, so simply free it when done.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_crtc.c |9 +
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index d2e09d9..9ccb92f 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -643,6 +643,9 @@ EXPORT_SYMBOL(drm_mode_create);
  */
 void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode)
 {
+   if (!mode)
+   return;
+
drm_mode_object_put(dev, &mode->base);

kfree(mode);
@@ -1812,6 +1815,11 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
}

mode = drm_mode_create(dev);
+   if (!mode) {
+   ret = -ENOMEM;
+   goto out;
+   }
+
drm_crtc_convert_umode(mode, &crtc_req->mode);
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
}
@@ -1881,6 +1889,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,

 out:
kfree(connector_set);
+   drm_mode_destroy(dev, mode);
mutex_unlock(&dev->mode_config.mutex);
return ret;
 }
-- 
1.7.3.4



[PATCH 05/15] drm: Make drm_mode_attachmode() void

2012-03-13 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

drm_mode_attachmode() always returns 0. Change the return type to void.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_crtc.c |   16 +---
 1 files changed, 5 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 3a42c9c..d2e09d9 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2379,21 +2379,17 @@ void drm_fb_release(struct drm_file *priv)
  *
  * Add @mode to @connector's user mode list.
  */
-static int drm_mode_attachmode(struct drm_device *dev,
-  struct drm_connector *connector,
-  struct drm_display_mode *mode)
+static void drm_mode_attachmode(struct drm_device *dev,
+   struct drm_connector *connector,
+   struct drm_display_mode *mode)
 {
-   int ret = 0;
-
list_add_tail(&mode->head, &connector->user_modes);
-   return ret;
 }

 int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc,
 struct drm_display_mode *mode)
 {
struct drm_connector *connector;
-   int ret = 0;
struct drm_display_mode *dup_mode;
int need_dup = 0;
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
@@ -2404,9 +2400,7 @@ int drm_mode_attachmode_crtc(struct drm_device *dev, 
struct drm_crtc *crtc,
dup_mode = drm_mode_duplicate(dev, mode);
else
dup_mode = mode;
-   ret = drm_mode_attachmode(dev, connector, dup_mode);
-   if (ret)
-   return ret;
+   drm_mode_attachmode(dev, connector, dup_mode);
need_dup = 1;
}
}
@@ -2491,7 +2485,7 @@ int drm_mode_attachmode_ioctl(struct drm_device *dev,

drm_crtc_convert_umode(mode, umode);

-   ret = drm_mode_attachmode(dev, connector, mode);
+   drm_mode_attachmode(dev, connector, mode);
 out:
mutex_unlock(&dev->mode_config.mutex);
return ret;
-- 
1.7.3.4



[PATCH 04/15] drm: Check crtc x and y coordinates

2012-03-13 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

The crtc x/y panning coordinates are stored as signed integers
internally. The user provides them as unsigned, so we should check
that the user provided values actually fit in the internal datatypes.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_crtc.c |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index d11763f..3a42c9c 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1774,6 +1774,10 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;

+   /* For some reason crtc x/y offsets are signed internally. */
+   if (crtc_req->x > INT_MAX || crtc_req->y > INT_MAX)
+   return -ERANGE;
+
mutex_lock(&dev->mode_config.mutex);
obj = drm_mode_object_find(dev, crtc_req->crtc_id,
   DRM_MODE_OBJECT_CRTC);
-- 
1.7.3.4



[PATCH 03/15] drm: Warn if mode to umode conversion overflows the destination types

2012-03-13 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

When converting from a drm_display_mode to drm_mode_modeinfo, print a
warning if the the timings values don't fit into the __u16 datatype.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_crtc.c |7 +++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index bbcecdb..d11763f 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1002,6 +1002,13 @@ EXPORT_SYMBOL(drm_mode_config_cleanup);
 void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out,
   struct drm_display_mode *in)
 {
+   WARN(in->hdisplay > USHRT_MAX || in->hsync_start > USHRT_MAX ||
+in->hsync_end > USHRT_MAX || in->htotal > USHRT_MAX ||
+in->hskew > USHRT_MAX || in->vdisplay > USHRT_MAX ||
+in->vsync_start > USHRT_MAX || in->vsync_end > USHRT_MAX ||
+in->vtotal > USHRT_MAX || in->vscan > USHRT_MAX,
+"timing values too large for mode info\n");
+
out->clock = in->clock;
out->hdisplay = in->hdisplay;
out->hsync_start = in->hsync_start;
-- 
1.7.3.4



[PATCH 02/15] drm: Change drm_display_mode::type to unsigned

2012-03-13 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

The drm_display_mode type is a bitmask so it should be unsigned.

Signed-off-by: Ville Syrj?l? 
---
 include/drm/drm_crtc.h |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 2a0872c..31715bd 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -121,7 +121,7 @@ struct drm_display_mode {
char name[DRM_DISPLAY_MODE_LEN];

enum drm_mode_status status;
-   int type;
+   unsigned int type;

/* Proposed mode values */
int clock;  /* in kHz */
-- 
1.7.3.4



[PATCH 01/15] drm: Reject mode set with current fb if no current fb is bound

2012-03-13 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

When doing a mode set with the special fb id -1, reject the mode set if
no fb is currently bound to the crtc.

Also remove the pointless list traversal to find the current crtc based
on the current crtc :)

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_crtc.c |   14 ++
 1 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 6fdaf6f..bbcecdb 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1755,7 +1755,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
struct drm_mode_config *config = &dev->mode_config;
struct drm_mode_crtc *crtc_req = data;
struct drm_mode_object *obj;
-   struct drm_crtc *crtc, *crtcfb;
+   struct drm_crtc *crtc;
struct drm_connector **connector_set = NULL, *connector;
struct drm_framebuffer *fb = NULL;
struct drm_display_mode *mode = NULL;
@@ -1782,14 +1782,12 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
/* If we have a mode we need a framebuffer. */
/* If we pass -1, set the mode with the currently bound fb */
if (crtc_req->fb_id == -1) {
-   list_for_each_entry(crtcfb,
-   &dev->mode_config.crtc_list, head) {
-   if (crtcfb == crtc) {
-   DRM_DEBUG_KMS("Using current fb for "
-   "setmode\n");
-   fb = crtc->fb;
-   }
+   if (!crtc->fb) {
+   DRM_DEBUG_KMS("CRTC doesn't have current FB\n");
+   ret = -EINVAL;
+   goto out;
}
+   fb = crtc->fb;
} else {
obj = drm_mode_object_find(dev, crtc_req->fb_id,
   DRM_MODE_OBJECT_FB);
-- 
1.7.3.4



[PATCH 00/15] drm: Bounds checking, error handling, etc.

2012-03-13 Thread ville.syrj...@linux.intel.com
Mostly fixes for various bits and pieces that caught my eye while
reading the mode setting code.


[Bug 46713] HDMI audio played back at a wrong rate

2012-03-13 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=46713

--- Comment #17 from Rafał Miłecki  2012-03-13 12:05:38 PDT 
---
If you wish, you can try switching to radeon and:
1) Start playback
2) Make sure speed is still wrong
3) Execute: "avivotool regset 0x05b0 0x000ea600"
4) Execute: "avivotool regset 0x05bc 0x0072"

Does it help?

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 46713] HDMI audio played back at a wrong rate

2012-03-13 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=46713

--- Comment #16 from Rafał Miłecki  2012-03-13 12:04:19 PDT 
---
Tvrtko: thanks a lot for your effort and dumps coming from fglrx.

What I can say now: it seems fglrx is using the same registers
(EVERGREEN_AUDIO_PLL1_MUL and EVERGREEN_AUDIO_PLL1_DIV) for your card.

However:
1) radeon uses 480'000 for MUL
2) fglrx uses 960'000 for MUL

On the other hand fglrx uses 0x72 instead of 0x71 for EVERGREEN_AUDIO_PLL1_UNK.
Maybe that 0x2 is some DIV? Maybe it tells GPU to take 960'000 and divide it by
2?

I've to investigate meaning of the register, but you gave me a track to follow,
thanks a lot for your effors! I'll take a look on that after my vacations (next
week).

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 47007] HDMI monitor polling causing 100ms rendering stalls

2012-03-13 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=47007

--- Comment #15 from Tvrtko Ursulin  2012-03-13 
04:44:04 PDT ---
Bad news from a different motherboard. This one has DVI-D and DP connectors.
With a DVI monitor connected stalls are still there due to the shared_ddc being
true (DDC shared between DVI and VGA). Connectors look like this here:

[drm] Radeon Display Connectors
[drm] Connector 0:
[drm]   DisplayPort
[drm]   HPD1
[drm]   DDC: 0x6430 0x6430 0x6434 0x6434 0x6438 0x6438 0x643c 0x643c
[drm]   Encoders:
[drm] DFP1: INTERNAL_UNIPHY
[drm] Connector 1:
[drm]   DVI-D
[drm]   HPD2
[drm]   DDC: 0x6440 0x6440 0x6444 0x6444 0x6448 0x6448 0x644c 0x644c
[drm]   Encoders:
[drm] DFP2: INTERNAL_UNIPHY
[drm] Connector 2:
[drm]   VGA
[drm]   DDC: 0x6440 0x6440 0x6444 0x6444 0x6448 0x6448 0x644c 0x644c
[drm]   Encoders:
[drm] CRT1: INTERNAL_KLDSCP_DAC1

If I remove the shared_ddc check from the patch that removes the 100ms stall in
radeon_dvi_detect. However in this configuration there is another 60ms stall
from drm_get_edid in radeon_vga_detect now.

Also, radeon_dp_getsinktype from radeon_dp_detect adds another 3ms for the
disconnected DP port.

Recap of latency contributors on this hardware:

1. radeon_dvi_detect

 * 100ms when connected from drm_get_edid

Can be fixed with the patch like the above, but with shared_ddc check criteria
removed if that is OK? That would then work for both motherboards that I tested
on. HDMI on the first one, and DVI on this one.

2. radeon_vga_detect

 * not connected
* 5ms from radeon_ddc_probe
* 60ms from drm_get_edid

Not sure how to improve this without making the code a lot smarter. It would
have to consider who is sharing DDC with who, and if another connector is
connected it would imply this one can not be and then skip the EDID fetch?

Also perhaps 5ms from radeon_ddc_probe could be saved by somehow passing the
header to drm_get_edid, if I gather correctly that the latter re-fetches the
same header radeon_ddc_probe retrieved.

3. radeon_dp_detect

 * 8ms when not connected from radeon_dp_getsinktype
 * haven't tested the connected case - that is unreliable anyway, bug 46711

Not sure if this would be passable if it remained the only latency source. It's
not ideal that's for sure. Does it need to do the radeon_dp_getsinktype call in
the absence of a HPD interrupt though? If not could we short-circuit it in some
way similar to radeon_dvi_detect? Call it after radeon_hpd_sense only if
something is connected? However looking at the code it doesn't suggest all
latency is avoidable since it doesn't seem to trust HPD sense. Same story with
OEM wiring reliability?

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.


[RFCv2 PATCH 9/9] v4l: s5p-tv: mixer: integrate with dmabuf

2012-03-13 Thread Tomasz Stanislawski
Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/s5p-tv/Kconfig   |1 +
 drivers/media/video/s5p-tv/mixer_video.c |   12 +++-
 2 files changed, 12 insertions(+), 1 deletions(-)

diff --git a/drivers/media/video/s5p-tv/Kconfig 
b/drivers/media/video/s5p-tv/Kconfig
index f248b28..2e80126 100644
--- a/drivers/media/video/s5p-tv/Kconfig
+++ b/drivers/media/video/s5p-tv/Kconfig
@@ -10,6 +10,7 @@ config VIDEO_SAMSUNG_S5P_TV
bool "Samsung TV driver for S5P platform (experimental)"
depends on PLAT_S5P && PM_RUNTIME
depends on EXPERIMENTAL
+   select DMA_SHARED_BUFFER
default n
---help---
  Say Y here to enable selecting the TV output devices for
diff --git a/drivers/media/video/s5p-tv/mixer_video.c 
b/drivers/media/video/s5p-tv/mixer_video.c
index f7ca5cc..f08edbf 100644
--- a/drivers/media/video/s5p-tv/mixer_video.c
+++ b/drivers/media/video/s5p-tv/mixer_video.c
@@ -697,6 +697,15 @@ static int mxr_dqbuf(struct file *file, void *priv, struct 
v4l2_buffer *p)
return vb2_dqbuf(&layer->vb_queue, p, file->f_flags & O_NONBLOCK);
 }

+static int mxr_expbuf(struct file *file, void *priv,
+   struct v4l2_exportbuffer *eb)
+{
+   struct mxr_layer *layer = video_drvdata(file);
+
+   mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
+   return vb2_expbuf(&layer->vb_queue, eb);
+}
+
 static int mxr_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
 {
struct mxr_layer *layer = video_drvdata(file);
@@ -724,6 +733,7 @@ static const struct v4l2_ioctl_ops mxr_ioctl_ops = {
.vidioc_querybuf = mxr_querybuf,
.vidioc_qbuf = mxr_qbuf,
.vidioc_dqbuf = mxr_dqbuf,
+   .vidioc_expbuf = mxr_expbuf,
/* Streaming control */
.vidioc_streamon = mxr_streamon,
.vidioc_streamoff = mxr_streamoff,
@@ -1074,7 +1084,7 @@ struct mxr_layer *mxr_base_layer_create(struct mxr_device 
*mdev,

layer->vb_queue = (struct vb2_queue) {
.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
-   .io_modes = VB2_MMAP | VB2_USERPTR,
+   .io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF,
.drv_priv = layer,
.buf_struct_size = sizeof(struct mxr_buffer),
.ops = &mxr_video_qops,
-- 
1.7.5.4



[RFCv2 PATCH 8/9] v4l: fimc: integrate capture i-face with dmabuf

2012-03-13 Thread Tomasz Stanislawski
Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/Kconfig |1 +
 drivers/media/video/s5p-fimc/fimc-capture.c |   11 ++-
 2 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 9495b6a..c9963f0 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -1099,6 +1099,7 @@ config  VIDEO_SAMSUNG_S5P_FIMC
VIDEO_V4L2_SUBDEV_API && EXPERIMENTAL
select VIDEOBUF2_DMA_CONTIG
select V4L2_MEM2MEM_DEV
+   select DMA_SHARED_BUFFER
---help---
  This is a v4l2 driver for Samsung S5P and EXYNOS4 camera
  host interface and video postprocessor.
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c 
b/drivers/media/video/s5p-fimc/fimc-capture.c
index a9e9653..7ecc36b 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -1011,6 +1011,14 @@ static int fimc_cap_qbuf(struct file *file, void *priv,
return vb2_qbuf(&fimc->vid_cap.vbq, buf);
 }

+static int fimc_cap_expbuf(struct file *file, void *priv,
+ struct v4l2_exportbuffer *eb)
+{
+   struct fimc_dev *fimc = video_drvdata(file);
+
+   return vb2_expbuf(&fimc->vid_cap.vbq, eb);
+}
+
 static int fimc_cap_dqbuf(struct file *file, void *priv,
   struct v4l2_buffer *buf)
 {
@@ -1081,6 +1089,7 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops 
= {

.vidioc_qbuf= fimc_cap_qbuf,
.vidioc_dqbuf   = fimc_cap_dqbuf,
+   .vidioc_expbuf  = fimc_cap_expbuf,

.vidioc_streamon= fimc_cap_streamon,
.vidioc_streamoff   = fimc_cap_streamoff,
@@ -1463,7 +1472,7 @@ int fimc_register_capture_device(struct fimc_dev *fimc,
q = &fimc->vid_cap.vbq;
memset(q, 0, sizeof(*q));
q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-   q->io_modes = VB2_MMAP | VB2_USERPTR;
+   q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
q->drv_priv = fimc->vid_cap.ctx;
q->ops = &fimc_capture_qops;
q->mem_ops = &vb2_dma_contig_memops;
-- 
1.7.5.4



[RFCv2 PATCH 7/9] v4l: vb2-dma-contig: change map/unmap behaviour

2012-03-13 Thread Tomasz Stanislawski
The DMABUF documentation says that the map_dma_buf callback should return
scatterlist that is mapped into a caller's address space. In practice, almost
none of existing implementations of DMABUF exporter does it.  This patch breaks
the DMABUF specification in order to allow exchange DMABUF buffers between
other APIs like DRM.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/videobuf2-dma-contig.c |   64 
 1 files changed, 27 insertions(+), 37 deletions(-)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index d95b23a..32bb16b 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -315,11 +315,6 @@ static int vb2_dc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
 /* DMABUF ops for exporters  */
 /*/

-struct vb2_dc_attachment {
-   struct sg_table sgt;
-   enum dma_data_direction dir;
-};
-
 static int vb2_dc_dmabuf_ops_attach(struct dma_buf *dbuf, struct device *dev,
struct dma_buf_attachment *dbuf_attach)
 {
@@ -330,17 +325,13 @@ static int vb2_dc_dmabuf_ops_attach(struct dma_buf *dbuf, 
struct device *dev,
 static void vb2_dc_dmabuf_ops_detach(struct dma_buf *dbuf,
struct dma_buf_attachment *db_attach)
 {
-   struct vb2_dc_attachment *attach = db_attach->priv;
-   struct sg_table *sgt;
+   struct sg_table *sgt = db_attach->priv;

-   if (!attach)
+   if (!sgt)
return;

-   sgt = &attach->sgt;
-
-   dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->nents, attach->dir);
sg_free_table(sgt);
-   kfree(attach);
+   kfree(sgt);
db_attach->priv = NULL;
 }

@@ -349,26 +340,22 @@ static struct sg_table *vb2_dc_dmabuf_ops_map(
 {
struct dma_buf *dbuf = db_attach->dmabuf;
struct vb2_dc_buf *buf = dbuf->priv;
-   struct vb2_dc_attachment *attach = db_attach->priv;
-   struct sg_table *sgt;
+   struct sg_table *sgt = db_attach->priv;
struct scatterlist *rd, *wr;
int i, ret;

/* return previously mapped sg table */
-   if (attach)
-   return &attach->sgt;
+   if (sgt)
+   return sgt;

-   attach = kzalloc(sizeof *attach, GFP_KERNEL);
-   if (!attach)
+   sgt = kzalloc(sizeof *sgt, GFP_KERNEL);
+   if (!sgt)
return ERR_PTR(-ENOMEM);

-   sgt = &attach->sgt;
-   attach->dir = dir;
-
/* copying the buf->base_sgt to attachment */
ret = sg_alloc_table(sgt, buf->sgt_base->orig_nents, GFP_KERNEL);
if (ret) {
-   kfree(attach);
+   kfree(sgt);
return ERR_PTR(-ENOMEM);
}

@@ -380,16 +367,7 @@ static struct sg_table *vb2_dc_dmabuf_ops_map(
wr = sg_next(wr);
}

-   /* mapping new sglist to the client */
-   ret = dma_map_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, dir);
-   if (ret <= 0) {
-   printk(KERN_ERR "failed to map scatterlist\n");
-   sg_free_table(sgt);
-   kfree(attach);
-   return ERR_PTR(-EIO);
-   }
-
-   db_attach->priv = attach;
+   db_attach->priv = sgt;

return sgt;
 }
@@ -623,7 +601,7 @@ static int vb2_dc_map_dmabuf(void *mem_priv)
struct vb2_dc_buf *buf = mem_priv;
struct sg_table *sgt;
unsigned long contig_size;
-   int ret = 0;
+   int ret = -EFAULT;

if (WARN_ON(!buf->db_attach)) {
printk(KERN_ERR "trying to pin a non attached buffer\n");
@@ -642,12 +620,20 @@ static int vb2_dc_map_dmabuf(void *mem_priv)
return -EINVAL;
}

+   /* mapping new sglist to the client */
+   sgt->nents = dma_map_sg(buf->dev, sgt->sgl, sgt->orig_nents,
+   buf->dma_dir);
+   if (sgt->nents <= 0) {
+   printk(KERN_ERR "failed to map scatterlist\n");
+   goto fail_map_attachment;
+   }
+
/* checking if dmabuf is big enough to store contiguous chunk */
contig_size = vb2_dc_get_contiguous_size(sgt);
if (contig_size < buf->size) {
-   printk(KERN_ERR "contiguous chunk of dmabuf is too small\n");
-   ret = -EFAULT;
-   goto fail_map;
+   printk(KERN_ERR "contiguous chunk of dmabuf is too small "
+   "%lu/%lu bytes\n", contig_size, buf->size);
+   goto fail_map_sg;
}

buf->dma_addr = sg_dma_address(sgt->sgl);
@@ -655,7 +641,10 @@ static int vb2_dc_map_dmabuf(void *mem_priv)

return 0;

-fail_map:
+fail_map_sg:
+   dma_unmap_sg(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
+
+fail_map_attachment:
dma_buf_unmap_attachment(buf->db_attach, sgt);

return ret;
@@ -676,6 +665,7 @@ static void vb2_dc_unmap_dmabuf(void *mem_priv)
return

[RFCv2 PATCH 6/9] v4l: vb2-dma-contig: add support for DMABUF exporting

2012-03-13 Thread Tomasz Stanislawski
This patch adds support for exporting a dma-contig buffer using
DMABUF interface.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/videobuf2-dma-contig.c |  128 
 1 files changed, 128 insertions(+), 0 deletions(-)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index 746dd5f..d95b23a 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -31,6 +31,7 @@ struct vb2_dc_buf {
/* MMAP related */
struct vb2_vmarea_handler   handler;
atomic_trefcount;
+   struct dma_buf  *dma_buf;
struct sg_table *sgt_base;

/* USERPTR related */
@@ -194,6 +195,8 @@ static void vb2_dc_put(void *buf_priv)
if (!atomic_dec_and_test(&buf->refcount))
return;

+   if (buf->dma_buf)
+   dma_buf_put(buf->dma_buf);
vb2_dc_release_sgtable(buf->sgt_base);
dma_free_coherent(buf->dev, buf->size, buf->vaddr,
buf->dma_addr);
@@ -309,6 +312,130 @@ static int vb2_dc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
 }

 /*/
+/* DMABUF ops for exporters  */
+/*/
+
+struct vb2_dc_attachment {
+   struct sg_table sgt;
+   enum dma_data_direction dir;
+};
+
+static int vb2_dc_dmabuf_ops_attach(struct dma_buf *dbuf, struct device *dev,
+   struct dma_buf_attachment *dbuf_attach)
+{
+   /* nothing to be done */
+   return 0;
+}
+
+static void vb2_dc_dmabuf_ops_detach(struct dma_buf *dbuf,
+   struct dma_buf_attachment *db_attach)
+{
+   struct vb2_dc_attachment *attach = db_attach->priv;
+   struct sg_table *sgt;
+
+   if (!attach)
+   return;
+
+   sgt = &attach->sgt;
+
+   dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->nents, attach->dir);
+   sg_free_table(sgt);
+   kfree(attach);
+   db_attach->priv = NULL;
+}
+
+static struct sg_table *vb2_dc_dmabuf_ops_map(
+   struct dma_buf_attachment *db_attach, enum dma_data_direction dir)
+{
+   struct dma_buf *dbuf = db_attach->dmabuf;
+   struct vb2_dc_buf *buf = dbuf->priv;
+   struct vb2_dc_attachment *attach = db_attach->priv;
+   struct sg_table *sgt;
+   struct scatterlist *rd, *wr;
+   int i, ret;
+
+   /* return previously mapped sg table */
+   if (attach)
+   return &attach->sgt;
+
+   attach = kzalloc(sizeof *attach, GFP_KERNEL);
+   if (!attach)
+   return ERR_PTR(-ENOMEM);
+
+   sgt = &attach->sgt;
+   attach->dir = dir;
+
+   /* copying the buf->base_sgt to attachment */
+   ret = sg_alloc_table(sgt, buf->sgt_base->orig_nents, GFP_KERNEL);
+   if (ret) {
+   kfree(attach);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   rd = buf->sgt_base->sgl;
+   wr = sgt->sgl;
+   for (i = 0; i < sgt->orig_nents; ++i) {
+   sg_set_page(wr, sg_page(rd), rd->length, rd->offset);
+   rd = sg_next(rd);
+   wr = sg_next(wr);
+   }
+
+   /* mapping new sglist to the client */
+   ret = dma_map_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, dir);
+   if (ret <= 0) {
+   printk(KERN_ERR "failed to map scatterlist\n");
+   sg_free_table(sgt);
+   kfree(attach);
+   return ERR_PTR(-EIO);
+   }
+
+   db_attach->priv = attach;
+
+   return sgt;
+}
+
+static void vb2_dc_dmabuf_ops_unmap(struct dma_buf_attachment *db_attach,
+   struct sg_table *sgt)
+{
+   /* nothing to be done here */
+}
+
+static void vb2_dc_dmabuf_ops_release(struct dma_buf *dbuf)
+{
+   /* drop reference obtained in vb2_dc_get_dmabuf */
+   vb2_dc_put(dbuf->priv);
+}
+
+static struct dma_buf_ops vb2_dc_dmabuf_ops = {
+   .attach = vb2_dc_dmabuf_ops_attach,
+   .detach = vb2_dc_dmabuf_ops_detach,
+   .map_dma_buf = vb2_dc_dmabuf_ops_map,
+   .unmap_dma_buf = vb2_dc_dmabuf_ops_unmap,
+   .release = vb2_dc_dmabuf_ops_release,
+};
+
+static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+   struct dma_buf *dbuf;
+
+   if (buf->dma_buf)
+   return buf->dma_buf;
+
+   /* dmabuf keeps reference to vb2 buffer */
+   atomic_inc(&buf->refcount);
+   dbuf = dma_buf_export(buf, &vb2_dc_dmabuf_ops, buf->size, 0);
+   if (IS_ERR(dbuf)) {
+   atomic_dec(&buf->refcount);
+   return NULL;
+   }
+
+   buf->dma_buf = dbuf;
+
+   return dbuf;
+}
+
+/*/
 /*   callbacks for USERPTR buffers   */
 /*/

@@ -603,6 +730,7 @@ static void *vb2_dc_attach_dmabuf(void *alloc_ctx, struct 
dma

[RFCv2 PATCH 5/9] v4l: vb2: add buffer exporting via dmabuf

2012-03-13 Thread Tomasz Stanislawski
This patch adds extension to videobuf2-core. It allow to export a mmap buffer
as a file descriptor.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/videobuf2-core.c |   64 ++
 include/media/videobuf2-core.h   |2 +
 2 files changed, 66 insertions(+), 0 deletions(-)

diff --git a/drivers/media/video/videobuf2-core.c 
b/drivers/media/video/videobuf2-core.c
index e7df560..41c4bf8 100644
--- a/drivers/media/video/videobuf2-core.c
+++ b/drivers/media/video/videobuf2-core.c
@@ -1553,6 +1553,70 @@ int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer 
*b, bool nonblocking)
 }
 EXPORT_SYMBOL_GPL(vb2_dqbuf);

+static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off,
+   unsigned int *_buffer, unsigned int *_plane);
+
+/**
+ * vb2_expbuf() - Export a buffer as a file descriptor
+ * @q: videobuf2 queue
+ * @b: export buffer structure passed from userspace to vidioc_expbuf
+ * handler in driver
+ *
+ * The return values from this function are intended to be directly returned
+ * from vidioc_expbuf handler in driver.
+ */
+int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
+{
+   struct vb2_buffer *vb = NULL;
+   struct vb2_plane *vb_plane;
+   unsigned int buffer, plane;
+   int ret;
+   struct dma_buf *dbuf;
+
+   if (q->memory != V4L2_MEMORY_MMAP) {
+   dprintk(1, "Queue is not currently set up for mmap\n");
+   return -EINVAL;
+   }
+
+   if (!q->mem_ops->get_dmabuf) {
+   dprintk(1, "Queue does not support DMA buffer exporting\n");
+   return -EINVAL;
+   }
+
+   /*
+* Find the plane corresponding to the offset passed by userspace.
+*/
+   ret = __find_plane_by_offset(q, eb->mem_offset, &buffer, &plane);
+   if (ret) {
+   dprintk(1, "invalid offset %u\n", eb->mem_offset);
+   return ret;
+   }
+
+   vb = q->bufs[buffer];
+   vb_plane = &vb->planes[plane];
+
+   dbuf = call_memop(q, get_dmabuf, vb_plane->mem_priv);
+   if (IS_ERR_OR_NULL(dbuf)) {
+   dprintk(1, "Failed to export buffer %d, plane %d\n",
+   buffer, plane);
+   return -EINVAL;
+   }
+
+   ret = dma_buf_fd(dbuf);
+   if (ret < 0) {
+   dprintk(3, "buffer %d, plane %d failed to export (%d)\n",
+   buffer, plane, ret);
+   return ret;
+   }
+
+   dprintk(3, "buffer %d, plane %d exported as %d descriptor\n",
+   buffer, plane, ret);
+   eb->fd = ret;
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(vb2_expbuf);
+
 /**
  * __vb2_queue_cancel() - cancel and stop (pause) streaming
  *
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 412c6a4..548252b 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -79,6 +79,7 @@ struct vb2_mem_ops {
void(*prepare)(void *buf_priv);
void(*finish)(void *buf_priv);
void(*put)(void *buf_priv);
+   struct dma_buf *(*get_dmabuf)(void *buf_priv);

void*(*get_userptr)(void *alloc_ctx, unsigned long vaddr,
unsigned long size, int write);
@@ -348,6 +349,7 @@ int vb2_queue_init(struct vb2_queue *q);
 void vb2_queue_release(struct vb2_queue *q);

 int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b);
+int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb);
 int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking);

 int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type);
-- 
1.7.5.4



[RFCv2 PATCH 4/9] v4l: add buffer exporting via dmabuf

2012-03-13 Thread Tomasz Stanislawski
This patch adds extension to V4L2 api. It allow to export a mmap buffer as file
descriptor. New ioctl VIDIOC_EXPBUF is added. It takes a buffer offset used by
mmap and return a file descriptor on success.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/v4l2-compat-ioctl32.c |1 +
 drivers/media/video/v4l2-ioctl.c  |   11 +++
 include/linux/videodev2.h |   20 
 include/media/v4l2-ioctl.h|2 ++
 4 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/drivers/media/video/v4l2-compat-ioctl32.c 
b/drivers/media/video/v4l2-compat-ioctl32.c
index e6f67aa..fd157cb 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -954,6 +954,7 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int 
cmd, unsigned long arg)
case VIDIOC_S_FBUF32:
case VIDIOC_OVERLAY32:
case VIDIOC_QBUF32:
+   case VIDIOC_EXPBUF:
case VIDIOC_DQBUF32:
case VIDIOC_STREAMON32:
case VIDIOC_STREAMOFF32:
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 74cab51..a125016 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -207,6 +207,7 @@ static const char *v4l2_ioctls[] = {
[_IOC_NR(VIDIOC_S_FBUF)]   = "VIDIOC_S_FBUF",
[_IOC_NR(VIDIOC_OVERLAY)]  = "VIDIOC_OVERLAY",
[_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF",
+   [_IOC_NR(VIDIOC_EXPBUF)]   = "VIDIOC_EXPBUF",
[_IOC_NR(VIDIOC_DQBUF)]= "VIDIOC_DQBUF",
[_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON",
[_IOC_NR(VIDIOC_STREAMOFF)]= "VIDIOC_STREAMOFF",
@@ -938,6 +939,16 @@ static long __video_do_ioctl(struct file *file,
dbgbuf(cmd, vfd, p);
break;
}
+   case VIDIOC_EXPBUF:
+   {
+   struct v4l2_exportbuffer *p = arg;
+
+   if (!ops->vidioc_expbuf)
+   break;
+
+   ret = ops->vidioc_expbuf(file, fh, p);
+   break;
+   }
case VIDIOC_DQBUF:
{
struct v4l2_buffer *p = arg;
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index bb6844e..e71c787 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -680,6 +680,25 @@ struct v4l2_buffer {
 #define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE  0x0800
 #define V4L2_BUF_FLAG_NO_CACHE_CLEAN   0x1000

+/**
+ * struct v4l2_exportbuffer - export of video buffer as DMABUF file descriptor
+ *
+ * @fd:file descriptor associated with DMABUF (set by driver)
+ * @mem_offset:for non-multiplanar buffers with memory == 
V4L2_MEMORY_MMAP;
+ * offset from the start of the device memory for this plane,
+ * (or a "cookie" that should be passed to mmap() as offset)
+ *
+ * Contains data used for exporting a video buffer as DMABUF file
+ * descriptor. Uses the same 'cookie' as mmap() syscall. All reserved fields
+ * must be set to zero.
+ */
+struct v4l2_exportbuffer {
+   __u32   fd;
+   __u32   reserved0;
+   __u32   mem_offset;
+   __u32   reserved[13];
+};
+
 /*
  * O V E R L A Y   P R E V I E W
  */
@@ -2303,6 +2322,7 @@ struct v4l2_create_buffers {
 #define VIDIOC_S_FBUF   _IOW('V', 11, struct v4l2_framebuffer)
 #define VIDIOC_OVERLAY  _IOW('V', 14, int)
 #define VIDIOC_QBUF_IOWR('V', 15, struct v4l2_buffer)
+#define VIDIOC_EXPBUF  _IOWR('V', 16, struct v4l2_exportbuffer)
 #define VIDIOC_DQBUF   _IOWR('V', 17, struct v4l2_buffer)
 #define VIDIOC_STREAMON _IOW('V', 18, int)
 #define VIDIOC_STREAMOFF_IOW('V', 19, int)
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index 4df031a..d8716c6f 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -120,6 +120,8 @@ struct v4l2_ioctl_ops {
int (*vidioc_reqbufs) (struct file *file, void *fh, struct 
v4l2_requestbuffers *b);
int (*vidioc_querybuf)(struct file *file, void *fh, struct v4l2_buffer 
*b);
int (*vidioc_qbuf)(struct file *file, void *fh, struct v4l2_buffer 
*b);
+   int (*vidioc_expbuf)  (struct file *file, void *fh,
+   struct v4l2_exportbuffer *e);
int (*vidioc_dqbuf)   (struct file *file, void *fh, struct v4l2_buffer 
*b);

int (*vidioc_create_bufs)(struct file *file, void *fh, struct 
v4l2_create_buffers *b);
-- 
1.7.5.4



[RFCv2 PATCH 3/9] v4l: vb2: Add dma-contig allocator as dma_buf user

2012-03-13 Thread Tomasz Stanislawski
From: Sumit Semwal 

This patch makes changes for adding dma-contig as a dma_buf user. It provides
function implementations for the {attach, detach, map, unmap}_dmabuf()
mem_ops of DMABUF memory type.

Signed-off-by: Sumit Semwal 
Signed-off-by: Sumit Semwal 
[author of the original patch]
Signed-off-by: Tomasz Stanislawski 
[integration with refactored dma-contig allocator]
---
 drivers/media/video/videobuf2-dma-contig.c |  116 
 1 files changed, 116 insertions(+), 0 deletions(-)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index c1dc043..746dd5f 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -35,6 +35,9 @@ struct vb2_dc_buf {

/* USERPTR related */
struct vm_area_struct   *vma;
+
+   /* DMABUF related */
+   struct dma_buf_attachment   *db_attach;
 };

 /*/
@@ -485,6 +488,115 @@ fail_buf:
 }

 /*/
+/*   callbacks for DMABUF buffers*/
+/*/
+
+static int vb2_dc_map_dmabuf(void *mem_priv)
+{
+   struct vb2_dc_buf *buf = mem_priv;
+   struct sg_table *sgt;
+   unsigned long contig_size;
+   int ret = 0;
+
+   if (WARN_ON(!buf->db_attach)) {
+   printk(KERN_ERR "trying to pin a non attached buffer\n");
+   return -EINVAL;
+   }
+
+   if (WARN_ON(buf->dma_sgt)) {
+   printk(KERN_ERR "dmabuf buffer is already pinned\n");
+   return 0;
+   }
+
+   /* get the associated scatterlist for this buffer */
+   sgt = dma_buf_map_attachment(buf->db_attach, buf->dma_dir);
+   if (IS_ERR_OR_NULL(sgt)) {
+   printk(KERN_ERR "Error getting dmabuf scatterlist\n");
+   return -EINVAL;
+   }
+
+   /* checking if dmabuf is big enough to store contiguous chunk */
+   contig_size = vb2_dc_get_contiguous_size(sgt);
+   if (contig_size < buf->size) {
+   printk(KERN_ERR "contiguous chunk of dmabuf is too small\n");
+   ret = -EFAULT;
+   goto fail_map;
+   }
+
+   buf->dma_addr = sg_dma_address(sgt->sgl);
+   buf->dma_sgt = sgt;
+
+   return 0;
+
+fail_map:
+   dma_buf_unmap_attachment(buf->db_attach, sgt);
+
+   return ret;
+}
+
+static void vb2_dc_unmap_dmabuf(void *mem_priv)
+{
+   struct vb2_dc_buf *buf = mem_priv;
+   struct sg_table *sgt = buf->dma_sgt;
+
+   if (WARN_ON(!buf->db_attach)) {
+   printk(KERN_ERR "trying to unpin a not attached buffer\n");
+   return;
+   }
+
+   if (WARN_ON(!sgt)) {
+   printk(KERN_ERR "dmabuf buffer is already unpinned\n");
+   return;
+   }
+
+   dma_buf_unmap_attachment(buf->db_attach, sgt);
+
+   buf->dma_addr = 0;
+   buf->dma_sgt = NULL;
+}
+
+static void vb2_dc_detach_dmabuf(void *mem_priv)
+{
+   struct vb2_dc_buf *buf = mem_priv;
+
+   if (buf->dma_addr)
+   vb2_dc_unmap_dmabuf(buf);
+
+   /* detach this attachment */
+   dma_buf_detach(buf->db_attach->dmabuf, buf->db_attach);
+   kfree(buf);
+}
+
+static void *vb2_dc_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf,
+   unsigned long size, int write)
+{
+   struct vb2_dc_buf *buf;
+   struct dma_buf_attachment *dba;
+
+   if (dbuf->size < size)
+   return ERR_PTR(-EFAULT);
+
+   buf = kzalloc(sizeof *buf, GFP_KERNEL);
+   if (!buf)
+   return ERR_PTR(-ENOMEM);
+
+   buf->dev = alloc_ctx;
+   /* create attachment for the dmabuf with the user device */
+   dba = dma_buf_attach(dbuf, buf->dev);
+   if (IS_ERR(dba)) {
+   printk(KERN_ERR "failed to attach dmabuf\n");
+   kfree(buf);
+   return dba;
+   }
+
+   buf->dma_dir = write ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+   buf->size = size;
+   buf->db_attach = dba;
+
+   return buf;
+}
+
+/*/
 /*   DMA CONTIG exported functions   */
 /*/

@@ -498,6 +610,10 @@ const struct vb2_mem_ops vb2_dma_contig_memops = {
.put_userptr= vb2_dc_put_userptr,
.prepare= vb2_dc_prepare,
.finish = vb2_dc_finish,
+   .map_dmabuf = vb2_dc_map_dmabuf,
+   .unmap_dmabuf   = vb2_dc_unmap_dmabuf,
+   .attach_dmabuf  = vb2_dc_attach_dmabuf,
+   .detach_dmabuf  = vb2_dc_detach_dmabuf,
.num_users  = vb2_dc_num_users,
 };
 EXPORT_SYMBOL_GPL(vb2_dma_contig_memops);
-- 
1.7.5.4



[RFCv2 PATCH 2/9] v4l: vb2-dma-contig: update and code refactoring

2012-03-13 Thread Tomasz Stanislawski
This patch combines updates and fixes to dma-contig allocator.
Moreover the allocator code was refactored.
The most important changes are:
- functions were reordered
- move compression of scatterlist to separete function
- add support for multichunk but contiguous scatterlists
- simplified implementation of vb2-dma-contig context structure
- let mmap method to use dma_mmap_writecombine
- add support for scatterlist in userptr mode

Signed-off-by: Marek Szyprowski 
[mmap method]
Signed-off-by: Andrzej Pietrasiewicz 
[scatterlist in userptr mode]
Signed-off-by: Kamil Debski 
[bugfixing]
Signed-off-by: Tomasz Stanislawski 
[core refactoring, helper functions]
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/videobuf2-dma-contig.c |  495 +++-
 1 files changed, 414 insertions(+), 81 deletions(-)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index f17ad98..c1dc043 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -10,173 +10,506 @@
  * the Free Software Foundation.
  */

+#include 
+#include 
 #include 
+#include 
+#include 
 #include 
-#include 

 #include 
 #include 

-struct vb2_dc_conf {
-   struct device   *dev;
-};
-
 struct vb2_dc_buf {
-   struct vb2_dc_conf  *conf;
+   struct device   *dev;
void*vaddr;
-   dma_addr_t  dma_addr;
unsigned long   size;
-   struct vm_area_struct   *vma;
-   atomic_trefcount;
+   dma_addr_t  dma_addr;
+   struct sg_table *dma_sgt;
+   enum dma_data_direction dma_dir;
+
+   /* MMAP related */
struct vb2_vmarea_handler   handler;
+   atomic_trefcount;
+   struct sg_table *sgt_base;
+
+   /* USERPTR related */
+   struct vm_area_struct   *vma;
 };

-static void vb2_dma_contig_put(void *buf_priv);
+/*/
+/*scatterlist table functions*/
+/*/

-static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned long size)
+static struct sg_table *vb2_dc_pages_to_sgt(struct page **pages,
+   unsigned long n_pages, size_t offset, size_t offset2)
 {
-   struct vb2_dc_conf *conf = alloc_ctx;
-   struct vb2_dc_buf *buf;
+   struct sg_table *sgt;
+   int i, j; /* loop counters */
+   int cur_page, chunks;
+   int ret;
+   struct scatterlist *s;

-   buf = kzalloc(sizeof *buf, GFP_KERNEL);
-   if (!buf)
+   sgt = kzalloc(sizeof *sgt, GFP_KERNEL);
+   if (!sgt)
return ERR_PTR(-ENOMEM);

-   buf->vaddr = dma_alloc_coherent(conf->dev, size, &buf->dma_addr,
-   GFP_KERNEL);
-   if (!buf->vaddr) {
-   dev_err(conf->dev, "dma_alloc_coherent of size %ld failed\n",
-   size);
-   kfree(buf);
+   /* compute number of chunks */
+   chunks = 1;
+   for (i = 1; i < n_pages; ++i)
+   if (pages[i] != pages[i - 1] + 1)
+   ++chunks;
+
+   ret = sg_alloc_table(sgt, chunks, GFP_KERNEL);
+   if (ret) {
+   kfree(sgt);
return ERR_PTR(-ENOMEM);
}

-   buf->conf = conf;
-   buf->size = size;
-
-   buf->handler.refcount = &buf->refcount;
-   buf->handler.put = vb2_dma_contig_put;
-   buf->handler.arg = buf;
+   /* merging chunks and putting them into the scatterlist */
+   cur_page = 0;
+   for_each_sg(sgt->sgl, s, sgt->orig_nents, i) {
+   size_t size = PAGE_SIZE;
+
+   for (j = cur_page + 1; j < n_pages; ++j) {
+   if (pages[j] != pages[j - 1] + 1)
+   break;
+   size += PAGE_SIZE;
+   }
+
+   /* cut offset if chunk starts at the first page */
+   if (cur_page == 0)
+   size -= offset;
+   /* cut offset2 if chunk ends at the last page */
+   if (j == n_pages)
+   size -= offset2;
+
+   sg_set_page(s, pages[cur_page], size, offset);
+   offset = 0;
+   cur_page = j;
+   }

-   atomic_inc(&buf->refcount);
+   return sgt;
+}

-   return buf;
+static void vb2_dc_release_sgtable(struct sg_table *sgt)
+{
+   sg_free_table(sgt);
+   kfree(sgt);
 }

-static void vb2_dma_contig_put(void *buf_priv)
+static void vb2_dc_put_sgtable(struct sg_table *sgt, int dirty)
 {
-   struct vb2_dc_buf *buf = buf_priv;
+   struct scatterlist *s;
+   int i, j;
+
+   for_each_sg(sgt->sgl, s, sgt->nents, i) {
+   struct page 

[RFCv2 PATCH 1/9] v4l: vb2: fixes for DMABUF support

2012-03-13 Thread Tomasz Stanislawski
This patch contains fixes to DMABUF support in vb2-core.
- fixes number of arguments of call_memop macro
- fixes setup of plane length
- fixes handling of error pointers

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/videobuf2-core.c |   24 +++-
 include/media/videobuf2-core.h   |6 +++---
 2 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/drivers/media/video/videobuf2-core.c 
b/drivers/media/video/videobuf2-core.c
index 951cb56..e7df560 100644
--- a/drivers/media/video/videobuf2-core.c
+++ b/drivers/media/video/videobuf2-core.c
@@ -118,7 +118,7 @@ static void __vb2_buf_dmabuf_put(struct vb2_buffer *vb)
void *mem_priv = vb->planes[plane].mem_priv;

if (mem_priv) {
-   call_memop(q, plane, detach_dmabuf, mem_priv);
+   call_memop(q, detach_dmabuf, mem_priv);
dma_buf_put(vb->planes[plane].dbuf);
vb->planes[plane].dbuf = NULL;
vb->planes[plane].mem_priv = NULL;
@@ -905,6 +905,8 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb, const 
struct v4l2_buffer *b,
}
if (b->memory == V4L2_MEMORY_DMABUF) {
for (plane = 0; plane < vb->num_planes; ++plane) {
+   v4l2_planes[plane].bytesused =
+   b->m.planes[plane].bytesused;
v4l2_planes[plane].m.fd = 
b->m.planes[plane].m.fd;
}
}
@@ -1052,17 +1054,13 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const 
struct v4l2_buffer *b)
if (IS_ERR_OR_NULL(dbuf)) {
dprintk(1, "qbuf: invalid dmabuf fd for "
"plane %d\n", plane);
-   ret = PTR_ERR(dbuf);
+   ret = -EINVAL;
goto err;
}

-   /* this doesn't get filled in until __fill_vb2_buffer(),
-* since it isn't known until after dma_buf_get()..
-*/
-   planes[plane].length = dbuf->size;
-
/* Skip the plane if already verified */
if (dbuf == vb->planes[plane].dbuf) {
+   planes[plane].length = dbuf->size;
dma_buf_put(dbuf);
continue;
}
@@ -1072,7 +1070,7 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const 
struct v4l2_buffer *b)

/* Release previously acquired memory if present */
if (vb->planes[plane].mem_priv) {
-   call_memop(q, plane, detach_dmabuf,
+   call_memop(q, detach_dmabuf,
vb->planes[plane].mem_priv);
dma_buf_put(vb->planes[plane].dbuf);
}
@@ -1080,8 +1078,8 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const 
struct v4l2_buffer *b)
vb->planes[plane].mem_priv = NULL;

/* Acquire each plane's memory */
-   mem_priv = q->mem_ops->attach_dmabuf(
-   q->alloc_ctx[plane], dbuf);
+   mem_priv = call_memop(q, attach_dmabuf, q->alloc_ctx[plane],
+   dbuf, q->plane_sizes[plane], write);
if (IS_ERR(mem_priv)) {
dprintk(1, "qbuf: failed acquiring dmabuf "
"memory for plane %d\n", plane);
@@ -1089,6 +1087,7 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const 
struct v4l2_buffer *b)
goto err;
}

+   planes[plane].length = dbuf->size;
vb->planes[plane].dbuf = dbuf;
vb->planes[plane].mem_priv = mem_priv;
}
@@ -1098,8 +1097,7 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const 
struct v4l2_buffer *b)
 * the buffer(s)..
 */
for (plane = 0; plane < vb->num_planes; ++plane) {
-   ret = q->mem_ops->map_dmabuf(
-   vb->planes[plane].mem_priv, write);
+   ret = call_memop(q, map_dmabuf, vb->planes[plane].mem_priv);
if (ret) {
dprintk(1, "qbuf: failed mapping dmabuf "
"memory for plane %d\n", plane);
@@ -1527,7 +1525,7 @@ int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, 
bool nonblocking)
 */
if (q->memory == V4L2_MEMORY_DMABUF)
for (plane = 0; plane < vb->num_planes; ++plane)
-   call_memop(q, plane, unmap_dmabuf,
+   call_memop(q, unmap_dmabuf,
vb->planes[plane].mem_priv);

switch (vb->state) {
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index d8b8171..412c6a4 100644
--- a/includ

[RFCv2 PATCH 0/9] Integration of videobuf2 with dmabuf

2012-03-13 Thread Tomasz Stanislawski
Hello everyone,
This patchset is an incremental patch to patchset created by Sumit Semwal [1].
The patches are dedicated to help find a better solution for support of buffer
sharing by V4L2 API.  It is expected to start discussion on the final
installment for dma-buf in vb2-dma-contig allocator.  Current version of the
patches contain little documentation. It is going to be fixed after achieving
consensus about design for buffer exporting.  Moreover the API between vb2-core
and the allocator should be revised.

The patches were successfully tested to cooperate with EXYNOS DRM driver using
DMABUF mechanism.

Please note, that the amount of changes to vb2-dma-contig.c was significant
making the difference patch very difficult to read.

The patchset makes use of dma_get_pages extension for DMA API, which is posted
on a top of dma-mapping patches by Marek Szyprowski [4] [5].

The tree, that contains all needed patches, can be found here [6].

v2:
- extended VIDIOC_EXPBUF argument from integer memoffset to struct
  v4l2_exportbuffer
- added patch that breaks DMABUF spec on (un)map_atachment callcacks but allows
  to work with existing implementation of DMABUF prime in DRM
- all dma-contig code refactoring patches were squashed
- bugfixes

v1: List of changes since [1].
- support for DMA api extension dma_get_pages, the function is used to retrieve
  pages used to create DMA mapping.
- small fixes/code cleanup to videobuf2
- added prepare and finish callbacks to vb2 allocators, it is used keep
  consistency between dma-cpu acess to the memory (by Marek Szyprowski)
- support for exporting of DMABUF buffer in V4L2 and Videobuf2, originated from
  [3].
- support for dma-buf exporting in vb2-dma-contig allocator
- support for DMABUF for s5p-tv and s5p-fimc (capture interface) drivers,
  originated from [3]
- changed handling for userptr buffers (by Marek Szyprowski, Andrzej
  Pietrasiewicz)
- let mmap method to use dma_mmap_writecombine call (by Marek Szyprowski)

[1] 
http://thread.gmane.org/gmane.linux.drivers.video-input-infrastructure/42966/focus=42968
[2] https://lkml.org/lkml/2011/12/26/29
[3] 
http://thread.gmane.org/gmane.linux.drivers.video-input-infrastructure/36354/focus=36355
[4] http://thread.gmane.org/gmane.linux.kernel.cross-arch/12819
[5] 
http://git.infradead.org/users/kmpark/linux-2.6-samsung/shortlog/refs/heads/3.3-rc5-dma-v7
[6] 
http://git.infradead.org/users/kmpark/linux-2.6-samsung/shortlog/refs/heads/3.3-rc5-vb2-dma-contig-dmabuf-drm


Sumit Semwal (1):
  v4l: vb2: Add dma-contig allocator as dma_buf user

Tomasz Stanislawski (8):
  v4l: vb2: fixes for DMABUF support
  v4l: vb2-dma-contig: update and code refactoring
  v4l: add buffer exporting via dmabuf
  v4l: vb2: add buffer exporting via dmabuf
  v4l: vb2-dma-contig: add support for DMABUF exporting
  v4l: vb2-dma-contig: change map/unmap behaviour
  v4l: fimc: integrate capture i-face with dmabuf
  v4l: s5p-tv: mixer: integrate with dmabuf

 drivers/media/video/Kconfig |1 +
 drivers/media/video/s5p-fimc/fimc-capture.c |   11 +-
 drivers/media/video/s5p-tv/Kconfig  |1 +
 drivers/media/video/s5p-tv/mixer_video.c|   12 +-
 drivers/media/video/v4l2-compat-ioctl32.c   |1 +
 drivers/media/video/v4l2-ioctl.c|   11 +
 drivers/media/video/videobuf2-core.c|   88 +++-
 drivers/media/video/videobuf2-dma-contig.c  |  717 ---
 include/linux/videodev2.h   |   20 +
 include/media/v4l2-ioctl.h  |2 +
 include/media/videobuf2-core.h  |8 +-
 11 files changed, 779 insertions(+), 93 deletions(-)

-- 
1.7.5.4



[PATCH 00/15] drm: Bounds checking, error handling, etc.

2012-03-13 Thread Alex Deucher
On Tue, Mar 13, 2012 at 6:35 AM,   wrote:
> Mostly fixes for various bits and pieces that caught my eye while
> reading the mode setting code.

For the series:

Reviewed-by: Alex Deucher 


[Bug 46725] Monitor "disconnected" and refuses to work anymore

2012-03-13 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=46725

--- Comment #10 from Tomi Pievil?inen  
2012-03-13 02:00:11 PDT ---
Unfortunately not.

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.


[Bug 47007] HDMI monitor polling causing 100ms rendering stalls

2012-03-13 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=47007

Tvrtko Ursulin  changed:

   What|Removed |Added

  Attachment #58318|0   |1
is obsolete||

--- Comment #14 from Tvrtko Ursulin  2012-03-13 
01:46:42 PDT ---
Created attachment 58360
  --> https://bugs.freedesktop.org/attachment.cgi?id=58360
Do not re-fetch full EDID while a HPD capable output remains connected

So something like this:
---
On multi output boards where one output is not connected it can cause KMS poll
helper to run periodically. This makes the connected DVI/HDMI output re-fetch
full EDID on every poll causing 100ms rendering stalls.

Fix is to skip re-fetching full EDID while a HPD capable output remains
connected on R600 and newer.

Reviewed-by: Alex Deucher 

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.


[RESEND][PATCH 09/10] drm/exynos: add G2D driver

2012-03-13 Thread Inki Dae
From: Joonyoung Shim 

G2D is a 2D graphic accelerator that supports Bit Block Transfer. This
G2D driver is exynos drm specific.

This adds below three exynos specific ioctl and one event for G2D.
 - DRM_EXYNOS_G2D_GET_VER
 - DRM_EXYNOS_G2D_SET_CMDLIST
 - DRM_EXYNOS_G2D_EXEC
 - DRM_EXYNOS_G2D_EVENT

Signed-off-by: Joonyoung Shim 
Signed-off-by: Inki Dae 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/Kconfig  |6 +
 drivers/gpu/drm/exynos/Makefile |1 +
 drivers/gpu/drm/exynos/exynos_drm_drv.c |   31 ++
 drivers/gpu/drm/exynos/exynos_drm_drv.h |   13 +
 drivers/gpu/drm/exynos/exynos_drm_g2d.c |  885 +++
 drivers/gpu/drm/exynos/exynos_drm_g2d.h |   36 ++
 include/drm/exynos_drm.h|   56 ++
 7 files changed, 1028 insertions(+), 0 deletions(-)
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_g2d.c
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_g2d.h

diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 9a9850a..8493fe9 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -21,3 +21,9 @@ config DRM_EXYNOS_HDMI
depends on DRM_EXYNOS && !VIDEO_SAMSUNG_S5P_TV
help
  Choose this option if you want to use Exynos HDMI for DRM.
+
+config DRM_EXYNOS_G2D
+   bool "Exynos DRM G2D"
+   depends on DRM_EXYNOS
+   help
+ Choose this option if you want to use Exynos G2D for DRM.
diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
index 5331fa3..d6c1a3c 100644
--- a/drivers/gpu/drm/exynos/Makefile
+++ b/drivers/gpu/drm/exynos/Makefile
@@ -12,5 +12,6 @@ exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD)   += exynos_drm_fimd.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI)+= exynos_hdmi.o exynos_mixer.o \
   exynos_ddc.o exynos_hdmiphy.o \
   exynos_drm_hdmi.o
+exynosdrm-$(CONFIG_DRM_EXYNOS_G2D) += exynos_drm_g2d.o
 
 obj-$(CONFIG_DRM_EXYNOS)   += exynosdrm.o
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c 
b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index b4e265f..2b72c5d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -37,6 +37,7 @@
 #include "exynos_drm_fbdev.h"
 #include "exynos_drm_fb.h"
 #include "exynos_drm_gem.h"
+#include "exynos_drm_g2d.h"
 #include "exynos_drm_plane.h"
 
 #define DRIVER_NAME"exynos"
@@ -146,8 +147,16 @@ static int exynos_drm_unload(struct drm_device *dev)
 
 static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
 {
+   struct drm_exynos_file_private *file_priv;
+
DRM_DEBUG_DRIVER("%s\n", __FILE__);
 
+   file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
+   if (!file_priv)
+   return -ENOMEM;
+
+   file->driver_priv = file_priv;
+
return exynos_drm_subdrv_open(dev, file);
 }
 
@@ -208,6 +217,13 @@ static struct drm_ioctl_desc exynos_ioctls[] = {
exynos_drm_gem_mmap_ioctl, DRM_UNLOCKED | DRM_AUTH),
DRM_IOCTL_DEF_DRV(EXYNOS_PLANE_SET_ZPOS, exynos_plane_set_zpos_ioctl,
DRM_UNLOCKED | DRM_AUTH),
+
+   DRM_IOCTL_DEF_DRV(EXYNOS_G2D_GET_VER,
+   exynos_g2d_get_ver_ioctl, DRM_UNLOCKED | DRM_AUTH),
+   DRM_IOCTL_DEF_DRV(EXYNOS_G2D_SET_CMDLIST,
+   exynos_g2d_set_cmdlist_ioctl, DRM_UNLOCKED | DRM_AUTH),
+   DRM_IOCTL_DEF_DRV(EXYNOS_G2D_EXEC,
+   exynos_g2d_exec_ioctl, DRM_UNLOCKED | DRM_AUTH),
 };
 
 static const struct file_operations exynos_drm_driver_fops = {
@@ -298,6 +314,12 @@ static int __init exynos_drm_init(void)
goto out_common_hdmi;
 #endif
 
+#ifdef CONFIG_DRM_EXYNOS_G2D
+   ret = platform_driver_register(&g2d_driver);
+   if (ret < 0)
+   goto out_g2d;
+#endif
+
ret = platform_driver_register(&exynos_drm_platform_driver);
if (ret < 0)
goto out;
@@ -305,6 +327,11 @@ static int __init exynos_drm_init(void)
return 0;
 
 out:
+#ifdef CONFIG_DRM_EXYNOS_G2D
+   platform_driver_unregister(&g2d_driver);
+out_g2d:
+#endif
+
 #ifdef CONFIG_DRM_EXYNOS_HDMI
platform_driver_unregister(&exynos_drm_common_hdmi_driver);
 out_common_hdmi:
@@ -327,6 +354,10 @@ static void __exit exynos_drm_exit(void)
 
platform_driver_unregister(&exynos_drm_platform_driver);
 
+#ifdef CONFIG_DRM_EXYNOS_G2D
+   platform_driver_unregister(&g2d_driver);
+#endif
+
 #ifdef CONFIG_DRM_EXYNOS_HDMI
platform_driver_unregister(&exynos_drm_common_hdmi_driver);
platform_driver_unregister(&mixer_driver);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h 
b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index b26c2f4..750daa9 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -203,6 +203,18 @@ struct exynos_drm_manager {
struct exynos_drm_

[PATCH 10/10] drm/exynos: added virtual display driver.

2012-03-13 Thread Inki Dae
this driver would be used for wireless display. virtual display
driver has independent crtc, encoder and connector and to use
this driver, user application should send edid data to this driver
from wireless display.

Signed-off-by: Inki Dae 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/Kconfig|6 +
 drivers/gpu/drm/exynos/Makefile   |1 +
 drivers/gpu/drm/exynos/exynos_drm_connector.c |4 +
 drivers/gpu/drm/exynos/exynos_drm_drv.c   |   18 +
 drivers/gpu/drm/exynos/exynos_drm_drv.h   |7 +-
 drivers/gpu/drm/exynos/exynos_drm_encoder.c   |1 +
 drivers/gpu/drm/exynos/exynos_drm_vidi.c  |  677 +
 drivers/gpu/drm/exynos/exynos_drm_vidi.h  |   36 ++
 include/drm/exynos_drm.h  |   20 +
 9 files changed, 768 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_vidi.c
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_vidi.h

diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 8493fe9..76aed3a 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -22,6 +22,12 @@ config DRM_EXYNOS_HDMI
help
  Choose this option if you want to use Exynos HDMI for DRM.
 
+config DRM_EXYNOS_VIDI
+   bool "Samsung DRM Virtual Display"
+   depends on DRM_EXYNOS
+   help
+ Choose this option if you want to use Samsung VIDI for DRM.
+
 config DRM_EXYNOS_G2D
bool "Exynos DRM G2D"
depends on DRM_EXYNOS
diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
index d6c1a3c..8ee8fb4 100644
--- a/drivers/gpu/drm/exynos/Makefile
+++ b/drivers/gpu/drm/exynos/Makefile
@@ -12,6 +12,7 @@ exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD)   += exynos_drm_fimd.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI)+= exynos_hdmi.o exynos_mixer.o \
   exynos_ddc.o exynos_hdmiphy.o \
   exynos_drm_hdmi.o
+exynosdrm-$(CONFIG_DRM_EXYNOS_VIDI)+= exynos_drm_vidi.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_G2D) += exynos_drm_g2d.o
 
 obj-$(CONFIG_DRM_EXYNOS)   += exynosdrm.o
diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c 
b/drivers/gpu/drm/exynos/exynos_drm_connector.c
index 33893a9..bf791fa 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_connector.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c
@@ -315,6 +315,10 @@ struct drm_connector *exynos_drm_connector_create(struct 
drm_device *dev,
connector->interlace_allowed = true;
connector->polled = DRM_CONNECTOR_POLL_HPD;
break;
+   case EXYNOS_DISPLAY_TYPE_VIDI:
+   type = DRM_MODE_CONNECTOR_VIRTUAL;
+   connector->polled = DRM_CONNECTOR_POLL_HPD;
+   break;
default:
type = DRM_MODE_CONNECTOR_Unknown;
break;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c 
b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 2b72c5d..76524f4 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -39,6 +39,7 @@
 #include "exynos_drm_gem.h"
 #include "exynos_drm_g2d.h"
 #include "exynos_drm_plane.h"
+#include "exynos_drm_vidi.h"
 
 #define DRIVER_NAME"exynos"
 #define DRIVER_DESC"Samsung SoC DRM"
@@ -217,6 +218,8 @@ static struct drm_ioctl_desc exynos_ioctls[] = {
exynos_drm_gem_mmap_ioctl, DRM_UNLOCKED | DRM_AUTH),
DRM_IOCTL_DEF_DRV(EXYNOS_PLANE_SET_ZPOS, exynos_plane_set_zpos_ioctl,
DRM_UNLOCKED | DRM_AUTH),
+   DRM_IOCTL_DEF_DRV(EXYNOS_VIDI_CONNECTION,
+   vidi_connection_ioctl, DRM_UNLOCKED | DRM_AUTH),
 
DRM_IOCTL_DEF_DRV(EXYNOS_G2D_GET_VER,
exynos_g2d_get_ver_ioctl, DRM_UNLOCKED | DRM_AUTH),
@@ -314,6 +317,12 @@ static int __init exynos_drm_init(void)
goto out_common_hdmi;
 #endif
 
+#ifdef CONFIG_DRM_EXYNOS_VIDI
+   ret = platform_driver_register(&vidi_driver);
+   if (ret < 0)
+   goto out_vidi;
+#endif
+
 #ifdef CONFIG_DRM_EXYNOS_G2D
ret = platform_driver_register(&g2d_driver);
if (ret < 0)
@@ -332,6 +341,11 @@ out:
 out_g2d:
 #endif
 
+#ifdef CONFIG_DRM_EXYNOS_VIDI
+   platform_driver_unregister(&vidi_driver);
+out_vidi:
+#endif
+
 #ifdef CONFIG_DRM_EXYNOS_HDMI
platform_driver_unregister(&exynos_drm_common_hdmi_driver);
 out_common_hdmi:
@@ -358,6 +372,10 @@ static void __exit exynos_drm_exit(void)
platform_driver_unregister(&g2d_driver);
 #endif
 
+#ifdef CONFIG_DRM_EXYNOS_VIDI
+   platform_driver_unregister(&vidi_driver);
+#endif
+
 #ifdef CONFIG_DRM_EXYNOS_HDMI
platform_driver_unregister(&exynos_drm_common_hdmi_driver);
platform_driver_unregister(&mixer_driver);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h 
b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index d7b50e5..943853a

[PATCH 09/10] drm/exynos: add G2D driver

2012-03-13 Thread Inki Dae
From: Joonyoung Shim 

G2D is a 2D graphic accelerator that supports Bit Block Transfer. This
G2D driver is exynos drm specific and supports only exynos4x12 series.
user application fills command set in cmdlist and once dma start request
these cmdlists are parsed and performed by dma.

This adds below three exynos specific ioctl and one event for G2D.
 - DRM_EXYNOS_G2D_GET_VER
 - DRM_EXYNOS_G2D_SET_CMDLIST
 - DRM_EXYNOS_G2D_EXEC
 - DRM_EXYNOS_G2D_EVENT

Signed-off-by: Joonyoung Shim 
Signed-off-by: Inki Dae 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/Kconfig  |6 +
 drivers/gpu/drm/exynos/Makefile |1 +
 drivers/gpu/drm/exynos/exynos_drm_drv.c |   31 ++
 drivers/gpu/drm/exynos/exynos_drm_drv.h |   11 +
 drivers/gpu/drm/exynos/exynos_drm_g2d.c |  864 +++
 drivers/gpu/drm/exynos/exynos_drm_g2d.h |   36 ++
 include/drm/exynos_drm.h|   56 ++
 7 files changed, 1005 insertions(+), 0 deletions(-)
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_g2d.c
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_g2d.h

diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 9a9850a..8493fe9 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -21,3 +21,9 @@ config DRM_EXYNOS_HDMI
depends on DRM_EXYNOS && !VIDEO_SAMSUNG_S5P_TV
help
  Choose this option if you want to use Exynos HDMI for DRM.
+
+config DRM_EXYNOS_G2D
+   bool "Exynos DRM G2D"
+   depends on DRM_EXYNOS
+   help
+ Choose this option if you want to use Exynos G2D for DRM.
diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
index 5331fa3..d6c1a3c 100644
--- a/drivers/gpu/drm/exynos/Makefile
+++ b/drivers/gpu/drm/exynos/Makefile
@@ -12,5 +12,6 @@ exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD)   += exynos_drm_fimd.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI)+= exynos_hdmi.o exynos_mixer.o \
   exynos_ddc.o exynos_hdmiphy.o \
   exynos_drm_hdmi.o
+exynosdrm-$(CONFIG_DRM_EXYNOS_G2D) += exynos_drm_g2d.o
 
 obj-$(CONFIG_DRM_EXYNOS)   += exynosdrm.o
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c 
b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index b4e265f..2b72c5d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -37,6 +37,7 @@
 #include "exynos_drm_fbdev.h"
 #include "exynos_drm_fb.h"
 #include "exynos_drm_gem.h"
+#include "exynos_drm_g2d.h"
 #include "exynos_drm_plane.h"
 
 #define DRIVER_NAME"exynos"
@@ -146,8 +147,16 @@ static int exynos_drm_unload(struct drm_device *dev)
 
 static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
 {
+   struct drm_exynos_file_private *file_priv;
+
DRM_DEBUG_DRIVER("%s\n", __FILE__);
 
+   file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
+   if (!file_priv)
+   return -ENOMEM;
+
+   file->driver_priv = file_priv;
+
return exynos_drm_subdrv_open(dev, file);
 }
 
@@ -208,6 +217,13 @@ static struct drm_ioctl_desc exynos_ioctls[] = {
exynos_drm_gem_mmap_ioctl, DRM_UNLOCKED | DRM_AUTH),
DRM_IOCTL_DEF_DRV(EXYNOS_PLANE_SET_ZPOS, exynos_plane_set_zpos_ioctl,
DRM_UNLOCKED | DRM_AUTH),
+
+   DRM_IOCTL_DEF_DRV(EXYNOS_G2D_GET_VER,
+   exynos_g2d_get_ver_ioctl, DRM_UNLOCKED | DRM_AUTH),
+   DRM_IOCTL_DEF_DRV(EXYNOS_G2D_SET_CMDLIST,
+   exynos_g2d_set_cmdlist_ioctl, DRM_UNLOCKED | DRM_AUTH),
+   DRM_IOCTL_DEF_DRV(EXYNOS_G2D_EXEC,
+   exynos_g2d_exec_ioctl, DRM_UNLOCKED | DRM_AUTH),
 };
 
 static const struct file_operations exynos_drm_driver_fops = {
@@ -298,6 +314,12 @@ static int __init exynos_drm_init(void)
goto out_common_hdmi;
 #endif
 
+#ifdef CONFIG_DRM_EXYNOS_G2D
+   ret = platform_driver_register(&g2d_driver);
+   if (ret < 0)
+   goto out_g2d;
+#endif
+
ret = platform_driver_register(&exynos_drm_platform_driver);
if (ret < 0)
goto out;
@@ -305,6 +327,11 @@ static int __init exynos_drm_init(void)
return 0;
 
 out:
+#ifdef CONFIG_DRM_EXYNOS_G2D
+   platform_driver_unregister(&g2d_driver);
+out_g2d:
+#endif
+
 #ifdef CONFIG_DRM_EXYNOS_HDMI
platform_driver_unregister(&exynos_drm_common_hdmi_driver);
 out_common_hdmi:
@@ -327,6 +354,10 @@ static void __exit exynos_drm_exit(void)
 
platform_driver_unregister(&exynos_drm_platform_driver);
 
+#ifdef CONFIG_DRM_EXYNOS_G2D
+   platform_driver_unregister(&g2d_driver);
+#endif
+
 #ifdef CONFIG_DRM_EXYNOS_HDMI
platform_driver_unregister(&exynos_drm_common_hdmi_driver);
platform_driver_unregister(&mixer_driver);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h 
b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index b26c2f4..d7b50e5 100644
--- a/driv

[PATCH 07/10] drm/exynos: add subdrv open/close functions

2012-03-13 Thread Inki Dae
From: Joonyoung Shim 

Some subdrv need open and close functions call when open and close drm.

Signed-off-by: Joonyoung Shim 
Signed-off-by: Inki Dae 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_drm_core.c |   35 ++
 drivers/gpu/drm/exynos/exynos_drm_drv.c  |   10 
 drivers/gpu/drm/exynos/exynos_drm_drv.h  |9 +++
 3 files changed, 54 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c 
b/drivers/gpu/drm/exynos/exynos_drm_core.c
index 937b059..4e29c71 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_core.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_core.c
@@ -175,3 +175,38 @@ int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv 
*subdrv)
return 0;
 }
 EXPORT_SYMBOL_GPL(exynos_drm_subdrv_unregister);
+
+int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file)
+{
+   struct exynos_drm_subdrv *subdrv;
+   int ret;
+
+   list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
+   if (subdrv->open) {
+   ret = subdrv->open(dev, subdrv->manager.dev, file);
+   if (ret)
+   goto err;
+   }
+   }
+
+   return 0;
+
+err:
+   list_for_each_entry_reverse(subdrv, &subdrv->list, list) {
+   if (subdrv->close)
+   subdrv->close(dev, subdrv->manager.dev, file);
+   }
+   return ret;
+}
+EXPORT_SYMBOL_GPL(exynos_drm_subdrv_open);
+
+void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file)
+{
+   struct exynos_drm_subdrv *subdrv;
+
+   list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
+   if (subdrv->close)
+   subdrv->close(dev, subdrv->manager.dev, file);
+   }
+}
+EXPORT_SYMBOL_GPL(exynos_drm_subdrv_close);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c 
b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index a2f8fae..b4e265f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -144,6 +144,13 @@ static int exynos_drm_unload(struct drm_device *dev)
return 0;
 }
 
+static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
+{
+   DRM_DEBUG_DRIVER("%s\n", __FILE__);
+
+   return exynos_drm_subdrv_open(dev, file);
+}
+
 static void exynos_drm_preclose(struct drm_device *dev,
struct drm_file *file)
 {
@@ -163,6 +170,8 @@ static void exynos_drm_preclose(struct drm_device *dev,
}
}
spin_unlock_irqrestore(&dev->event_lock, flags);
+
+   exynos_drm_subdrv_close(dev, file);
 }
 
 static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
@@ -216,6 +225,7 @@ static struct drm_driver exynos_drm_driver = {
  DRIVER_MODESET | DRIVER_GEM,
.load   = exynos_drm_load,
.unload = exynos_drm_unload,
+   .open   = exynos_drm_open,
.preclose   = exynos_drm_preclose,
.lastclose  = exynos_drm_lastclose,
.postclose  = exynos_drm_postclose,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h 
b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index f8bac0e..a412454 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -229,6 +229,8 @@ struct exynos_drm_private {
  * subdrv is registered to it.
  * @remove: this callback is used to release resources created
  * by probe callback.
+ * @open: this would be called with drm device file open.
+ * @close: this would be called with drm device file close.
  * @manager: subdrv has its own manager to control a hardware appropriately
  * and we can access a hardware drawing on this manager.
  * @encoder: encoder object owned by this sub driver.
@@ -240,6 +242,10 @@ struct exynos_drm_subdrv {
 
int (*probe)(struct drm_device *drm_dev, struct device *dev);
void (*remove)(struct drm_device *dev);
+   int (*open)(struct drm_device *drm_dev, struct device *dev,
+   struct drm_file *file);
+   void (*close)(struct drm_device *drm_dev, struct device *dev,
+   struct drm_file *file);
 
struct exynos_drm_manager manager;
struct drm_encoder *encoder;
@@ -269,6 +275,9 @@ int exynos_drm_subdrv_register(struct exynos_drm_subdrv 
*drm_subdrv);
 /* this function removes subdrv list from exynos drm driver */
 int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv *drm_subdrv);
 
+int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file);
+void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file);
+
 extern struct platform_driver fimd_driver;
 extern struct platform_driver hdmi_driver;
 extern struct platform_driver mixer_driver;
-- 
1.7.4.1

_

[PATCH 08/10] drm/exynos: add is_local member in exynos_drm_subdrv struct

2012-03-13 Thread Inki Dae
From: Joonyoung Shim 

The is_local member indicates unused subdrv such connector and encoder
so doesn't make resources for them.

Signed-off-by: Joonyoung Shim 
Signed-off-by: Inki Dae 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_drm_core.c |3 +++
 drivers/gpu/drm/exynos/exynos_drm_drv.h  |2 ++
 2 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c 
b/drivers/gpu/drm/exynos/exynos_drm_core.c
index 4e29c71..411832e 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_core.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_core.c
@@ -59,6 +59,9 @@ static int exynos_drm_subdrv_probe(struct drm_device *dev,
return ret;
}
 
+   if (subdrv->is_local)
+   return 0;
+
/* create and initialize a encoder for this sub driver. */
encoder = exynos_drm_encoder_create(dev, &subdrv->manager,
(1 << MAX_CRTC) - 1);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h 
b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index a412454..b26c2f4 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -225,6 +225,7 @@ struct exynos_drm_private {
  * @list: sub driver has its own list object to register to exynos drm driver.
  * @drm_dev: pointer to drm_device and this pointer would be set
  * when sub driver calls exynos_drm_subdrv_register().
+ * @is_local: appear encoder and connector disrelated device.
  * @probe: this callback would be called by exynos drm driver after
  * subdrv is registered to it.
  * @remove: this callback is used to release resources created
@@ -239,6 +240,7 @@ struct exynos_drm_private {
 struct exynos_drm_subdrv {
struct list_head list;
struct drm_device *drm_dev;
+   bool is_local;
 
int (*probe)(struct drm_device *drm_dev, struct device *dev);
void (*remove)(struct drm_device *dev);
-- 
1.7.4.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 06/10] drm/exynos: remove module of exynos drm subdrv

2012-03-13 Thread Inki Dae
From: Joonyoung Shim 

The exynos drm driver has several subdrv. They each can be module but it
causes unfixed probe order of exynodr drm driver and each subdrv. It
also needs some weird codes such as exynos_drm_fbdev_reinit and
exynos_drm_mode_group_reinit. This patch can remove weird codes and
clear codes through we doesn't modularity each subdrv.

Also this removes unnecessary codes related module.

Signed-off-by: Joonyoung Shim 
Signed-off-by: Inki Dae 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/Kconfig|8 +--
 drivers/gpu/drm/exynos/Makefile   |   10 ++-
 drivers/gpu/drm/exynos/exynos_ddc.c   |1 -
 drivers/gpu/drm/exynos/exynos_drm_buf.c   |4 -
 drivers/gpu/drm/exynos/exynos_drm_connector.c |6 --
 drivers/gpu/drm/exynos/exynos_drm_core.c  |  112 ++---
 drivers/gpu/drm/exynos/exynos_drm_crtc.c  |6 --
 drivers/gpu/drm/exynos/exynos_drm_drv.c   |   52 +++-
 drivers/gpu/drm/exynos/exynos_drm_drv.h   |   12 ++--
 drivers/gpu/drm/exynos/exynos_drm_encoder.c   |6 --
 drivers/gpu/drm/exynos/exynos_drm_fb.c|6 --
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c |   86 ---
 drivers/gpu/drm/exynos/exynos_drm_fimd.c  |   20 +
 drivers/gpu/drm/exynos/exynos_drm_gem.c   |4 -
 drivers/gpu/drm/exynos/exynos_drm_hdmi.c  |   87 +--
 drivers/gpu/drm/exynos/exynos_hdmi.c  |9 --
 drivers/gpu/drm/exynos/exynos_mixer.c |7 --
 17 files changed, 77 insertions(+), 359 deletions(-)

diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index b9e5266..9a9850a 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -1,7 +1,6 @@
 config DRM_EXYNOS
tristate "DRM Support for Samsung SoC EXYNOS Series"
depends on DRM && PLAT_SAMSUNG
-   default n
select DRM_KMS_HELPER
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
@@ -12,16 +11,13 @@ config DRM_EXYNOS
  If M is selected the module will be called exynosdrm.
 
 config DRM_EXYNOS_FIMD
-   tristate "Exynos DRM FIMD"
+   bool "Exynos DRM FIMD"
depends on DRM_EXYNOS && !FB_S3C
-   default n
help
  Choose this option if you want to use Exynos FIMD for DRM.
- If M is selected, the module will be called exynos_drm_fimd
 
 config DRM_EXYNOS_HDMI
-   tristate "Exynos DRM HDMI"
+   bool "Exynos DRM HDMI"
depends on DRM_EXYNOS && !VIDEO_SAMSUNG_S5P_TV
help
  Choose this option if you want to use Exynos HDMI for DRM.
- If M is selected, the module will be called exynos_drm_hdmi
diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
index 395e69c..5331fa3 100644
--- a/drivers/gpu/drm/exynos/Makefile
+++ b/drivers/gpu/drm/exynos/Makefile
@@ -8,7 +8,9 @@ exynosdrm-y := exynos_drm_drv.o exynos_drm_encoder.o 
exynos_drm_connector.o \
exynos_drm_buf.o exynos_drm_gem.o exynos_drm_core.o \
exynos_drm_plane.o
 
-obj-$(CONFIG_DRM_EXYNOS) += exynosdrm.o
-obj-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o
-obj-$(CONFIG_DRM_EXYNOS_HDMI) += exynos_hdmi.o exynos_mixer.o exynos_ddc.o \
-exynos_hdmiphy.o exynos_drm_hdmi.o
+exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD)+= exynos_drm_fimd.o
+exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI)+= exynos_hdmi.o exynos_mixer.o \
+  exynos_ddc.o exynos_hdmiphy.o \
+  exynos_drm_hdmi.o
+
+obj-$(CONFIG_DRM_EXYNOS)   += exynosdrm.o
diff --git a/drivers/gpu/drm/exynos/exynos_ddc.c 
b/drivers/gpu/drm/exynos/exynos_ddc.c
index 84b614f..7e1051d 100644
--- a/drivers/gpu/drm/exynos/exynos_ddc.c
+++ b/drivers/gpu/drm/exynos/exynos_ddc.c
@@ -55,4 +55,3 @@ struct i2c_driver ddc_driver = {
.remove = __devexit_p(s5p_ddc_remove),
.command= NULL,
 };
-EXPORT_SYMBOL(ddc_driver);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c 
b/drivers/gpu/drm/exynos/exynos_drm_buf.c
index 554f674..0fb5ceb 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_buf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c
@@ -211,7 +211,3 @@ void exynos_drm_buf_destroy(struct drm_device *dev,
kfree(buffer);
buffer = NULL;
 }
-
-MODULE_AUTHOR("Inki Dae ");
-MODULE_DESCRIPTION("Samsung SoC DRM Buffer Management Module");
-MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c 
b/drivers/gpu/drm/exynos/exynos_drm_connector.c
index 303af60..33893a9 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_connector.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c
@@ -348,9 +348,3 @@ err_connector:
kfree(exynos_connector);
return NULL;
 }
-
-MODULE_AUTHOR("Inki Dae ");
-MODULE_AUTHOR("Joonyoung Shim ");
-MODULE_AUTHOR("Seung-Woo Kim ");
-MODULE_DESCRIPTION("Samsung SoC DRM Connector Driv

[PATCH 04/10] drm/exynos: added new funtion to get/put dma address.

2012-03-13 Thread Inki Dae
this function would be used for drm based 2d acceleration driver
to get/put dma address through gem handle.
when exynos_drm_get_dma_address is called reference count of
gem object would be increased not to be released by gem close and
when exynos_drm_put_dma_address is called the reference count of
this gem object would be decreased to be released.

Signed-off-by: Inki Dae 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c |   58 +++
 drivers/gpu/drm/exynos/exynos_drm_gem.h |   18 +
 2 files changed, 76 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 36d081d..ddcb7e3 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -377,6 +377,64 @@ int exynos_drm_gem_create_ioctl(struct drm_device *dev, 
void *data,
return 0;
 }
 
+void *exynos_drm_gem_get_dma_addr(struct drm_device *dev,
+   unsigned int gem_handle,
+   struct drm_file *file_priv)
+{
+   struct exynos_drm_gem_obj *exynos_gem_obj;
+   struct drm_gem_object *obj;
+
+   obj = drm_gem_object_lookup(dev, file_priv, gem_handle);
+   if (!obj) {
+   DRM_ERROR("failed to lookup gem object.\n");
+   return ERR_PTR(-EINVAL);
+   }
+
+   exynos_gem_obj = to_exynos_gem_obj(obj);
+
+   if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) {
+   DRM_DEBUG_KMS("not support NONCONTIG type.\n");
+   drm_gem_object_unreference_unlocked(obj);
+
+   /* TODO */
+   return ERR_PTR(-EINVAL);
+   }
+
+   return &exynos_gem_obj->buffer->dma_addr;
+}
+
+void exynos_drm_gem_put_dma_addr(struct drm_device *dev,
+   unsigned int gem_handle,
+   struct drm_file *file_priv)
+{
+   struct exynos_drm_gem_obj *exynos_gem_obj;
+   struct drm_gem_object *obj;
+
+   obj = drm_gem_object_lookup(dev, file_priv, gem_handle);
+   if (!obj) {
+   DRM_ERROR("failed to lookup gem object.\n");
+   return;
+   }
+
+   exynos_gem_obj = to_exynos_gem_obj(obj);
+
+   if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) {
+   DRM_DEBUG_KMS("not support NONCONTIG type.\n");
+   drm_gem_object_unreference_unlocked(obj);
+
+   /* TODO */
+   return;
+   }
+
+   drm_gem_object_unreference_unlocked(obj);
+
+   /*
+* decrease obj->refcount one more time because we has already
+* increased it at exynos_drm_gem_get_dma_addr().
+*/
+   drm_gem_object_unreference_unlocked(obj);
+}
+
 int exynos_drm_gem_map_offset_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
 {
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h 
b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index 096267d..e40fbad 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -88,6 +88,24 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct 
drm_device *dev,
 int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
 
+/*
+ * get dma address from gem handle and this function could be used for
+ * other drivers such as 2d/3d acceleration drivers.
+ * with this function call, gem object reference count would be increased.
+ */
+void *exynos_drm_gem_get_dma_addr(struct drm_device *dev,
+   unsigned int gem_handle,
+   struct drm_file *file_priv);
+
+/*
+ * put dma address from gem handle and this function could be used for
+ * other drivers such as 2d/3d acceleration drivers.
+ * with this function call, gem object reference count would be decreased.
+ */
+void exynos_drm_gem_put_dma_addr(struct drm_device *dev,
+   unsigned int gem_handle,
+   struct drm_file *file_priv);
+
 /* get buffer offset to map to user space. */
 int exynos_drm_gem_map_offset_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-- 
1.7.4.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 05/10] drm/exynos: release pending pageflip events when closed

2012-03-13 Thread Inki Dae
From: Joonyoung Shim 

We should release pending pageflip events when closed. If not, they will
be dangling events.

Signed-off-by: Joonyoung Shim 
Signed-off-by: Inki Dae 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_drm_drv.c |   14 ++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c 
b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 09cc13f..aaa1b40 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -147,8 +147,22 @@ static int exynos_drm_unload(struct drm_device *dev)
 static void exynos_drm_preclose(struct drm_device *dev,
struct drm_file *file)
 {
+   struct exynos_drm_private *private = dev->dev_private;
+   struct drm_pending_vblank_event *e, *t;
+   unsigned long flags;
+
DRM_DEBUG_DRIVER("%s\n", __FILE__);
 
+   /* release events of current file */
+   spin_lock_irqsave(&dev->event_lock, flags);
+   list_for_each_entry_safe(e, t, &private->pageflip_event_list,
+   base.link) {
+   if (e->base.file_priv == file) {
+   list_del(&e->base.link);
+   e->base.destroy(&e->base);
+   }
+   }
+   spin_unlock_irqrestore(&dev->event_lock, flags);
 }
 
 static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
-- 
1.7.4.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 03/10] drm/exynos: added buffer allocation type.

2012-03-13 Thread Inki Dae
with this patch, we can allocate physically continuous or non-continuous
memory and also it creates scatterlist for iommu support so allocated
memory region can be mapped to iommu page table using scatterlist.

Signed-off-by: Inki Dae 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_drm_buf.c   |  148 +--
 drivers/gpu/drm/exynos/exynos_drm_buf.h   |4 +-
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c |4 +-
 drivers/gpu/drm/exynos/exynos_drm_gem.c   |  284 ++---
 drivers/gpu/drm/exynos/exynos_drm_gem.h   |   11 +-
 include/drm/exynos_drm.h  |6 +
 6 files changed, 407 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c 
b/drivers/gpu/drm/exynos/exynos_drm_buf.c
index 3cf785c..554f674 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_buf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c
@@ -25,45 +25,151 @@
 
 #include "drmP.h"
 #include "drm.h"
+#include "exynos_drm.h"
 
 #include "exynos_drm_drv.h"
 #include "exynos_drm_gem.h"
 #include "exynos_drm_buf.h"
 
 static int lowlevel_buffer_allocate(struct drm_device *dev,
-   struct exynos_drm_gem_buf *buffer)
+   unsigned int flags, struct exynos_drm_gem_buf *buf)
 {
+   int ret = 0;
+
DRM_DEBUG_KMS("%s\n", __FILE__);
 
-   buffer->kvaddr = dma_alloc_writecombine(dev->dev, buffer->size,
-   &buffer->dma_addr, GFP_KERNEL);
-   if (!buffer->kvaddr) {
-   DRM_ERROR("failed to allocate buffer.\n");
-   return -ENOMEM;
+   /*
+* allocate only physically continuous memory and
+* non-continuous memory would be allocated by exynos
+* gem framework.
+*/
+   if (!(flags & EXYNOS_BO_NONCONTIG)) {
+   dma_addr_t start_addr, end_addr;
+   unsigned int npages, page_size, i = 0;
+   struct scatterlist *sgl;
+
+   if (buf->dma_addr) {
+   DRM_DEBUG_KMS("already allocated.\n");
+   return -EINVAL;
+   }
+
+   /*
+* according to desired size, it sets page size
+* for performance with using iommu so physically
+* continuous memory could be mapped to iommu in
+* multiple page size.
+*/
+   if (buf->size >= SZ_1M) {
+   npages = (buf->size >> SECTION_SHIFT) + 1;
+   page_size = SECTION_SIZE;
+   } else if (buf->size >= SZ_64K) {
+   npages = (buf->size >> 16) + 1;
+   page_size = SZ_64K;
+   } else {
+   npages = (buf->size >> PAGE_SHIFT) + 1;
+   page_size = PAGE_SIZE;
+   }
+
+   buf->sgt = kzalloc(sizeof(struct sg_table), GFP_KERNEL);
+   if (!buf->sgt) {
+   DRM_ERROR("failed to allocate sg table.\n");
+   return -ENOMEM;
+   }
+
+   ret = sg_alloc_table(buf->sgt, npages, GFP_KERNEL);
+   if (ret < 0) {
+   DRM_ERROR("failed to initialize sg table.\n");
+   kfree(buf->sgt);
+   buf->sgt = NULL;
+   return -ENOMEM;
+   }
+
+   buf->kvaddr = dma_alloc_writecombine(dev->dev, buf->size,
+   &buf->dma_addr, GFP_KERNEL);
+   if (!buf->kvaddr) {
+   DRM_ERROR("failed to allocate buffer.\n");
+   ret = -ENOMEM;
+   goto err1;
+   }
+
+   start_addr = buf->dma_addr;
+   end_addr = buf->dma_addr + buf->size;
+
+   buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL);
+   if (!buf->pages) {
+   DRM_ERROR("failed to allocate pages.\n");
+   ret = -ENOMEM;
+   goto err2;
+   }
+
+   sgl = buf->sgt->sgl;
+
+   while (i < npages) {
+   buf->pages[i] = phys_to_page(start_addr);
+   sg_set_page(sgl, buf->pages[i], page_size, 0);
+   sg_dma_address(sgl) = start_addr;
+   start_addr += page_size;
+   if (end_addr - start_addr < page_size)
+   break;
+   sgl = sg_next(sgl);
+   i++;
+   }
+
+   buf->pages[i] = phys_to_page(start_addr);
+
+   sgl = sg_next(sgl);
+   sg_set_page(sgl, buf->pages[i+1], end_addr - start_addr, 0);
}
 
DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n",
-   (unsigned long)buffer->kvaddr,
-   (unsigned long)buffer->dma_addr,
-   buffe

[PATCH 02/10] drm/exynos: added mode_fixup feature and code clean.

2012-03-13 Thread Inki Dae
this patch adds mode_fixup feature for hdmi module that
specific driver changes current mode to driver desired mode
properly.

Signed-off-by: Inki Dae 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_drm_connector.c |   25 +++-
 drivers/gpu/drm/exynos/exynos_drm_crtc.c  |6 ++-
 drivers/gpu/drm/exynos/exynos_drm_drv.h   |8 +++
 drivers/gpu/drm/exynos/exynos_drm_encoder.c   |   17 -
 drivers/gpu/drm/exynos/exynos_drm_hdmi.c  |   28 +
 drivers/gpu/drm/exynos/exynos_drm_hdmi.h  |5 ++
 drivers/gpu/drm/exynos/exynos_hdmi.c  |   81 ++--
 7 files changed, 157 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c 
b/drivers/gpu/drm/exynos/exynos_drm_connector.c
index 99d5527..303af60 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_connector.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c
@@ -225,6 +225,29 @@ static struct drm_connector_helper_funcs 
exynos_connector_helper_funcs = {
.best_encoder   = exynos_drm_best_encoder,
 };
 
+static int exynos_drm_connector_fill_modes(struct drm_connector *connector,
+   unsigned int max_width, unsigned int max_height)
+{
+   struct exynos_drm_connector *exynos_connector =
+   to_exynos_connector(connector);
+   struct exynos_drm_manager *manager = exynos_connector->manager;
+   struct exynos_drm_manager_ops *ops = manager->ops;
+   unsigned int width, height;
+
+   width = max_width;
+   height = max_height;
+
+   /*
+* if specific driver want to find desired_mode using maxmum
+* resolution then get max width and height from that driver.
+*/
+   if (ops && ops->get_max_resol)
+   ops->get_max_resol(manager->dev, &width, &height);
+
+   return drm_helper_probe_single_connector_modes(connector, width,
+   height);
+}
+
 /* get detection status of display device. */
 static enum drm_connector_status
 exynos_drm_connector_detect(struct drm_connector *connector, bool force)
@@ -262,7 +285,7 @@ static void exynos_drm_connector_destroy(struct 
drm_connector *connector)
 
 static struct drm_connector_funcs exynos_connector_funcs = {
.dpms   = drm_helper_connector_dpms,
-   .fill_modes = drm_helper_probe_single_connector_modes,
+   .fill_modes = exynos_drm_connector_fill_modes,
.detect = exynos_drm_connector_detect,
.destroy= exynos_drm_connector_destroy,
 };
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c 
b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index de81883..2d9a0e6 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -249,7 +249,11 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct 
drm_display_mode *mode,
 {
DRM_DEBUG_KMS("%s\n", __FILE__);
 
-   mode = adjusted_mode;
+   /*
+* copy the mode data adjusted by mode_fixup() into crtc->mode
+* so that hardware can be seet to proper mode.
+*/
+   memcpy(&crtc->mode, adjusted_mode, sizeof(*adjusted_mode));
 
return exynos_drm_crtc_update(crtc);
 }
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h 
b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 13540de..4115a9f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -155,8 +155,10 @@ struct exynos_drm_display_ops {
  *
  * @dpms: control device power.
  * @apply: set timing, vblank and overlay data to registers.
+ * @mode_fixup: fix mode data comparing to hw specific display mode.
  * @mode_set: convert drm_display_mode to hw specific display mode and
  *   would be called by encoder->mode_set().
+ * @get_max_resol: get maximum resolution to specific hardware.
  * @commit: set current hw specific display mode to hw.
  * @enable_vblank: specific driver callback for enabling vblank interrupt.
  * @disable_vblank: specific driver callback for disabling vblank interrupt.
@@ -164,7 +166,13 @@ struct exynos_drm_display_ops {
 struct exynos_drm_manager_ops {
void (*dpms)(struct device *subdrv_dev, int mode);
void (*apply)(struct device *subdrv_dev);
+   void (*mode_fixup)(struct device *subdrv_dev,
+   struct drm_connector *connector,
+   struct drm_display_mode *mode,
+   struct drm_display_mode *adjusted_mode);
void (*mode_set)(struct device *subdrv_dev, void *mode);
+   void (*get_max_resol)(struct device *subdrv_dev, unsigned int *width,
+   unsigned int *height);
void (*commit)(struct device *subdrv_dev);
int (*enable_vblank)(struct device *subdrv_dev);
void (*disable_vblank)(struct device *subdrv_dev);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c 
b/dri

[PATCH 00/10] updated exynos-drm-next

2012-03-13 Thread Inki Dae
Hi, Dave and all.

this patch set includes the following features.
- add HDMI version 1.4 support.
- add mode_fixup feature.
  . hdmi module would change current mode to driver desired mode properly.
- add buffer alloction type.
  . we can allocate physically continuous or non-continuous
memory and also it creates scatterlist for iommu support so allocated
memory region can be mapped to iommu page table using scatterlist.
- add dma address get/put interface.
  . this function would be used for drm based 2d acceleration driver
to get/put dma address through gem handle.
when exynos_drm_get_dma_address is called reference count of
gem object would be increased not to be released by gem close and
when exynos_drm_put_dma_address is called the reference count of
this gem object would be decreased to be released.
- add virtual display driver.
  . this driver would be used for wireless display.
- add direct rendering based 2d graphics acceleration module.
  . exynos SoC chip has fimg2d named 2d graphics accelerator and this driver
supports only exynos4x12 series.


this patch set is based on git repository below:
git://git.infradead.org/users/kmpark/linux-samsung exynos-drm-fixes
commit-id: f6d69d1e77509d71c29f2a7b119214b8fdf86ae2

and exynos-drm-fixes is based on git repository below:
git://people.freedesktop.org/~airlied/linux.git drm-fixes
commit-id: 38aa4a568ba4c3ccba83e862a01e3e60e3b811ee

P.S.
drm-next doesn't reflect updated latest codes of mainline so this patch set
should be merged to drm-next after latest mainline codes are merged to
drm-next. now is just for review and if latest codes are merged to drm-next
then I will merge this patch set to exynos-drm-next for git pull request.

Thanks.

Inki Dae (5):
  drm/exynos: add HDMI version 1.4 support
  drm/exynos: added mode_fixup feature and code clean.
  drm/exynos: added buffer allocation type.
  drm/exynos: added new funtion to get/put dma address.
  drm/exynos: added virtual display driver.

Joonyoung Shim (5):
  drm/exynos: release pending pageflip events when closed
  drm/exynos: remove module of exynos drm subdrv
  drm/exynos: add subdrv open/close functions
  drm/exynos: add is_local member in exynos_drm_subdrv struct
  drm/exynos: add G2D driver

 drivers/gpu/drm/exynos/Kconfig|   20 +-
 drivers/gpu/drm/exynos/Makefile   |   12 +-
 drivers/gpu/drm/exynos/exynos_ddc.c   |1 -
 drivers/gpu/drm/exynos/exynos_drm_buf.c   |  152 +++-
 drivers/gpu/drm/exynos/exynos_drm_buf.h   |4 +-
 drivers/gpu/drm/exynos/exynos_drm_connector.c |   35 +-
 drivers/gpu/drm/exynos/exynos_drm_core.c  |  140 +--
 drivers/gpu/drm/exynos/exynos_drm_crtc.c  |   12 +-
 drivers/gpu/drm/exynos/exynos_drm_drv.c   |  125 +++-
 drivers/gpu/drm/exynos/exynos_drm_drv.h   |   49 +-
 drivers/gpu/drm/exynos/exynos_drm_encoder.c   |   24 +-
 drivers/gpu/drm/exynos/exynos_drm_fb.c|6 -
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c |   90 +--
 drivers/gpu/drm/exynos/exynos_drm_fimd.c  |   20 +-
 drivers/gpu/drm/exynos/exynos_drm_g2d.c   |  864 +
 drivers/gpu/drm/exynos/exynos_drm_g2d.h   |   36 +
 drivers/gpu/drm/exynos/exynos_drm_gem.c   |  346 +++-
 drivers/gpu/drm/exynos/exynos_drm_gem.h   |   29 +-
 drivers/gpu/drm/exynos/exynos_drm_hdmi.c  |  115 +--
 drivers/gpu/drm/exynos/exynos_drm_hdmi.h  |5 +
 drivers/gpu/drm/exynos/exynos_drm_vidi.c  |  677 ++
 drivers/gpu/drm/exynos/exynos_drm_vidi.h  |   36 +
 drivers/gpu/drm/exynos/exynos_hdmi.c  | 1234 ++---
 drivers/gpu/drm/exynos/exynos_hdmi.h  |   10 +-
 drivers/gpu/drm/exynos/exynos_mixer.c |7 -
 drivers/gpu/drm/exynos/regs-hdmi.h|  306 ++-
 include/drm/exynos_drm.h  |   84 ++
 27 files changed, 3879 insertions(+), 560 deletions(-)
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_g2d.c
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_g2d.h
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_vidi.c
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_vidi.h

-- 
1.7.4.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/i915: no-lvds quirk on MSI DC500

2012-03-13 Thread Anisse Astier
Any opinion on this quirk ?

On Wed,  7 Mar 2012 18:36:35 +0100, Anisse Astier  wrote :

> This hardware doesn't have an LVDS, it's a desktop box. Fix incorrect
> LVDS detection.
> 
> Cc: sta...@kernel.org
> Signed-off-by: Anisse Astier 
> ---
>  drivers/gpu/drm/i915/intel_lvds.c |8 
>  1 files changed, 8 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_lvds.c 
> b/drivers/gpu/drm/i915/intel_lvds.c
> index b103c3b..2dee11e 100644
> --- a/drivers/gpu/drm/i915/intel_lvds.c
> +++ b/drivers/gpu/drm/i915/intel_lvds.c
> @@ -739,6 +739,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
>   DMI_MATCH(DMI_BOARD_NAME, "AT5NM10T-I"),
>   },
>   },
> + {
> + .callback = intel_no_lvds_dmi_callback,
> + .ident = "MSI Wind Box DC500",
> + .matches = {
> + DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL 
> CO., LTD"),
> + DMI_MATCH(DMI_BOARD_NAME, "MS-7469"),
> + },
> + },
>  
>   { } /* terminating entry */
>  };
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 42920] Radeon with KMS and UMA works only up to 128MB

2012-03-13 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=42920





--- Comment #3 from Alex Deucher   2012-03-13 14:13:34 
---
radeontool is for older chips.  The register is at a different location on
them.  Note I said radeonreg rather than radeontool, but either will work as
long as you specify the proper offset (0x5428).

-- 
Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are watching the assignee of the bug.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 42920] Radeon with KMS and UMA works only up to 128MB

2012-03-13 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=42920





--- Comment #2 from j.fi...@gmail.com  2012-03-13 13:55:08 ---
for 128MB it shows this:

./radeontool regmatch 0x5428
0x5428  0x0800 (134217728)

but

./radeontool regs | grep MEMSIZE
RADEON_CONFIG_MEMSIZE   


is this it? I'll add values for 256MB later.

-- 
Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are watching the assignee of the bug.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 42920] Radeon with KMS and UMA works only up to 128MB

2012-03-13 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=42920


Alex Deucher  changed:

   What|Removed |Added

 CC||alexdeuc...@gmail.com




--- Comment #1 from Alex Deucher   2012-03-13 13:34:13 
---
Looks like the bios sets up the vram size wrong for values > 128 MB.  Can you
print the value of the CONFIG_MEMSIZE register (0x5428) when you select various
vram sizes over 128 MB?  You can either use radeonreg
(http://cgit.freedesktop.org/~airlied/radeontool/):

radeonreg regmatch 0x5428

or the following patch:

diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 426cc65..6f02970 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -1204,6 +1204,7 @@ int r600_mc_init(struct radeon_device *rdev)
/* Setup GPU memory space */
rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
+   DRM_INFO("CONFIG_MEMSIZE: 0x%08x\n", RREG32(CONFIG_MEMSIZE));
rdev->mc.visible_vram_size = rdev->mc.aper_size;
r600_vram_gtt_location(rdev, &rdev->mc);

-- 
Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are watching the assignee of the bug.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 00/15] drm: Bounds checking, error handling, etc.

2012-03-13 Thread Alex Deucher
On Tue, Mar 13, 2012 at 6:35 AM,   wrote:
> Mostly fixes for various bits and pieces that caught my eye while
> reading the mode setting code.

For the series:

Reviewed-by: Alex Deucher 
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 42920] New: Radeon with KMS and UMA works only up to 128MB

2012-03-13 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=42920

   Summary: Radeon with KMS and UMA works only up to 128MB
   Product: Drivers
   Version: 2.5
Kernel Version: 3.3-rc7
  Platform: All
OS/Version: Linux
  Tree: Mainline
Status: NEW
  Severity: normal
  Priority: P1
 Component: Video(DRI - non Intel)
AssignedTo: drivers_video-...@kernel-bugs.osdl.org
ReportedBy: j.fi...@gmail.com
Regression: No


Hardware: Asus M4A88TD-M EVO with integrated Radeon HD 4250 (RS780)

Description: in bios I can choose UMA from 32MB up to 1024MB, but only values
up to 128MB work. Higher values lock the console in text mode before switching
to KMS. It also happens on older kernels with KMS (2.6.27), but the console is
not locked, the radeon module oopses and resolution stays VGA.

There is also option to locate UMA "above 4G" or "below 4G" in bios, it doesn't
matter. Also it has 128MB of sideport memory, this option doesn't matter
neither. (I have it off for now).

vramlimit parameter doesn't matter either.

System is x86_64, 16GB ECC DDR3 RAM.

lspci: 01:05.0 VGA compatible controller: Advanced Micro Devices [AMD] nee ATI
RS880 [Radeon HD 4250] (prog-if 00 [VGA controller])
Subsystem: ASUSTeK Computer Inc. M5A88-V EVO
Flags: bus master, fast devsel, latency 0, IRQ 18
Memory at f000 (32-bit, prefetchable) [size=128M]
I/O ports at d000 [size=256]
Memory at febe (32-bit, non-prefetchable) [size=64K]
Memory at fea0 (32-bit, non-prefetchable) [size=1M]
Expansion ROM at  [disabled]
Capabilities: [50] Power Management version 3
Capabilities: [a0] MSI: Enable- Count=1/1 Maskable- 64bit+
Kernel driver in use: radeon
Kernel modules: radeon

dmesg | grep -i -E "drm|radeon" on UMA=128MB; working:

[0.00] Kernel command line: root=/dev/md1
md=1,/dev/sda3,/dev/sdb3,/dev/sdc3,/dev/sdd3
rootflags=logbsize=256k,inode64,logbufs=8 mce=bootlog usbcore.autosuspend=1
radeon.benchmark=1 radeon.test=0 radeon.hw_i2c=0 zcache lockd.nlm_udpport=4001
lockd.nlm_tcpport=4001
[5.544881] [drm] Initialized drm 1.1.0 20060810
[5.644935] [drm] radeon defaulting to kernel modesetting.
[5.644937] [drm] radeon kernel modesetting enabled.
[5.644989] radeon :01:05.0: setting latency timer to 64
[5.645114] [drm] initializing kernel modesetting (RS880 0x1002:0x9715
0x1043:0x843E).
[5.645130] [drm] register mmio base: 0xFEBE
[5.645131] [drm] register mmio size: 65536
[5.645707] radeon :01:05.0: VRAM: 128M 0xC000 -
0xC7FF (128M used)
[5.645709] radeon :01:05.0: GTT: 512M 0xA000 -
0xBFFF
[5.649847] [drm] Detected VRAM RAM=128M, BAR=128M
[5.649850] [drm] RAM width 32bits DDR
[5.649943] [drm] radeon: 128M of VRAM memory ready
[5.649945] [drm] radeon: 512M of GTT memory ready.
[5.649958] [drm] Supports vblank timestamp caching Rev 1 (10.10.2010).
[5.649959] [drm] Driver supports precise vblank timestamp query.
[5.649976] [drm] radeon: irq initialized.
[5.649979] [drm] GART: num cpu pages 131072, num gpu pages 131072
[5.650514] [drm] radeon: ib pool ready.
[5.650588] [drm] Loading RS780 Microcode
[5.812474] [drm] PCIE GART of 512M enabled (table at 0xC004).
[5.812535] radeon :01:05.0: WB enabled
[5.812537] [drm] fence driver on ring 0 use gpu addr 0xac00 and cpu
addr 0x88040037ec00
[5.844636] [drm] ring test on 0 succeeded in 1 usecs
[5.844706] [drm] ib test on ring 0 succeeded in 0 usecs
[6.150041] [drm] radeon: blit 1024 bo moves of 1024 kB from 2 to 4 in 306
ms, throughput: 27408 Mb/s or 3426 MB/s
[6.455242] [drm] radeon: blit 1024 bo moves of 1024 kB from 4 to 2 in 305
ms, throughput: 27496 Mb/s or 3437 MB/s
[6.455574] [drm] Radeon Display Connectors
[6.455576] [drm] Connector 0:
[6.455577] [drm]   VGA
[6.455578] [drm]   DDC: 0x7e40 0x7e40 0x7e44 0x7e44 0x7e48 0x7e48 0x7e4c
0x7e4c
[6.455579] [drm]   Encoders:
[6.455580] [drm] CRT1: INTERNAL_KLDSCP_DAC1
[6.455581] [drm] Connector 1:
[6.455582] [drm]   HDMI-A
[6.455583] [drm]   HPD3
[6.455584] [drm]   DDC: 0x7e50 0x7e50 0x7e54 0x7e54 0x7e58 0x7e58 0x7e5c
0x7e5c
[6.455585] [drm]   Encoders:
[6.455586] [drm] DFP3: INTERNAL_KLDSCP_LVTMA
[6.455604] [drm] radeon: power management initialized
[6.528664] [drm] fb mappable at 0xF0142000
[6.528666] [drm] vram apper at 0xF000
[6.528667] [drm] size 3932160
[6.528668] [drm] fb depth is 24
[6.528669] [drm]pitch is 5120
[6.528727] fbcon: radeondrmfb (fb0) is primary device
[6.551936] fb0: radeondrmfb frame buffer device
[6.551937] drm: registered panic notifier
[6.551941] [drm] Initialized radeon 2.13.0 20080528 for :01:05.0 on
minor 0

dmesg | grep -i -E "drm|radeon" on UM

Re: Re: [korg]help: How to submit a kernel driver on kernel.org.

2012-03-13 Thread Aaron . Chen 陈俊杰
Hi Ilija,

Thank you for your reply. We will check the coding style next time.

I don't know about the license thing. Is there any different license for 
choosing?

Regards
Aaron

-邮件原件-
发件人: Ilija Hadzic [mailto:ihad...@research.bell-labs.com] 
发送时间: 2012年3月10日 0:30
收件人: Aaron.Chen 陈俊杰
抄送: Paul Menzel; Alex Deucher; dri-devel@lists.freedesktop.org; caesar.qiu 裘赛海
主题: Re: 答复: [korg]help: How to submit a kernel driver on kernel.org.


A couple of non-technical things. First, I think you are sending the patch 
to the wrong list. dri-devel is for drivers that go under drivers/gpu/drm. 
Your driver is apparently fbdev driver and thus belongs to 
linux-fb...@vger.kernel.org list (see the Maintainers file)

Second, your patch generates about 9000 coding style errors when you run 
through ./scripts/checkpatch.pl script available in the Linux kernel tree. 
You need to clean up. See also Documentation/CodingStyle. Also, you must 
break up the patch into smaller self-contained units that logically make 
sense. Nobody can review 17000 lines of code in one shot.

Last, but probably the most important. All your files have the proprietary 
license in the comment overhead. You (actually your company lawyers) have 
to decide which license you are releasing this dirver under and make sure 
it is compatible with Linux kernel (i.e. GPL) and you have to state that 
in each file that is being added.

-- Ilija


On Fri, 9 Mar 2012, [utf-8] Aaron.Chen  ~Y~H~J~] wrote:

> Hi Paul&Alex,
>
> Thank you very much for your great help.
>
> Here is the first patch.
>
> Regards
> Aaron
>
> -邮件原件-
> 发件人: Paul Menzel [mailto:paulepan...@users.sourceforge.net]
> 发送时间: 2012年3月6日 22:38
> 收件人: Alex Deucher
> 抄送: Aaron.Chen 陈俊杰; caesar.qiu 裘赛海; dri-devel@lists.freedesktop.org
> 主题: Re: [korg]help: How to submit a kernel driver on kernel.org.
>
> Dear Aaron,
>
>
> Am Dienstag, den 06.03.2012, 08:47 -0500 schrieb Alex Deucher:
>> On Mon, Mar 5, 2012 at 11:13 PM, Aaron.Chen  陈俊杰 wrote:
>
>>> Thank you very much for your guide. It's a great help for me.
>>>
>>> But I still have a little problem with the patch thing. I'm not familiar 
>>> with the git.
>>> 1.Shall I need to do the clone and get the source location and target 
>>> directory first?
>>> 2.Where is the source location and target directory?
>>> 3.Our driver has pass the customer's test from kernel version 2.6.5 to 
>>> 3.0.0, So what shall I do to submit a driver cover all these kernel version.
>
> you can only get new features included upstream in the latest Linux kernel. 
> So earliest version would be 3.4. You have to maintain you own repository for 
> earlier version. But backporting should be not so much trouble if you have it 
> included upstream.
>
>>> 4.or just email you the source code and tell you the changes?
>>>
>>> I'm looking forward your re-guide. Thank you so much.
>>
>> Your best bet it to clone Linus' git tree and then apply your patches:
>>
>> 1. clone Linus' git tree:
>> git clone
>> git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
>
> you can do this in between.
>
>cd linux
>git config --global user.name "陈俊杰 (Aaron Chen)"
>git config --global user.email aaron.c...@siliconmotion.com
>
>> 2.a) apply your first patch
>>b)  if you patch adds new files to the source tree, add them:
>> git add path/to/files/file.c
>> git add path/to/files/file.h
>> etc.  if the patch only modifies patches that are already
>> in the tree, you do not need to add them.
>>c) when the patch is applied commit it:
>>git commit -a -s
>>d) when you run the commit command you will be prompted to
>> enter a commit message.  The commit message has the following format:
>>
>> subsystem: patch description
>>
>> description of what the patch does.
>>
>> Signed-off-by: Your name 
>>
>> E.g.,
>>
>> fb: add initial code for video 5000 graphics
>>
>> This adds the initial support for the video 5000 graphics adapter.  It
>> supports vga and lcd connectors.
>>
>> Signed-off-by: Joe Developer 
>>
>> e) repeat steps a-d for all of your patches 3. generate patches:
>> git format-patch -n
>>
>> where n is the number of patches you committed.  E.g., if your driver
>> consists of 5 patches:
>> git format-patch -5
>>
>> 4. Send the patches to the list.
>
> Aaron, Git is nowadays documented pretty well. So just use
>
>git help command
>
> (like `git help commit`) to read the manual. Additionally you can just search 
> for it using your favorite search engine. Interesting reads should be 
> [1][2][3].
>
>
> Thanks,
>
> Paul
>
>
> [1] http://schacon.github.com/git/user-manual.html#cleaning-up-history
> [2] http://git-scm.com/documentation
> [3] http://progit.org/book/
>
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 47007] HDMI monitor polling causing 100ms rendering stalls

2012-03-13 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=47007

--- Comment #15 from Tvrtko Ursulin  2012-03-13 
04:44:04 PDT ---
Bad news from a different motherboard. This one has DVI-D and DP connectors.
With a DVI monitor connected stalls are still there due to the shared_ddc being
true (DDC shared between DVI and VGA). Connectors look like this here:

[drm] Radeon Display Connectors
[drm] Connector 0:
[drm]   DisplayPort
[drm]   HPD1
[drm]   DDC: 0x6430 0x6430 0x6434 0x6434 0x6438 0x6438 0x643c 0x643c
[drm]   Encoders:
[drm] DFP1: INTERNAL_UNIPHY
[drm] Connector 1:
[drm]   DVI-D
[drm]   HPD2
[drm]   DDC: 0x6440 0x6440 0x6444 0x6444 0x6448 0x6448 0x644c 0x644c
[drm]   Encoders:
[drm] DFP2: INTERNAL_UNIPHY
[drm] Connector 2:
[drm]   VGA
[drm]   DDC: 0x6440 0x6440 0x6444 0x6444 0x6448 0x6448 0x644c 0x644c
[drm]   Encoders:
[drm] CRT1: INTERNAL_KLDSCP_DAC1

If I remove the shared_ddc check from the patch that removes the 100ms stall in
radeon_dvi_detect. However in this configuration there is another 60ms stall
from drm_get_edid in radeon_vga_detect now.

Also, radeon_dp_getsinktype from radeon_dp_detect adds another 3ms for the
disconnected DP port.

Recap of latency contributors on this hardware:

1. radeon_dvi_detect

 * 100ms when connected from drm_get_edid

Can be fixed with the patch like the above, but with shared_ddc check criteria
removed if that is OK? That would then work for both motherboards that I tested
on. HDMI on the first one, and DVI on this one.

2. radeon_vga_detect

 * not connected
* 5ms from radeon_ddc_probe
* 60ms from drm_get_edid

Not sure how to improve this without making the code a lot smarter. It would
have to consider who is sharing DDC with who, and if another connector is
connected it would imply this one can not be and then skip the EDID fetch?

Also perhaps 5ms from radeon_ddc_probe could be saved by somehow passing the
header to drm_get_edid, if I gather correctly that the latter re-fetches the
same header radeon_ddc_probe retrieved.

3. radeon_dp_detect

 * 8ms when not connected from radeon_dp_getsinktype
 * haven't tested the connected case - that is unreliable anyway, bug 46711

Not sure if this would be passable if it remained the only latency source. It's
not ideal that's for sure. Does it need to do the radeon_dp_getsinktype call in
the absence of a HPD interrupt though? If not could we short-circuit it in some
way similar to radeon_dvi_detect? Call it after radeon_hpd_sense only if
something is connected? However looking at the code it doesn't suggest all
latency is avoidable since it doesn't seem to trust HPD sense. Same story with
OEM wiring reliability?

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 11/15] drm: Handle drm_object_get() failures

2012-03-13 Thread ville . syrjala
From: Ville Syrjälä 

Check drm_mode_object_get() return value everywhere.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_crtc.c|   95 -
 drivers/gpu/drm/drm_crtc_helper.c |2 +
 include/drm/drm_crtc.h|   22 
 3 files changed, 85 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index e36bd43..f5b098e 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -293,9 +293,8 @@ int drm_framebuffer_init(struct drm_device *dev, struct 
drm_framebuffer *fb,
int ret;
 
ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB);
-   if (ret) {
+   if (ret)
return ret;
-   }
 
fb->dev = dev;
fb->funcs = funcs;
@@ -365,19 +364,31 @@ EXPORT_SYMBOL(drm_framebuffer_cleanup);
  * Caller must hold mode config lock.
  *
  * Inits a new object created as base part of an driver crtc object.
+ *
+ * RETURNS:
+ * Zero on success, error code on failure.
  */
-void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
+int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
   const struct drm_crtc_funcs *funcs)
 {
+   int ret;
+
crtc->dev = dev;
crtc->funcs = funcs;
 
mutex_lock(&dev->mode_config.mutex);
-   drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
+
+   ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
+   if (ret)
+   goto out;
 
list_add_tail(&crtc->head, &dev->mode_config.crtc_list);
dev->mode_config.num_crtc++;
+
+ out:
mutex_unlock(&dev->mode_config.mutex);
+
+   return ret;
 }
 EXPORT_SYMBOL(drm_crtc_init);
 
@@ -453,17 +464,25 @@ EXPORT_SYMBOL(drm_mode_remove);
  *
  * Initialises a preallocated connector. Connectors should be
  * subclassed as part of driver connector objects.
+ *
+ * RETURNS:
+ * Zero on success, error code on failure.
  */
-void drm_connector_init(struct drm_device *dev,
-struct drm_connector *connector,
-const struct drm_connector_funcs *funcs,
-int connector_type)
+int drm_connector_init(struct drm_device *dev,
+  struct drm_connector *connector,
+  const struct drm_connector_funcs *funcs,
+  int connector_type)
 {
+   int ret;
+
mutex_lock(&dev->mode_config.mutex);
 
+   ret = drm_mode_object_get(dev, &connector->base, 
DRM_MODE_OBJECT_CONNECTOR);
+   if (ret)
+   goto out;
+
connector->dev = dev;
connector->funcs = funcs;
-   drm_mode_object_get(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR);
connector->connector_type = connector_type;
connector->connector_type_id =
++drm_connector_enum_list[connector_type].count; /* TODO */
@@ -483,7 +502,10 @@ void drm_connector_init(struct drm_device *dev,
drm_connector_attach_property(connector,
  dev->mode_config.dpms_property, 0);
 
+ out:
mutex_unlock(&dev->mode_config.mutex);
+
+   return ret;
 }
 EXPORT_SYMBOL(drm_connector_init);
 
@@ -518,23 +540,30 @@ void drm_connector_cleanup(struct drm_connector 
*connector)
 }
 EXPORT_SYMBOL(drm_connector_cleanup);
 
-void drm_encoder_init(struct drm_device *dev,
- struct drm_encoder *encoder,
- const struct drm_encoder_funcs *funcs,
- int encoder_type)
+int drm_encoder_init(struct drm_device *dev,
+struct drm_encoder *encoder,
+const struct drm_encoder_funcs *funcs,
+int encoder_type)
 {
+   int ret;
+
mutex_lock(&dev->mode_config.mutex);
 
+   ret = drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER);
+   if (ret)
+   goto out;
+
encoder->dev = dev;
-
-   drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER);
encoder->encoder_type = encoder_type;
encoder->funcs = funcs;
 
list_add_tail(&encoder->head, &dev->mode_config.encoder_list);
dev->mode_config.num_encoder++;
 
+ out:
mutex_unlock(&dev->mode_config.mutex);
+
+   return ret;
 }
 EXPORT_SYMBOL(drm_encoder_init);
 
@@ -555,18 +584,23 @@ int drm_plane_init(struct drm_device *dev, struct 
drm_plane *plane,
   const uint32_t *formats, uint32_t format_count,
   bool priv)
 {
+   int ret;
+
mutex_lock(&dev->mode_config.mutex);
 
+   ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
+   if (ret)
+   goto out;
+
plane->dev = dev;
-   drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
plane->funcs = funcs;
plane->format_types = kmalloc(sizeof(uint32_t) * format_count,
  GF

[PATCH 14/15] drm: Add drm_mode_copy()

2012-03-13 Thread ville . syrjala
From: Ville Syrjälä 

Add a helper function to copy a display mode. Use it in
drm_mode_duplicate() and nouveau mode_fixup hooks.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_modes.c|   28 +++-
 drivers/gpu/drm/nouveau/nv50_dac.c |7 ++-
 drivers/gpu/drm/nouveau/nv50_sor.c |7 ++-
 include/drm/drm_crtc.h |1 +
 4 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 7ff13bc..b7adb4a 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -714,6 +714,27 @@ EXPORT_SYMBOL(drm_mode_set_crtcinfo);
 
 
 /**
+ * drm_mode_copy - copy the mode
+ * @dst: mode to overwrite
+ * @src: mode to copy
+ *
+ * LOCKING:
+ * None.
+ *
+ * Copy an existing mode into another mode, preserving the object id
+ * of the destination mode.
+ */
+void drm_mode_copy(struct drm_display_mode *dst, const struct drm_display_mode 
*src)
+{
+   int id = dst->base.id;
+
+   *dst = *src;
+   dst->base.id = id;
+   INIT_LIST_HEAD(&dst->head);
+}
+EXPORT_SYMBOL(drm_mode_copy);
+
+/**
  * drm_mode_duplicate - allocate and duplicate an existing mode
  * @m: mode to duplicate
  *
@@ -727,16 +748,13 @@ struct drm_display_mode *drm_mode_duplicate(struct 
drm_device *dev,
const struct drm_display_mode *mode)
 {
struct drm_display_mode *nmode;
-   int new_id;
 
nmode = drm_mode_create(dev);
if (!nmode)
return NULL;
 
-   new_id = nmode->base.id;
-   *nmode = *mode;
-   nmode->base.id = new_id;
-   INIT_LIST_HEAD(&nmode->head);
+   drm_mode_copy(nmode, mode);
+
return nmode;
 }
 EXPORT_SYMBOL(drm_mode_duplicate);
diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c 
b/drivers/gpu/drm/nouveau/nv50_dac.c
index a0f2beb..55c5633 100644
--- a/drivers/gpu/drm/nouveau/nv50_dac.c
+++ b/drivers/gpu/drm/nouveau/nv50_dac.c
@@ -190,11 +190,8 @@ nv50_dac_mode_fixup(struct drm_encoder *encoder, struct 
drm_display_mode *mode,
}
 
if (connector->scaling_mode != DRM_MODE_SCALE_NONE &&
-connector->native_mode) {
-   int id = adjusted_mode->base.id;
-   *adjusted_mode = *connector->native_mode;
-   adjusted_mode->base.id = id;
-   }
+connector->native_mode)
+   drm_mode_copy(adjusted_mode, connector->native_mode);
 
return true;
 }
diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c 
b/drivers/gpu/drm/nouveau/nv50_sor.c
index c4423ba..1706964 100644
--- a/drivers/gpu/drm/nouveau/nv50_sor.c
+++ b/drivers/gpu/drm/nouveau/nv50_sor.c
@@ -162,11 +162,8 @@ nv50_sor_mode_fixup(struct drm_encoder *encoder, struct 
drm_display_mode *mode,
}
 
if (connector->scaling_mode != DRM_MODE_SCALE_NONE &&
-connector->native_mode) {
-   int id = adjusted_mode->base.id;
-   *adjusted_mode = *connector->native_mode;
-   adjusted_mode->base.id = id;
-   }
+connector->native_mode)
+   drm_mode_copy(adjusted_mode, connector->native_mode);
 
return true;
 }
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 53cb49a..9595c2c 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -855,6 +855,7 @@ extern struct edid *drm_get_edid(struct drm_connector 
*connector,
 extern int drm_add_edid_modes(struct drm_connector *connector, struct edid 
*edid);
 extern void drm_mode_probed_add(struct drm_connector *connector, struct 
drm_display_mode *mode);
 extern void drm_mode_remove(struct drm_connector *connector, struct 
drm_display_mode *mode);
+extern void drm_mode_copy(struct drm_display_mode *dst, const struct 
drm_display_mode *src);
 extern struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev,
   const struct 
drm_display_mode *mode);
 extern void drm_mode_debug_printmodeline(struct drm_display_mode *mode);
-- 
1.7.3.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 02/15] drm: Change drm_display_mode::type to unsigned

2012-03-13 Thread ville . syrjala
From: Ville Syrjälä 

The drm_display_mode type is a bitmask so it should be unsigned.

Signed-off-by: Ville Syrjälä 
---
 include/drm/drm_crtc.h |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 2a0872c..31715bd 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -121,7 +121,7 @@ struct drm_display_mode {
char name[DRM_DISPLAY_MODE_LEN];
 
enum drm_mode_status status;
-   int type;
+   unsigned int type;
 
/* Proposed mode values */
int clock;  /* in kHz */
-- 
1.7.3.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 08/15] drm: Check CRTC viewport against framebuffer size

2012-03-13 Thread ville . syrjala
From: Ville Syrjälä 

Make sure the requested CRTC viewport fits inside the
framebuffer.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_crtc.c |   24 
 1 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 4d9e69c..3f5c603 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1835,6 +1835,18 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
}
 
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
+
+   if (mode->hdisplay > fb->width ||
+   mode->vdisplay > fb->height ||
+   crtc_req->x > fb->width - mode->hdisplay ||
+   crtc_req->y > fb->height - mode->vdisplay) {
+   DRM_DEBUG_KMS("Invalid CRTC viewport %ux%u+%u+%u for fb 
size %ux%u.\n",
+ mode->hdisplay, mode->vdisplay,
+ crtc_req->x, crtc_req->y,
+ fb->width, fb->height);
+   ret = -ENOSPC;
+   goto out;
+   }
}
 
if (crtc_req->count_connectors == 0 && mode) {
@@ -3206,6 +3218,18 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
goto out;
fb = obj_to_fb(obj);
 
+   if (crtc->mode.hdisplay > fb->width ||
+   crtc->mode.vdisplay > fb->height ||
+   crtc->x > fb->width - crtc->mode.hdisplay ||
+   crtc->y > fb->height - crtc->mode.vdisplay) {
+   DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport 
%ux%u+%d+%d.\n",
+ fb->width, fb->height,
+ crtc->mode.hdisplay, crtc->mode.vdisplay,
+ crtc->x, crtc->y);
+   ret = -ENOSPC;
+   goto out;
+   }
+
if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
ret = -ENOMEM;
spin_lock_irqsave(&dev->event_lock, flags);
-- 
1.7.3.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 00/15] drm: Bounds checking, error handling, etc.

2012-03-13 Thread ville . syrjala
Mostly fixes for various bits and pieces that caught my eye while
reading the mode setting code.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 15/15] drm: Fix drm_mode_objecte_get() return values

2012-03-13 Thread ville . syrjala
From: Ville Syrjälä 

Change drm_mode_object_get() to return -ENOMEM if idr_pre_get() fails,
and also handle -ENOSPC from idr_get_new_above().

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_crtc.c |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 12333ca..8f66a15 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -227,7 +227,7 @@ static int drm_mode_object_get(struct drm_device *dev,
do {
if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) {
DRM_ERROR("Ran out memory getting a mode number\n");
-   return -EINVAL;
+   return -ENOMEM;
}
 
mutex_lock(&dev->mode_config.idr_mutex);
@@ -236,6 +236,9 @@ static int drm_mode_object_get(struct drm_device *dev,
mutex_unlock(&dev->mode_config.idr_mutex);
} while (ret == -EAGAIN);
 
+   if (ret)
+   return ret;
+
obj->id = new_id;
obj->type = obj_type;
return 0;
-- 
1.7.3.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 13/15] drm: Eliminate pointless goto

2012-03-13 Thread ville . syrjala
From: Ville Syrjälä 

Use a do {} while() loop instead of a goto in drm_mode_object_get().

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_crtc.c |   20 ++--
 1 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index d2d9dc5..12333ca 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -224,17 +224,17 @@ static int drm_mode_object_get(struct drm_device *dev,
int new_id = 0;
int ret;
 
-again:
-   if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) {
-   DRM_ERROR("Ran out memory getting a mode number\n");
-   return -EINVAL;
-   }
+   do {
+   if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) {
+   DRM_ERROR("Ran out memory getting a mode number\n");
+   return -EINVAL;
+   }
 
-   mutex_lock(&dev->mode_config.idr_mutex);
-   ret = idr_get_new_above(&dev->mode_config.crtc_idr, obj, 1, &new_id);
-   mutex_unlock(&dev->mode_config.idr_mutex);
-   if (ret == -EAGAIN)
-   goto again;
+   mutex_lock(&dev->mode_config.idr_mutex);
+   ret = idr_get_new_above(&dev->mode_config.crtc_idr,
+   obj, 1, &new_id);
+   mutex_unlock(&dev->mode_config.idr_mutex);
+   } while (ret == -EAGAIN);
 
obj->id = new_id;
obj->type = obj_type;
-- 
1.7.3.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 12/15] drm: Use a flexible array member for blob property data

2012-03-13 Thread ville . syrjala
From: Ville Syrjälä 

The blob property data is always allocated immediately after the object
header. No need for the extra indirection when accessing it, just use
a flexible array member.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_crtc.c |1 -
 include/drm/drm_crtc.h |2 +-
 2 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index f5b098e..d2d9dc5 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2943,7 +2943,6 @@ static struct drm_property_blob 
*drm_property_create_blob(struct drm_device *dev
return NULL;
}
 
-   blob->data = (void *)((char *)blob + sizeof(struct drm_property_blob));
blob->length = length;
 
memcpy(blob->data, data, length);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 00f4007..53cb49a 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -257,7 +257,7 @@ struct drm_property_blob {
struct drm_mode_object base;
struct list_head head;
unsigned int length;
-   void *data;
+   unsigned char data[];
 };
 
 struct drm_property_enum {
-- 
1.7.3.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 10/15] drm: Make drm_crtc_convert_{umode, to_umode} static and constify their params

2012-03-13 Thread ville . syrjala
From: Ville Syrjälä 

drm_crtc_convert_umode() and drm_crtc_convert_to_umode() are never
used outside drm_crtc.c, so make them static. Also make the input
mode structure const for both functions.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_crtc.c |8 
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 37d34ad..e36bd43 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1002,8 +1002,8 @@ EXPORT_SYMBOL(drm_mode_config_cleanup);
  * Convert a drm_display_mode into a drm_mode_modeinfo structure to return to
  * the user.
  */
-void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out,
-  struct drm_display_mode *in)
+static void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out,
+ const struct drm_display_mode *in)
 {
WARN(in->hdisplay > USHRT_MAX || in->hsync_start > USHRT_MAX ||
 in->hsync_end > USHRT_MAX || in->htotal > USHRT_MAX ||
@@ -1044,8 +1044,8 @@ void drm_crtc_convert_to_umode(struct drm_mode_modeinfo 
*out,
  * RETURNS:
  * Zero on success, errno on failure.
  */
-int drm_crtc_convert_umode(struct drm_display_mode *out,
-  struct drm_mode_modeinfo *in)
+static int drm_crtc_convert_umode(struct drm_display_mode *out,
+ const struct drm_mode_modeinfo *in)
 {
if (in->clock > INT_MAX || in->vrefresh > INT_MAX)
return -ERANGE;
-- 
1.7.3.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 09/15] drm: Fix drm_mode_attachmode_crtc()

2012-03-13 Thread ville . syrjala
From: Ville Syrjälä 

Change drm_mode_attachmode_crtc() to take an "all or nothing" approach.
If an error is returned, there are no side effects visible.

Also change the function to always duplicate the mode passed in.

Also change the function to not give up when it finds the first
connector without and encoder.

A simpler approach would be to just remove the function completely as
it's unused currently.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_crtc.c |   38 +++---
 include/drm/drm_crtc.h |2 +-
 2 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 3f5c603..37d34ad 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2421,24 +2421,40 @@ static void drm_mode_attachmode(struct drm_device *dev,
 }
 
 int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc,
-struct drm_display_mode *mode)
+const struct drm_display_mode *mode)
 {
struct drm_connector *connector;
-   struct drm_display_mode *dup_mode;
-   int need_dup = 0;
+   int ret = 0;
+   struct drm_display_mode *dup_mode, *next;
+   LIST_HEAD(list);
+
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
if (!connector->encoder)
-   break;
+   continue;
if (connector->encoder->crtc == crtc) {
-   if (need_dup)
-   dup_mode = drm_mode_duplicate(dev, mode);
-   else
-   dup_mode = mode;
-   drm_mode_attachmode(dev, connector, dup_mode);
-   need_dup = 1;
+   dup_mode = drm_mode_duplicate(dev, mode);
+   if (!dup_mode) {
+   ret = -ENOMEM;
+   goto out;
+   }
+   list_add_tail(&dup_mode->head, &list);
}
}
-   return 0;
+
+   list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+   if (!connector->encoder)
+   continue;
+   if (connector->encoder->crtc == crtc)
+   list_move_tail(list.next, &connector->user_modes);
+   }
+
+   WARN_ON(!list_empty(&list));
+
+ out:
+   list_for_each_entry_safe(dup_mode, next, &list, head)
+   drm_mode_destroy(dev, dup_mode);
+
+   return ret;
 }
 EXPORT_SYMBOL(drm_mode_attachmode_crtc);
 
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 31715bd..fe7ebc6 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -869,7 +869,7 @@ extern int drm_mode_height(struct drm_display_mode *mode);
 /* for us by fb module */
 extern int drm_mode_attachmode_crtc(struct drm_device *dev,
struct drm_crtc *crtc,
-   struct drm_display_mode *mode);
+   const struct drm_display_mode *mode);
 extern int drm_mode_detachmode_crtc(struct drm_device *dev, struct 
drm_display_mode *mode);
 
 extern struct drm_display_mode *drm_mode_create(struct drm_device *dev);
-- 
1.7.3.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 07/15] drm: Check user mode against overflows

2012-03-13 Thread ville . syrjala
From: Ville Syrjälä 

The internal mode representation drm_display_mode uses signed data
types. When converting the user mode to internal representation,
check that the unsigned values don't overflow the signed datatypes.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_crtc.c |   33 -
 1 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 9ccb92f..4d9e69c 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1040,10 +1040,16 @@ void drm_crtc_convert_to_umode(struct drm_mode_modeinfo 
*out,
  *
  * Convert a drm_mode_modeinfo into a drm_display_mode structure to return to
  * the caller.
+ *
+ * RETURNS:
+ * Zero on success, errno on failure.
  */
-void drm_crtc_convert_umode(struct drm_display_mode *out,
-   struct drm_mode_modeinfo *in)
+int drm_crtc_convert_umode(struct drm_display_mode *out,
+  struct drm_mode_modeinfo *in)
 {
+   if (in->clock > INT_MAX || in->vrefresh > INT_MAX)
+   return -ERANGE;
+
out->clock = in->clock;
out->hdisplay = in->hdisplay;
out->hsync_start = in->hsync_start;
@@ -1060,6 +1066,8 @@ void drm_crtc_convert_umode(struct drm_display_mode *out,
out->type = in->type;
strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
+
+   return 0;
 }
 
 /**
@@ -1820,7 +1828,12 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
goto out;
}
 
-   drm_crtc_convert_umode(mode, &crtc_req->mode);
+   ret = drm_crtc_convert_umode(mode, &crtc_req->mode);
+   if (ret) {
+   DRM_DEBUG_KMS("Invalid mode\n");
+   goto out;
+   }
+
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
}
 
@@ -2492,7 +2505,12 @@ int drm_mode_attachmode_ioctl(struct drm_device *dev,
goto out;
}
 
-   drm_crtc_convert_umode(mode, umode);
+   ret = drm_crtc_convert_umode(mode, umode);
+   if (ret) {
+   DRM_DEBUG_KMS("Invalid mode\n");
+   drm_mode_destroy(dev, mode);
+   goto out;
+   }
 
drm_mode_attachmode(dev, connector, mode);
 out:
@@ -2535,7 +2553,12 @@ int drm_mode_detachmode_ioctl(struct drm_device *dev,
}
connector = obj_to_connector(obj);
 
-   drm_crtc_convert_umode(&mode, umode);
+   ret = drm_crtc_convert_umode(&mode, umode);
+   if (ret) {
+   DRM_DEBUG_KMS("Invalid mode\n");
+   goto out;
+   }
+
ret = drm_mode_detachmode(dev, connector, &mode);
 out:
mutex_unlock(&dev->mode_config.mutex);
-- 
1.7.3.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 06/15] drm: Fix memory leak in drm_mode_setcrtc()

2012-03-13 Thread ville . syrjala
From: Ville Syrjälä 

The mode passed to the .set_config() hook was never freed. The drivers
will make a copy of the mode, so simply free it when done.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_crtc.c |9 +
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index d2e09d9..9ccb92f 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -643,6 +643,9 @@ EXPORT_SYMBOL(drm_mode_create);
  */
 void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode)
 {
+   if (!mode)
+   return;
+
drm_mode_object_put(dev, &mode->base);
 
kfree(mode);
@@ -1812,6 +1815,11 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
}
 
mode = drm_mode_create(dev);
+   if (!mode) {
+   ret = -ENOMEM;
+   goto out;
+   }
+
drm_crtc_convert_umode(mode, &crtc_req->mode);
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
}
@@ -1881,6 +1889,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
 
 out:
kfree(connector_set);
+   drm_mode_destroy(dev, mode);
mutex_unlock(&dev->mode_config.mutex);
return ret;
 }
-- 
1.7.3.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 05/15] drm: Make drm_mode_attachmode() void

2012-03-13 Thread ville . syrjala
From: Ville Syrjälä 

drm_mode_attachmode() always returns 0. Change the return type to void.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_crtc.c |   16 +---
 1 files changed, 5 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 3a42c9c..d2e09d9 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2379,21 +2379,17 @@ void drm_fb_release(struct drm_file *priv)
  *
  * Add @mode to @connector's user mode list.
  */
-static int drm_mode_attachmode(struct drm_device *dev,
-  struct drm_connector *connector,
-  struct drm_display_mode *mode)
+static void drm_mode_attachmode(struct drm_device *dev,
+   struct drm_connector *connector,
+   struct drm_display_mode *mode)
 {
-   int ret = 0;
-
list_add_tail(&mode->head, &connector->user_modes);
-   return ret;
 }
 
 int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc,
 struct drm_display_mode *mode)
 {
struct drm_connector *connector;
-   int ret = 0;
struct drm_display_mode *dup_mode;
int need_dup = 0;
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
@@ -2404,9 +2400,7 @@ int drm_mode_attachmode_crtc(struct drm_device *dev, 
struct drm_crtc *crtc,
dup_mode = drm_mode_duplicate(dev, mode);
else
dup_mode = mode;
-   ret = drm_mode_attachmode(dev, connector, dup_mode);
-   if (ret)
-   return ret;
+   drm_mode_attachmode(dev, connector, dup_mode);
need_dup = 1;
}
}
@@ -2491,7 +2485,7 @@ int drm_mode_attachmode_ioctl(struct drm_device *dev,
 
drm_crtc_convert_umode(mode, umode);
 
-   ret = drm_mode_attachmode(dev, connector, mode);
+   drm_mode_attachmode(dev, connector, mode);
 out:
mutex_unlock(&dev->mode_config.mutex);
return ret;
-- 
1.7.3.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 04/15] drm: Check crtc x and y coordinates

2012-03-13 Thread ville . syrjala
From: Ville Syrjälä 

The crtc x/y panning coordinates are stored as signed integers
internally. The user provides them as unsigned, so we should check
that the user provided values actually fit in the internal datatypes.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_crtc.c |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index d11763f..3a42c9c 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1774,6 +1774,10 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
 
+   /* For some reason crtc x/y offsets are signed internally. */
+   if (crtc_req->x > INT_MAX || crtc_req->y > INT_MAX)
+   return -ERANGE;
+
mutex_lock(&dev->mode_config.mutex);
obj = drm_mode_object_find(dev, crtc_req->crtc_id,
   DRM_MODE_OBJECT_CRTC);
-- 
1.7.3.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 03/15] drm: Warn if mode to umode conversion overflows the destination types

2012-03-13 Thread ville . syrjala
From: Ville Syrjälä 

When converting from a drm_display_mode to drm_mode_modeinfo, print a
warning if the the timings values don't fit into the __u16 datatype.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_crtc.c |7 +++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index bbcecdb..d11763f 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1002,6 +1002,13 @@ EXPORT_SYMBOL(drm_mode_config_cleanup);
 void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out,
   struct drm_display_mode *in)
 {
+   WARN(in->hdisplay > USHRT_MAX || in->hsync_start > USHRT_MAX ||
+in->hsync_end > USHRT_MAX || in->htotal > USHRT_MAX ||
+in->hskew > USHRT_MAX || in->vdisplay > USHRT_MAX ||
+in->vsync_start > USHRT_MAX || in->vsync_end > USHRT_MAX ||
+in->vtotal > USHRT_MAX || in->vscan > USHRT_MAX,
+"timing values too large for mode info\n");
+
out->clock = in->clock;
out->hdisplay = in->hdisplay;
out->hsync_start = in->hsync_start;
-- 
1.7.3.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 01/15] drm: Reject mode set with current fb if no current fb is bound

2012-03-13 Thread ville . syrjala
From: Ville Syrjälä 

When doing a mode set with the special fb id -1, reject the mode set if
no fb is currently bound to the crtc.

Also remove the pointless list traversal to find the current crtc based
on the current crtc :)

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_crtc.c |   14 ++
 1 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 6fdaf6f..bbcecdb 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1755,7 +1755,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
struct drm_mode_config *config = &dev->mode_config;
struct drm_mode_crtc *crtc_req = data;
struct drm_mode_object *obj;
-   struct drm_crtc *crtc, *crtcfb;
+   struct drm_crtc *crtc;
struct drm_connector **connector_set = NULL, *connector;
struct drm_framebuffer *fb = NULL;
struct drm_display_mode *mode = NULL;
@@ -1782,14 +1782,12 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
/* If we have a mode we need a framebuffer. */
/* If we pass -1, set the mode with the currently bound fb */
if (crtc_req->fb_id == -1) {
-   list_for_each_entry(crtcfb,
-   &dev->mode_config.crtc_list, head) {
-   if (crtcfb == crtc) {
-   DRM_DEBUG_KMS("Using current fb for "
-   "setmode\n");
-   fb = crtc->fb;
-   }
+   if (!crtc->fb) {
+   DRM_DEBUG_KMS("CRTC doesn't have current FB\n");
+   ret = -EINVAL;
+   goto out;
}
+   fb = crtc->fb;
} else {
obj = drm_mode_object_find(dev, crtc_req->fb_id,
   DRM_MODE_OBJECT_FB);
-- 
1.7.3.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[RFCv2 PATCH 9/9] v4l: s5p-tv: mixer: integrate with dmabuf

2012-03-13 Thread Tomasz Stanislawski
Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/s5p-tv/Kconfig   |1 +
 drivers/media/video/s5p-tv/mixer_video.c |   12 +++-
 2 files changed, 12 insertions(+), 1 deletions(-)

diff --git a/drivers/media/video/s5p-tv/Kconfig 
b/drivers/media/video/s5p-tv/Kconfig
index f248b28..2e80126 100644
--- a/drivers/media/video/s5p-tv/Kconfig
+++ b/drivers/media/video/s5p-tv/Kconfig
@@ -10,6 +10,7 @@ config VIDEO_SAMSUNG_S5P_TV
bool "Samsung TV driver for S5P platform (experimental)"
depends on PLAT_S5P && PM_RUNTIME
depends on EXPERIMENTAL
+   select DMA_SHARED_BUFFER
default n
---help---
  Say Y here to enable selecting the TV output devices for
diff --git a/drivers/media/video/s5p-tv/mixer_video.c 
b/drivers/media/video/s5p-tv/mixer_video.c
index f7ca5cc..f08edbf 100644
--- a/drivers/media/video/s5p-tv/mixer_video.c
+++ b/drivers/media/video/s5p-tv/mixer_video.c
@@ -697,6 +697,15 @@ static int mxr_dqbuf(struct file *file, void *priv, struct 
v4l2_buffer *p)
return vb2_dqbuf(&layer->vb_queue, p, file->f_flags & O_NONBLOCK);
 }
 
+static int mxr_expbuf(struct file *file, void *priv,
+   struct v4l2_exportbuffer *eb)
+{
+   struct mxr_layer *layer = video_drvdata(file);
+
+   mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
+   return vb2_expbuf(&layer->vb_queue, eb);
+}
+
 static int mxr_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
 {
struct mxr_layer *layer = video_drvdata(file);
@@ -724,6 +733,7 @@ static const struct v4l2_ioctl_ops mxr_ioctl_ops = {
.vidioc_querybuf = mxr_querybuf,
.vidioc_qbuf = mxr_qbuf,
.vidioc_dqbuf = mxr_dqbuf,
+   .vidioc_expbuf = mxr_expbuf,
/* Streaming control */
.vidioc_streamon = mxr_streamon,
.vidioc_streamoff = mxr_streamoff,
@@ -1074,7 +1084,7 @@ struct mxr_layer *mxr_base_layer_create(struct mxr_device 
*mdev,
 
layer->vb_queue = (struct vb2_queue) {
.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
-   .io_modes = VB2_MMAP | VB2_USERPTR,
+   .io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF,
.drv_priv = layer,
.buf_struct_size = sizeof(struct mxr_buffer),
.ops = &mxr_video_qops,
-- 
1.7.5.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[RFCv2 PATCH 4/9] v4l: add buffer exporting via dmabuf

2012-03-13 Thread Tomasz Stanislawski
This patch adds extension to V4L2 api. It allow to export a mmap buffer as file
descriptor. New ioctl VIDIOC_EXPBUF is added. It takes a buffer offset used by
mmap and return a file descriptor on success.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/v4l2-compat-ioctl32.c |1 +
 drivers/media/video/v4l2-ioctl.c  |   11 +++
 include/linux/videodev2.h |   20 
 include/media/v4l2-ioctl.h|2 ++
 4 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/drivers/media/video/v4l2-compat-ioctl32.c 
b/drivers/media/video/v4l2-compat-ioctl32.c
index e6f67aa..fd157cb 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -954,6 +954,7 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int 
cmd, unsigned long arg)
case VIDIOC_S_FBUF32:
case VIDIOC_OVERLAY32:
case VIDIOC_QBUF32:
+   case VIDIOC_EXPBUF:
case VIDIOC_DQBUF32:
case VIDIOC_STREAMON32:
case VIDIOC_STREAMOFF32:
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 74cab51..a125016 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -207,6 +207,7 @@ static const char *v4l2_ioctls[] = {
[_IOC_NR(VIDIOC_S_FBUF)]   = "VIDIOC_S_FBUF",
[_IOC_NR(VIDIOC_OVERLAY)]  = "VIDIOC_OVERLAY",
[_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF",
+   [_IOC_NR(VIDIOC_EXPBUF)]   = "VIDIOC_EXPBUF",
[_IOC_NR(VIDIOC_DQBUF)]= "VIDIOC_DQBUF",
[_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON",
[_IOC_NR(VIDIOC_STREAMOFF)]= "VIDIOC_STREAMOFF",
@@ -938,6 +939,16 @@ static long __video_do_ioctl(struct file *file,
dbgbuf(cmd, vfd, p);
break;
}
+   case VIDIOC_EXPBUF:
+   {
+   struct v4l2_exportbuffer *p = arg;
+
+   if (!ops->vidioc_expbuf)
+   break;
+
+   ret = ops->vidioc_expbuf(file, fh, p);
+   break;
+   }
case VIDIOC_DQBUF:
{
struct v4l2_buffer *p = arg;
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index bb6844e..e71c787 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -680,6 +680,25 @@ struct v4l2_buffer {
 #define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE  0x0800
 #define V4L2_BUF_FLAG_NO_CACHE_CLEAN   0x1000
 
+/**
+ * struct v4l2_exportbuffer - export of video buffer as DMABUF file descriptor
+ *
+ * @fd:file descriptor associated with DMABUF (set by driver)
+ * @mem_offset:for non-multiplanar buffers with memory == 
V4L2_MEMORY_MMAP;
+ * offset from the start of the device memory for this plane,
+ * (or a "cookie" that should be passed to mmap() as offset)
+ *
+ * Contains data used for exporting a video buffer as DMABUF file
+ * descriptor. Uses the same 'cookie' as mmap() syscall. All reserved fields
+ * must be set to zero.
+ */
+struct v4l2_exportbuffer {
+   __u32   fd;
+   __u32   reserved0;
+   __u32   mem_offset;
+   __u32   reserved[13];
+};
+
 /*
  * O V E R L A Y   P R E V I E W
  */
@@ -2303,6 +2322,7 @@ struct v4l2_create_buffers {
 #define VIDIOC_S_FBUF   _IOW('V', 11, struct v4l2_framebuffer)
 #define VIDIOC_OVERLAY  _IOW('V', 14, int)
 #define VIDIOC_QBUF_IOWR('V', 15, struct v4l2_buffer)
+#define VIDIOC_EXPBUF  _IOWR('V', 16, struct v4l2_exportbuffer)
 #define VIDIOC_DQBUF   _IOWR('V', 17, struct v4l2_buffer)
 #define VIDIOC_STREAMON _IOW('V', 18, int)
 #define VIDIOC_STREAMOFF_IOW('V', 19, int)
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index 4df031a..d8716c6f 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -120,6 +120,8 @@ struct v4l2_ioctl_ops {
int (*vidioc_reqbufs) (struct file *file, void *fh, struct 
v4l2_requestbuffers *b);
int (*vidioc_querybuf)(struct file *file, void *fh, struct v4l2_buffer 
*b);
int (*vidioc_qbuf)(struct file *file, void *fh, struct v4l2_buffer 
*b);
+   int (*vidioc_expbuf)  (struct file *file, void *fh,
+   struct v4l2_exportbuffer *e);
int (*vidioc_dqbuf)   (struct file *file, void *fh, struct v4l2_buffer 
*b);
 
int (*vidioc_create_bufs)(struct file *file, void *fh, struct 
v4l2_create_buffers *b);
-- 
1.7.5.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[RFCv2 PATCH 7/9] v4l: vb2-dma-contig: change map/unmap behaviour

2012-03-13 Thread Tomasz Stanislawski
The DMABUF documentation says that the map_dma_buf callback should return
scatterlist that is mapped into a caller's address space. In practice, almost
none of existing implementations of DMABUF exporter does it.  This patch breaks
the DMABUF specification in order to allow exchange DMABUF buffers between
other APIs like DRM.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/videobuf2-dma-contig.c |   64 
 1 files changed, 27 insertions(+), 37 deletions(-)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index d95b23a..32bb16b 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -315,11 +315,6 @@ static int vb2_dc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
 /* DMABUF ops for exporters  */
 /*/
 
-struct vb2_dc_attachment {
-   struct sg_table sgt;
-   enum dma_data_direction dir;
-};
-
 static int vb2_dc_dmabuf_ops_attach(struct dma_buf *dbuf, struct device *dev,
struct dma_buf_attachment *dbuf_attach)
 {
@@ -330,17 +325,13 @@ static int vb2_dc_dmabuf_ops_attach(struct dma_buf *dbuf, 
struct device *dev,
 static void vb2_dc_dmabuf_ops_detach(struct dma_buf *dbuf,
struct dma_buf_attachment *db_attach)
 {
-   struct vb2_dc_attachment *attach = db_attach->priv;
-   struct sg_table *sgt;
+   struct sg_table *sgt = db_attach->priv;
 
-   if (!attach)
+   if (!sgt)
return;
 
-   sgt = &attach->sgt;
-
-   dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->nents, attach->dir);
sg_free_table(sgt);
-   kfree(attach);
+   kfree(sgt);
db_attach->priv = NULL;
 }
 
@@ -349,26 +340,22 @@ static struct sg_table *vb2_dc_dmabuf_ops_map(
 {
struct dma_buf *dbuf = db_attach->dmabuf;
struct vb2_dc_buf *buf = dbuf->priv;
-   struct vb2_dc_attachment *attach = db_attach->priv;
-   struct sg_table *sgt;
+   struct sg_table *sgt = db_attach->priv;
struct scatterlist *rd, *wr;
int i, ret;
 
/* return previously mapped sg table */
-   if (attach)
-   return &attach->sgt;
+   if (sgt)
+   return sgt;
 
-   attach = kzalloc(sizeof *attach, GFP_KERNEL);
-   if (!attach)
+   sgt = kzalloc(sizeof *sgt, GFP_KERNEL);
+   if (!sgt)
return ERR_PTR(-ENOMEM);
 
-   sgt = &attach->sgt;
-   attach->dir = dir;
-
/* copying the buf->base_sgt to attachment */
ret = sg_alloc_table(sgt, buf->sgt_base->orig_nents, GFP_KERNEL);
if (ret) {
-   kfree(attach);
+   kfree(sgt);
return ERR_PTR(-ENOMEM);
}
 
@@ -380,16 +367,7 @@ static struct sg_table *vb2_dc_dmabuf_ops_map(
wr = sg_next(wr);
}
 
-   /* mapping new sglist to the client */
-   ret = dma_map_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, dir);
-   if (ret <= 0) {
-   printk(KERN_ERR "failed to map scatterlist\n");
-   sg_free_table(sgt);
-   kfree(attach);
-   return ERR_PTR(-EIO);
-   }
-
-   db_attach->priv = attach;
+   db_attach->priv = sgt;
 
return sgt;
 }
@@ -623,7 +601,7 @@ static int vb2_dc_map_dmabuf(void *mem_priv)
struct vb2_dc_buf *buf = mem_priv;
struct sg_table *sgt;
unsigned long contig_size;
-   int ret = 0;
+   int ret = -EFAULT;
 
if (WARN_ON(!buf->db_attach)) {
printk(KERN_ERR "trying to pin a non attached buffer\n");
@@ -642,12 +620,20 @@ static int vb2_dc_map_dmabuf(void *mem_priv)
return -EINVAL;
}
 
+   /* mapping new sglist to the client */
+   sgt->nents = dma_map_sg(buf->dev, sgt->sgl, sgt->orig_nents,
+   buf->dma_dir);
+   if (sgt->nents <= 0) {
+   printk(KERN_ERR "failed to map scatterlist\n");
+   goto fail_map_attachment;
+   }
+
/* checking if dmabuf is big enough to store contiguous chunk */
contig_size = vb2_dc_get_contiguous_size(sgt);
if (contig_size < buf->size) {
-   printk(KERN_ERR "contiguous chunk of dmabuf is too small\n");
-   ret = -EFAULT;
-   goto fail_map;
+   printk(KERN_ERR "contiguous chunk of dmabuf is too small "
+   "%lu/%lu bytes\n", contig_size, buf->size);
+   goto fail_map_sg;
}
 
buf->dma_addr = sg_dma_address(sgt->sgl);
@@ -655,7 +641,10 @@ static int vb2_dc_map_dmabuf(void *mem_priv)
 
return 0;
 
-fail_map:
+fail_map_sg:
+   dma_unmap_sg(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
+
+fail_map_attachment:
dma_buf_unmap_attachment(buf->db_attach, sgt);
 
return ret;
@@ -676,6 +665,7 @@ static void vb2_dc_unmap_dmabuf(void *mem_priv)
  

[RFCv2 PATCH 6/9] v4l: vb2-dma-contig: add support for DMABUF exporting

2012-03-13 Thread Tomasz Stanislawski
This patch adds support for exporting a dma-contig buffer using
DMABUF interface.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/videobuf2-dma-contig.c |  128 
 1 files changed, 128 insertions(+), 0 deletions(-)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index 746dd5f..d95b23a 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -31,6 +31,7 @@ struct vb2_dc_buf {
/* MMAP related */
struct vb2_vmarea_handler   handler;
atomic_trefcount;
+   struct dma_buf  *dma_buf;
struct sg_table *sgt_base;
 
/* USERPTR related */
@@ -194,6 +195,8 @@ static void vb2_dc_put(void *buf_priv)
if (!atomic_dec_and_test(&buf->refcount))
return;
 
+   if (buf->dma_buf)
+   dma_buf_put(buf->dma_buf);
vb2_dc_release_sgtable(buf->sgt_base);
dma_free_coherent(buf->dev, buf->size, buf->vaddr,
buf->dma_addr);
@@ -309,6 +312,130 @@ static int vb2_dc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
 }
 
 /*/
+/* DMABUF ops for exporters  */
+/*/
+
+struct vb2_dc_attachment {
+   struct sg_table sgt;
+   enum dma_data_direction dir;
+};
+
+static int vb2_dc_dmabuf_ops_attach(struct dma_buf *dbuf, struct device *dev,
+   struct dma_buf_attachment *dbuf_attach)
+{
+   /* nothing to be done */
+   return 0;
+}
+
+static void vb2_dc_dmabuf_ops_detach(struct dma_buf *dbuf,
+   struct dma_buf_attachment *db_attach)
+{
+   struct vb2_dc_attachment *attach = db_attach->priv;
+   struct sg_table *sgt;
+
+   if (!attach)
+   return;
+
+   sgt = &attach->sgt;
+
+   dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->nents, attach->dir);
+   sg_free_table(sgt);
+   kfree(attach);
+   db_attach->priv = NULL;
+}
+
+static struct sg_table *vb2_dc_dmabuf_ops_map(
+   struct dma_buf_attachment *db_attach, enum dma_data_direction dir)
+{
+   struct dma_buf *dbuf = db_attach->dmabuf;
+   struct vb2_dc_buf *buf = dbuf->priv;
+   struct vb2_dc_attachment *attach = db_attach->priv;
+   struct sg_table *sgt;
+   struct scatterlist *rd, *wr;
+   int i, ret;
+
+   /* return previously mapped sg table */
+   if (attach)
+   return &attach->sgt;
+
+   attach = kzalloc(sizeof *attach, GFP_KERNEL);
+   if (!attach)
+   return ERR_PTR(-ENOMEM);
+
+   sgt = &attach->sgt;
+   attach->dir = dir;
+
+   /* copying the buf->base_sgt to attachment */
+   ret = sg_alloc_table(sgt, buf->sgt_base->orig_nents, GFP_KERNEL);
+   if (ret) {
+   kfree(attach);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   rd = buf->sgt_base->sgl;
+   wr = sgt->sgl;
+   for (i = 0; i < sgt->orig_nents; ++i) {
+   sg_set_page(wr, sg_page(rd), rd->length, rd->offset);
+   rd = sg_next(rd);
+   wr = sg_next(wr);
+   }
+
+   /* mapping new sglist to the client */
+   ret = dma_map_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, dir);
+   if (ret <= 0) {
+   printk(KERN_ERR "failed to map scatterlist\n");
+   sg_free_table(sgt);
+   kfree(attach);
+   return ERR_PTR(-EIO);
+   }
+
+   db_attach->priv = attach;
+
+   return sgt;
+}
+
+static void vb2_dc_dmabuf_ops_unmap(struct dma_buf_attachment *db_attach,
+   struct sg_table *sgt)
+{
+   /* nothing to be done here */
+}
+
+static void vb2_dc_dmabuf_ops_release(struct dma_buf *dbuf)
+{
+   /* drop reference obtained in vb2_dc_get_dmabuf */
+   vb2_dc_put(dbuf->priv);
+}
+
+static struct dma_buf_ops vb2_dc_dmabuf_ops = {
+   .attach = vb2_dc_dmabuf_ops_attach,
+   .detach = vb2_dc_dmabuf_ops_detach,
+   .map_dma_buf = vb2_dc_dmabuf_ops_map,
+   .unmap_dma_buf = vb2_dc_dmabuf_ops_unmap,
+   .release = vb2_dc_dmabuf_ops_release,
+};
+
+static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+   struct dma_buf *dbuf;
+
+   if (buf->dma_buf)
+   return buf->dma_buf;
+
+   /* dmabuf keeps reference to vb2 buffer */
+   atomic_inc(&buf->refcount);
+   dbuf = dma_buf_export(buf, &vb2_dc_dmabuf_ops, buf->size, 0);
+   if (IS_ERR(dbuf)) {
+   atomic_dec(&buf->refcount);
+   return NULL;
+   }
+
+   buf->dma_buf = dbuf;
+
+   return dbuf;
+}
+
+/*/
 /*   callbacks for USERPTR buffers   */
 /*/
 
@@ -603,6 +730,7 @@ static void *vb2_dc_attach_dmabuf(void *alloc_ctx, struct 

[RFCv2 PATCH 8/9] v4l: fimc: integrate capture i-face with dmabuf

2012-03-13 Thread Tomasz Stanislawski
Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/Kconfig |1 +
 drivers/media/video/s5p-fimc/fimc-capture.c |   11 ++-
 2 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 9495b6a..c9963f0 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -1099,6 +1099,7 @@ config  VIDEO_SAMSUNG_S5P_FIMC
VIDEO_V4L2_SUBDEV_API && EXPERIMENTAL
select VIDEOBUF2_DMA_CONTIG
select V4L2_MEM2MEM_DEV
+   select DMA_SHARED_BUFFER
---help---
  This is a v4l2 driver for Samsung S5P and EXYNOS4 camera
  host interface and video postprocessor.
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c 
b/drivers/media/video/s5p-fimc/fimc-capture.c
index a9e9653..7ecc36b 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -1011,6 +1011,14 @@ static int fimc_cap_qbuf(struct file *file, void *priv,
return vb2_qbuf(&fimc->vid_cap.vbq, buf);
 }
 
+static int fimc_cap_expbuf(struct file *file, void *priv,
+ struct v4l2_exportbuffer *eb)
+{
+   struct fimc_dev *fimc = video_drvdata(file);
+
+   return vb2_expbuf(&fimc->vid_cap.vbq, eb);
+}
+
 static int fimc_cap_dqbuf(struct file *file, void *priv,
   struct v4l2_buffer *buf)
 {
@@ -1081,6 +1089,7 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops 
= {
 
.vidioc_qbuf= fimc_cap_qbuf,
.vidioc_dqbuf   = fimc_cap_dqbuf,
+   .vidioc_expbuf  = fimc_cap_expbuf,
 
.vidioc_streamon= fimc_cap_streamon,
.vidioc_streamoff   = fimc_cap_streamoff,
@@ -1463,7 +1472,7 @@ int fimc_register_capture_device(struct fimc_dev *fimc,
q = &fimc->vid_cap.vbq;
memset(q, 0, sizeof(*q));
q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-   q->io_modes = VB2_MMAP | VB2_USERPTR;
+   q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
q->drv_priv = fimc->vid_cap.ctx;
q->ops = &fimc_capture_qops;
q->mem_ops = &vb2_dma_contig_memops;
-- 
1.7.5.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[RFCv2 PATCH 5/9] v4l: vb2: add buffer exporting via dmabuf

2012-03-13 Thread Tomasz Stanislawski
This patch adds extension to videobuf2-core. It allow to export a mmap buffer
as a file descriptor.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/videobuf2-core.c |   64 ++
 include/media/videobuf2-core.h   |2 +
 2 files changed, 66 insertions(+), 0 deletions(-)

diff --git a/drivers/media/video/videobuf2-core.c 
b/drivers/media/video/videobuf2-core.c
index e7df560..41c4bf8 100644
--- a/drivers/media/video/videobuf2-core.c
+++ b/drivers/media/video/videobuf2-core.c
@@ -1553,6 +1553,70 @@ int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer 
*b, bool nonblocking)
 }
 EXPORT_SYMBOL_GPL(vb2_dqbuf);
 
+static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off,
+   unsigned int *_buffer, unsigned int *_plane);
+
+/**
+ * vb2_expbuf() - Export a buffer as a file descriptor
+ * @q: videobuf2 queue
+ * @b: export buffer structure passed from userspace to vidioc_expbuf
+ * handler in driver
+ *
+ * The return values from this function are intended to be directly returned
+ * from vidioc_expbuf handler in driver.
+ */
+int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
+{
+   struct vb2_buffer *vb = NULL;
+   struct vb2_plane *vb_plane;
+   unsigned int buffer, plane;
+   int ret;
+   struct dma_buf *dbuf;
+
+   if (q->memory != V4L2_MEMORY_MMAP) {
+   dprintk(1, "Queue is not currently set up for mmap\n");
+   return -EINVAL;
+   }
+
+   if (!q->mem_ops->get_dmabuf) {
+   dprintk(1, "Queue does not support DMA buffer exporting\n");
+   return -EINVAL;
+   }
+
+   /*
+* Find the plane corresponding to the offset passed by userspace.
+*/
+   ret = __find_plane_by_offset(q, eb->mem_offset, &buffer, &plane);
+   if (ret) {
+   dprintk(1, "invalid offset %u\n", eb->mem_offset);
+   return ret;
+   }
+
+   vb = q->bufs[buffer];
+   vb_plane = &vb->planes[plane];
+
+   dbuf = call_memop(q, get_dmabuf, vb_plane->mem_priv);
+   if (IS_ERR_OR_NULL(dbuf)) {
+   dprintk(1, "Failed to export buffer %d, plane %d\n",
+   buffer, plane);
+   return -EINVAL;
+   }
+
+   ret = dma_buf_fd(dbuf);
+   if (ret < 0) {
+   dprintk(3, "buffer %d, plane %d failed to export (%d)\n",
+   buffer, plane, ret);
+   return ret;
+   }
+
+   dprintk(3, "buffer %d, plane %d exported as %d descriptor\n",
+   buffer, plane, ret);
+   eb->fd = ret;
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(vb2_expbuf);
+
 /**
  * __vb2_queue_cancel() - cancel and stop (pause) streaming
  *
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 412c6a4..548252b 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -79,6 +79,7 @@ struct vb2_mem_ops {
void(*prepare)(void *buf_priv);
void(*finish)(void *buf_priv);
void(*put)(void *buf_priv);
+   struct dma_buf *(*get_dmabuf)(void *buf_priv);
 
void*(*get_userptr)(void *alloc_ctx, unsigned long vaddr,
unsigned long size, int write);
@@ -348,6 +349,7 @@ int vb2_queue_init(struct vb2_queue *q);
 void vb2_queue_release(struct vb2_queue *q);
 
 int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b);
+int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb);
 int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking);
 
 int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type);
-- 
1.7.5.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


  1   2   >