drm/i915: Convert to atomic, part 2.
Subsystems (3)
Maarten Lankhorst
maintainerv2 cover drm/i915: Convert to atomic, part 2.
I made a small mistake in the original ordering of this series. This resulted in patches trying to do too much, and things became too confusing. I removed the atomic plane conversion patches, and changed ordering.
The new ordering should be more logical, instead of converting planes to atomic first I do it after this series, to reduce the review burden on this series and to unblock others.
The goal of this patch series is to implement hardware readout using atomic state, and restore sw state with a call to intel_set_mode.
After that's done intel_crtc_toggle can be safely converted to atomic modeset, because nothing relies on transitional state any more.
This series contains everything except conversion to atomic planes and almost all of the crtc->config and crtc->active removal patches are removed too, I need to split those up some more.
Ander Conselvan de Oliveira (6):
drm/i915: Set mode_changed for audio in intel_modeset_pipe_config() drm/i915: Make __intel_set_mode() take only atomic state as argument drm/i915: Support modeset across multiple pipes
drm/i915: Use global atomic state for staged pll config drm/i915: Read hw state into an atomic state struct drm/i915: Move cdclk and pll setup to intel_modeset_compute_config()
Maarten Lankhorst (11):
drm/atomic: update crtc->hwmode in legacy state drm/atomic: Allow drivers to subclass drm_atomic_state, v2 drm/i915: get rid of put_shared_dpll
drm/i915: get rid of intel_crtc_disable and related code, v2 drm/i915: use intel_crtc_control everywhere drm/i915: Use drm_atomic_helper_update_legacy_modeset_state drm/i915: Use crtc_state->active instead of crtc_state->enable drm/i915: Implement intel_crtc_toggle using atomic state, v3 drm/i915: Calculate haswell plane workaround, v2. drm/i915: Use crtc->hwmode for vblanks.
drm/i915: Remove use of crtc->config from i915_debugfs.c
drivers/gpu/drm/drm_atomic.c | 116 +++- drivers/gpu/drm/drm_atomic_helper.c | 1 + drivers/gpu/drm/i915/i915_debugfs.c | 50 +- drivers/gpu/drm/i915/i915_drv.h | 2 - drivers/gpu/drm/i915/i915_irq.c | 13 +- drivers/gpu/drm/i915/intel_atomic.c | 49 ++ drivers/gpu/drm/i915/intel_display.c | 1105 ++++++++++++++++------------------ drivers/gpu/drm/i915/intel_drv.h | 32 +- include/drm/drm_atomic.h | 5 + include/drm/drm_crtc.h | 6 + 10 files changed, 729 insertions(+), 650 deletions(-)
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Maarten Lankhorst
maintainerPATCH v2 1/17 drm/atomic: update crtc->hwmode in legacy state
This is useful when calculating vblank in drivers that support it. During a modeset the atomic state may not match the hardware state, so if the driver wants to wait on a vblank they'll want to use crtc->hwmode rather than crtc->state->adjusted_mode.
--- drivers/gpu/drm/drm_atomic_helper.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/drm_atomic_helper.c +1 -0
@@ -673,6 +673,7 @@ drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev,/* set legacy state in the crtc structure */ for_each_crtc_in_state (old_state, crtc, old_crtc_state, i) { crtc->mode = crtc->state->mode; + crtc->hwmode = crtc->state->adjusted_mode; crtc->enabled = crtc->state->enable; crtc->x = crtc->primary->state->src_x >>16 ; crtc->y = crtc->primary->state->src_y >>16 ;
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Maarten Lankhorst
maintainerRe: [PATCH v2 01/17] drm/atomic: update crtc->hwmode in legacy state
Op 13-05-15 om 22:23 schreef Maarten Lankhorst:
Quoted 7 lines
This is useful when calculating vblank in drivers that support it. During a modeset the atomic state may not match the hardware state, so if the driver wants to wait on a vblank they'll want to use
crtc->hwmoderather thancrtc->state->adjusted_mode.Signed-off-by Maarten Lankhorst <[email protected]>
Drop this patch please, after discussion with danvet it seems better to do this inside the intel code of "[PATCH v2 16/17] drm/i915: Use crtc->hwmode for vblanks." instead.
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Maarten Lankhorst
maintainerPATCH v2 2/17 drm/atomic: Allow drivers to subclass drm_atomic_state, v2
In reply to Maarten LankhorstDrivers may need to store the state of shared resources, such as PLLs or FIFO space, into the atomic state. Allow this by making it possible to subclass drm_atomic_state.
Changes since v1:
- Change member names for functions to atomic_state_(alloc,clear)
- Change __drm_atomic_state_new to drm_atomic_state_init
- Allow free function to be overridden too, in case extra memory is allocated in alloc.
--- drivers/gpu/drm/drm_atomic.c | 116 ++++++++++++++++++++++++++++++++----------- include/drm/drm_atomic.h | 5 ++ include/drm/drm_crtc.h | 6 +++ 3 files changed, 99 insertions(+), 28 deletions(-)
drivers/gpu/drm/drm_atomic.c +88 -28
@@ -30,7 +30,15 @@#include <drm/drm_atomic.h> #include <drm/drm_plane_helper.h> -static void kfree_state (struct drm_atomic_state *state) +/** +* drm_atomic_state_default_free - +* free memory initialized by drm_atomic_state_init +* @state: atomic state +* +* Free all the memory allocated by drm_atomic_state_init. +* This is useful for drivers that subclass the atomic state. +*/ +void drm_atomic_state_default_free (struct drm_atomic_state *state) {kfree (state->connectors);kfree (state->connector_states);
@@ -38,24 +46,20 @@ static void kfree_state(struct drm_atomic_state *state)kfree (state->crtc_states);kfree (state->planes);kfree (state->plane_states); -kfree (state); } +EXPORT_SYMBOL (drm_atomic_state_default_free);/** -* drm_atomic_state_alloc - allocate atomic state +* drm_atomic_state_init - init new atomic state * @dev: DRM device +* @state: atomic state * -* This allocates an empty atomic state to track updates. +* Default implementation for filling in a new atomic state. +* This is useful for drivers that subclass the atomic state. */ -struct drm_atomic_state * -drm_atomic_state_alloc (struct drm_device *dev) +int +drm_atomic_state_init (struct drm_device *dev,struct drm_atomic_state *state) { -struct drm_atomic_state *state; - - state =kzalloc (sizeof (*state),GFP_KERNEL ); -if (!state) -return NULL ; -/* TODO legacy paths should maybe do a better job about * setting this appropriately? */
@@ -92,31 +96,50 @@ drm_atomic_state_alloc(struct drm_device *dev) state->dev = dev; -DRM_DEBUG_ATOMIC ("Allocate atomic state %p\n" , state); +DRM_DEBUG_ATOMIC ("Allocated atomic state %p\n" , state); -return state; +return 0 ; fail: -kfree_state (state); +drm_atomic_state_default_free (state); +return -ENOMEM ; +} +EXPORT_SYMBOL (drm_atomic_state_init); + +/** +* drm_atomic_state_alloc - allocate atomic state +* @dev: DRM device +* +* This allocates an empty atomic state to track updates. +*/ +struct drm_atomic_state * +drm_atomic_state_alloc (struct drm_device *dev) +{ +struct drm_mode_config *config = &dev->mode_config; +struct drm_atomic_state *state; + +if (!config->funcs->atomic_state_alloc) { + state =kzalloc (sizeof (*state),GFP_KERNEL ); +if (!state) +return NULL ; +if (drm_atomic_state_init (dev, state) <0 ) { +kfree (state); +return NULL ; + } +return state; + } -return NULL ; +return config->funcs->atomic_state_alloc (dev); }EXPORT_SYMBOL (drm_atomic_state_alloc);/** -* drm_atomic_state_clear - clear state object +* drm_atomic_state_default_clear - clear base atomic state * @state: atomic state * -* When the w/w mutex algorithm detects a deadlock we need to back off and drop -* all locks. So someone else could sneak in and change the current modeset -* configuration. Which means that all the state assembled in @state is no -* longer an atomic update to the current state, but to some arbitrary earlier -* state. Which could break assumptions the driver's ->atomic_check likely -* relies on. -* -* Hence we must clear all cached state and completely start over, using this -* function. +* Default implementation for clearing atomic state. +* This is useful for drivers that subclass the atomic state. */ -void drm_atomic_state_clear (struct drm_atomic_state *state) +void drm_atomic_state_default_clear (struct drm_atomic_state *state) {struct drm_device *dev = state->dev;struct drm_mode_config *config = &dev->mode_config;
@@ -162,6 +185,32 @@ void drm_atomic_state_clear(struct drm_atomic_state *state) state->plane_states[i] =NULL ; } } +EXPORT_SYMBOL (drm_atomic_state_default_clear); + +/** +* drm_atomic_state_clear - clear state object +* @state: atomic state +* +* When the w/w mutex algorithm detects a deadlock we need to back off and drop +* all locks. So someone else could sneak in and change the current modeset +* configuration. Which means that all the state assembled in @state is no +* longer an atomic update to the current state, but to some arbitrary earlier +* state. Which could break assumptions the driver's ->atomic_check likely +* relies on. +* +* Hence we must clear all cached state and completely start over, using this +* function. +*/ +void drm_atomic_state_clear (struct drm_atomic_state *state) +{ +struct drm_device *dev = state->dev; +struct drm_mode_config *config = &dev->mode_config; + +if (config->funcs->atomic_state_clear) + config->funcs->atomic_state_clear (state); +else +drm_atomic_state_default_clear (state); +}EXPORT_SYMBOL (drm_atomic_state_clear);/**
@@ -173,14 +222,25 @@ EXPORT_SYMBOL(drm_atomic_state_clear);*/ void drm_atomic_state_free (struct drm_atomic_state *state) { +struct drm_device *dev; +struct drm_mode_config *config; +if (!state)return ; + dev = state->dev; + config = &dev->mode_config; +drm_atomic_state_clear (state);DRM_DEBUG_ATOMIC ("Freeing atomic state %p\n" , state); -kfree_state (state); +if (config->funcs->atomic_state_free) { + config->funcs->atomic_state_free (state); + }else { +drm_atomic_state_default_free (state); +kfree (state); + } }EXPORT_SYMBOL (drm_atomic_state_free);
include/drm/drm_atomic.h +5 -0
@@ -35,6 +35,11 @@ drm_atomic_state_alloc(struct drm_device *dev);void drm_atomic_state_clear (struct drm_atomic_state *state);void drm_atomic_state_free (struct drm_atomic_state *state); +int __must_check +drm_atomic_state_init (struct drm_device *dev,struct drm_atomic_state *state); +void drm_atomic_state_default_clear (struct drm_atomic_state *state); +void drm_atomic_state_default_free (struct drm_atomic_state *state); +struct drm_crtc_state *__must_check drm_atomic_get_crtc_state (struct drm_atomic_state *state,struct drm_crtc *crtc);
include/drm/drm_crtc.h +6 -0
@@ -985,6 +985,9 @@ struct drm_mode_set {* @atomic_check: check whether a given atomic state update is possible * @atomic_commit: commit an atomic state update previously verified with * atomic_check() +* @atomic_state_alloc: allocate a new atomic state +* @atomic_state_clear: clear the atomic state +* @atomic_state_free: free the atomic state * * Some global (i.e. not per-CRTC, connector, etc) mode setting functions that * involve drivers.
@@ -1000,6 +1003,9 @@ struct drm_mode_config_funcs {int (*atomic_commit)(struct drm_device *dev,struct drm_atomic_state *a,bool async); +struct drm_atomic_state *(*atomic_state_alloc)(struct drm_device *dev); +void (*atomic_state_clear)(struct drm_atomic_state *state); +void (*atomic_state_free)(struct drm_atomic_state *state); };/**
Signature · 6 lines
2.1.0 _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
Maarten Lankhorst
maintainerPATCH v2 2/17 drm/atomic: Allow drivers to subclass drm_atomic_state, v3
Drivers may need to store the state of shared resources, such as PLLs or FIFO space, into the atomic state. Allow this by making it possible to subclass drm_atomic_state.
Changes since v1:
- Change member names for functions to atomic_state_(alloc,clear)
- Change __drm_atomic_state_new to drm_atomic_state_init
- Allow free function to be overridden too, in case extra memory is allocated in alloc.
Changes since v2:
- Rename *_default_free to default_release, to make clear it doesn't free the state object itself.
drivers/gpu/drm/drm_atomic.c +88 -28
@@ -30,7 +30,15 @@#include <drm/drm_atomic.h> #include <drm/drm_plane_helper.h> -static void kfree_state (struct drm_atomic_state *state) +/** +* drm_atomic_state_default_release - +* release memory initialized by drm_atomic_state_init +* @state: atomic state +* +* Free all the memory allocated by drm_atomic_state_init. +* This is useful for drivers that subclass the atomic state. +*/ +void drm_atomic_state_default_release (struct drm_atomic_state *state) {kfree (state->connectors);kfree (state->connector_states);
@@ -38,24 +46,20 @@ static void kfree_state(struct drm_atomic_state *state)kfree (state->crtc_states);kfree (state->planes);kfree (state->plane_states); -kfree (state); } +EXPORT_SYMBOL (drm_atomic_state_default_release);/** -* drm_atomic_state_alloc - allocate atomic state +* drm_atomic_state_init - init new atomic state * @dev: DRM device +* @state: atomic state * -* This allocates an empty atomic state to track updates. +* Default implementation for filling in a new atomic state. +* This is useful for drivers that subclass the atomic state. */ -struct drm_atomic_state * -drm_atomic_state_alloc (struct drm_device *dev) +int +drm_atomic_state_init (struct drm_device *dev,struct drm_atomic_state *state) { -struct drm_atomic_state *state; - - state =kzalloc (sizeof (*state),GFP_KERNEL ); -if (!state) -return NULL ; -/* TODO legacy paths should maybe do a better job about * setting this appropriately? */
@@ -92,31 +96,50 @@ drm_atomic_state_alloc(struct drm_device *dev) state->dev = dev; -DRM_DEBUG_ATOMIC ("Allocate atomic state %p\n" , state); +DRM_DEBUG_ATOMIC ("Allocated atomic state %p\n" , state); -return state; +return 0 ; fail: -kfree_state (state); +drm_atomic_state_default_release (state); +return -ENOMEM ; +} +EXPORT_SYMBOL (drm_atomic_state_init); + +/** +* drm_atomic_state_alloc - allocate atomic state +* @dev: DRM device +* +* This allocates an empty atomic state to track updates. +*/ +struct drm_atomic_state * +drm_atomic_state_alloc (struct drm_device *dev) +{ +struct drm_mode_config *config = &dev->mode_config; +struct drm_atomic_state *state; + +if (!config->funcs->atomic_state_alloc) { + state =kzalloc (sizeof (*state),GFP_KERNEL ); +if (!state) +return NULL ; +if (drm_atomic_state_init (dev, state) <0 ) { +kfree (state); +return NULL ; + } +return state; + } -return NULL ; +return config->funcs->atomic_state_alloc (dev); }EXPORT_SYMBOL (drm_atomic_state_alloc);/** -* drm_atomic_state_clear - clear state object +* drm_atomic_state_default_clear - clear base atomic state * @state: atomic state * -* When the w/w mutex algorithm detects a deadlock we need to back off and drop -* all locks. So someone else could sneak in and change the current modeset -* configuration. Which means that all the state assembled in @state is no -* longer an atomic update to the current state, but to some arbitrary earlier -* state. Which could break assumptions the driver's ->atomic_check likely -* relies on. -* -* Hence we must clear all cached state and completely start over, using this -* function. +* Default implementation for clearing atomic state. +* This is useful for drivers that subclass the atomic state. */ -void drm_atomic_state_clear (struct drm_atomic_state *state) +void drm_atomic_state_default_clear (struct drm_atomic_state *state) {struct drm_device *dev = state->dev;struct drm_mode_config *config = &dev->mode_config;
@@ -162,6 +185,32 @@ void drm_atomic_state_clear(struct drm_atomic_state *state) state->plane_states[i] =NULL ; } } +EXPORT_SYMBOL (drm_atomic_state_default_clear); + +/** +* drm_atomic_state_clear - clear state object +* @state: atomic state +* +* When the w/w mutex algorithm detects a deadlock we need to back off and drop +* all locks. So someone else could sneak in and change the current modeset +* configuration. Which means that all the state assembled in @state is no +* longer an atomic update to the current state, but to some arbitrary earlier +* state. Which could break assumptions the driver's ->atomic_check likely +* relies on. +* +* Hence we must clear all cached state and completely start over, using this +* function. +*/ +void drm_atomic_state_clear (struct drm_atomic_state *state) +{ +struct drm_device *dev = state->dev; +struct drm_mode_config *config = &dev->mode_config; + +if (config->funcs->atomic_state_clear) + config->funcs->atomic_state_clear (state); +else +drm_atomic_state_default_clear (state); +}EXPORT_SYMBOL (drm_atomic_state_clear);/**
@@ -173,14 +222,25 @@ EXPORT_SYMBOL(drm_atomic_state_clear);*/ void drm_atomic_state_free (struct drm_atomic_state *state) { +struct drm_device *dev; +struct drm_mode_config *config; +if (!state)return ; + dev = state->dev; + config = &dev->mode_config; +drm_atomic_state_clear (state);DRM_DEBUG_ATOMIC ("Freeing atomic state %p\n" , state); -kfree_state (state); +if (config->funcs->atomic_state_free) { + config->funcs->atomic_state_free (state); + }else { +drm_atomic_state_default_release (state); +kfree (state); + } }EXPORT_SYMBOL (drm_atomic_state_free);
include/drm/drm_atomic.h +5 -0
@@ -35,6 +35,11 @@ drm_atomic_state_alloc(struct drm_device *dev);void drm_atomic_state_clear (struct drm_atomic_state *state);void drm_atomic_state_free (struct drm_atomic_state *state); +int __must_check +drm_atomic_state_init (struct drm_device *dev,struct drm_atomic_state *state); +void drm_atomic_state_default_clear (struct drm_atomic_state *state); +void drm_atomic_state_default_release (struct drm_atomic_state *state); +struct drm_crtc_state *__must_check drm_atomic_get_crtc_state (struct drm_atomic_state *state,struct drm_crtc *crtc);
include/drm/drm_crtc.h +6 -0
@@ -985,6 +985,9 @@ struct drm_mode_set {* @atomic_check: check whether a given atomic state update is possible * @atomic_commit: commit an atomic state update previously verified with * atomic_check() +* @atomic_state_alloc: allocate a new atomic state +* @atomic_state_clear: clear the atomic state +* @atomic_state_free: free the atomic state * * Some global (i.e. not per-CRTC, connector, etc) mode setting functions that * involve drivers.
@@ -1000,6 +1003,9 @@ struct drm_mode_config_funcs {int (*atomic_commit)(struct drm_device *dev,struct drm_atomic_state *a,bool async); +struct drm_atomic_state *(*atomic_state_alloc)(struct drm_device *dev); +void (*atomic_state_clear)(struct drm_atomic_state *state); +void (*atomic_state_free)(struct drm_atomic_state *state); };/**
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Daniel Vetter
AppliedRe: [PATCH v2 02/17] drm/atomic: Allow drivers to subclass drm_atomic_state, v3
Quoted 4 lines · Maarten Lankhorst
Drivers may need to store the state of shared resources, such as PLLs or FIFO space, into the atomic state. Allow this by making it possible to subclass
drm_atomic_state.
Quoted 8 lines
Changes since v1:
- Change member names for functions toatomic_state_(alloc,clear)
- Change__drm_atomic_state_newtodrm_atomic_state_init
- Allow free function to be overridden too, in case extra memory is allocated in alloc.
Changes since v2:
- Rename*_default_freetodefault_release, to make clear it doesn't free the state object itself.
I'd have gone with just _release since we don't have a ->release hook nor a drm_atomic_helper_state_release wrapper. But that's really a bikeshed now ;-)
Quoted 3 lines
Signed-off-by Maarten Lankhorst <[email protected]>
Applied to topic/drm-misc, thanks.
-Daniel
Quoted 225 lines
drivers/gpu/drm/drm_atomic.c +88
-28@@ -30,7 +30,15 @@#include <drm/drm_atomic.h> #include <drm/drm_plane_helper.h> -static void kfree_state (struct drm_atomic_state *state) +/** +* drm_atomic_state_default_release - +* release memory initialized by drm_atomic_state_init +* @state: atomic state +* +* Free all the memory allocated by drm_atomic_state_init. +* This is useful for drivers that subclass the atomic state. +*/ +void drm_atomic_state_default_release (struct drm_atomic_state *state) {kfree (state->connectors);kfree (state->connector_states);@@ -38,24 +46,20 @@ static void kfree_state(struct drm_atomic_state *state)kfree (state->crtc_states);kfree (state->planes);kfree (state->plane_states); -kfree (state); } +EXPORT_SYMBOL (drm_atomic_state_default_release);/** -* drm_atomic_state_alloc - allocate atomic state +* drm_atomic_state_init - init new atomic state * @dev: DRM device +* @state: atomic state * -* This allocates an empty atomic state to track updates. +* Default implementation for filling in a new atomic state. +* This is useful for drivers that subclass the atomic state. */ -struct drm_atomic_state * -drm_atomic_state_alloc (struct drm_device *dev) +int +drm_atomic_state_init (struct drm_device *dev,struct drm_atomic_state *state) { -struct drm_atomic_state *state; - - state =kzalloc (sizeof (*state),GFP_KERNEL ); -if (!state) -return NULL ; -/* TODO legacy paths should maybe do a better job about * setting this appropriately? */ @@ -92,31 +96,50 @@ drm_atomic_state_alloc(struct drm_device *dev) state->dev = dev; -DRM_DEBUG_ATOMIC ("Allocate atomic state %p\n" , state); +DRM_DEBUG_ATOMIC ("Allocated atomic state %p\n" , state); -return state; +return 0 ; fail: -kfree_state (state); +drm_atomic_state_default_release (state); +return -ENOMEM ; +} +EXPORT_SYMBOL (drm_atomic_state_init); + +/** +* drm_atomic_state_alloc - allocate atomic state +* @dev: DRM device +* +* This allocates an empty atomic state to track updates. +*/ +struct drm_atomic_state * +drm_atomic_state_alloc (struct drm_device *dev) +{ +struct drm_mode_config *config = &dev->mode_config; +struct drm_atomic_state *state; + +if (!config->funcs->atomic_state_alloc) { + state =kzalloc (sizeof (*state),GFP_KERNEL ); +if (!state) +return NULL ; +if (drm_atomic_state_init (dev, state) <0 ) { +kfree (state); +return NULL ; + } +return state; + } -return NULL ; +return config->funcs->atomic_state_alloc (dev); }EXPORT_SYMBOL (drm_atomic_state_alloc);/** -* drm_atomic_state_clear - clear state object +* drm_atomic_state_default_clear - clear base atomic state * @state: atomic state * -* When the w/w mutex algorithm detects a deadlock we need to back off and drop -* all locks. So someone else could sneak in and change the current modeset -* configuration. Which means that all the state assembled in @state is no -* longer an atomic update to the current state, but to some arbitrary earlier -* state. Which could break assumptions the driver's ->atomic_check likely -* relies on. -* -* Hence we must clear all cached state and completely start over, using this -* function. +* Default implementation for clearing atomic state. +* This is useful for drivers that subclass the atomic state. */ -void drm_atomic_state_clear (struct drm_atomic_state *state) +void drm_atomic_state_default_clear (struct drm_atomic_state *state) {struct drm_device *dev = state->dev;struct drm_mode_config *config = &dev->mode_config;@@ -162,6 +185,32 @@ void drm_atomic_state_clear(struct drm_atomic_state *state) state->plane_states[i] =NULL ; } } +EXPORT_SYMBOL (drm_atomic_state_default_clear); + +/** +* drm_atomic_state_clear - clear state object +* @state: atomic state +* +* When the w/w mutex algorithm detects a deadlock we need to back off and drop +* all locks. So someone else could sneak in and change the current modeset +* configuration. Which means that all the state assembled in @state is no +* longer an atomic update to the current state, but to some arbitrary earlier +* state. Which could break assumptions the driver's ->atomic_check likely +* relies on. +* +* Hence we must clear all cached state and completely start over, using this +* function. +*/ +void drm_atomic_state_clear (struct drm_atomic_state *state) +{ +struct drm_device *dev = state->dev; +struct drm_mode_config *config = &dev->mode_config; + +if (config->funcs->atomic_state_clear) + config->funcs->atomic_state_clear (state); +else +drm_atomic_state_default_clear (state); +}EXPORT_SYMBOL (drm_atomic_state_clear);/** @@ -173,14 +222,25 @@ EXPORT_SYMBOL(drm_atomic_state_clear);*/ void drm_atomic_state_free (struct drm_atomic_state *state) { +struct drm_device *dev; +struct drm_mode_config *config; +if (!state)return ; + dev = state->dev; + config = &dev->mode_config; +drm_atomic_state_clear (state);DRM_DEBUG_ATOMIC ("Freeing atomic state %p\n" , state); -kfree_state (state); +if (config->funcs->atomic_state_free) { + config->funcs->atomic_state_free (state); + }else { +drm_atomic_state_default_release (state); +kfree (state); + } }EXPORT_SYMBOL (drm_atomic_state_free);include/drm/drm_atomic.h +5
-0@@ -35,6 +35,11 @@ drm_atomic_state_alloc(struct drm_device *dev);void drm_atomic_state_clear (struct drm_atomic_state *state);void drm_atomic_state_free (struct drm_atomic_state *state); +int __must_check +drm_atomic_state_init (struct drm_device *dev,struct drm_atomic_state *state); +void drm_atomic_state_default_clear (struct drm_atomic_state *state); +void drm_atomic_state_default_release (struct drm_atomic_state *state); +struct drm_crtc_state *__must_check drm_atomic_get_crtc_state (struct drm_atomic_state *state,struct drm_crtc *crtc);include/drm/drm_crtc.h +6
-0@@ -985,6 +985,9 @@ struct drm_mode_set {* @atomic_check: check whether a given atomic state update is possible * @atomic_commit: commit an atomic state update previously verified with * atomic_check() +* @atomic_state_alloc: allocate a new atomic state +* @atomic_state_clear: clear the atomic state +* @atomic_state_free: free the atomic state * * Some global (i.e. not per-CRTC, connector, etc) mode setting functions that * involve drivers. @@ -1000,6 +1003,9 @@ struct drm_mode_config_funcs {int (*atomic_commit)(struct drm_device *dev,struct drm_atomic_state *a,bool async); +struct drm_atomic_state *(*atomic_state_alloc)(struct drm_device *dev); +void (*atomic_state_clear)(struct drm_atomic_state *state); +void (*atomic_state_free)(struct drm_atomic_state *state); };/** _______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Signature · 7 lines
Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Maarten Lankhorst
maintainerPATCH v2 3/17 drm/i915: get rid of put_shared_dpll
In reply to Maarten LankhorstNow that the pll updates are staged the put_shared_dpll function consists only of checks that are done in check_shared_dpll_state after a modeset too.
The changes to pll->config are overwritten by intel_shared_dpll_commit, so this entire function is a noop.
--- drivers/gpu/drm/i915/intel_display.c | 34 +++------------------------------- drivers/gpu/drm/i915/intel_drv.h | 1 - 2 files changed, 3 insertions(+), 32 deletions(-)
drivers/gpu/drm/i915/intel_display.c +3 -31
@@ -4239,27 +4239,6 @@ static void lpt_pch_enable(struct drm_crtc *crtc)lpt_enable_pch_transcoder (dev_priv, cpu_transcoder); } -void intel_put_shared_dpll (struct intel_crtc *crtc) -{ -struct intel_shared_dpll *pll =intel_crtc_to_shared_dpll (crtc); - -if (pll ==NULL ) -return ; - -if (!(pll->config.crtc_mask & (1 << crtc->pipe))) { -WARN (1 ,"bad %s crtc mask\n" , pll->name); -return ; - } - - pll->config.crtc_mask &= ~(1 << crtc->pipe); -if (pll->config.crtc_mask ==0 ) { -WARN_ON (pll->on); -WARN_ON (pll->active); - } - - crtc->config->shared_dpll =DPLL_ID_PRIVATE ; -} -struct intel_shared_dpll *intel_get_shared_dpll (struct intel_crtc *crtc,struct intel_crtc_state *crtc_state) {
@@ -5235,13 +5214,6 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)intel_disable_shared_dpll (intel_crtc); } -static void ironlake_crtc_off (struct drm_crtc *crtc) -{ -struct intel_crtc *intel_crtc =to_intel_crtc (crtc); -intel_put_shared_dpll (intel_crtc); -} - -static void i9xx_pfit_enable (struct intel_crtc *crtc) {struct drm_device *dev = crtc->base.dev;
@@ -14084,7 +14056,7 @@ static void intel_init_display(struct drm_device *dev) haswell_crtc_compute_clock; dev_priv->display.crtc_enable = haswell_crtc_enable; dev_priv->display.crtc_disable = haswell_crtc_disable; - dev_priv->display.off = ironlake_crtc_off; + dev_priv->display.off = i9xx_crtc_off; dev_priv->display.update_primary_plane = skylake_update_primary_plane; }else if (HAS_DDI (dev)) {
@@ -14095,7 +14067,7 @@ static void intel_init_display(struct drm_device *dev) haswell_crtc_compute_clock; dev_priv->display.crtc_enable = haswell_crtc_enable; dev_priv->display.crtc_disable = haswell_crtc_disable; - dev_priv->display.off = ironlake_crtc_off; + dev_priv->display.off = i9xx_crtc_off; dev_priv->display.update_primary_plane = ironlake_update_primary_plane; }else if (HAS_PCH_SPLIT (dev)) {
@@ -14106,7 +14078,7 @@ static void intel_init_display(struct drm_device *dev) ironlake_crtc_compute_clock; dev_priv->display.crtc_enable = ironlake_crtc_enable; dev_priv->display.crtc_disable = ironlake_crtc_disable; - dev_priv->display.off = ironlake_crtc_off; + dev_priv->display.off = i9xx_crtc_off; dev_priv->display.update_primary_plane = ironlake_update_primary_plane; }else if (IS_VALLEYVIEW (dev)) {
drivers/gpu/drm/i915/intel_drv.h +0 -1
@@ -1082,7 +1082,6 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv,#define assert_shared_dpll_disabled (d, p) assert_shared_dpll(d, p, false)struct intel_shared_dpll *intel_get_shared_dpll (struct intel_crtc *crtc,struct intel_crtc_state *state); -void intel_put_shared_dpll (struct intel_crtc *crtc);void vlv_force_pll_on (struct drm_device *dev,enum pipe pipe,const struct dpll *dpll);
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Maarten Lankhorst
maintainerPATCH v2 4/17 drm/i915: get rid of intel_crtc_disable and related code, v2
In reply to Maarten LankhorstNow that the dpll updates are (mostly) atomic, the .off() code is a noop, and intel_crtc_disable does mostly the same as intel_modeset_update_state.
Move all logic for connectors_active and setting dpms to that function.
Changes since v1:
- Move drm_atomic_helper_swap_state up.
Changes since v2:
- Split out intel_put_shared_dpll removal.
--- drivers/gpu/drm/i915/i915_drv.h | 1 - drivers/gpu/drm/i915/intel_display.c | 75 ++++++++---------------------------- 2 files changed, 15 insertions(+), 61 deletions(-)
drivers/gpu/drm/i915/i915_drv.h +0 -1
@@ -574,7 +574,6 @@ struct drm_i915_display_funcs { struct intel_crtc_state *crtc_state);void (*crtc_enable)(struct drm_crtc *crtc);void (*crtc_disable)(struct drm_crtc *crtc); -void (*off)(struct drm_crtc *crtc);void (*audio_codec_enable)(struct drm_connector *connector,struct intel_encoder *encoder,struct drm_display_mode *mode);
drivers/gpu/drm/i915/intel_display.c +15 -60
155 lines not on this page · raw message
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Maarten Lankhorst
maintainerPATCH v2 5/17 drm/i915: use intel_crtc_control everywhere
In reply to Maarten LankhorstHaving a single path for everything makes it a lot easier to keep crtc_state->active in sync with intel_crtc->active.
A crtc cannot be changed to active when not enabled, because it means no mode is set and no connectors are connected.
This should also make intel_crtc->active match crtc_state->active.
--- drivers/gpu/drm/i915/i915_debugfs.c | 18 ++++++++-- drivers/gpu/drm/i915/intel_display.c | 64 +++++++++++++----------------------- drivers/gpu/drm/i915/intel_drv.h | 1 - 3 files changed, 37 insertions(+), 46 deletions(-)
drivers/gpu/drm/i915/i915_debugfs.c +15 -3
@@ -3606,12 +3606,18 @@ static void hsw_trans_edp_pipe_A_crc_wa(struct drm_device *dev)*/ if (crtc->config->cpu_transcoder ==TRANSCODER_EDP && !crtc->config->pch_pfit.enabled) { +bool active = crtc->active; + +if (active) +intel_crtc_control (&crtc->base, false); + crtc->config->pch_pfit.force_thru = true;intel_display_power_get (dev_priv,POWER_DOMAIN_PIPE_PANEL_FITTER (PIPE_A )); -intel_crtc_reset (crtc); +if (active) +intel_crtc_control (&crtc->base, true); }drm_modeset_unlock_all (dev); }
@@ -3630,12 +3636,18 @@ static void hsw_undo_trans_edp_pipe_A_crc_wa(struct drm_device *dev)* routing. */ if (crtc->config->pch_pfit.force_thru) { - crtc->config->pch_pfit.force_thru = false; +bool active = crtc->active; -intel_crtc_reset (crtc); +if (active) +intel_crtc_control (&crtc->base, false); + + crtc->config->pch_pfit.force_thru = false;intel_display_power_put (dev_priv,POWER_DOMAIN_PIPE_PANEL_FITTER (PIPE_A )); + +if (active) +intel_crtc_control (&crtc->base, true); }drm_modeset_unlock_all (dev); }
drivers/gpu/drm/i915/intel_display.c +22 -42
104 lines not on this page · raw message
drivers/gpu/drm/i915/intel_drv.h +0 -1
@@ -993,7 +993,6 @@ void intel_mark_busy(struct drm_device *dev);void intel_mark_idle (struct drm_device *dev);void intel_crtc_restore_mode (struct drm_crtc *crtc);void intel_crtc_control (struct drm_crtc *crtc,bool enable); -void intel_crtc_reset (struct intel_crtc *crtc);void intel_crtc_update_dpms (struct drm_crtc *crtc);void intel_encoder_destroy (struct drm_encoder *encoder);int intel_connector_init (struct intel_connector *);
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Maarten Lankhorst
maintainerPATCH v2 6/17 drm/i915: Use drm_atomic_helper_update_legacy_modeset_state
In reply to Maarten LankhorstNow that the helper is exported there's no need to duplicate this code any more.
--- drivers/gpu/drm/i915/intel_display.c | 61 +++--------------------------------- 1 file changed, 4 insertions(+), 57 deletions(-)
drivers/gpu/drm/i915/intel_display.c +4 -57
@@ -11088,43 +11088,6 @@ static void intel_modeset_update_connector_atomic_state(struct drm_device *dev) } } -/* Fixup legacy state after an atomic state swap. -*/ -static void intel_modeset_fixup_state (struct drm_atomic_state *state) -{ -struct intel_crtc *crtc; -struct intel_encoder *encoder; -struct intel_connector *connector; - -for_each_intel_connector (state->dev, connector) { - connector->base.encoder = connector->base.state->best_encoder; -if (connector->base.encoder) - connector->base.encoder->crtc = - connector->base.state->crtc; - } - -/* Update crtc of disabled encoders */ -for_each_intel_encoder (state->dev, encoder) { -int num_connectors =0 ; - -for_each_intel_connector (state->dev, connector) -if (connector->base.encoder == &encoder->base) - num_connectors++; - -if (num_connectors ==0 ) - encoder->base.crtc =NULL ; - } - -for_each_intel_crtc (state->dev, crtc) { - crtc->base.enabled = crtc->base.state->enable; - crtc->config =to_intel_crtc_state (crtc->base.state); - } - -/* Copy the new configuration to the staged state, to keep the few -* pieces of code that haven't been converted yet happy */ -intel_modeset_update_staged_output_state (state->dev); -} -static void connected_sink_compute_bpp (struct intel_connector *connector,struct intel_crtc_state *pipe_config)
@@ -11571,11 +11534,14 @@ intel_modeset_update_state(struct drm_atomic_state *state) intel_encoder->connectors_active = false; } -intel_modeset_fixup_state (state); +intel_modeset_update_staged_output_state (state->dev); +drm_atomic_helper_update_legacy_modeset_state (state->dev, state);/* Double check state. */ for_each_crtc (dev, crtc) {WARN_ON (crtc->state->enable !=intel_crtc_in_use (crtc)); + +to_intel_crtc (crtc)->config =to_intel_crtc_state (crtc->state); }list_for_each_entry (connector, &dev->mode_config.connector_list, head) {
@@ -12282,25 +12248,6 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,drm_plane_helper_disable (crtc->primary); } -/* crtc->mode is already used by the ->mode_set callbacks, hence we need -* to set it here already despite that we pass it down the callchain. -* -* Note we'll need to fix this up when we start tracking multiple -* pipes; here we assume a single modeset_pipe and only track the -* single crtc and mode. -*/ -if (pipe_config->base.enable &&needs_modeset (&pipe_config->base)) { - modeset_crtc->mode = pipe_config->base.mode; - -/* -* Calculate and store various constants which -* are later needed by vblank and swap-completion -* timestamping. They are derived from true hwmode. -*/ -drm_calc_timestamping_constants (modeset_crtc, - &pipe_config->base.adjusted_mode); - } -/* Only after disabling all output pipelines that will be changed can we * update the the output configuration. */ intel_modeset_update_state (state);
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Maarten Lankhorst
maintainerPATCH v2 7/17 drm/i915: Use crtc_state->active instead of crtc_state->enable
In reply to Maarten Lankhorstcrtc_state->enable means a crtc is configured, but it may be turned off for dpms. Until the previous commit crtc_state->active was not updated on crtc off, but now that we do we should use that for tracking whether a crtc is scanning out or not.
At this point crtc->active should mirror crtc_state->active, so some paranoia from the crtc_disable functions can be removed.
Note that intel_set_mode_setup_plls still checks for ->enable, because all resources that are needed have to be calculated, so dpms changes will still succeed.
--- drivers/gpu/drm/i915/i915_irq.c | 2 +- drivers/gpu/drm/i915/intel_display.c | 44 ++++++++++++++++++------------------ 2 files changed, 23 insertions(+), 23 deletions(-)
drivers/gpu/drm/i915/i915_irq.c +1 -1
@@ -796,7 +796,7 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,return -EINVAL ; } -if (!crtc->state->enable) { +if (!crtc->state->active) {DRM_DEBUG_KMS ("crtc %d is disabled\n" , pipe);return -EBUSY ; }
drivers/gpu/drm/i915/intel_display.c +22 -22
140 lines not on this page · raw message
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH v2 07/17] drm/i915: Use crtc_state->active instead of crtc_state->enable
Quoted 5 lines · Maarten Lankhorst
crtc_state->enablemeans a crtc is configured, but it may be turned off for dpms. Until the previous commitcrtc_state->activewas not updated on crtc off, but now that we do we should use that for tracking whether a crtc is scanning out or not.
Quoted 8 lines
At this point
crtc->activeshould mirrorcrtc_state->active, so some paranoia from thecrtc_disablefunctions can be removed.Note that
intel_set_mode_setup_pllsstill checks for ->enable, because all resources that are needed have to be calculated, so dpms changes will still succeed.Signed-off-by Maarten Lankhorst <[email protected]>
A few detail comments below.
-Daniel
Quoted 10 lines
--- drivers/gpu/drm/i915/i915_irq.c | 2 +- drivers/gpu/drm/i915/intel_display.c | 44 ++++++++++++++++++------------------ 2 files changed, 23 insertions(+), 23 deletions(-)drivers/gpu/drm/i915/i915_irq.c +0
-0
drivers/gpu/drm/i915/i915_irq.c static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe, · line 799
Quoted 5 lines
drivers/gpu/drm/i915/i915_irq.c +1
-1@@ -796,7 +796,7 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,return -EINVAL ; } -if (!crtc->state->enable) { +if (!crtc->state->active) {
This change looks unjustified I think.
Quoted 57 lines
drivers/gpu/drm/i915/i915_irq.c +0
-0DRM_DEBUG_KMS ("crtc %d is disabled\n" , pipe);return -EBUSY ; }drivers/gpu/drm/i915/intel_display.c +5
-9@@ -4667,7 +4667,7 @@ static void intel_crtc_load_lut(struct drm_crtc *crtc)bool reenable_ips = false;/* The clocks have to be on to load the palette. */ -if (!crtc->state->enable || !intel_crtc->active) +if (!crtc->state->active)return ;if (HAS_GMCH_DISPLAY (dev_priv->dev)) {@@ -4872,9 +4872,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)struct intel_encoder *encoder;int pipe = intel_crtc->pipe; -WARN_ON (!crtc->state->enable); - -if (intel_crtc->active) +if (WARN_ON (intel_crtc->active))return ;if (intel_crtc->config->has_pch_encoder)@@ -4978,9 +4976,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)struct intel_encoder *encoder;int pipe = intel_crtc->pipe; -WARN_ON (!crtc->state->enable); - -if (intel_crtc->active) +if (WARN_ON (intel_crtc->active))return ;if (intel_crtc_to_shared_dpll (intel_crtc))@@ -5082,7 +5078,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)int pipe = intel_crtc->pipe;u32 reg, temp; -if (!intel_crtc->active) +if (WARN_ON (!intel_crtc->active))return ;for_each_encoder_on_crtc (dev, crtc, encoder)@@ -5144,7 +5140,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)struct intel_encoder *encoder;enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; -if (!intel_crtc->active) +if (WARN_ON (!intel_crtc->active))return ;for_each_encoder_on_crtc (dev, crtc, encoder) {
drivers/gpu/drm/i915/intel_display.c static int valleyview_modeset_global_pipes(struct drm_atomic_state *state) · line 5741
Quoted 5 lines
drivers/gpu/drm/i915/intel_display.c +1
-1@@ -5742,7 +5738,7 @@ static int valleyview_modeset_global_pipes(struct drm_atomic_state *state)/* add all active pipes to the state */ for_each_crtc (state->dev, crtc) { -if (!crtc->state->enable) +if (!crtc->state->active)
This is a functional change to the cdclk code and might break it and/or conflict with the ongoing cdclk work from Ville/Mika. Definitely needs to be split out.
drivers/gpu/drm/i915/intel_display.c static int valleyview_modeset_global_pipes(struct drm_atomic_state *state) · line 5752
Quoted 10 lines
drivers/gpu/drm/i915/intel_display.c +1
-1continue ; crtc_state =drm_atomic_get_crtc_state (state, crtc);@@ -5752,7 +5748,7 @@ static int valleyview_modeset_global_pipes(struct drm_atomic_state *state)/* disable/enable all currently active pipes while we change cdclk */ for_each_crtc_in_state (state, crtc, crtc_state, i) -if (crtc_state->enable) +if (crtc_state->active) crtc_state->mode_changed = true;
Same here.
Hm, aside of all that maybe we should drop vlv_modeset_global_pipes and instead just look at crtc_state->mode_changed? That way we don't need to duplicate the same checks twice, once to set ->mode_changed and once to for the prepare_pipes mask. Or is that duplication already getting removed?
Quoted 98 lines
drivers/gpu/drm/i915/intel_display.c +15
-11return 0 ;@@ -5840,9 +5836,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)int pipe = intel_crtc->pipe;bool is_dsi; -WARN_ON (!crtc->state->enable); - -if (intel_crtc->active) +if (WARN_ON (intel_crtc->active))return ; is_dsi =intel_pipe_has_type (intel_crtc,INTEL_OUTPUT_DSI );@@ -5918,9 +5912,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)struct intel_encoder *encoder;int pipe = intel_crtc->pipe; -WARN_ON (!crtc->state->enable); - -if (intel_crtc->active) +if (WARN_ON (intel_crtc->active))return ;i9xx_set_pll_dividers (intel_crtc);@@ -5980,7 +5972,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)struct intel_encoder *encoder;int pipe = intel_crtc->pipe; -if (!intel_crtc->active) +if (WARN_ON (!intel_crtc->active))return ;/* @@ -11553,7 +11545,7 @@ intel_modeset_update_state(struct drm_atomic_state *state)if (!crtc_state || !needs_modeset (crtc->state))continue ; -if (crtc->state->enable) { +if (crtc->state->active) {struct drm_property *dpms_property = dev->mode_config.dpms_property;@@ -11970,6 +11962,10 @@ check_crtc_state(struct drm_device *dev)"crtc active state doesn't match with hw state " "(expected %i, found %i)\n", crtc->active, active); +I915_STATE_WARN (crtc->active != crtc->base.state->active, +"transitional active state does not match atomic hw state " +"(expected %i, found %i)\n" , crtc->base.state->active, crtc->active); +if (active && !intel_pipe_config_compare (dev, crtc->config, &pipe_config)) {I915_STATE_WARN (1 ,"pipe state doesn't match!\n" );@@ -12115,6 +12111,10 @@ intel_modeset_compute_config(struct drm_crtc *crtc,if (IS_ERR (pipe_config))return pipe_config; +if (!pipe_config->base.enable && +WARN_ON (pipe_config->base.active)) + pipe_config->base.active = false; +if (!pipe_config->base.enable)return pipe_config;@@ -12239,7 +12239,7 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,return ret;for_each_crtc_in_state (state, crtc, crtc_state, i) { -if (!needs_modeset (crtc_state)) +if (!needs_modeset (crtc_state) || !crtc->state->active)continue ;intel_crtc_disable_planes (crtc);@@ -12261,7 +12261,7 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,/* Now enable the clocks, plane, pipe, and connectors that we set up. */ for_each_crtc_in_state (state, crtc, crtc_state, i) { -if (!needs_modeset (crtc->state) || !crtc->state->enable) +if (!needs_modeset (crtc->state) || !crtc->state->active)continue ;update_scanline_offset (to_intel_crtc (crtc));@@ -14494,7 +14494,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)* have active connectors/encoders. */ intel_crtc_update_dpms (&crtc->base); -if (crtc->active != crtc->base.state->enable) { +if (crtc->active != crtc->base.state->active) {struct intel_encoder *encoder;/* This can happen either due to bugs in the get_hw_state Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Signature · 7 lines
Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Maarten Lankhorst
maintainerRe: [PATCH v2 07/17] drm/i915: Use crtc_state->active instead of crtc_state->enable
Op 18-05-15 om 17:30 schreef Daniel Vetter:
Quoted 30 lines · Maarten Lankhorst
Quoted 5 lines
crtc_state->enablemeans a crtc is configured, but it may be turned off for dpms. Until the previous commitcrtc_state->activewas not updated on crtc off, but now that we do we should use that for tracking whether a crtc is scanning out or not.Quoted 8 lines
At this point
crtc->activeshould mirrorcrtc_state->active, so some paranoia from thecrtc_disablefunctions can be removed.Note that
intel_set_mode_setup_pllsstill checks for ->enable, because all resources that are needed have to be calculated, so dpms changes will still succeed.Signed-off-by Maarten Lankhorst <[email protected]>A few detail comments below.
-DanielQuoted 13 lines
--- drivers/gpu/drm/i915/i915_irq.c | 2 +- drivers/gpu/drm/i915/intel_display.c | 44 ++++++++++++++++++------------------ 2 files changed, 23 insertions(+), 23 deletions(-)drivers/gpu/drm/i915/i915_irq.c +0
-0@@ -796,7 +796,7 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,return -EINVAL ; }
Quoted 3 lines
drivers/gpu/drm/i915/i915_irq.c static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe, · line 799
Quoted 2 lines
drivers/gpu/drm/i915/i915_irq.c +1
-1-if (!crtc->state->enable) { +if (!crtc->state->active) {This change looks unjustified I think.
Why? Can you get a vblank on crtc that is dpms off? I think not..
Either way later on I use hwmode->crtc_clock which renders this moot.
Quoted 10 lines
drivers/gpu/drm/i915/i915_irq.c static int valleyview_modeset_global_pipes(struct drm_atomic_state *state) · line 5741
Quoted 7 lines
<snip>
drivers/gpu/drm/i915/i915_irq.c +1
-1@@ -5742,7 +5738,7 @@ static int valleyview_modeset_global_pipes(struct drm_atomic_state *state)/* add all active pipes to the state */ for_each_crtc (state->dev, crtc) { -if (!crtc->state->enable) +if (!crtc->state->active)This is a functional change to the cdclk code and might break it and/or conflict with the ongoing cdclk work from Ville/Mika. Definitely needs to be split out.
No this function just sets mode_changed on all active crtc's.
This is done to turn them off while changing the clock. In case they're already turned off you don't have to turn them off.
Quoted 12 lines
drivers/gpu/drm/i915/i915_irq.c static int valleyview_modeset_global_pipes(struct drm_atomic_state *state) · line 5752
Quoted 10 lines
drivers/gpu/drm/i915/i915_irq.c +1
-1continue ; crtc_state =drm_atomic_get_crtc_state (state, crtc);@@ -5752,7 +5748,7 @@ static int valleyview_modeset_global_pipes(struct drm_atomic_state *state)/* disable/enable all currently active pipes while we change cdclk */ for_each_crtc_in_state (state, crtc, crtc_state, i) -if (crtc_state->enable) +if (crtc_state->active) crtc_state->mode_changed = true;Same here.
Quoted 5 lines
Hm, aside of all that maybe we should drop
vlv_modeset_global_pipesand instead just look atcrtc_state->mode_changed? That way we don't need to duplicate the same checks twice, once to set ->mode_changed and once to for theprepare_pipesmask. Or is that duplication already getting removed?
I think we could get rid of a lot of those extra loops if we want to later, but for now readability is more important.
~Maarten
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH v2 07/17] drm/i915: Use crtc_state->active instead of crtc_state->enable
Quoted 63 lines · Maarten Lankhorst
Op 18-05-15 om 17:30 schreef Daniel Vetter:
Quoted 30 lines · Maarten Lankhorst
Quoted 5 lines
crtc_state->enablemeans a crtc is configured, but it may be turned off for dpms. Until the previous commitcrtc_state->activewas not updated on crtc off, but now that we do we should use that for tracking whether a crtc is scanning out or not.Quoted 8 lines
At this point
crtc->activeshould mirrorcrtc_state->active, so some paranoia from thecrtc_disablefunctions can be removed.Note that
intel_set_mode_setup_pllsstill checks for ->enable, because all resources that are needed have to be calculated, so dpms changes will still succeed.Signed-off-by Maarten Lankhorst <[email protected]>A few detail comments below.
-DanielQuoted 13 lines
--- drivers/gpu/drm/i915/i915_irq.c | 2 +- drivers/gpu/drm/i915/intel_display.c | 44 ++++++++++++++++++------------------ 2 files changed, 23 insertions(+), 23 deletions(-)drivers/gpu/drm/i915/i915_irq.c +0
-0@@ -796,7 +796,7 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,return -EINVAL ; }Quoted 3 lines
drivers/gpu/drm/i915/i915_irq.c static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe, · line 799
Quoted 2 lines
drivers/gpu/drm/i915/i915_irq.c +1
-1-if (!crtc->state->enable) { +if (!crtc->state->active) {This change looks unjustified I think.
Why? Can you get a vblank on crtc that is dpms off? I think not..
Either way later on I use
hwmode->crtc_clockwhich renders this moot.Quoted 10 lines
drivers/gpu/drm/i915/i915_irq.c static int valleyview_modeset_global_pipes(struct drm_atomic_state *state) · line 5741
Quoted 7 lines
<snip>
drivers/gpu/drm/i915/i915_irq.c +1
-1@@ -5742,7 +5738,7 @@ static int valleyview_modeset_global_pipes(struct drm_atomic_state *state)/* add all active pipes to the state */ for_each_crtc (state->dev, crtc) { -if (!crtc->state->enable) +if (!crtc->state->active)This is a functional change to the cdclk code and might break it and/or conflict with the ongoing cdclk work from Ville/Mika. Definitely needs to be split out.
No this function just sets
mode_changedon all active crtc's.This is done to turn them off while changing the clock. In case they're already turned off you don't have to turn them off.
Quoted 12 lines
drivers/gpu/drm/i915/i915_irq.c static int valleyview_modeset_global_pipes(struct drm_atomic_state *state) · line 5752
Quoted 10 lines
drivers/gpu/drm/i915/i915_irq.c +1
-1continue ; crtc_state =drm_atomic_get_crtc_state (state, crtc);@@ -5752,7 +5748,7 @@ static int valleyview_modeset_global_pipes(struct drm_atomic_state *state)/* disable/enable all currently active pipes while we change cdclk */ for_each_crtc_in_state (state, crtc, crtc_state, i) -if (crtc_state->enable) +if (crtc_state->active) crtc_state->mode_changed = true;Same here.
Quoted 7 lines
Quoted 5 lines
Hm, aside of all that maybe we should drop
vlv_modeset_global_pipesand instead just look atcrtc_state->mode_changed? That way we don't need to duplicate the same checks twice, once to set ->mode_changed and once to for theprepare_pipesmask. Or is that duplication already getting removed?I think we could get rid of a lot of those extra loops if we want to later, but for now readability is more important.
Hm makes sense with your replies - there's a few cases indeed where we need to switch from checking ->enable to ->active if we start using the mode_set machinery for dpms. I think it'd be good to explain that a bit in the commit message for all the different cases, so that reviewers can go hunting for more and make sure there aren't ;-)
-Daniel
Signature · 7 lines
Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Maarten Lankhorst
maintainerPATCH v2 8/17 drm/i915: Set mode_changed for audio in intel_modeset_pipe_config()
In reply to Maarten LankhorstFrom: Ander Conselvan de Oliveira <[email protected]>
A follow up patch will make intel_modeset_compute_config() deal with multiple crtcs, so move crtc specific stuff into the lower level crtc specific function.
--- drivers/gpu/drm/i915/intel_display.c | 51 ++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 23 deletions(-)
drivers/gpu/drm/i915/intel_display.c +28 -23
@@ -427,6 +427,12 @@ static void vlv_clock(int refclk, intel_clock_t *clock) clock->dot =DIV_ROUND_CLOSEST (clock->vco, clock->p); } +static bool +needs_modeset (struct drm_crtc_state *state) +{ +return state->mode_changed || state->active_changed; +} +/** * Returns whether any output on the specified pipe is of the specified type */
@@ -11387,6 +11393,15 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,return -EINVAL ; } +/* +* XXX: Add all connectors to make the crtc state match the encoders. +*/ +if (!needs_modeset (&pipe_config->base)) { + ret =drm_atomic_add_affected_connectors (state, crtc); +if (ret) +return ret; + } +clear_intel_crtc_state (pipe_config); pipe_config->cpu_transcoder =
@@ -11478,6 +11493,18 @@ encoder_retry:DRM_DEBUG_KMS ("plane bpp: %i, pipe bpp: %i, dithering: %i\n" , base_bpp, pipe_config->pipe_bpp, pipe_config->dither); +/* Check if we need to force a modeset */ +if (pipe_config->has_audio != +to_intel_crtc_state (crtc->state)->has_audio) + pipe_config->base.mode_changed = true; + +/* +* Note we have an issue here with infoframes: current code +* only updates them on the full mode set path per hw +* requirements. So here we should be checking for any +* required changes and forcing a mode set. +*/ +return 0 ; fail:return ret;
@@ -11495,12 +11522,6 @@ static bool intel_crtc_in_use(struct drm_crtc *crtc)return false; } -static bool -needs_modeset (struct drm_crtc_state *state) -{ -return state->mode_changed || state->active_changed; -} -static void intel_modeset_update_state (struct drm_atomic_state *state) {
@@ -12093,10 +12114,6 @@ intel_modeset_compute_config(struct drm_crtc *crtc,struct intel_crtc_state *pipe_config;int ret =0 ; - ret =drm_atomic_add_affected_connectors (state, crtc); -if (ret) -return ERR_PTR (ret); - ret =drm_atomic_helper_check_modeset (state->dev, state);if (ret)return ERR_PTR (ret);
@@ -12122,19 +12139,7 @@ intel_modeset_compute_config(struct drm_crtc *crtc,if (ret)return ERR_PTR (ret); -/* Check things that can only be changed through modeset */ -if (pipe_config->has_audio != -to_intel_crtc (crtc)->config->has_audio) - pipe_config->base.mode_changed = true; - -/* -* Note we have an issue here with infoframes: current code -* only updates them on the full mode set path per hw -* requirements. So here we should be checking for any -* required changes and forcing a mode set. -*/ - -intel_dump_pipe_config (to_intel_crtc (crtc), pipe_config,"[modeset]" ); +intel_dump_pipe_config (to_intel_crtc (crtc), pipe_config,"[modeset]" ); ret =drm_atomic_helper_check_planes (state->dev, state);if (ret)
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH v2 08/17] drm/i915: Set mode_changed for audio in intel_modeset_pipe_config()
Quoted 30 lines · Maarten Lankhorst
From: Ander Conselvan de Oliveira <[email protected]>
A follow up patch will make
intel_modeset_compute_config()deal with multiple crtcs, so move crtc specific stuff into the lower level crtc specific function.Signed-off-by Maarten Lankhorst <[email protected]>--- drivers/gpu/drm/i915/intel_display.c | 51 ++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 23 deletions(-)drivers/gpu/drm/i915/intel_display.c +6
-0@@ -427,6 +427,12 @@ static void vlv_clock(int refclk, intel_clock_t *clock) clock->dot =DIV_ROUND_CLOSEST (clock->vco, clock->p); } +static bool +needs_modeset (struct drm_crtc_state *state) +{ +return state->mode_changed || state->active_changed; +} +/** * Returns whether any output on the specified pipe is of the specified type */ @@ -11387,6 +11393,15 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,return -EINVAL ;
drivers/gpu/drm/i915/intel_display.c intel_modeset_pipe_config(struct drm_crtc *crtc, · line 11403
Quoted 10 lines
drivers/gpu/drm/i915/intel_display.c +8
-0} +/* +* XXX: Add all connectors to make the crtc state match the encoders. +*/ +if (!needs_modeset (&pipe_config->base)) { + ret =drm_atomic_add_affected_connectors (state, crtc); +if (ret) +return ret; + }
Comment aside: Eventually we need to invert this check and use intel_pipe_config_compare with a special mode to a) not scream into dmesg
b) ignore any changes we can fixup without a full modeset (i.e. pfit). And then use that to decide whether we need a modeset or not for the crtc. We still rely upon our internal set_mode functions to at least in some cases do an unconditional modeset on the passed-in crtc for property updates. But once converted to atomic we need to be more intelligent, especially since userspace expects no-op changes to get filtered out. So unconditionally doing a modeset wont cut it either (with the current code all the set_prop hooks have such checks hand-rolled).
-Daniel
Quoted 75 lines
drivers/gpu/drm/i915/intel_display.c +14
-23+clear_intel_crtc_state (pipe_config); pipe_config->cpu_transcoder =@@ -11478,6 +11493,18 @@ encoder_retry:DRM_DEBUG_KMS ("plane bpp: %i, pipe bpp: %i, dithering: %i\n" , base_bpp, pipe_config->pipe_bpp, pipe_config->dither); +/* Check if we need to force a modeset */ +if (pipe_config->has_audio != +to_intel_crtc_state (crtc->state)->has_audio) + pipe_config->base.mode_changed = true; + +/* +* Note we have an issue here with infoframes: current code +* only updates them on the full mode set path per hw +* requirements. So here we should be checking for any +* required changes and forcing a mode set. +*/ +return 0 ; fail:return ret;@@ -11495,12 +11522,6 @@ static bool intel_crtc_in_use(struct drm_crtc *crtc)return false; } -static bool -needs_modeset (struct drm_crtc_state *state) -{ -return state->mode_changed || state->active_changed; -} -static void intel_modeset_update_state (struct drm_atomic_state *state) {@@ -12093,10 +12114,6 @@ intel_modeset_compute_config(struct drm_crtc *crtc,struct intel_crtc_state *pipe_config;int ret =0 ; - ret =drm_atomic_add_affected_connectors (state, crtc); -if (ret) -return ERR_PTR (ret); - ret =drm_atomic_helper_check_modeset (state->dev, state);if (ret)return ERR_PTR (ret);@@ -12122,19 +12139,7 @@ intel_modeset_compute_config(struct drm_crtc *crtc,if (ret)return ERR_PTR (ret); -/* Check things that can only be changed through modeset */ -if (pipe_config->has_audio != -to_intel_crtc (crtc)->config->has_audio) - pipe_config->base.mode_changed = true; - -/* -* Note we have an issue here with infoframes: current code -* only updates them on the full mode set path per hw -* requirements. So here we should be checking for any -* required changes and forcing a mode set. -*/ - -intel_dump_pipe_config (to_intel_crtc (crtc), pipe_config,"[modeset]" ); +intel_dump_pipe_config (to_intel_crtc (crtc), pipe_config,"[modeset]" ); ret =drm_atomic_helper_check_planes (state->dev, state);if (ret)Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Signature · 7 lines
Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Maarten Lankhorst
maintainerRe: [PATCH v2 08/17] drm/i915: Set mode_changed for audio in intel_modeset_pipe_config()
Op 18-05-15 om 17:36 schreef Daniel Vetter:
Quoted 43 lines · Maarten Lankhorst
Quoted 30 lines
From: Ander Conselvan de Oliveira <[email protected]>
A follow up patch will make
intel_modeset_compute_config()deal with multiple crtcs, so move crtc specific stuff into the lower level crtc specific function.Signed-off-by Maarten Lankhorst <[email protected]>--- drivers/gpu/drm/i915/intel_display.c | 51 ++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 23 deletions(-)drivers/gpu/drm/i915/intel_display.c +6
-0@@ -427,6 +427,12 @@ static void vlv_clock(int refclk, intel_clock_t *clock) clock->dot =DIV_ROUND_CLOSEST (clock->vco, clock->p); } +static bool +needs_modeset (struct drm_crtc_state *state) +{ +return state->mode_changed || state->active_changed; +} +/** * Returns whether any output on the specified pipe is of the specified type */ @@ -11387,6 +11393,15 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,return -EINVAL ;drivers/gpu/drm/i915/intel_display.c intel_modeset_pipe_config(struct drm_crtc *crtc, · line 11403
Quoted 10 lines
drivers/gpu/drm/i915/intel_display.c +8
-0} +/* +* XXX: Add all connectors to make the crtc state match the encoders. +*/ +if (!needs_modeset (&pipe_config->base)) { + ret =drm_atomic_add_affected_connectors (state, crtc); +if (ret) +return ret; + }Comment aside: Eventually we need to invert this check and use
intel_pipe_config_comparewith a special mode to a) not scream into dmesg
Quoted 8 lines
b) ignore any changes we can fixup without a full modeset (i.e. pfit). And then use that to decide whether we need a modeset or not for the crtc. We still rely upon our internal
set_modefunctions to at least in some cases do an unconditional modeset on the passed-in crtc for property updates. But once converted to atomic we need to be more intelligent, especially since userspace expects no-op changes to get filtered out. So unconditionally doing a modeset wont cut it either (with the current code all theset_prophooks have such checks hand-rolled).
Yeah, but for now I can't get that to work properly until everything looks more atomic first.
~Maarten
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Maarten Lankhorst
maintainerPATCH v2 9/17 drm/i915: Make __intel_set_mode() take only atomic state as argument
In reply to Maarten LankhorstFrom: Ander Conselvan de Oliveira <[email protected]>
The last remaining portion that required the modeset_crtc argument is converted to deal with all crtcs in the state that need_modeset(). By doing that, __intel_set_mode() is generic enough, behaving like a commit function for the atomic state.
--- drivers/gpu/drm/i915/intel_display.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
drivers/gpu/drm/i915/intel_display.c +3 -5
@@ -12224,12 +12224,10 @@ static int __intel_set_mode_checks(struct drm_atomic_state *state)return 0 ; } -static int __intel_set_mode (struct drm_crtc *modeset_crtc, -struct intel_crtc_state *pipe_config) +static int __intel_set_mode (struct drm_atomic_state *state) { -struct drm_device *dev = modeset_crtc->dev; +struct drm_device *dev = state->dev;struct drm_i915_private *dev_priv = dev->dev_private; -struct drm_atomic_state *state = pipe_config->base.state;struct drm_crtc *crtc;struct drm_crtc_state *crtc_state;int ret =0 ;
@@ -12289,7 +12287,7 @@ static int intel_set_mode_with_config(struct drm_crtc *crtc, {int ret; - ret =__intel_set_mode (crtc, pipe_config); + ret =__intel_set_mode (pipe_config->base.state);if (ret ==0 )intel_modeset_check_state (crtc->dev);
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH v2 09/17] drm/i915: Make __intel_set_mode() take only atomic state as argument
Quoted 6 lines · Maarten Lankhorst
From: Ander Conselvan de Oliveira <[email protected]>
The last remaining portion that required the
modeset_crtcargument is converted to deal with all crtcs in the state thatneed_modeset(). By doing that,__intel_set_mode()is generic enough, behaving like a commit function for the atomic state.
Now that I read this I realized I didn't do a good job writing that commit message. It refers to the move drm_calc_timestamping_constants() into intel_modeset_update_state(), which is not part of this patch anymore, so the text makes even less sense now.
Ander
Quoted 25 lines
Signed-off-by Maarten Lankhorst <[email protected]>--- drivers/gpu/drm/i915/intel_display.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)drivers/gpu/drm/i915/intel_display.c +2
-4@@ -12224,12 +12224,10 @@ static int __intel_set_mode_checks(struct drm_atomic_state *state)return 0 ; } -static int __intel_set_mode (struct drm_crtc *modeset_crtc, -struct intel_crtc_state *pipe_config) +static int __intel_set_mode (struct drm_atomic_state *state) { -struct drm_device *dev = modeset_crtc->dev; +struct drm_device *dev = state->dev;struct drm_i915_private *dev_priv = dev->dev_private; -struct drm_atomic_state *state = pipe_config->base.state;struct drm_crtc *crtc;struct drm_crtc_state *crtc_state;int ret =0 ;
drivers/gpu/drm/i915/intel_display.c static int intel_set_mode_with_config(struct drm_crtc *crtc, · line 12293
Quoted 8 lines
drivers/gpu/drm/i915/intel_display.c +1
-1@@ -12289,7 +12287,7 @@ static int intel_set_mode_with_config(struct drm_crtc *crtc, {int ret; - ret =__intel_set_mode (crtc, pipe_config); + ret =__intel_set_mode (pipe_config->base.state);if (ret ==0 )intel_modeset_check_state (crtc->dev);
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Maarten Lankhorst
maintainerPATCH v2 10/17 drm/i915: Support modeset across multiple pipes
In reply to Maarten LankhorstFrom: Ander Conselvan de Oliveira <[email protected]>
Compute new pipe_configs for all crtcs in the atomic state. The commit part of the mode set (__intel_set_mode()) is already enabled to support multiple pipes, the only thing missing was calculating a new pipe_config for every crtc.
--- drivers/gpu/drm/i915/intel_display.c | 138 +++++++++++++---------------------- 1 file changed, 52 insertions(+), 86 deletions(-)
drivers/gpu/drm/i915/intel_display.c +52 -86
@@ -82,8 +82,7 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc,static void ironlake_pch_clock_get (struct intel_crtc *crtc,struct intel_crtc_state *pipe_config); -static int intel_set_mode (struct drm_crtc *crtc, -struct drm_atomic_state *state); +static int intel_set_mode (struct drm_atomic_state *state); static int intel_framebuffer_init(struct drm_device *dev, struct intel_framebuffer *ifb, struct drm_mode_fb_cmd2 *mode_cmd,
@@ -9830,7 +9829,7 @@ retry:drm_mode_copy (&crtc_state->base.mode, mode); -if (intel_set_mode (crtc, state)) { +if (intel_set_mode (state)) {DRM_DEBUG_KMS ("failed to set mode on load-detect pipe\n" );if (old->release_fb) old->release_fb->funcs->destroy (old->release_fb);
@@ -9904,7 +9903,7 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,if (ret) goto fail; - ret =intel_set_mode (crtc, state); + ret =intel_set_mode (state);if (ret) goto fail;
@@ -11373,9 +11372,10 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)static int intel_modeset_pipe_config (struct drm_crtc *crtc, -struct drm_atomic_state *state, -struct intel_crtc_state *pipe_config) +struct drm_atomic_state *state) { +struct drm_crtc_state *crtc_state; +struct intel_crtc_state *pipe_config;struct intel_encoder *encoder;struct drm_connector *connector;struct drm_connector_state *connector_state;
@@ -11393,6 +11393,12 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,return -EINVAL ; } + crtc_state =drm_atomic_get_existing_crtc_state (state, crtc); +if (WARN_ON (!crtc_state)) +return -EINVAL ; + + pipe_config =to_intel_crtc_state (crtc_state); +/* * XXX: Add all connectors to make the crtc state match the encoders. */
@@ -12107,45 +12113,35 @@ static void update_scanline_offset(struct intel_crtc *crtc) crtc->scanline_offset =1 ; } -static struct intel_crtc_state * -intel_modeset_compute_config (struct drm_crtc *crtc, -struct drm_atomic_state *state) +static int +intel_modeset_compute_config (struct drm_atomic_state *state) { -struct intel_crtc_state *pipe_config; -int ret =0 ; +struct drm_crtc *crtc; +struct drm_crtc_state *crtc_state; +int ret, i; ret =drm_atomic_helper_check_modeset (state->dev, state);if (ret) -return ERR_PTR (ret); - -/* -* Note this needs changes when we start tracking multiple modes -* and crtcs. At that point we'll need to compute the whole config -* (i.e. one pipe_config for each crtc) rather than just the one -* for this crtc. -*/ - pipe_config =intel_atomic_get_crtc_state (state,to_intel_crtc (crtc)); -if (IS_ERR (pipe_config)) -return pipe_config; - -if (!pipe_config->base.enable && -WARN_ON (pipe_config->base.active)) - pipe_config->base.active = false; +return ret; -if (!pipe_config->base.enable) -return pipe_config; +for_each_crtc_in_state (state, crtc, crtc_state, i) { +if (!crtc_state->enable && +WARN_ON (crtc_state->active)) + crtc_state->active = false; - ret =intel_modeset_pipe_config (crtc, state, pipe_config); -if (ret) -return ERR_PTR (ret); +if (!crtc_state->enable) +continue ; -intel_dump_pipe_config (to_intel_crtc (crtc), pipe_config,"[modeset]" ); + ret =intel_modeset_pipe_config (crtc, state); +if (ret) +return ret; - ret =drm_atomic_helper_check_planes (state->dev, state); -if (ret) -return ERR_PTR (ret); +intel_dump_pipe_config (to_intel_crtc (crtc), +to_intel_crtc_state (crtc_state), +"[modeset]" ); + } -return pipe_config; +return drm_atomic_helper_check_planes (state->dev, state); }static int __intel_set_mode_setup_plls (struct drm_atomic_state *state)
@@ -12282,37 +12278,27 @@ static int __intel_set_mode(struct drm_atomic_state *state)return 0 ; } -static int intel_set_mode_with_config (struct drm_crtc *crtc, -struct intel_crtc_state *pipe_config) +static int intel_set_mode_checked (struct drm_atomic_state *state) { +struct drm_device *dev = state->dev;int ret; - ret =__intel_set_mode (pipe_config->base.state); - + ret =__intel_set_mode (state);if (ret ==0 ) -intel_modeset_check_state (crtc->dev); +intel_modeset_check_state (dev);return ret; } -static int intel_set_mode (struct drm_crtc *crtc, -struct drm_atomic_state *state) +static int intel_set_mode (struct drm_atomic_state *state) { -struct intel_crtc_state *pipe_config; -int ret =0 ; - - pipe_config =intel_modeset_compute_config (crtc, state); -if (IS_ERR (pipe_config)) { - ret =PTR_ERR (pipe_config); - goto out; - } +int ret; - ret =intel_set_mode_with_config (crtc, pipe_config); + ret =intel_modeset_compute_config (state);if (ret) - goto out; +return ret; -out: -return ret; +return intel_set_mode_checked (state); }void intel_crtc_restore_mode (struct drm_crtc *crtc)
@@ -12384,7 +12370,7 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc)intel_modeset_setup_plane_state (state, crtc, &crtc->mode, crtc->primary->fb, crtc->x, crtc->y); - ret =intel_set_mode (crtc, state); + ret =intel_set_mode (state);if (ret)drm_atomic_state_free (state); }
@@ -12542,7 +12528,6 @@ static int intel_crtc_set_config(struct drm_mode_set *set) {struct drm_device *dev;struct drm_atomic_state *state =NULL ; -struct intel_crtc_state *pipe_config;bool primary_plane_was_visible;int ret;
@@ -12574,44 +12559,25 @@ static int intel_crtc_set_config(struct drm_mode_set *set)if (ret) goto out; - pipe_config =intel_modeset_compute_config (set->crtc, state); -if (IS_ERR (pipe_config)) { - ret =PTR_ERR (pipe_config); + primary_plane_was_visible =primary_plane_visible (set->crtc); + + ret =intel_modeset_compute_config (state); +if (ret) goto out; - }intel_update_pipe_size (to_intel_crtc (set->crtc)); - primary_plane_was_visible =primary_plane_visible (set->crtc); - - ret =intel_set_mode_with_config (set->crtc, pipe_config); - + ret =intel_set_mode_checked (state);if (ret ==0 && - pipe_config->base.enable && - pipe_config->base.planes_changed && - !needs_modeset (&pipe_config->base)) { -struct intel_crtc *intel_crtc =to_intel_crtc (set->crtc); - + set->crtc->state->active && + !needs_modeset (set->crtc->state) && + !primary_plane_was_visible && +primary_plane_visible (set->crtc)) {/* * We need to make sure the primary plane is re-enabled if it * has previously been turned off. */ -if (ret ==0 && !primary_plane_was_visible && -primary_plane_visible (set->crtc)) { -WARN_ON (!intel_crtc->active); -intel_post_enable_primary (set->crtc); - } - -/* -* In the fastboot case this may be our only check of the -* state after boot. It would be better to only do it on -* the first update, but we don't have a nice way of doing that -* (and really, set_config isn't used much for high freq page -* flipping, so increasing its cost here shouldn't be a big -* deal). -*/ -if (i915.fastboot && ret ==0 ) -intel_modeset_check_state (set->crtc->dev); +intel_post_enable_primary (set->crtc); }if (ret) {
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Maarten Lankhorst
maintainerPATCH v2 11/17 drm/i915: Use global atomic state for staged pll config
In reply to Maarten LankhorstFrom: Ander Conselvan de Oliveira <[email protected]>
Now that we can subclass drm_atomic_state we can also use it to keep track of all the pll settings. atomic_state is a better place to hold all shared state than keeping pll->new_config everywhere.
--- drivers/gpu/drm/i915/i915_drv.h | 1 - drivers/gpu/drm/i915/intel_atomic.c | 49 ++++++++++++++++ drivers/gpu/drm/i915/intel_display.c | 111 +++++++++++------------------------ drivers/gpu/drm/i915/intel_drv.h | 13 ++++ 4 files changed, 95 insertions(+), 79 deletions(-)
drivers/gpu/drm/i915/i915_drv.h +0 -1
@@ -319,7 +319,6 @@ struct intel_shared_dpll_config {struct intel_shared_dpll {struct intel_shared_dpll_config config; -struct intel_shared_dpll_config *new_config;int active;/* count of number of active CRTCs (i.e. DPMS on) */ bool on;/* is the PLL actually active? Disabled during modeset */
drivers/gpu/drm/i915/intel_atomic.c +49 -0
52 lines not on this page · raw message
drivers/gpu/drm/i915/intel_display.c +33 -78
201 lines not on this page · raw message
drivers/gpu/drm/i915/intel_drv.h +13 -0
@@ -241,6 +241,13 @@ typedef struct dpll {int p; } intel_clock_t; +struct intel_atomic_state { +struct drm_atomic_state base; + +bool dpll_set; +struct intel_shared_dpll_config shared_dpll[I915_NUM_PLLS ]; +}; +struct intel_plane_state {struct drm_plane_state base;struct drm_rect src;
@@ -627,6 +634,7 @@ struct cxsr_latency {unsigned long cursor_hpll_disable; }; +#define to_intel_atomic_state (x) container_of(x, struct intel_atomic_state, base)#define to_intel_crtc (x) container_of(x, struct intel_crtc, base)#define to_intel_crtc_state (x) container_of(x, struct intel_crtc_state, base)#define to_intel_connector (x) container_of(x, struct intel_connector, base)
@@ -1402,6 +1410,11 @@ int intel_connector_atomic_get_property(struct drm_connector *connector,struct drm_crtc_state *intel_crtc_duplicate_state (struct drm_crtc *crtc);void intel_crtc_destroy_state (struct drm_crtc *crtc,struct drm_crtc_state *state); +struct drm_atomic_state *intel_atomic_state_alloc (struct drm_device *dev); +void intel_atomic_state_clear (struct drm_atomic_state *); +struct intel_shared_dpll_config * +intel_atomic_get_shared_dpll_state (struct drm_atomic_state *s); +static inline struct intel_crtc_state *intel_atomic_get_crtc_state (struct drm_atomic_state *state,struct intel_crtc *crtc)
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH v2 11/17] drm/i915: Use global atomic state for staged pll config
Quoted 33 lines · Maarten Lankhorst
From: Ander Conselvan de Oliveira <[email protected]>
Now that we can subclass
drm_atomic_statewe can also use it to keep track of all the pll settings.atomic_stateis a better place to hold all shared state than keepingpll->new_configeverywhere.Signed-off-by Maarten Lankhorst <[email protected]>--- drivers/gpu/drm/i915/i915_drv.h | 1 - drivers/gpu/drm/i915/intel_atomic.c | 49 ++++++++++++++++ drivers/gpu/drm/i915/intel_display.c | 111 +++++++++++------------------------ drivers/gpu/drm/i915/intel_drv.h | 13 ++++ 4 files changed, 95 insertions(+), 79 deletions(-)drivers/gpu/drm/i915/i915_drv.h +0
-1@@ -319,7 +319,6 @@ struct intel_shared_dpll_config {struct intel_shared_dpll {struct intel_shared_dpll_config config; -struct intel_shared_dpll_config *new_config;int active;/* count of number of active CRTCs (i.e. DPMS on) */ bool on;/* is the PLL actually active? Disabled during modeset */ drivers/gpu/drm/i915/intel_atomic.c +0
-0@@ -421,3 +421,52 @@ int intel_atomic_setup_scalers(struct drm_device *dev,return 0 ;
drivers/gpu/drm/i915/intel_atomic.c int intel_atomic_setup_scalers(struct drm_device *dev, · line 432
Quoted 10 lines
drivers/gpu/drm/i915/intel_atomic.c +9
-0} + +static void intel_atomic_duplicate_dpll_state (struct drm_device *dev, +struct intel_atomic_state *state) +{ +struct drm_i915_private *dev_priv =to_i915 (dev); +struct intel_shared_dpll *pll; +enum intel_dpll_id i; + + state->dpll_set = true;
The ww mutex locking dance here is missing. For simplicity I think we could just repurpose the dev->mode_config.connection_mutex. We need that anyway full modesets, and dpll changes should only be required in those. Which means this wont introduce any unecessary parallelism.
It means though that we need to wire up a proper error code to all callers of duplicate/get_dpll_state, like with all the other atomic states. Might be best to follow the design for connector/crtc/planes an pass around pointers with error codes explicitly (instead of returning state->shared_dpll below since that can only cope with NULL and not with -EDEADLK).
Sorry that I didn't spot this earlier.
-Daniel
Quoted 300 lines
drivers/gpu/drm/i915/intel_atomic.c +40
-0+ +/* Copy shared dpll state */ +for (i =0 ; i < dev_priv->num_shared_dpll; i++) { + pll = &dev_priv->shared_dplls[i]; + +memcpy (&state->shared_dpll[i], + &pll->config,sizeof (pll->config)); + } +} + +struct intel_shared_dpll_config * +intel_atomic_get_shared_dpll_state (struct drm_atomic_state *s) +{ +struct intel_atomic_state *state =to_intel_atomic_state (s); + +if (!state->dpll_set) +intel_atomic_duplicate_dpll_state (state->base.dev, state); + +return state->shared_dpll; +} + +struct drm_atomic_state * +intel_atomic_state_alloc (struct drm_device *dev) +{ +struct intel_atomic_state *state =kzalloc (GFP_KERNEL ,sizeof (*state)); + +if (!state ||drm_atomic_state_init (dev, &state->base) <0 ) { +kfree (state); +return NULL ; + } + +return &state->base; +} + +void intel_atomic_state_clear (struct drm_atomic_state *s) +{ +struct intel_atomic_state *state =to_intel_atomic_state (s); +drm_atomic_state_default_clear (&state->base); + state->dpll_set = false; +}drivers/gpu/drm/i915/intel_display.c +33
-78@@ -4229,8 +4229,11 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, {struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;struct intel_shared_dpll *pll; +struct intel_shared_dpll_config *shared_dpll;enum intel_dpll_id i; + shared_dpll =intel_atomic_get_shared_dpll_state (crtc_state->base.state); +if (HAS_PCH_IBX (dev_priv->dev)) {/* Ironlake PCH has a fixed PLL->PCH pipe mapping. */ i = (enum intel_dpll_id ) crtc->pipe;@@ -4239,7 +4242,7 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,DRM_DEBUG_KMS ("CRTC:%d using pre-allocated %s\n" , crtc->base.base.id, pll->name); -WARN_ON (pll->new_config->crtc_mask); +WARN_ON (shared_dpll[i].crtc_mask); goto found; }@@ -4259,7 +4262,7 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, pll = &dev_priv->shared_dplls[i];DRM_DEBUG_KMS ("CRTC:%d using pre-allocated %s\n" , crtc->base.base.id, pll->name); -WARN_ON (pll->new_config->crtc_mask); +WARN_ON (shared_dpll[i].crtc_mask); goto found; }@@ -4268,15 +4271,15 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, pll = &dev_priv->shared_dplls[i];/* Only want to check enabled timings first */ -if (pll->new_config->crtc_mask ==0 ) +if (shared_dpll[i].crtc_mask ==0 )continue ;if (memcmp (&crtc_state->dpll_hw_state, - &pll->new_config->hw_state, -sizeof (pll->new_config->hw_state)) ==0 ) { + &shared_dpll[i].hw_state, +sizeof (crtc_state->dpll_hw_state)) ==0 ) {DRM_DEBUG_KMS ("CRTC:%d sharing existing %s (crtc mask 0x%08x, ative %d)\n" , crtc->base.base.id, pll->name, - pll->new_config->crtc_mask, + shared_dpll[i].crtc_mask, pll->active); goto found; }@@ -4285,7 +4288,7 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,/* Ok no matching timings, maybe there's a free one? */ for (i =0 ; i < dev_priv->num_shared_dpll; i++) { pll = &dev_priv->shared_dplls[i]; -if (pll->new_config->crtc_mask ==0 ) { +if (shared_dpll[i].crtc_mask ==0 ) {DRM_DEBUG_KMS ("CRTC:%d allocated %s\n" , crtc->base.base.id, pll->name); goto found;@@ -4295,83 +4298,33 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,return NULL ; found: -if (pll->new_config->crtc_mask ==0 ) - pll->new_config->hw_state = crtc_state->dpll_hw_state; +if (shared_dpll[i].crtc_mask ==0 ) + shared_dpll[i].hw_state = + crtc_state->dpll_hw_state; crtc_state->shared_dpll = i;DRM_DEBUG_DRIVER ("using %s for pipe %c\n" , pll->name,pipe_name (crtc->pipe)); - pll->new_config->crtc_mask |=1 << crtc->pipe; + shared_dpll[i].crtc_mask |=1 << crtc->pipe;return pll; } -/** -* intel_shared_dpll_start_config - start a new PLL staged config -* @dev_priv: DRM device -* @clear_pipes: mask of pipes that will have their PLLs freed -* -* Starts a new PLL staged config, copying the current config but -* releasing the references of pipes specified in clear_pipes. -*/ -static int intel_shared_dpll_start_config (struct drm_i915_private *dev_priv, -unsigned clear_pipes) -{ -struct intel_shared_dpll *pll; -enum intel_dpll_id i; - -for (i =0 ; i < dev_priv->num_shared_dpll; i++) { - pll = &dev_priv->shared_dplls[i]; - - pll->new_config =kmemdup (&pll->config,sizeof pll->config, -GFP_KERNEL ); -if (!pll->new_config) - goto cleanup; - - pll->new_config->crtc_mask &= ~clear_pipes; - } - -return 0 ; - -cleanup: -while (--i >=0 ) { - pll = &dev_priv->shared_dplls[i]; -kfree (pll->new_config); - pll->new_config =NULL ; - } - -return -ENOMEM ; -} - -static void intel_shared_dpll_commit (struct drm_i915_private *dev_priv) +static void intel_shared_dpll_commit (struct drm_atomic_state *state) { +struct drm_i915_private *dev_priv =to_i915 (state->dev); +struct intel_shared_dpll_config *shared_dpll;struct intel_shared_dpll *pll;enum intel_dpll_id i; -for (i =0 ; i < dev_priv->num_shared_dpll; i++) { - pll = &dev_priv->shared_dplls[i]; - -WARN_ON (pll->new_config == &pll->config); - - pll->config = *pll->new_config; -kfree (pll->new_config); - pll->new_config =NULL ; - } -} - -static void intel_shared_dpll_abort_config (struct drm_i915_private *dev_priv) -{ -struct intel_shared_dpll *pll; -enum intel_dpll_id i; +if (!to_intel_atomic_state (state)->dpll_set) +return ; + shared_dpll =to_intel_atomic_state (state)->shared_dpll;for (i =0 ; i < dev_priv->num_shared_dpll; i++) { pll = &dev_priv->shared_dplls[i]; - -WARN_ON (pll->new_config == &pll->config); - -kfree (pll->new_config); - pll->new_config =NULL ; + pll->config = shared_dpll[i]; } }@@ -11532,13 +11485,12 @@ static void intel_modeset_update_state(struct drm_atomic_state *state) {struct drm_device *dev = state->dev; -struct drm_i915_private *dev_priv = dev->dev_private;struct intel_encoder *intel_encoder;struct drm_crtc *crtc;struct drm_crtc_state *crtc_state;struct drm_connector *connector; -intel_shared_dpll_commit (dev_priv); +intel_shared_dpll_commit (state);drm_atomic_helper_swap_state (state->dev, state);for_each_intel_encoder (dev, intel_encoder) {@@ -12171,9 +12123,13 @@ static int __intel_set_mode_setup_plls(struct drm_atomic_state *state) } } - ret =intel_shared_dpll_start_config (dev_priv, clear_pipes); -if (ret) - goto done; +if (clear_pipes) { +struct intel_shared_dpll_config *shared_dpll = +intel_atomic_get_shared_dpll_state (state); + +for (i =0 ; i < dev_priv->num_shared_dpll; i++) + shared_dpll[i].crtc_mask &= ~clear_pipes; + }for_each_crtc_in_state (state, crtc, crtc_state, i) {if (!needs_modeset (crtc_state) || !crtc_state->enable)@@ -12184,13 +12140,10 @@ static int __intel_set_mode_setup_plls(struct drm_atomic_state *state) ret = dev_priv->display.crtc_compute_clock (intel_crtc, intel_crtc_state); -if (ret) { -intel_shared_dpll_abort_config (dev_priv); - goto done; - } +if (ret) +return ret; } -done:return ret; }@@ -13887,6 +13840,8 @@ static const struct drm_mode_config_funcs intel_mode_funcs = { .output_poll_changed = intel_fbdev_output_poll_changed, .atomic_check = intel_atomic_check, .atomic_commit = intel_atomic_commit, + .atomic_state_alloc = intel_atomic_state_alloc, + .atomic_state_clear = intel_atomic_state_clear, };/* Set up chip specific display functions */ drivers/gpu/drm/i915/intel_drv.h +13
-0@@ -241,6 +241,13 @@ typedef struct dpll {int p; } intel_clock_t; +struct intel_atomic_state { +struct drm_atomic_state base; + +bool dpll_set; +struct intel_shared_dpll_config shared_dpll[I915_NUM_PLLS ]; +}; +struct intel_plane_state {struct drm_plane_state base;struct drm_rect src;@@ -627,6 +634,7 @@ struct cxsr_latency {unsigned long cursor_hpll_disable; }; +#define to_intel_atomic_state (x) container_of(x, struct intel_atomic_state, base)#define to_intel_crtc (x) container_of(x, struct intel_crtc, base)#define to_intel_crtc_state (x) container_of(x, struct intel_crtc_state, base)#define to_intel_connector (x) container_of(x, struct intel_connector, base)@@ -1402,6 +1410,11 @@ int intel_connector_atomic_get_property(struct drm_connector *connector,struct drm_crtc_state *intel_crtc_duplicate_state (struct drm_crtc *crtc);void intel_crtc_destroy_state (struct drm_crtc *crtc,struct drm_crtc_state *state); +struct drm_atomic_state *intel_atomic_state_alloc (struct drm_device *dev); +void intel_atomic_state_clear (struct drm_atomic_state *); +struct intel_shared_dpll_config * +intel_atomic_get_shared_dpll_state (struct drm_atomic_state *s); +static inline struct intel_crtc_state *intel_atomic_get_crtc_state (struct drm_atomic_state *state,struct intel_crtc *crtc)Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Signature · 7 lines
Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Maarten Lankhorst
maintainerRe: [PATCH v2 11/17] drm/i915: Use global atomic state for staged pll config
Op 18-05-15 om 17:45 schreef Daniel Vetter:
Quoted 49 lines · Maarten Lankhorst
Quoted 33 lines
From: Ander Conselvan de Oliveira <[email protected]>
Now that we can subclass
drm_atomic_statewe can also use it to keep track of all the pll settings.atomic_stateis a better place to hold all shared state than keepingpll->new_configeverywhere.Signed-off-by Maarten Lankhorst <[email protected]>--- drivers/gpu/drm/i915/i915_drv.h | 1 - drivers/gpu/drm/i915/intel_atomic.c | 49 ++++++++++++++++ drivers/gpu/drm/i915/intel_display.c | 111 +++++++++++------------------------ drivers/gpu/drm/i915/intel_drv.h | 13 ++++ 4 files changed, 95 insertions(+), 79 deletions(-)drivers/gpu/drm/i915/i915_drv.h +0
-1@@ -319,7 +319,6 @@ struct intel_shared_dpll_config {struct intel_shared_dpll {struct intel_shared_dpll_config config; -struct intel_shared_dpll_config *new_config;int active;/* count of number of active CRTCs (i.e. DPMS on) */ bool on;/* is the PLL actually active? Disabled during modeset */ drivers/gpu/drm/i915/intel_atomic.c +0
-0@@ -421,3 +421,52 @@ int intel_atomic_setup_scalers(struct drm_device *dev,return 0 ;drivers/gpu/drm/i915/intel_atomic.c int intel_atomic_setup_scalers(struct drm_device *dev, · line 432
Quoted 10 lines
drivers/gpu/drm/i915/intel_atomic.c +9
-0} + +static void intel_atomic_duplicate_dpll_state (struct drm_device *dev, +struct intel_atomic_state *state) +{ +struct drm_i915_private *dev_priv =to_i915 (dev); +struct intel_shared_dpll *pll; +enum intel_dpll_id i; + + state->dpll_set = true;The ww mutex locking dance here is missing. For simplicity I think we could just repurpose the
dev->mode_config.connection_mutex. We need that anyway full modesets, and dpll changes should only be required in those. Which means this wont introduce any unecessary parallelism.
Quoted 9 lines
It means though that we need to wire up a proper error code to all callers of duplicate/get_dpll_state, like with all the other atomic states. Might be best to follow the design for connector/crtc/planes an pass around pointers with error codes explicitly (instead of returning
state->shared_dpllbelow since that can only cope with NULL and not with-EDEADLK).Sorry that I didn't spot this earlier.
The dpll state should only ever be done during a modeset in which case the connection_mutex is guaranteed to be held. Instead of making this return a value can we add a lockdep_assert_held ?
~Maarten
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH v2 11/17] drm/i915: Use global atomic state for staged pll config
Quoted 57 lines · Maarten Lankhorst
Op 18-05-15 om 17:45 schreef Daniel Vetter:
Quoted 56 lines · Maarten Lankhorst
Quoted 33 lines
From: Ander Conselvan de Oliveira <[email protected]>
Now that we can subclass
drm_atomic_statewe can also use it to keep track of all the pll settings.atomic_stateis a better place to hold all shared state than keepingpll->new_configeverywhere.Signed-off-by Maarten Lankhorst <[email protected]>--- drivers/gpu/drm/i915/i915_drv.h | 1 - drivers/gpu/drm/i915/intel_atomic.c | 49 ++++++++++++++++ drivers/gpu/drm/i915/intel_display.c | 111 +++++++++++------------------------ drivers/gpu/drm/i915/intel_drv.h | 13 ++++ 4 files changed, 95 insertions(+), 79 deletions(-)drivers/gpu/drm/i915/i915_drv.h +0
-1@@ -319,7 +319,6 @@ struct intel_shared_dpll_config {struct intel_shared_dpll {struct intel_shared_dpll_config config; -struct intel_shared_dpll_config *new_config;int active;/* count of number of active CRTCs (i.e. DPMS on) */ bool on;/* is the PLL actually active? Disabled during modeset */ drivers/gpu/drm/i915/intel_atomic.c +0
-0@@ -421,3 +421,52 @@ int intel_atomic_setup_scalers(struct drm_device *dev,return 0 ;drivers/gpu/drm/i915/intel_atomic.c int intel_atomic_setup_scalers(struct drm_device *dev, · line 432
Quoted 10 lines
drivers/gpu/drm/i915/intel_atomic.c +9
-0} + +static void intel_atomic_duplicate_dpll_state (struct drm_device *dev, +struct intel_atomic_state *state) +{ +struct drm_i915_private *dev_priv =to_i915 (dev); +struct intel_shared_dpll *pll; +enum intel_dpll_id i; + + state->dpll_set = true;The ww mutex locking dance here is missing. For simplicity I think we could just repurpose the
dev->mode_config.connection_mutex. We need that anyway full modesets, and dpll changes should only be required in those. Which means this wont introduce any unecessary parallelism.It means though that we need to wire up a proper error code to all callers of duplicate/get_dpll_state, like with all the other atomic states. Might be best to follow the design for connector/crtc/planes an pass around pointers with error codes explicitly (instead of returning
state->shared_dpllbelow since that can only cope with NULL and not with-EDEADLK).
Quoted 4 lines
Quoted 2 lines
Sorry that I didn't spot this earlier.
The dpll state should only ever be done during a modeset in which case the
connection_mutexis guaranteed to be held. Instead of making this return a value can we add alockdep_assert_held?
The problem is that the atomic core might only grab the crtc state and crtc mutex if e.g. userspace only changes the mode. But I've forgotten that we're using the helpers to handle modesets, and those will acquire all the needed connector states and hence the connection_mutex.
A locking check is therefore indeed enough. But please use WARN_ON(!mutex_is_locked) since imo a locking check which can be compiled out is useless. And the additional correctness lockdep provides isn't needed - we'll catch the bug since no one always hits the race by doing modesets in parallel ;-)
-Daniel
Signature · 7 lines
Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Maarten Lankhorst
maintainerPATCH v2 12/17 drm/i915: Read hw state into an atomic state struct
In reply to Maarten LankhorstFrom: Ander Conselvan de Oliveira <[email protected]>
To make this work we load the new hardware state into the atomic_state, then swap it with the sw state.
This lets us change the force restore path in setup_hw_state() to use a single call to intel_mode_set() to restore all the previous state.
As a nice bonus this kills off encoder->new_encoder, connector->new_enabled and crtc->new_enabled. They were used only to restore the state after a modeset.
--- drivers/gpu/drm/i915/intel_atomic.c | 22 +-- drivers/gpu/drm/i915/intel_display.c | 371 ++++++++++++++++++++++------------- drivers/gpu/drm/i915/intel_drv.h | 14 +- 3 files changed, 246 insertions(+), 161 deletions(-)
drivers/gpu/drm/i915/intel_atomic.c +11 -11
@@ -422,21 +422,17 @@ int intel_atomic_setup_scalers(struct drm_device *dev,return 0 ; } -static void intel_atomic_duplicate_dpll_state (struct drm_device *dev, -struct intel_atomic_state *state) +void +intel_atomic_duplicate_dpll_state (struct drm_i915_private *dev_priv, +struct intel_shared_dpll_config *shared_dpll) { -struct drm_i915_private *dev_priv =to_i915 (dev); -struct intel_shared_dpll *pll;enum intel_dpll_id i; - state->dpll_set = true; -/* Copy shared dpll state */ for (i =0 ; i < dev_priv->num_shared_dpll; i++) { - pll = &dev_priv->shared_dplls[i]; +struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i]; -memcpy (&state->shared_dpll[i], - &pll->config,sizeof (pll->config)); + shared_dpll[i] = pll->config; } }
@@ -445,8 +441,12 @@ intel_atomic_get_shared_dpll_state(struct drm_atomic_state *s) {struct intel_atomic_state *state =to_intel_atomic_state (s); -if (!state->dpll_set) -intel_atomic_duplicate_dpll_state (state->base.dev, state); +if (!state->dpll_set) { + state->dpll_set = true; + +intel_atomic_duplicate_dpll_state (to_i915 (state->base.dev), + state->shared_dpll); + }return state->shared_dpll; }
drivers/gpu/drm/i915/intel_display.c +233 -138
552 lines not on this page · raw message
drivers/gpu/drm/i915/intel_drv.h +2 -12
@@ -130,11 +130,6 @@ struct intel_fbdev {struct intel_encoder {struct drm_encoder base; -/* -* The new crtc this encoder will be driven from. Only differs from -* base->crtc while a modeset is in progress. -*/ -struct intel_crtc *new_crtc;enum intel_output_type type;unsigned int cloneable;
@@ -195,12 +190,6 @@ struct intel_connector {*/ struct intel_encoder *encoder; -/* -* The new encoder this connector will be driven. Only differs from -* encoder while a modeset is in progress. -*/ -struct intel_encoder *new_encoder; -/* Reads out the current hw, returning true if the connector is enabled * and active (i.e. dpms ON state). */ bool (*get_hw_state)(struct intel_connector *);
@@ -534,7 +523,6 @@ struct intel_crtc {struct intel_initial_plane_config plane_config;struct intel_crtc_state *config; -bool new_enabled;/* reset counter value when the last flip was submitted */ unsigned int reset_counter;
@@ -1414,6 +1402,8 @@ struct drm_atomic_state *intel_atomic_state_alloc(struct drm_device *dev);void intel_atomic_state_clear (struct drm_atomic_state *);struct intel_shared_dpll_config *intel_atomic_get_shared_dpll_state (struct drm_atomic_state *s); +void intel_atomic_duplicate_dpll_state (struct drm_i915_private *, +struct intel_shared_dpll_config *);static inline struct intel_crtc_state * intel_atomic_get_crtc_state(struct drm_atomic_state *state,
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Maarten Lankhorst
maintainerPATCH v2 13/17 drm/i915: Move cdclk and pll setup to intel_modeset_compute_config()
In reply to Maarten LankhorstFrom: Ander Conselvan de Oliveira <[email protected]>
It makes more sense there, since these are computation steps that can fail.
--- drivers/gpu/drm/i915/intel_display.c | 70 ++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 35 deletions(-)
drivers/gpu/drm/i915/intel_display.c +35 -35
@@ -12029,37 +12029,6 @@ static void update_scanline_offset(struct intel_crtc *crtc) crtc->scanline_offset =1 ; } -static int -intel_modeset_compute_config (struct drm_atomic_state *state) -{ -struct drm_crtc *crtc; -struct drm_crtc_state *crtc_state; -int ret, i; - - ret =drm_atomic_helper_check_modeset (state->dev, state); -if (ret) -return ret; - -for_each_crtc_in_state (state, crtc, crtc_state, i) { -if (!crtc_state->enable && -WARN_ON (crtc_state->active)) - crtc_state->active = false; - -if (!crtc_state->enable) -continue ; - - ret =intel_modeset_pipe_config (crtc, state); -if (ret) -return ret; - -intel_dump_pipe_config (to_intel_crtc (crtc), -to_intel_crtc_state (crtc_state), -"[modeset]" ); - } - -return drm_atomic_helper_check_planes (state->dev, state); -} -static int __intel_set_mode_setup_plls (struct drm_atomic_state *state) {struct drm_device *dev = state->dev;
@@ -12137,6 +12106,41 @@ static int __intel_set_mode_checks(struct drm_atomic_state *state)return 0 ; } +static int +intel_modeset_compute_config (struct drm_atomic_state *state) +{ +struct drm_crtc *crtc; +struct drm_crtc_state *crtc_state; +int ret, i; + + ret =drm_atomic_helper_check_modeset (state->dev, state); +if (ret) +return ret; + +for_each_crtc_in_state (state, crtc, crtc_state, i) { +if (!crtc_state->enable && +WARN_ON (crtc_state->active)) + crtc_state->active = false; + +if (!crtc_state->enable) +continue ; + + ret =intel_modeset_pipe_config (crtc, state); +if (ret) +return ret; + +intel_dump_pipe_config (to_intel_crtc (crtc), +to_intel_crtc_state (crtc_state), +"[modeset]" ); + } + + ret =drm_atomic_helper_check_planes (state->dev, state); +if (ret) +return ret; + +return __intel_set_mode_checks (state); +} +static int __intel_set_mode (struct drm_atomic_state *state) {struct drm_device *dev = state->dev;
@@ -12146,10 +12150,6 @@ static int __intel_set_mode(struct drm_atomic_state *state)int ret =0 ;int i; - ret =__intel_set_mode_checks (state); -if (ret <0 ) -return ret; - ret =drm_atomic_helper_prepare_planes (dev, state);if (ret)return ret;
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Maarten Lankhorst
maintainerPATCH v2 14/17 drm/i915: Implement intel_crtc_toggle using atomic state, v3
In reply to Maarten LankhorstAssume the callers lock everything with drm_modeset_lock_all.
This change had to be done after converting suspend/resume to use atomic_state so the atomic state is preserved, otherwise all transitional state is erased.
Now all callers of .crtc_enable and .crtc_disable go through atomic modeset! :-D
Changes since v1:
- Only check for crtc_state->active in valleyview_modeset_global_pipes.
- Only check for crtc_state->active in modeset_update_crtc_power_domains. Changes since v2:
- Rework on top of the changed patch order.
--- drivers/gpu/drm/i915/intel_display.c | 55 ++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 18 deletions(-)
drivers/gpu/drm/i915/intel_display.c +37 -18
@@ -5979,10 +5979,13 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)void intel_crtc_control (struct drm_crtc *crtc,bool enable) {struct drm_device *dev = crtc->dev; -struct drm_i915_private *dev_priv = dev->dev_private; +struct drm_mode_config *config = &dev->mode_config; +struct drm_modeset_acquire_ctx *ctx = config->acquire_ctx;struct intel_crtc *intel_crtc =to_intel_crtc (crtc); -enum intel_display_power_domain domain; -unsigned long domains; +struct intel_crtc_state *pipe_config; +struct drm_plane_state *plane_state; +struct drm_atomic_state *state; +int ret;if (enable == intel_crtc->active)return ;
@@ -5990,24 +5993,40 @@ void intel_crtc_control(struct drm_crtc *crtc, bool enable)if (enable && !crtc->state->enable)return ; - crtc->state->active = enable; -if (enable) { - domains =get_crtc_power_domains (crtc); -for_each_power_domain (domain, domains) -intel_display_power_get (dev_priv, domain); - intel_crtc->enabled_power_domains = domains; +/* this function should be called with drm_modeset_lock_all for now */ +if (WARN_ON (!ctx)) +return ; +lockdep_assert_held (&ctx->ww_ctx); - dev_priv->display.crtc_enable (crtc); -intel_crtc_enable_planes (crtc); - }else { -intel_crtc_disable_planes (crtc); - dev_priv->display.crtc_disable (crtc); + state =drm_atomic_state_alloc (dev); +if (WARN_ON (!state)) +return ; - domains = intel_crtc->enabled_power_domains; -for_each_power_domain (domain, domains) -intel_display_power_put (dev_priv, domain); - intel_crtc->enabled_power_domains =0 ; + state->acquire_ctx = ctx; + state->allow_modeset = true; + + pipe_config =intel_atomic_get_crtc_state (state, intel_crtc); +if (IS_ERR (pipe_config)) { + ret =PTR_ERR (pipe_config); + goto err; + } + pipe_config->base.active = enable; + + plane_state =drm_atomic_get_plane_state (state, crtc->primary); +if (IS_ERR (plane_state)) { + ret =PTR_ERR (plane_state); + goto err; } + + ret =intel_set_mode (state); +if (!ret) +return ; + +DRM_ERROR ("Failed to toggle crtc!\n" ); + +err: +DRM_ERROR ("Updating crtc active failed with %i\n" , ret); +drm_atomic_state_free (state); }/**
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Maarten Lankhorst
maintainerPATCH v2 15/17 drm/i915: Calculate haswell plane workaround, v2.
In reply to Maarten LankhorstThis needs to be a global check because at the time of crtc checking not all modesets have to be calculated yet. Use intel_crtc->atomic because there's no reason to keep it in state.
Changes since v1:
- Use intel_crtc->atomic as a place to put hsw_workaround_pipe.
- Make sure quirk only applies to haswell.
- Use first loop to iterate over newly enabled crtc's only. This increases readability.
--- drivers/gpu/drm/i915/intel_display.c | 100 ++++++++++++++++++++++++----------- drivers/gpu/drm/i915/intel_drv.h | 3 ++ 2 files changed, 72 insertions(+), 31 deletions(-)
drivers/gpu/drm/i915/intel_display.c +69 -31
@@ -4897,42 +4897,13 @@ static bool hsw_crtc_supports_ips(struct intel_crtc *crtc)return HAS_IPS (crtc->base.dev) && crtc->pipe ==PIPE_A ; } -/* -* This implements the workaround described in the "notes" section of the mode -* set sequence documentation. When going from no pipes or single pipe to -* multiple pipes, and planes are enabled after the pipe, we need to wait at -* least 2 vblanks on the first pipe before enabling planes on the second pipe. -*/ -static void haswell_mode_set_planes_workaround (struct intel_crtc *crtc) -{ -struct drm_device *dev = crtc->base.dev; -struct intel_crtc *crtc_it, *other_active_crtc =NULL ; - -/* We want to get the other_active_crtc only if there's only 1 other -* active crtc. */ -for_each_intel_crtc (dev, crtc_it) { -if (!crtc_it->active || crtc_it == crtc) -continue ; - -if (other_active_crtc) -return ; - - other_active_crtc = crtc_it; - } -if (!other_active_crtc) -return ; - -intel_wait_for_vblank (dev, other_active_crtc->pipe); -intel_wait_for_vblank (dev, other_active_crtc->pipe); -} -static void haswell_crtc_enable (struct drm_crtc *crtc) {struct drm_device *dev = crtc->dev;struct drm_i915_private *dev_priv = dev->dev_private;struct intel_crtc *intel_crtc =to_intel_crtc (crtc);struct intel_encoder *encoder; -int pipe = intel_crtc->pipe; +int pipe = intel_crtc->pipe, hsw_workaround_pipe;if (WARN_ON (intel_crtc->active))return ;
@@ -5009,7 +4980,11 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)/* If we change the relative order between pipe/planes enabling, we need * to change the workaround. */ -haswell_mode_set_planes_workaround (intel_crtc); + hsw_workaround_pipe = intel_crtc->atomic.hsw_workaround_pipe; +if (IS_HASWELL (dev) && hsw_workaround_pipe !=INVALID_PIPE ) { +intel_wait_for_vblank (dev, hsw_workaround_pipe); +intel_wait_for_vblank (dev, hsw_workaround_pipe); + } }static void ironlake_pfit_disable (struct intel_crtc *crtc)
@@ -12099,6 +12074,66 @@ static int __intel_set_mode_setup_plls(struct drm_atomic_state *state)return ret; } +/* +* This implements the workaround described in the "notes" section of the mode +* set sequence documentation. When going from no pipes or single pipe to +* multiple pipes, and planes are enabled after the pipe, we need to wait at +* least 2 vblanks on the first pipe before enabling planes on the second pipe. +*/ +static int haswell_mode_set_planes_workaround (struct drm_atomic_state *state) +{ +struct drm_crtc *crtc; +struct drm_crtc_state *crtc_state; +struct intel_crtc *intel_crtc, *enabled_crtc; +struct intel_crtc *first_crtc =NULL , *other_crtc =NULL ; +int enabled_crtcs =0 , i; + +/* look at all crtc's that are going to be enabled in during modeset */ +for_each_crtc_in_state (state, crtc, crtc_state, i) { + intel_crtc =to_intel_crtc (crtc); + +if (!crtc_state->active || !needs_modeset (crtc_state)) +continue ; + +if (first_crtc) { + other_crtc = intel_crtc; +break ; + }else { + first_crtc = intel_crtc; + } + } + +/* No workaround needed? */ +if (!first_crtc) +return 0 ; + +/* w/a possibly needed, check how many crtc's are already enabled. */ +for_each_intel_crtc (state->dev, intel_crtc) { + intel_crtc->atomic.hsw_workaround_pipe =INVALID_PIPE ; + + crtc_state =drm_atomic_get_crtc_state (state, + &intel_crtc->base); +if (IS_ERR (crtc_state)) +return PTR_ERR (crtc_state); + +if (!crtc_state->active ||needs_modeset (crtc_state)) +continue ; + +/* 2 or more enabled crtcs means no need for w/a */ +if (++enabled_crtcs >=2 ) +return 0 ; + + enabled_crtc = intel_crtc; + } + +if (enabled_crtcs ==1 ) + first_crtc->atomic.hsw_workaround_pipe = enabled_crtc->pipe; +else if (other_crtc) + other_crtc->atomic.hsw_workaround_pipe = first_crtc->pipe; + +return 0 ; +} +/* Code that should eventually be part of atomic_check() */ static int __intel_set_mode_checks (struct drm_atomic_state *state) {
@@ -12122,6 +12157,9 @@ static int __intel_set_mode_checks(struct drm_atomic_state *state)if (ret)return ret; +if (IS_HASWELL (dev)) +haswell_mode_set_planes_workaround (state); +return 0 ; }
drivers/gpu/drm/i915/intel_drv.h +3 -0
@@ -490,6 +490,9 @@ struct intel_crtc_atomic_commit {bool update_fbc;bool post_enable_primary;unsigned update_sprite_watermarks; + +/* Operations to perform during modeset */ +enum pipe hsw_workaround_pipe; };struct intel_crtc {
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH v2 15/17] drm/i915: Calculate haswell plane workaround, v2.
Quoted 3 lines · Maarten Lankhorst
This needs to be a global check because at the time of crtc checking not all modesets have to be calculated yet. Use
intel_crtc->atomicbecause there's no reason to keep it in state.
Hm, intel_crtc->atomic needs to be moved into intel_crtc_state eventually, so I don't really understand your reasoning here. Yes it's not really a static state, but we carry all the other state transition hints like ->need_modeset or ->active_changed around in state objects too. Imo it's the right place for this stuff, the only tricky part is that we must clear them all in the relevant duplicate_state hooks.
Anyway nothing that blocks this one, just something to keep in mind for the road ahead.
-Daniel
Quoted 172 lines
Changes since v1:
- Useintel_crtc->atomicas a place to puthsw_workaround_pipe.
- Make sure quirk only applies to haswell.
- Use first loop to iterate over newly enabled crtc's only. This increases readability.Signed-off-by Maarten Lankhorst <[email protected]>--- drivers/gpu/drm/i915/intel_display.c | 100 ++++++++++++++++++++++++----------- drivers/gpu/drm/i915/intel_drv.h | 3 ++ 2 files changed, 72 insertions(+), 31 deletions(-)drivers/gpu/drm/i915/intel_display.c +69
-31@@ -4897,42 +4897,13 @@ static bool hsw_crtc_supports_ips(struct intel_crtc *crtc)return HAS_IPS (crtc->base.dev) && crtc->pipe ==PIPE_A ; } -/* -* This implements the workaround described in the "notes" section of the mode -* set sequence documentation. When going from no pipes or single pipe to -* multiple pipes, and planes are enabled after the pipe, we need to wait at -* least 2 vblanks on the first pipe before enabling planes on the second pipe. -*/ -static void haswell_mode_set_planes_workaround (struct intel_crtc *crtc) -{ -struct drm_device *dev = crtc->base.dev; -struct intel_crtc *crtc_it, *other_active_crtc =NULL ; - -/* We want to get the other_active_crtc only if there's only 1 other -* active crtc. */ -for_each_intel_crtc (dev, crtc_it) { -if (!crtc_it->active || crtc_it == crtc) -continue ; - -if (other_active_crtc) -return ; - - other_active_crtc = crtc_it; - } -if (!other_active_crtc) -return ; - -intel_wait_for_vblank (dev, other_active_crtc->pipe); -intel_wait_for_vblank (dev, other_active_crtc->pipe); -} -static void haswell_crtc_enable (struct drm_crtc *crtc) {struct drm_device *dev = crtc->dev;struct drm_i915_private *dev_priv = dev->dev_private;struct intel_crtc *intel_crtc =to_intel_crtc (crtc);struct intel_encoder *encoder; -int pipe = intel_crtc->pipe; +int pipe = intel_crtc->pipe, hsw_workaround_pipe;if (WARN_ON (intel_crtc->active))return ;@@ -5009,7 +4980,11 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)/* If we change the relative order between pipe/planes enabling, we need * to change the workaround. */ -haswell_mode_set_planes_workaround (intel_crtc); + hsw_workaround_pipe = intel_crtc->atomic.hsw_workaround_pipe; +if (IS_HASWELL (dev) && hsw_workaround_pipe !=INVALID_PIPE ) { +intel_wait_for_vblank (dev, hsw_workaround_pipe); +intel_wait_for_vblank (dev, hsw_workaround_pipe); + } }static void ironlake_pfit_disable (struct intel_crtc *crtc)@@ -12099,6 +12074,66 @@ static int __intel_set_mode_setup_plls(struct drm_atomic_state *state)return ret; } +/* +* This implements the workaround described in the "notes" section of the mode +* set sequence documentation. When going from no pipes or single pipe to +* multiple pipes, and planes are enabled after the pipe, we need to wait at +* least 2 vblanks on the first pipe before enabling planes on the second pipe. +*/ +static int haswell_mode_set_planes_workaround (struct drm_atomic_state *state) +{ +struct drm_crtc *crtc; +struct drm_crtc_state *crtc_state; +struct intel_crtc *intel_crtc, *enabled_crtc; +struct intel_crtc *first_crtc =NULL , *other_crtc =NULL ; +int enabled_crtcs =0 , i; + +/* look at all crtc's that are going to be enabled in during modeset */ +for_each_crtc_in_state (state, crtc, crtc_state, i) { + intel_crtc =to_intel_crtc (crtc); + +if (!crtc_state->active || !needs_modeset (crtc_state)) +continue ; + +if (first_crtc) { + other_crtc = intel_crtc; +break ; + }else { + first_crtc = intel_crtc; + } + } + +/* No workaround needed? */ +if (!first_crtc) +return 0 ; + +/* w/a possibly needed, check how many crtc's are already enabled. */ +for_each_intel_crtc (state->dev, intel_crtc) { + intel_crtc->atomic.hsw_workaround_pipe =INVALID_PIPE ; + + crtc_state =drm_atomic_get_crtc_state (state, + &intel_crtc->base); +if (IS_ERR (crtc_state)) +return PTR_ERR (crtc_state); + +if (!crtc_state->active ||needs_modeset (crtc_state)) +continue ; + +/* 2 or more enabled crtcs means no need for w/a */ +if (++enabled_crtcs >=2 ) +return 0 ; + + enabled_crtc = intel_crtc; + } + +if (enabled_crtcs ==1 ) + first_crtc->atomic.hsw_workaround_pipe = enabled_crtc->pipe; +else if (other_crtc) + other_crtc->atomic.hsw_workaround_pipe = first_crtc->pipe; + +return 0 ; +} +/* Code that should eventually be part of atomic_check() */ static int __intel_set_mode_checks (struct drm_atomic_state *state) {@@ -12122,6 +12157,9 @@ static int __intel_set_mode_checks(struct drm_atomic_state *state)if (ret)return ret; +if (IS_HASWELL (dev)) +haswell_mode_set_planes_workaround (state); +return 0 ; }drivers/gpu/drm/i915/intel_drv.h +3
-0@@ -490,6 +490,9 @@ struct intel_crtc_atomic_commit {bool update_fbc;bool post_enable_primary;unsigned update_sprite_watermarks; + +/* Operations to perform during modeset */ +enum pipe hsw_workaround_pipe; };struct intel_crtc {Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Signature · 7 lines
Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH v2 15/17] drm/i915: Calculate haswell plane workaround, v2.
Hi,
Quoted 12 lines · Daniel Vetter
Quoted 3 lines · Maarten Lankhorst
This needs to be a global check because at the time of crtc checking not all modesets have to be calculated yet. Use
intel_crtc->atomicbecause there's no reason to keep it in state.Hm,
intel_crtc->atomicneeds to be moved intointel_crtc_stateeventually, so I don't really understand your reasoning here. Yes it's not really a static state, but we carry all the other state transition hints like ->need_modeset or ->active_changed around in state objects too. Imo it's the right place for this stuff, the only tricky part is that we must clear them all in the relevantduplicate_statehooks.
Quoted 2 lines
Anyway nothing that blocks this one, just something to keep in mind for the road ahead.
What makes me slightly nervous is the number of places where we duplicate the state, meaning that we could easily bleed those if we're not extremely careful about how we do it. I argued for this one to go into intel_crtc->atomic as it was much more suited than the static state, but if we're implementing a transient state section of intel_crtc_state (ideally under its own sub-struct, so it can easily be zeroed), then I guess that wfm.
Cheers,
Daniel
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Maarten Lankhorst
maintainerPATCH v2 16/17 drm/i915: Use crtc->hwmode for vblanks.
In reply to Maarten Lankhorstintel_crtc->config will be removed eventually, so use crtc->hwmode. drm_atomic_helper_update_legacy_modeset_state updates hwmode, but crtc->active will eventually be gone too. Set dotclock to zero to indicate the crtc is inactive.
--- drivers/gpu/drm/i915/i915_irq.c | 13 ++++++------- drivers/gpu/drm/i915/intel_display.c | 3 +++ 2 files changed, 9 insertions(+), 7 deletions(-)
drivers/gpu/drm/i915/i915_irq.c +6 -7
@@ -564,8 +564,7 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)u32 high1, high2, low, pixel, vbl_start, hsync_start, htotal;struct intel_crtc *intel_crtc =to_intel_crtc (dev_priv->pipe_to_crtc_mapping[pipe]); -const struct drm_display_mode *mode = - &intel_crtc->config->base.adjusted_mode; +const struct drm_display_mode *mode = &intel_crtc->base.hwmode; htotal = mode->crtc_htotal; hsync_start = mode->crtc_hsync_start;
@@ -620,7 +619,7 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) {struct drm_device *dev = crtc->base.dev;struct drm_i915_private *dev_priv = dev->dev_private; -const struct drm_display_mode *mode = &crtc->config->base.adjusted_mode; +const struct drm_display_mode *mode = &crtc->base.hwmode;enum pipe pipe = crtc->pipe;int position, vtotal;
@@ -647,14 +646,14 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,struct drm_i915_private *dev_priv = dev->dev_private;struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];struct intel_crtc *intel_crtc =to_intel_crtc (crtc); -const struct drm_display_mode *mode = &intel_crtc->config->base.adjusted_mode; +const struct drm_display_mode *mode = &intel_crtc->base.hwmode;int position;int vbl_start, vbl_end, hsync_start, htotal, vtotal;bool in_vbl = true;int ret =0 ;unsigned long irqflags; -if (!intel_crtc->active) { +if (WARN_ON (!mode->crtc_clock)) {DRM_DEBUG_DRIVER ("trying to get scanoutpos for disabled " "pipe %c\n" ,pipe_name (pipe));return 0 ;
@@ -796,7 +795,7 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,return -EINVAL ; } -if (!crtc->state->active) { +if (!crtc->hwmode.crtc_clock) {DRM_DEBUG_KMS ("crtc %d is disabled\n" , pipe);return -EBUSY ; }
@@ -805,7 +804,7 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,return drm_calc_vbltimestamp_from_scanoutpos (dev, pipe, max_error, vblank_time, flags, crtc, - &to_intel_crtc (crtc)->config->base.adjusted_mode); + &crtc->hwmode); } static bool intel_hpd_irq_event(struct drm_device *dev,
drivers/gpu/drm/i915/intel_display.c +3 -0
@@ -11467,6 +11467,9 @@ intel_modeset_update_state(struct drm_atomic_state *state)WARN_ON (crtc->state->enable !=intel_crtc_in_use (crtc));to_intel_crtc (crtc)->config =to_intel_crtc_state (crtc->state); + +if (!crtc->state->active) + crtc->hwmode.crtc_clock =0 ; }list_for_each_entry (connector, &dev->mode_config.connector_list, head) {
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH v2 16/17] drm/i915: Use crtc->hwmode for vblanks.
Quoted 6 lines · Maarten Lankhorst
intel_crtc->configwill be removed eventually, so usecrtc->hwmode.drm_atomic_helper_update_legacy_modeset_stateupdates hwmode, butcrtc->activewill eventually be gone too. Set dotclock to zero to indicate the crtc is inactive.Signed-off-by Maarten Lankhorst <[email protected]>
I think adding a code comment to our assignment of crtc->hw_mode that we need this for i915_get_vblank_timestamp (and only for that) would be really good. Especially since I can't find it with a quick grep, at least in current upstream ;-)
-Daniel
Quoted 84 lines
--- drivers/gpu/drm/i915/i915_irq.c | 13 ++++++------- drivers/gpu/drm/i915/intel_display.c | 3 +++ 2 files changed, 9 insertions(+), 7 deletions(-)drivers/gpu/drm/i915/i915_irq.c +6
-7@@ -564,8 +564,7 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)u32 high1, high2, low, pixel, vbl_start, hsync_start, htotal;struct intel_crtc *intel_crtc =to_intel_crtc (dev_priv->pipe_to_crtc_mapping[pipe]); -const struct drm_display_mode *mode = - &intel_crtc->config->base.adjusted_mode; +const struct drm_display_mode *mode = &intel_crtc->base.hwmode; htotal = mode->crtc_htotal; hsync_start = mode->crtc_hsync_start;@@ -620,7 +619,7 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) {struct drm_device *dev = crtc->base.dev;struct drm_i915_private *dev_priv = dev->dev_private; -const struct drm_display_mode *mode = &crtc->config->base.adjusted_mode; +const struct drm_display_mode *mode = &crtc->base.hwmode;enum pipe pipe = crtc->pipe;int position, vtotal;@@ -647,14 +646,14 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,struct drm_i915_private *dev_priv = dev->dev_private;struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];struct intel_crtc *intel_crtc =to_intel_crtc (crtc); -const struct drm_display_mode *mode = &intel_crtc->config->base.adjusted_mode; +const struct drm_display_mode *mode = &intel_crtc->base.hwmode;int position;int vbl_start, vbl_end, hsync_start, htotal, vtotal;bool in_vbl = true;int ret =0 ;unsigned long irqflags; -if (!intel_crtc->active) { +if (WARN_ON (!mode->crtc_clock)) {DRM_DEBUG_DRIVER ("trying to get scanoutpos for disabled " "pipe %c\n" ,pipe_name (pipe));return 0 ;@@ -796,7 +795,7 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,return -EINVAL ; } -if (!crtc->state->active) { +if (!crtc->hwmode.crtc_clock) {DRM_DEBUG_KMS ("crtc %d is disabled\n" , pipe);return -EBUSY ; }@@ -805,7 +804,7 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,return drm_calc_vbltimestamp_from_scanoutpos (dev, pipe, max_error, vblank_time, flags, crtc, - &to_intel_crtc (crtc)->config->base.adjusted_mode); + &crtc->hwmode); } static bool intel_hpd_irq_event(struct drm_device *dev,drivers/gpu/drm/i915/intel_display.c +3
-0@@ -11467,6 +11467,9 @@ intel_modeset_update_state(struct drm_atomic_state *state)WARN_ON (crtc->state->enable !=intel_crtc_in_use (crtc));to_intel_crtc (crtc)->config =to_intel_crtc_state (crtc->state); + +if (!crtc->state->active) + crtc->hwmode.crtc_clock =0 ; }list_for_each_entry (connector, &dev->mode_config.connector_list, head) {Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Signature · 7 lines
Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH v2 16/17] drm/i915: Use crtc->hwmode for vblanks.
Quoted 6 lines · Daniel Vetter
Quoted 5 lines · Maarten Lankhorst
intel_crtc->configwill be removed eventually, so usecrtc->hwmode.drm_atomic_helper_update_legacy_modeset_stateupdates hwmode, butcrtc->activewill eventually be gone too. Set dotclock to zero to indicate the crtc is inactive.
Quoted 6 lines
Quoted 1 line
Signed-off-by Maarten Lankhorst <[email protected]>I think adding a code comment to our assignment of
crtc->hw_modethat we need this fori915_get_vblank_timestamp(and only for that) would be really good. Especially since I can't find it with a quick grep, at least in current upstream ;-)
I don't particularly like resurrecting this zombie. Why we can't just use crtc->state->adjusted_mode (or wherever the current adjusted mode is kept)?
Quoted 95 lines
-Daniel
Quoted 84 lines
--- drivers/gpu/drm/i915/i915_irq.c | 13 ++++++------- drivers/gpu/drm/i915/intel_display.c | 3 +++ 2 files changed, 9 insertions(+), 7 deletions(-)drivers/gpu/drm/i915/i915_irq.c +6
-7@@ -564,8 +564,7 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)u32 high1, high2, low, pixel, vbl_start, hsync_start, htotal;struct intel_crtc *intel_crtc =to_intel_crtc (dev_priv->pipe_to_crtc_mapping[pipe]); -const struct drm_display_mode *mode = - &intel_crtc->config->base.adjusted_mode; +const struct drm_display_mode *mode = &intel_crtc->base.hwmode; htotal = mode->crtc_htotal; hsync_start = mode->crtc_hsync_start;@@ -620,7 +619,7 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) {struct drm_device *dev = crtc->base.dev;struct drm_i915_private *dev_priv = dev->dev_private; -const struct drm_display_mode *mode = &crtc->config->base.adjusted_mode; +const struct drm_display_mode *mode = &crtc->base.hwmode;enum pipe pipe = crtc->pipe;int position, vtotal;@@ -647,14 +646,14 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,struct drm_i915_private *dev_priv = dev->dev_private;struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];struct intel_crtc *intel_crtc =to_intel_crtc (crtc); -const struct drm_display_mode *mode = &intel_crtc->config->base.adjusted_mode; +const struct drm_display_mode *mode = &intel_crtc->base.hwmode;int position;int vbl_start, vbl_end, hsync_start, htotal, vtotal;bool in_vbl = true;int ret =0 ;unsigned long irqflags; -if (!intel_crtc->active) { +if (WARN_ON (!mode->crtc_clock)) {DRM_DEBUG_DRIVER ("trying to get scanoutpos for disabled " "pipe %c\n" ,pipe_name (pipe));return 0 ;@@ -796,7 +795,7 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,return -EINVAL ; } -if (!crtc->state->active) { +if (!crtc->hwmode.crtc_clock) {DRM_DEBUG_KMS ("crtc %d is disabled\n" , pipe);return -EBUSY ; }@@ -805,7 +804,7 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,return drm_calc_vbltimestamp_from_scanoutpos (dev, pipe, max_error, vblank_time, flags, crtc, - &to_intel_crtc (crtc)->config->base.adjusted_mode); + &crtc->hwmode); } static bool intel_hpd_irq_event(struct drm_device *dev,drivers/gpu/drm/i915/intel_display.c +3
-0@@ -11467,6 +11467,9 @@ intel_modeset_update_state(struct drm_atomic_state *state)WARN_ON (crtc->state->enable !=intel_crtc_in_use (crtc));to_intel_crtc (crtc)->config =to_intel_crtc_state (crtc->state); + +if (!crtc->state->active) + crtc->hwmode.crtc_clock =0 ; }list_for_each_entry (connector, &dev->mode_config.connector_list, head) {Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfxSignature · 7 lines
Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Signature · 6 lines
Ville Syrjälä Intel OTC _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Maarten Lankhorst
maintainerRe: [PATCH v2 16/17] drm/i915: Use crtc->hwmode for vblanks.
Op 18-05-15 om 18:28 schreef Ville Syrjälä:
Quoted 7 lines · Daniel Vetter
Quoted 6 lines · Maarten Lankhorst
Quoted 5 lines
intel_crtc->configwill be removed eventually, so usecrtc->hwmode.drm_atomic_helper_update_legacy_modeset_stateupdates hwmode, butcrtc->activewill eventually be gone too. Set dotclock to zero to indicate the crtc is inactive.
Quoted 8 lines
Quoted 5 lines
Quoted 1 line
Signed-off-by Maarten Lankhorst <[email protected]>I think adding a code comment to our assignment of
crtc->hw_modethat we need this fori915_get_vblank_timestamp(and only for that) would be really good. Especially since I can't find it with a quick grep, at least in current upstream ;-)I don't particularly like resurrecting this zombie. Why we can't just use
crtc->state->adjusted_mode(or wherever the current adjusted mode is kept)?
Because we want to get rid of intel_crtc->config, and if drm_atomic_swap_state is moved to be done before any call to then crtc->state->adjusted_mode will not be in sync with the hw state, and any wai tfor vblank will produce funny results.
Since I don't think you should want to pass a state to vblank you would have to use some crtc local variable somewhere, in this case I chose to use hwmode for that.
~Maarten
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH v2 16/17] drm/i915: Use crtc->hwmode for vblanks.
Quoted 16 lines · Maarten Lankhorst
Op 18-05-15 om 18:28 schreef Ville Syrjälä:
Quoted 7 lines · Daniel Vetter
Quoted 6 lines · Maarten Lankhorst
Quoted 5 lines
intel_crtc->configwill be removed eventually, so usecrtc->hwmode.drm_atomic_helper_update_legacy_modeset_stateupdates hwmode, butcrtc->activewill eventually be gone too. Set dotclock to zero to indicate the crtc is inactive.Quoted 8 lines
Quoted 5 lines
Quoted 1 line
Signed-off-by Maarten Lankhorst <[email protected]>I think adding a code comment to our assignment of
crtc->hw_modethat we need this fori915_get_vblank_timestamp(and only for that) would be really good. Especially since I can't find it with a quick grep, at least in current upstream ;-)I don't particularly like resurrecting this zombie. Why we can't just use
crtc->state->adjusted_mode(or wherever the current adjusted mode is kept)?
Quoted 6 lines
Because we want to get rid of
intel_crtc->config, and ifdrm_atomic_swap_stateis moved to be done before any call to thencrtc->state->adjusted_modewill not be in sync with the hw state, and any wai tfor vblank will produce funny results.Since I don't think you should want to pass a state to vblank you would have to use some crtc local variable somewhere, in this case I chose to use hwmode for that.
I guess plan be could be to the required values (and only those we need, not the entire mode struct) in struct intel_crtc. Not sure whether that's worth the bother.
-Daniel
Signature · 7 lines
Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Maarten Lankhorst
maintainerPATCH v2 17/17 drm/i915: Remove use of crtc->config from i915_debugfs.c
In reply to Maarten Lankhorstcrtc->config is a pointer to the current crtc->state, and will be removed eventually. Same for crtc->active, instead use crtc->state->active.
--- drivers/gpu/drm/i915/i915_debugfs.c | 42 ++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 15 deletions(-)
drivers/gpu/drm/i915/i915_debugfs.c +27 -15
@@ -2755,13 +2755,16 @@ static int i915_display_info(struct seq_file *m, void *unused)seq_printf (m,"---------\n" );for_each_intel_crtc (dev, crtc) {bool active; +struct intel_crtc_state *pipe_config;int x, y; + pipe_config =to_intel_crtc_state (crtc->base.state); +seq_printf (m,"CRTC %d: pipe: %c, active=%s (size=%dx%d)\n" , crtc->base.base.id,pipe_name (crtc->pipe), -yesno (crtc->active), crtc->config->pipe_src_w, - crtc->config->pipe_src_h); -if (crtc->active) { +yesno (pipe_config->base.active), + pipe_config->pipe_src_w, pipe_config->pipe_src_h); +if (pipe_config->base.active) {intel_crtc_info (m, crtc); active =cursor_position (dev, crtc->pipe, &x, &y);
@@ -3002,7 +3005,7 @@ static void drrs_status_per_crtc(struct seq_file *m,seq_puts (m,"\n\n" ); -if (intel_crtc->config->has_drrs) { +if (to_intel_crtc_state (intel_crtc->base.state)->has_drrs) {struct intel_panel *panel;mutex_lock (&drrs->mutex);
@@ -3054,7 +3057,7 @@ static int i915_drrs_status(struct seq_file *m, void *unused)for_each_intel_crtc (dev, intel_crtc) {drm_modeset_lock (&intel_crtc->base.mutex,NULL ); -if (intel_crtc->active) { +if (intel_crtc->base.state->active) { active_crtc_cnt++;seq_printf (m,"\nCRTC %d: " , active_crtc_cnt);
@@ -3596,22 +3599,27 @@ static void hsw_trans_edp_pipe_A_crc_wa(struct drm_device *dev)struct drm_i915_private *dev_priv = dev->dev_private;struct intel_crtc *crtc =to_intel_crtc (dev_priv->pipe_to_crtc_mapping[PIPE_A ]); +struct intel_crtc_state *pipe_config;drm_modeset_lock_all (dev); + pipe_config =to_intel_crtc_state (crtc->base.state); +/* * If we use the eDP transcoder we need to make sure that we don't * bypass the pfit, since otherwise the pipe CRC source won't work. Only * relevant on hsw with pipe A when using the always-on power well * routing. */ -if (crtc->config->cpu_transcoder ==TRANSCODER_EDP && - !crtc->config->pch_pfit.enabled) { -bool active = crtc->active; +if (pipe_config->cpu_transcoder ==TRANSCODER_EDP && + !pipe_config->pch_pfit.enabled) { +bool active = pipe_config->base.active; -if (active) +if (active) {intel_crtc_control (&crtc->base, false); + pipe_config =to_intel_crtc_state (crtc->base.state); + } - crtc->config->pch_pfit.force_thru = true; + pipe_config->pch_pfit.force_thru = true;intel_display_power_get (dev_priv,POWER_DOMAIN_PIPE_PANEL_FITTER (PIPE_A ));
@@ -3627,6 +3635,7 @@ static void hsw_undo_trans_edp_pipe_A_crc_wa(struct drm_device *dev)struct drm_i915_private *dev_priv = dev->dev_private;struct intel_crtc *crtc =to_intel_crtc (dev_priv->pipe_to_crtc_mapping[PIPE_A ]); +struct intel_crtc_state *pipe_config;drm_modeset_lock_all (dev);/*
@@ -3635,13 +3644,16 @@ static void hsw_undo_trans_edp_pipe_A_crc_wa(struct drm_device *dev)* relevant on hsw with pipe A when using the always-on power well * routing. */ -if (crtc->config->pch_pfit.force_thru) { -bool active = crtc->active; + pipe_config =to_intel_crtc_state (crtc->base.state); +if (pipe_config->pch_pfit.force_thru) { +bool active = pipe_config->base.active; -if (active) +if (active) {intel_crtc_control (&crtc->base, false); + pipe_config =to_intel_crtc_state (crtc->base.state); + } - crtc->config->pch_pfit.force_thru = false; + pipe_config->pch_pfit.force_thru = false;intel_display_power_put (dev_priv,POWER_DOMAIN_PIPE_PANEL_FITTER (PIPE_A ));
@@ -3763,7 +3775,7 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe, pipe_name(pipe));drm_modeset_lock (&crtc->base.mutex,NULL ); -if (crtc->active) +if (crtc->base.state->active)intel_wait_for_vblank (dev, pipe);drm_modeset_unlock (&crtc->base.mutex);
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH v2 17/17] drm/i915: Remove use of crtc->config from i915_debugfs.c
Quoted 4 lines · Maarten Lankhorst
crtc->configis a pointer to the currentcrtc->state, and will be removed eventually. Same forcrtc->active, instead usecrtc->state->active.Signed-off-by Maarten Lankhorst <[email protected]>
Maybe assert here in the commit message that with all the previous changes ->config and ->state are now updated in lockstep and hence we can switch them over. Same for ->active. Just to make sure that you and reviewers agree on what the crucial bit is here.
-Daniel
Quoted 124 lines
--- drivers/gpu/drm/i915/i915_debugfs.c | 42 ++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 15 deletions(-)drivers/gpu/drm/i915/i915_debugfs.c +27
-15@@ -2755,13 +2755,16 @@ static int i915_display_info(struct seq_file *m, void *unused)seq_printf (m,"---------\n" );for_each_intel_crtc (dev, crtc) {bool active; +struct intel_crtc_state *pipe_config;int x, y; + pipe_config =to_intel_crtc_state (crtc->base.state); +seq_printf (m,"CRTC %d: pipe: %c, active=%s (size=%dx%d)\n" , crtc->base.base.id,pipe_name (crtc->pipe), -yesno (crtc->active), crtc->config->pipe_src_w, - crtc->config->pipe_src_h); -if (crtc->active) { +yesno (pipe_config->base.active), + pipe_config->pipe_src_w, pipe_config->pipe_src_h); +if (pipe_config->base.active) {intel_crtc_info (m, crtc); active =cursor_position (dev, crtc->pipe, &x, &y);@@ -3002,7 +3005,7 @@ static void drrs_status_per_crtc(struct seq_file *m,seq_puts (m,"\n\n" ); -if (intel_crtc->config->has_drrs) { +if (to_intel_crtc_state (intel_crtc->base.state)->has_drrs) {struct intel_panel *panel;mutex_lock (&drrs->mutex);@@ -3054,7 +3057,7 @@ static int i915_drrs_status(struct seq_file *m, void *unused)for_each_intel_crtc (dev, intel_crtc) {drm_modeset_lock (&intel_crtc->base.mutex,NULL ); -if (intel_crtc->active) { +if (intel_crtc->base.state->active) { active_crtc_cnt++;seq_printf (m,"\nCRTC %d: " , active_crtc_cnt);@@ -3596,22 +3599,27 @@ static void hsw_trans_edp_pipe_A_crc_wa(struct drm_device *dev)struct drm_i915_private *dev_priv = dev->dev_private;struct intel_crtc *crtc =to_intel_crtc (dev_priv->pipe_to_crtc_mapping[PIPE_A ]); +struct intel_crtc_state *pipe_config;drm_modeset_lock_all (dev); + pipe_config =to_intel_crtc_state (crtc->base.state); +/* * If we use the eDP transcoder we need to make sure that we don't * bypass the pfit, since otherwise the pipe CRC source won't work. Only * relevant on hsw with pipe A when using the always-on power well * routing. */ -if (crtc->config->cpu_transcoder ==TRANSCODER_EDP && - !crtc->config->pch_pfit.enabled) { -bool active = crtc->active; +if (pipe_config->cpu_transcoder ==TRANSCODER_EDP && + !pipe_config->pch_pfit.enabled) { +bool active = pipe_config->base.active; -if (active) +if (active) {intel_crtc_control (&crtc->base, false); + pipe_config =to_intel_crtc_state (crtc->base.state); + } - crtc->config->pch_pfit.force_thru = true; + pipe_config->pch_pfit.force_thru = true;intel_display_power_get (dev_priv,POWER_DOMAIN_PIPE_PANEL_FITTER (PIPE_A ));@@ -3627,6 +3635,7 @@ static void hsw_undo_trans_edp_pipe_A_crc_wa(struct drm_device *dev)struct drm_i915_private *dev_priv = dev->dev_private;struct intel_crtc *crtc =to_intel_crtc (dev_priv->pipe_to_crtc_mapping[PIPE_A ]); +struct intel_crtc_state *pipe_config;drm_modeset_lock_all (dev);/* @@ -3635,13 +3644,16 @@ static void hsw_undo_trans_edp_pipe_A_crc_wa(struct drm_device *dev)* relevant on hsw with pipe A when using the always-on power well * routing. */ -if (crtc->config->pch_pfit.force_thru) { -bool active = crtc->active; + pipe_config =to_intel_crtc_state (crtc->base.state); +if (pipe_config->pch_pfit.force_thru) { +bool active = pipe_config->base.active; -if (active) +if (active) {intel_crtc_control (&crtc->base, false); + pipe_config =to_intel_crtc_state (crtc->base.state); + } - crtc->config->pch_pfit.force_thru = false; + pipe_config->pch_pfit.force_thru = false;intel_display_power_put (dev_priv,POWER_DOMAIN_PIPE_PANEL_FITTER (PIPE_A ));@@ -3763,7 +3775,7 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe, pipe_name(pipe));drm_modeset_lock (&crtc->base.mutex,NULL ); -if (crtc->active) +if (crtc->base.state->active)intel_wait_for_vblank (dev, pipe);drm_modeset_unlock (&crtc->base.mutex);Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Signature · 7 lines
Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx