[RFC][PATCH 6/6] WIP drm/i915: "Atomic" modeset test implementation

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

Just a quick prototype to test the atomic modeset API. Implemented
via already existing non-atomic mechanisms internally.
---
 drivers/gpu/drm/i915/Makefile|1 +
 drivers/gpu/drm/i915/intel_atomic.c  |  788 ++
 drivers/gpu/drm/i915/intel_display.c |7 +
 3 files changed, 796 insertions(+), 0 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_atomic.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 2e9268d..f97e7a4 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -15,6 +15,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \
  i915_gem_tiling.o \
  i915_sysfs.o \
  i915_trace_points.o \
+ intel_atomic.o \
  intel_display.o \
  intel_crt.o \
  intel_lvds.o \
diff --git a/drivers/gpu/drm/i915/intel_atomic.c 
b/drivers/gpu/drm/i915/intel_atomic.c
new file mode 100644
index 000..a6643fd
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -0,0 +1,788 @@
+/*
+ */
+
+#include 
+#include 
+
+static struct drm_property *prop_src_x;
+static struct drm_property *prop_src_y;
+static struct drm_property *prop_src_w;
+static struct drm_property *prop_src_h;
+static struct drm_property *prop_crtc_x;
+static struct drm_property *prop_crtc_y;
+static struct drm_property *prop_crtc_w;
+static struct drm_property *prop_crtc_h;
+static struct drm_property *prop_fb_id;
+static struct drm_property *prop_crtc_id;
+static struct drm_property *prop_mode_id;
+static struct drm_property *prop_connector_ids;
+/* FIXME must be per-CRTC */
+static struct drm_property_blob *blob_connector_ids;
+
+static uint32_t *connector_ids;
+
+struct intel_plane_state {
+   struct drm_plane *plane;
+   int32_t crtc_x, crtc_y;
+   uint32_t crtc_w, crtc_h;
+   uint32_t src_x, src_y, src_w, src_h;
+   struct drm_framebuffer *fb;
+   struct drm_crtc *crtc;
+   uint32_t fb_id;
+   uint32_t crtc_id;
+   bool dirty;
+};
+
+struct intel_crtc_state {
+   struct drm_crtc *crtc;
+   struct drm_display_mode *mode;
+   int x, y;
+   struct drm_framebuffer *fb;
+   uint32_t fb_id;
+   bool mode_dirty;
+   bool fb_dirty;
+   bool active_dirty;
+   unsigned int count_connectors;
+   struct drm_connector **connectors;
+};
+
+struct intel_atomic_state {
+   struct intel_plane_state plane[3];
+   struct intel_crtc_state crtc[3];
+   bool fbs_pinned;
+   bool dirty;
+};
+
+static int populate_connectors(const struct drm_crtc *crtc,
+  struct drm_connector **connector_list)
+{
+   struct drm_connector *connector;
+
+   int i = 0;
+
+   list_for_each_entry(connector, &crtc->dev->mode_config.connector_list, 
head) {
+   if (!connector->encoder || connector->encoder->crtc != crtc)
+   continue;
+
+   connector_list[i++] = connector;
+   }
+
+   return i;
+}
+
+static void *intel_atomic_begin(struct drm_device *dev, uint32_t flags)
+{
+   struct intel_atomic_state *state;
+   struct drm_plane *plane;
+   struct drm_crtc *crtc;
+   struct drm_connector **connector_ptr;
+   int i;
+
+   state = kzalloc(sizeof *state + dev->mode_config.num_connector *
+   sizeof(struct drm_connector *) * 
ARRAY_SIZE(state->crtc), GFP_KERNEL);
+   if (!state)
+   return ERR_PTR(-ENOMEM);
+
+   connector_ptr = (struct drm_connector **)(state + 1);
+
+   i = 0;
+   list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+   if (i >= ARRAY_SIZE(state->crtc))
+   break;
+
+   state->crtc[i].crtc = crtc;
+   state->crtc[i].mode = &crtc->mode;
+   state->crtc[i].x = crtc->x;
+   state->crtc[i].y = crtc->y;
+   state->crtc[i].fb = crtc->fb;
+   state->crtc[i].fb_id = crtc->fb ? crtc->fb->base.id : 0;
+
+   state->crtc[i].count_connectors = populate_connectors(crtc, 
connector_ptr);
+   state->crtc[i].connectors = connector_ptr;
+   connector_ptr += dev->mode_config.num_connector;
+
+   i++;
+   }
+
+   i = 0;
+   list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+   if (i >= ARRAY_SIZE(state->plane))
+   break;
+
+   state->plane[i].plane = plane;
+   state->plane[i].crtc_x = plane->crtc_x;
+   state->plane[i].crtc_y = plane->crtc_y;
+   state->plane[i].crtc_w = plane->crtc_w;
+   state->plane[i].crtc_h = plane->crtc_h;
+   state->plane[i].src_x = plane->src_x;
+   state->plane[i].src_y = plane->src_y;
+   state->plane[i].src_w = plane->src_w;
+   state->plane[i].src_h = plane->src_h;
+   state->plane[i].fb = plane-

