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;
is_lvds = true;
break;
case INTEL_OUTPUT_SDVO:
+ case INTEL_OUTPUT_HDMI:
is_sdvo = true;
break;
case INTEL_OUTPUT_DVO:
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 */
if (bo->size < width * height * 4) {
DRM_ERROR("buffer is to small\n");
- drm_gem_object_unreference(bo);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto fail;
}
- 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");
+ goto fail;
+ }
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");
+ goto fail;
+ }
+ 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);
+ mutex_lock(&dev->struct_mutex);
+ drm_gem_object_unreference(intel_crtc->cursor_bo);
+ mutex_unlock(&dev->struct_mutex);
+ }
+
+ intel_crtc->cursor_addr = addr;
+ intel_crtc->cursor_bo = bo;
+
return 0;
+fail:
+ mutex_lock(&dev->struct_mutex);
+ drm_gem_object_unreference(bo);
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
}
static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
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) {
/* 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)|