summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/drm_atomic.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-06-09 04:19:28 +0300
committerDave Airlie <airlied@redhat.com>2016-06-09 04:19:28 +0300
commit2cca45574007b4a77fa5f63ea45d664510cec22a (patch)
treedd32a0b2bea4f3cef900b15c6badc8dfde69ab69 /drivers/gpu/drm/drm_atomic.c
parentbb4cec0222f984d7ef282c06cc3644069db21bac (diff)
parente8395081636734da19778b0446d65588a06bc40d (diff)
downloadlinux-2cca45574007b4a77fa5f63ea45d664510cec22a.tar.xz
Merge tag 'topic/drm-misc-2016-06-07' of git://anongit.freedesktop.org/drm-intel into drm-next
As promised, piles of prep work all around: - drm_atomic_state rework, prep for nonblocking commit helpers - fence patches from Gustavo and Christian to prep for atomic fences and some cool work in ttm/amdgpu from Christian - drm event prep for both nonblocking commit and atomic fences - Gustavo seems on a crusade against the non-kms-native version of the vblank functions. - prep work from Boris to nuke all the silly ->best_encoder implementations we have (we really only need that for truly dynamic cases like dvi-i vs dvi-d or dp mst selecting the right transcoder on intel) - prep work from Laurent to rework the format handling functions - and few small things all over * tag 'topic/drm-misc-2016-06-07' of git://anongit.freedesktop.org/drm-intel: (47 commits) drm/dsi: Implement set tear scanline drm/fb_cma_helper: Implement fb_mmap callback drm/qxl: Remove useless drm_fb_get_bpp_depth() call drm/ast: Remove useless drm_fb_get_bpp_depth() call drm/atomic: Fix remaining places where !funcs->best_encoder is valid drm/core: Change declaration for gamma_set. Documentation: add fence-array to kernel DocBook drm/shmobile: use drm_crtc_vblank_{get,put}() drm/radeon: use drm_crtc_vblank_{get,put}() drm/qxl: use drm_crtc_vblank_{get,put}() drm/atmel: use drm_crtc_vblank_{get,put}() drm/armada: use drm_crtc_vblank_{get,put}() drm/amdgpu: use drm_crtc_vblank_{get,put}() drm/virtio: use drm_crtc_send_vblank_event() drm/udl: use drm_crtc_send_vblank_event() drm/qxl: use drm_crtc_send_vblank_event() drm/atmel: use drm_crtc_send_vblank_event() drm/armada: use drm_crtc_send_vblank_event() drm/doc: Switch to sphinx/rst fixed-width quoting drm/doc: Drop kerneldoc for static functions in drm_irq.c ...
Diffstat (limited to 'drivers/gpu/drm/drm_atomic.c')
-rw-r--r--drivers/gpu/drm/drm_atomic.c80
1 files changed, 34 insertions, 46 deletions
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index c204ef32df16..5e4b820a977c 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -44,11 +44,8 @@
void drm_atomic_state_default_release(struct drm_atomic_state *state)
{
kfree(state->connectors);
- kfree(state->connector_states);
kfree(state->crtcs);
- kfree(state->crtc_states);
kfree(state->planes);
- kfree(state->plane_states);
}
EXPORT_SYMBOL(drm_atomic_state_default_release);
@@ -72,18 +69,10 @@ drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
sizeof(*state->crtcs), GFP_KERNEL);
if (!state->crtcs)
goto fail;
- state->crtc_states = kcalloc(dev->mode_config.num_crtc,
- sizeof(*state->crtc_states), GFP_KERNEL);
- if (!state->crtc_states)
- goto fail;
state->planes = kcalloc(dev->mode_config.num_total_plane,
sizeof(*state->planes), GFP_KERNEL);
if (!state->planes)
goto fail;
- state->plane_states = kcalloc(dev->mode_config.num_total_plane,
- sizeof(*state->plane_states), GFP_KERNEL);
- if (!state->plane_states)
- goto fail;
state->dev = dev;
@@ -139,40 +128,40 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
DRM_DEBUG_ATOMIC("Clearing atomic state %p\n", state);
for (i = 0; i < state->num_connector; i++) {
- struct drm_connector *connector = state->connectors[i];
+ struct drm_connector *connector = state->connectors[i].ptr;
if (!connector)
continue;
connector->funcs->atomic_destroy_state(connector,
- state->connector_states[i]);
- state->connectors[i] = NULL;
- state->connector_states[i] = NULL;
+ state->connectors[i].state);
+ state->connectors[i].ptr = NULL;
+ state->connectors[i].state = NULL;
drm_connector_unreference(connector);
}
for (i = 0; i < config->num_crtc; i++) {
- struct drm_crtc *crtc = state->crtcs[i];
+ struct drm_crtc *crtc = state->crtcs[i].ptr;
if (!crtc)
continue;
crtc->funcs->atomic_destroy_state(crtc,
- state->crtc_states[i]);
- state->crtcs[i] = NULL;
- state->crtc_states[i] = NULL;
+ state->crtcs[i].state);
+ state->crtcs[i].ptr = NULL;
+ state->crtcs[i].state = NULL;
}
for (i = 0; i < config->num_total_plane; i++) {
- struct drm_plane *plane = state->planes[i];
+ struct drm_plane *plane = state->planes[i].ptr;
if (!plane)
continue;
plane->funcs->atomic_destroy_state(plane,
- state->plane_states[i]);
- state->planes[i] = NULL;
- state->plane_states[i] = NULL;
+ state->planes[i].state);
+ state->planes[i].ptr = NULL;
+ state->planes[i].state = NULL;
}
}
EXPORT_SYMBOL(drm_atomic_state_default_clear);
@@ -270,8 +259,8 @@ drm_atomic_get_crtc_state(struct drm_atomic_state *state,
if (!crtc_state)
return ERR_PTR(-ENOMEM);
- state->crtc_states[index] = crtc_state;
- state->crtcs[index] = crtc;
+ state->crtcs[index].state = crtc_state;
+ state->crtcs[index].ptr = crtc;
crtc_state->state = state;
DRM_DEBUG_ATOMIC("Added [CRTC:%d:%s] %p state to %p\n",
@@ -632,8 +621,8 @@ drm_atomic_get_plane_state(struct drm_atomic_state *state,
if (!plane_state)
return ERR_PTR(-ENOMEM);
- state->plane_states[index] = plane_state;
- state->planes[index] = plane;
+ state->planes[index].state = plane_state;
+ state->planes[index].ptr = plane;
plane_state->state = state;
DRM_DEBUG_ATOMIC("Added [PLANE:%d:%s] %p state to %p\n",
@@ -897,8 +886,7 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state,
index = drm_connector_index(connector);
if (index >= state->num_connector) {
- struct drm_connector **c;
- struct drm_connector_state **cs;
+ struct __drm_connnectors_state *c;
int alloc = max(index + 1, config->num_connector);
c = krealloc(state->connectors, alloc * sizeof(*state->connectors), GFP_KERNEL);
@@ -909,26 +897,19 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state,
memset(&state->connectors[state->num_connector], 0,
sizeof(*state->connectors) * (alloc - state->num_connector));
- cs = krealloc(state->connector_states, alloc * sizeof(*state->connector_states), GFP_KERNEL);
- if (!cs)
- return ERR_PTR(-ENOMEM);
-
- state->connector_states = cs;
- memset(&state->connector_states[state->num_connector], 0,
- sizeof(*state->connector_states) * (alloc - state->num_connector));
state->num_connector = alloc;
}
- if (state->connector_states[index])
- return state->connector_states[index];
+ if (state->connectors[index].state)
+ return state->connectors[index].state;
connector_state = connector->funcs->atomic_duplicate_state(connector);
if (!connector_state)
return ERR_PTR(-ENOMEM);
drm_connector_reference(connector);
- state->connector_states[index] = connector_state;
- state->connectors[index] = connector;
+ state->connectors[index].state = connector_state;
+ state->connectors[index].ptr = connector;
connector_state->state = state;
DRM_DEBUG_ATOMIC("Added [CONNECTOR:%d] %p state to %p\n",
@@ -1432,7 +1413,8 @@ EXPORT_SYMBOL(drm_atomic_nonblocking_commit);
*/
static struct drm_pending_vblank_event *create_vblank_event(
- struct drm_device *dev, struct drm_file *file_priv, uint64_t user_data)
+ struct drm_device *dev, struct drm_file *file_priv,
+ struct fence *fence, uint64_t user_data)
{
struct drm_pending_vblank_event *e = NULL;
int ret;
@@ -1445,12 +1427,17 @@ static struct drm_pending_vblank_event *create_vblank_event(
e->event.base.length = sizeof(e->event);
e->event.user_data = user_data;
- ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base);
- if (ret) {
- kfree(e);
- return NULL;
+ if (file_priv) {
+ ret = drm_event_reserve_init(dev, file_priv, &e->base,
+ &e->event.base);
+ if (ret) {
+ kfree(e);
+ return NULL;
+ }
}
+ e->base.fence = fence;
+
return e;
}
@@ -1690,7 +1677,8 @@ retry:
for_each_crtc_in_state(state, crtc, crtc_state, i) {
struct drm_pending_vblank_event *e;
- e = create_vblank_event(dev, file_priv, arg->user_data);
+ e = create_vblank_event(dev, file_priv, NULL,
+ arg->user_data);
if (!e) {
ret = -ENOMEM;
goto out;