[Intel-gfx] [PATCH 2/5] [drm/i915]: require_pipe_a helper functions
Daniel Vetter
daniel.vetter at ffwll.ch
Fri Sep 11 14:39:10 CEST 2009
These will be used to ensure that the clock of pipe a is running
when the overlay is switched on. Programming logic more or less
directly ported over from userspace.
Also export the already existing helper function drm_encoder_crtc_ok.
Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
---
drivers/gpu/drm/drm_crtc_helper.c | 3 +-
drivers/gpu/drm/i915/intel_display.c | 83 ++++++++++++++++++++++++++++++++++
drivers/gpu/drm/i915/intel_drv.h | 5 ++
include/drm/drm_crtc_helper.h | 2 +
4 files changed, 92 insertions(+), 1 deletions(-)
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index ff447f1..13afdfe 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -488,7 +488,7 @@ static void drm_setup_crtcs(struct drm_device *dev)
*
* Return false if @encoder can't be driven by @crtc, true otherwise.
*/
-static bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
+bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
struct drm_crtc *crtc)
{
struct drm_device *dev;
@@ -509,6 +509,7 @@ static bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
return true;
return false;
}
+EXPORT_SYMBOL(drm_encoder_crtc_ok);
/*
* Check the CRTC we're going to map each output to vs. its current
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 155719f..d0a74e5 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3069,6 +3069,89 @@ void intel_release_load_detect_pipe(struct intel_output *intel_output, int dpms_
}
}
+/** Ensure that pipe A is enabled. Returns the crtc that runs pipe A or NULL
+ * if pipe A is already enabled */
+struct drm_crtc *intel_require_pipe_a_start(struct drm_device *dev,
+ int *dpms_mode)
+{
+ struct drm_crtc *crtc;
+ struct intel_crtc *intel_crtc;
+ struct drm_connector *connector;
+ struct drm_crtc_helper_funcs *crtc_funcs;
+ struct intel_output *intel_output;
+
+ crtc = intel_get_crtc_from_pipe(dev, 0);
+ intel_crtc = to_intel_crtc(crtc);
+ BUG_ON(intel_crtc->pipe != 0);
+
+ if (crtc->enabled && intel_crtc->dpms_mode == DRM_MODE_DPMS_ON)
+ return NULL;
+
+ DRM_DEBUG("i915: require PIPEA, switching on crtc ...\n");
+
+ *dpms_mode = intel_crtc->dpms_mode;
+
+ if (crtc->enabled && intel_crtc->dpms_mode != DRM_MODE_DPMS_ON) {
+ /* just switch it on */
+ crtc_funcs = crtc->helper_private;
+ crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
+
+ return crtc;
+ }
+
+ if (!drm_helper_crtc_in_use(crtc)) {
+ /* look for an encoder/connector */
+ list_for_each_entry(connector,
+ &dev->mode_config.connector_list, head) {
+ intel_output = to_intel_output(connector);
+
+ if (intel_output->enc.crtc)
+ /* don't steal connectors */
+ continue;
+
+ if (!drm_encoder_crtc_ok(&intel_output->enc, crtc))
+ continue;
+
+ intel_output->enc.crtc = crtc;
+ break;
+ }
+ }
+
+ drm_crtc_helper_set_mode(crtc, &load_detect_mode, 0, 0, crtc->fb);
+ WARN_ON(!crtc->enabled);
+
+ return crtc;
+}
+
+void intel_require_pipe_a_end(struct drm_device *dev,
+ struct drm_crtc *crtc,
+ int dpms_mode)
+{
+ struct drm_encoder_helper_funcs *encoder_funcs;
+ struct drm_encoder *encoder;
+ struct drm_crtc_helper_funcs *crtc_funcs;
+
+ if (!crtc)
+ return;
+
+ crtc_funcs = crtc->helper_private;
+
+ DRM_DEBUG("i915: require PIPEA, switching off crtc ...\n");
+
+ /* Switch crtc and output back off if necessary */
+ if (crtc->enabled && dpms_mode != DRM_MODE_DPMS_ON) {
+ list_for_each_entry(encoder,
+ &dev->mode_config.encoder_list, head) {
+ if (encoder->crtc != crtc)
+ continue;
+ encoder_funcs = encoder->helper_private;
+ encoder_funcs->dpms(encoder, dpms_mode);
+ }
+
+ crtc_funcs->dpms(crtc, dpms_mode);
+ }
+}
+
/* Returns the clock of the currently programmed mode of the given pipe. */
static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
{
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index b9e47f1..33e6980 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -163,6 +163,11 @@ extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_ou
int *dpms_mode);
extern void intel_release_load_detect_pipe(struct intel_output *intel_output,
int dpms_mode);
+extern struct drm_crtc *intel_require_pipe_a_start(struct drm_device *dev,
+ int *dpms_mode);
+extern void intel_require_pipe_a_end(struct drm_device *dev,
+ struct drm_crtc *crtc,
+ int dpms_mode);
extern struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB);
extern int intel_sdvo_supports_hotplug(struct drm_connector *connector);
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
index 4c8daca..43a0a09 100644
--- a/include/drm/drm_crtc_helper.h
+++ b/include/drm/drm_crtc_helper.h
@@ -126,4 +126,6 @@ static inline void drm_connector_helper_add(struct drm_connector *connector,
}
extern int drm_helper_resume_force_mode(struct drm_device *dev);
+extern bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
+ struct drm_crtc *crtc);
#endif
--
1.6.3.3
More information about the Intel-gfx
mailing list