intel_clock_t *clock)
{
if (IS_I9XX(dev))
- return i9xx_clock (refclk, clock);
+ i9xx_clock (refclk, clock);
else
- return i8xx_clock (refclk, clock);
+ i8xx_clock (refclk, clock);
}
/**
udelay(20000);
}
-void
-intel_pipe_set_base(struct drm_crtc *crtc, int x, int y)
+static void
+intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
+ struct drm_framebuffer *old_fb)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
- u32 dspcntr;
+ u32 dspcntr, alignment;
/* no fb bound */
if (!crtc->fb) {
}
intel_fb = to_intel_framebuffer(crtc->fb);
-
obj = intel_fb->obj;
obj_priv = obj->driver_private;
+ switch (obj_priv->tiling_mode) {
+ case I915_TILING_NONE:
+ alignment = 64 * 1024;
+ break;
+ case I915_TILING_X:
+ if (IS_I9XX(dev))
+ alignment = 1024 * 1024;
+ else
+ alignment = 512 * 1024;
+ break;
+ case I915_TILING_Y:
+ /* FIXME: Is this true? */
+ DRM_ERROR("Y tiled not allowed for scan out buffers\n");
+ return;
+ default:
+ BUG();
+ }
+
+ if (i915_gem_object_pin(intel_fb->obj, alignment))
+ return;
+
+ i915_gem_object_set_to_gtt_domain(intel_fb->obj, 1);
+
Start = obj_priv->gtt_offset;
Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
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;
I915_READ(dspbase);
}
+ intel_wait_for_vblank(dev);
+
+ if (old_fb) {
+ intel_fb = to_intel_framebuffer(old_fb);
+ i915_gem_object_unpin(intel_fb->obj);
+ }
if (!dev->primary->master)
return;
static void intel_crtc_mode_set(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode,
- int x, int y)
+ int x, int y,
+ struct drm_framebuffer *old_fb)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
is_lvds = true;
break;
case INTEL_OUTPUT_SDVO:
+ case INTEL_OUTPUT_HDMI:
is_sdvo = true;
break;
case INTEL_OUTPUT_DVO:
I915_WRITE(dspcntr_reg, dspcntr);
/* Flush the plane changes */
- intel_pipe_set_base(crtc, x, y);
-
- intel_wait_for_vblank(dev);
+ intel_pipe_set_base(crtc, x, y, old_fb);
drm_vblank_post_modeset(dev, pipe);
}
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 */
addr = obj_priv->gtt_offset;
}
- intel_crtc->cursor_addr = addr;
+ 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;
+ }
+
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) {
+ 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;
}
if (!crtc->enabled) {
if (!mode)
mode = &load_detect_mode;
- drm_crtc_helper_set_mode(crtc, mode, 0, 0);
+ drm_crtc_helper_set_mode(crtc, mode, 0, 0, crtc->fb);
} else {
if (intel_crtc->dpms_mode != DRM_MODE_DPMS_ON) {
crtc_funcs = crtc->helper_private;
};
-void intel_crtc_init(struct drm_device *dev, int pipe)
+static void intel_crtc_init(struct drm_device *dev, int pipe)
{
struct intel_crtc *intel_crtc;
int i;
return crtc;
}
-int intel_connector_clones(struct drm_device *dev, int type_mask)
+static int intel_connector_clones(struct drm_device *dev, int type_mask)
{
int index_mask = 0;
struct drm_connector *connector;
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)|
return fb;
}
-static int intel_insert_new_fb(struct drm_device *dev,
- struct drm_file *file_priv,
- struct drm_framebuffer *fb,
- struct drm_mode_fb_cmd *mode_cmd)
-{
- struct intel_framebuffer *intel_fb;
- struct drm_gem_object *obj;
- struct drm_crtc *crtc;
-
- intel_fb = to_intel_framebuffer(fb);
-
- obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle);
-
- if (!obj)
- return -EINVAL;
-
- intel_fb->obj = obj;
- drm_gem_object_unreference(intel_fb->obj);
- drm_helper_mode_fill_fb_struct(fb, mode_cmd);
- mutex_unlock(&dev->struct_mutex);
-
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
- if (crtc->fb == fb) {
- struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
- crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y);
- }
- }
- return 0;
-}
-
static const struct drm_mode_config_funcs intel_mode_funcs = {
- .resize_fb = intel_insert_new_fb,
.fb_create = intel_user_framebuffer_create,
.fb_changed = intelfb_probe,
};