]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/gpu/drm/i915/intel_display.c
drm/i915: add support for physical memory objects
[linux-2.6-omap-h63xx.git] / drivers / gpu / drm / i915 / intel_display.c
index e5c1c80d1f9051ca506084f3a18191b18bc896a6..114a7a1a8740096217b62d5fc108210c3cc8f44d 100644 (file)
@@ -401,6 +401,8 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
        I915_WRITE(dspstride, crtc->fb->pitch);
 
        dspcntr = I915_READ(dspcntr_reg);
+       /* Mask out pixel format bits in case we change it */
+       dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
        switch (crtc->fb->bits_per_pixel) {
        case 8:
                dspcntr |= DISPPLANE_8BPP;
@@ -751,6 +753,7 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc,
                        is_lvds = true;
                        break;
                case INTEL_OUTPUT_SDVO:
+               case INTEL_OUTPUT_HDMI:
                        is_sdvo = true;
                        break;
                case INTEL_OUTPUT_DVO:
@@ -986,19 +989,17 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
        uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
        uint32_t temp;
        size_t addr;
+       int ret;
 
        DRM_DEBUG("\n");
 
        /* if we want to turn off the cursor ignore width and height */
        if (!handle) {
                DRM_DEBUG("cursor off\n");
-               /* turn of the cursor */
-               temp = 0;
-               temp |= CURSOR_MODE_DISABLE;
-
-               I915_WRITE(control, temp);
-               I915_WRITE(base, 0);
-               return 0;
+               temp = CURSOR_MODE_DISABLE;
+               addr = 0;
+               bo = NULL;
+               goto finish;
        }
 
        /* Currently we only support 64x64 cursors */
@@ -1019,21 +1020,46 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
                return -ENOMEM;
        }
 
-       if (dev_priv->cursor_needs_physical) {
-               addr = dev->agp->base + obj_priv->gtt_offset;
-       } else {
+       /* we only need to pin inside GTT if cursor is non-phy */
+       if (!dev_priv->cursor_needs_physical) {
+               ret = i915_gem_object_pin(bo, PAGE_SIZE);
+               if (ret) {
+                       DRM_ERROR("failed to pin cursor bo\n");
+                       drm_gem_object_unreference(bo);
+                       return ret;
+               }
                addr = obj_priv->gtt_offset;
+       } else {
+               ret = i915_gem_attach_phys_object(dev, bo, (pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1);
+               if (ret) {
+                       DRM_ERROR("failed to attach phys object\n");
+                       drm_gem_object_unreference(bo);
+                       return ret;
+               }
+               addr = obj_priv->phys_obj->handle->busaddr;
        }
 
-       intel_crtc->cursor_addr = addr;
        temp = 0;
        /* set the pipe for the cursor */
        temp |= (pipe << 28);
        temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
 
+ finish:
        I915_WRITE(control, temp);
        I915_WRITE(base, addr);
 
+       if (intel_crtc->cursor_bo) {
+               if (dev_priv->cursor_needs_physical) {
+                       if (intel_crtc->cursor_bo != bo)
+                               i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo);
+               } else
+                       i915_gem_object_unpin(intel_crtc->cursor_bo);
+               drm_gem_object_unreference(intel_crtc->cursor_bo);
+       }
+
+       intel_crtc->cursor_addr = addr;
+       intel_crtc->cursor_bo = bo;
+
        return 0;
 }
 
@@ -1430,12 +1456,19 @@ static void intel_setup_outputs(struct drm_device *dev)
                intel_lvds_init(dev);
 
        if (IS_I9XX(dev)) {
-               intel_sdvo_init(dev, SDVOB);
-               intel_sdvo_init(dev, SDVOC);
+               int found;
+
+               found = intel_sdvo_init(dev, SDVOB);
+               if (!found && SUPPORTS_INTEGRATED_HDMI(dev))
+                       intel_hdmi_init(dev, SDVOB);
+
+               found = intel_sdvo_init(dev, SDVOC);
+               if (!found && SUPPORTS_INTEGRATED_HDMI(dev))
+                       intel_hdmi_init(dev, SDVOC);
        } else
                intel_dvo_init(dev);
 
-       if (IS_I9XX(dev) && !IS_I915G(dev))
+       if (IS_I9XX(dev) && IS_MOBILE(dev))
                intel_tv_init(dev);
 
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
@@ -1445,6 +1478,11 @@ static void intel_setup_outputs(struct drm_device *dev)
 
                /* valid crtcs */
                switch(intel_output->type) {
+               case INTEL_OUTPUT_HDMI:
+                       crtc_mask = ((1 << 0)|
+                                    (1 << 1));
+                       clone_mask = ((1 << INTEL_OUTPUT_HDMI));
+                       break;
                case INTEL_OUTPUT_DVO:
                case INTEL_OUTPUT_SDVO:
                        crtc_mask = ((1 << 0)|