[RFC][PATCH 6/6] WIP drm/i915: "Atomic" modeset test implementation

2012-05-24 Thread ville . syrjala
From: Ville Syrjälä 

Just a quick prototype to test the atomic modeset API. Implemented
via already existing non-atomic mechanisms internally.
---
 drivers/gpu/drm/i915/Makefile|1 +
 drivers/gpu/drm/i915/intel_atomic.c  |  788 ++
 drivers/gpu/drm/i915/intel_display.c |7 +
 3 files changed, 796 insertions(+), 0 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_atomic.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 2e9268d..f97e7a4 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -15,6 +15,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \
  i915_gem_tiling.o \
  i915_sysfs.o \
  i915_trace_points.o \
+ intel_atomic.o \
  intel_display.o \
  intel_crt.o \
  intel_lvds.o \
diff --git a/drivers/gpu/drm/i915/intel_atomic.c 
b/drivers/gpu/drm/i915/intel_atomic.c
new file mode 100644
index 000..a6643fd
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -0,0 +1,788 @@
+/*
+ */
+
+#include 
+#include 
+
+static struct drm_property *prop_src_x;
+static struct drm_property *prop_src_y;
+static struct drm_property *prop_src_w;
+static struct drm_property *prop_src_h;
+static struct drm_property *prop_crtc_x;
+static struct drm_property *prop_crtc_y;
+static struct drm_property *prop_crtc_w;
+static struct drm_property *prop_crtc_h;
+static struct drm_property *prop_fb_id;
+static struct drm_property *prop_crtc_id;
+static struct drm_property *prop_mode_id;
+static struct drm_property *prop_connector_ids;
+/* FIXME must be per-CRTC */
+static struct drm_property_blob *blob_connector_ids;
+
+static uint32_t *connector_ids;
+
+struct intel_plane_state {
+   struct drm_plane *plane;
+   int32_t crtc_x, crtc_y;
+   uint32_t crtc_w, crtc_h;
+   uint32_t src_x, src_y, src_w, src_h;
+   struct drm_framebuffer *fb;
+   struct drm_crtc *crtc;
+   uint32_t fb_id;
+   uint32_t crtc_id;
+   bool dirty;
+};
+
+struct intel_crtc_state {
+   struct drm_crtc *crtc;
+   struct drm_display_mode *mode;
+   int x, y;
+   struct drm_framebuffer *fb;
+   uint32_t fb_id;
+   bool mode_dirty;
+   bool fb_dirty;
+   bool active_dirty;
+   unsigned int count_connectors;
+   struct drm_connector **connectors;
+};
+
+struct intel_atomic_state {
+   struct intel_plane_state plane[3];
+   struct intel_crtc_state crtc[3];
+   bool fbs_pinned;
+   bool dirty;
+};
+
+static int populate_connectors(const struct drm_crtc *crtc,
+  struct drm_connector **connector_list)
+{
+   struct drm_connector *connector;
+
+   int i = 0;
+
+   list_for_each_entry(connector, &crtc->dev->mode_config.connector_list, 
head) {
+   if (!connector->encoder || connector->encoder->crtc != crtc)
+   continue;
+
+   connector_list[i++] = connector;
+   }
+
+   return i;
+}
+
+static void *intel_atomic_begin(struct drm_device *dev, uint32_t flags)
+{
+   struct intel_atomic_state *state;
+   struct drm_plane *plane;
+   struct drm_crtc *crtc;
+   struct drm_connector **connector_ptr;
+   int i;
+
+   state = kzalloc(sizeof *state + dev->mode_config.num_connector *
+   sizeof(struct drm_connector *) * 
ARRAY_SIZE(state->crtc), GFP_KERNEL);
+   if (!state)
+   return ERR_PTR(-ENOMEM);
+
+   connector_ptr = (struct drm_connector **)(state + 1);
+
+   i = 0;
+   list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+   if (i >= ARRAY_SIZE(state->crtc))
+   break;
+
+   state->crtc[i].crtc = crtc;
+   state->crtc[i].mode = &crtc->mode;
+   state->crtc[i].x = crtc->x;
+   state->crtc[i].y = crtc->y;
+   state->crtc[i].fb = crtc->fb;
+   state->crtc[i].fb_id = crtc->fb ? crtc->fb->base.id : 0;
+
+   state->crtc[i].count_connectors = populate_connectors(crtc, 
connector_ptr);
+   state->crtc[i].connectors = connector_ptr;
+   connector_ptr += dev->mode_config.num_connector;
+
+   i++;
+   }
+
+   i = 0;
+   list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+   if (i >= ARRAY_SIZE(state->plane))
+   break;
+
+   state->plane[i].plane = plane;
+   state->plane[i].crtc_x = plane->crtc_x;
+   state->plane[i].crtc_y = plane->crtc_y;
+   state->plane[i].crtc_w = plane->crtc_w;
+   state->plane[i].crtc_h = plane->crtc_h;
+   state->plane[i].src_x = plane->src_x;
+   state->plane[i].src_y = plane->src_y;
+   state->plane[i].src_w = plane->src_w;
+   state->plane[i].src_h = plane->src_h;
+   state->plane[i].fb = plane-