[RFC][PATCH 6/6] WIP drm/i915: "Atomic" modeset test implementation
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
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-