modesetting: reorganise out crtc/outputs are allocated.
[profile/ivi/libdrm.git] / linux-core / intel_crt.c
index a9fb50a..584dea2 100644 (file)
@@ -28,6 +28,7 @@
 #include "drmP.h"
 #include "drm.h"
 #include "drm_crtc.h"
+#include "drm_crtc_helper.h"
 #include "intel_drv.h"
 #include "i915_drm.h"
 #include "i915_drv.h"
@@ -95,7 +96,7 @@ static void intel_crt_mode_set(struct drm_output *output,
 {
        struct drm_device *dev = output->dev;
        struct drm_crtc *crtc = output->crtc;
-       struct intel_crtc *intel_crtc = crtc->driver_private;
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct drm_i915_private *dev_priv = dev->dev_private;
        int dpll_md_reg;
        u32 adpa, dpll_md;
@@ -132,7 +133,7 @@ static void intel_crt_mode_set(struct drm_output *output,
 /**
  * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence.
  *
- * Only for I945G/GM.
+ * Not for i915G/i915GM
  *
  * \return TRUE if CRT is connected.
  * \return FALSE if CRT is disconnected.
@@ -142,7 +143,7 @@ static bool intel_crt_detect_hotplug(struct drm_output *output)
        struct drm_device *dev = output->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        u32 temp;
-#if 1
+
        unsigned long timeout = jiffies + msecs_to_jiffies(1000);
 
        temp = I915_READ(PORT_HOTPLUG_EN);
@@ -161,20 +162,11 @@ static bool intel_crt_detect_hotplug(struct drm_output *output)
                return true;
 
        return false;
-#else
-       temp = I915_READ(PORT_HOTPLUG_STAT);
-       DRM_DEBUG("HST 0x%08x\n", temp);
-
-       if (temp & (1 << 8) && temp & (1 << 9))
-               return true;
-
-       return false;
-#endif
 }
 
 static bool intel_crt_detect_ddc(struct drm_output *output)
 {
-       struct intel_output *intel_output = output->driver_private;
+       struct intel_output *intel_output = to_intel_output(output);
 
        /* CRT should always be at 0, but check anyway */
        if (intel_output->type != INTEL_OUTPUT_ANALOG)
@@ -187,7 +179,7 @@ static enum drm_output_status intel_crt_detect(struct drm_output *output)
 {
        struct drm_device *dev = output->dev;
        
-       if (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev)) {
+       if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) {
                if (intel_crt_detect_hotplug(output))
                        return output_status_connected;
                else
@@ -203,10 +195,11 @@ static enum drm_output_status intel_crt_detect(struct drm_output *output)
 
 static void intel_crt_destroy(struct drm_output *output)
 {
-       struct intel_output *intel_output = output->driver_private;
+       struct intel_output *intel_output = to_intel_output(output);
 
        intel_i2c_destroy(intel_output->ddc_bus);
-       kfree(output->driver_private);
+       drm_output_cleanup(output);
+       kfree(output);
 }
 
 static int intel_crt_get_modes(struct drm_output *output)
@@ -229,19 +222,24 @@ static bool intel_crt_set_property(struct drm_output *output,
 /*
  * Routines for controlling stuff on the analog port
  */
+
+static const struct drm_output_helper_funcs intel_crt_helper_funcs = {
+       .mode_fixup = intel_crt_mode_fixup,
+       .prepare = intel_output_prepare,
+       .commit = intel_output_commit,
+       .mode_set = intel_crt_mode_set,
+};
+
 static const struct drm_output_funcs intel_crt_output_funcs = {
        .dpms = intel_crt_dpms,
        .save = intel_crt_save,
        .restore = intel_crt_restore,
-       .mode_valid = intel_crt_mode_valid,
-       .mode_fixup = intel_crt_mode_fixup,
-       .prepare = intel_output_prepare,
-       .mode_set = intel_crt_mode_set,
-       .commit = intel_output_commit,
        .detect = intel_crt_detect,
        .get_modes = intel_crt_get_modes,
-       .cleanup = intel_crt_destroy,
+       .destroy = intel_crt_destroy,
        .set_property = intel_crt_set_property,
+       .mode_valid = intel_crt_mode_valid,
+
 };
 
 void intel_crt_init(struct drm_device *dev)
@@ -249,26 +247,28 @@ void intel_crt_init(struct drm_device *dev)
        struct drm_output *output;
        struct intel_output *intel_output;
 
-       output = drm_output_create(dev, &intel_crt_output_funcs,
-                                  DRM_MODE_OUTPUT_DAC);
-
-       intel_output = kmalloc(sizeof(struct intel_output), GFP_KERNEL);
-       if (!intel_output) {
-               drm_output_destroy(output);
+       intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
+       if (!intel_output)
                return;
-       }
+
+       output = &intel_output->base;
+       drm_output_init(dev, &intel_output->base, &intel_crt_output_funcs, DRM_MODE_OUTPUT_DAC);
+
        /* Set up the DDC bus. */
        intel_output->ddc_bus = intel_i2c_create(dev, GPIOA, "CRTDDC_A");
        if (!intel_output->ddc_bus) {
                dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
                           "failed.\n");
+               intel_crt_destroy(output);
                return;
        }
 
        intel_output->type = INTEL_OUTPUT_ANALOG;
-       output->driver_private = intel_output;
        output->interlace_allowed = 0;
        output->doublescan_allowed = 0;
 
+       drm_output_helper_add(output, &intel_crt_helper_funcs);
+       drm_sysfs_output_add(output);
+
        drm_output_attach_property(output, dev->mode_config.connector_type_property, ConnectorVGA);
 }