Commit 44040f10 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6

* 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: (133 commits)
  drm/vgaarb: add VGA arbitration support to the drm and kms.
  drm/radeon: some r420s have a CP race with the DMA engine.
  drm/radeon/r600/kms: rv670 is not DCE3
  drm/radeon/kms: r420 idle after programming GA_ENHANCE
  drm/radeon/kms: more fixes to rv770 suspend/resume path.
  drm/radeon/kms: more alignment for rv770.c with r600.c
  drm/radeon/kms: rv770 blit init called too late.
  drm/radeon/kms: move around new init path code to avoid posting at init
  drm/radeon/r600: fix some issues with suspend/resume.
  drm/radeon/kms: disable VGA rendering engine before taking over VRAM
  drm/radeon/kms: Move radeon_get_clock_info() call out of radeon_clocks_init().
  drm/radeon/kms: add initial connector properties
  drm/radeon/kms: Use surfaces for scanout / cursor byte swapping on big endian.
  drm/radeon/kms: don't fail if we fail to init GPU acceleration
  drm/r600/kms: fixup number of loops per blit calculation.
  drm/radeon/kms: reprogram format in set base.
  drm/radeon: avivo chips have no separate int bit for display
  drm/radeon/r600: don't do interrupts
  drm: fix _DRM_GEM addmap error message
  drm: update crtc x/y when only fb changes
  ...

Fixed up trivial conflicts in firmware/Makefile due to network driver
(cxgb3) and drm (mga/r128/radeon) firmware being listed next to each
other.
parents 388dba30 28d52043
......@@ -18,6 +18,14 @@ menuconfig DRM
details. You should also select and configure AGP
(/dev/agpgart) support.
config DRM_KMS_HELPER
tristate
depends on DRM
select FB
select FRAMEBUFFER_CONSOLE if !EMBEDDED
help
FB and CRTC helpers for KMS drivers.
config DRM_TTM
tristate
depends on DRM
......@@ -36,6 +44,7 @@ config DRM_TDFX
config DRM_R128
tristate "ATI Rage 128"
depends on DRM && PCI
select FW_LOADER
help
Choose this option if you have an ATI Rage 128 graphics card. If M
is selected, the module will be called r128. AGP support for
......@@ -47,8 +56,9 @@ config DRM_RADEON
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select FB
select FRAMEBUFFER_CONSOLE if !EMBEDDED
select FW_LOADER
select DRM_KMS_HELPER
select DRM_TTM
help
Choose this option if you have an ATI Radeon graphics card. There
are both PCI and AGP versions. You don't need to choose this to
......@@ -82,11 +92,10 @@ config DRM_I830
config DRM_I915
tristate "i915 driver"
depends on AGP_INTEL
select DRM_KMS_HELPER
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select FB
select FRAMEBUFFER_CONSOLE if !EMBEDDED
# i915 depends on ACPI_VIDEO when ACPI is enabled
# but for select to work, need to select ACPI_VIDEO's dependencies, ick
select VIDEO_OUTPUT_CONTROL if ACPI
......@@ -116,6 +125,7 @@ endchoice
config DRM_MGA
tristate "Matrox g200/g400"
depends on DRM
select FW_LOADER
help
Choose this option if you have a Matrox G200, G400 or G450 graphics
card. If M is selected, the module will be called mga. AGP
......
......@@ -10,11 +10,15 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \
drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \
drm_crtc.o drm_crtc_helper.o drm_modes.o drm_edid.o \
drm_info.o drm_debugfs.o
drm_crtc.o drm_modes.o drm_edid.o \
drm_info.o drm_debugfs.o drm_encoder_slave.o
drm-$(CONFIG_COMPAT) += drm_ioc32.o
drm_kms_helper-y := drm_fb_helper.o drm_crtc_helper.o
obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
obj-$(CONFIG_DRM) += drm.o
obj-$(CONFIG_DRM_TTM) += ttm/
obj-$(CONFIG_DRM_TDFX) += tdfx/
......
......@@ -310,10 +310,10 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset,
(unsigned long long)map->offset, map->size);
break;
}
case _DRM_GEM:
DRM_ERROR("tried to rmmap GEM object\n");
DRM_ERROR("tried to addmap GEM object\n");
break;
}
case _DRM_SCATTER_GATHER:
if (!dev->sg) {
kfree(map);
......
......@@ -45,6 +45,23 @@ drm_clflush_page(struct page *page)
clflush(page_virtual + i);
kunmap_atomic(page_virtual, KM_USER0);
}
static void drm_cache_flush_clflush(struct page *pages[],
unsigned long num_pages)
{
unsigned long i;
mb();
for (i = 0; i < num_pages; i++)
drm_clflush_page(*pages++);
mb();
}
static void
drm_clflush_ipi_handler(void *null)
{
wbinvd();
}
#endif
void
......@@ -53,17 +70,30 @@ drm_clflush_pages(struct page *pages[], unsigned long num_pages)
#if defined(CONFIG_X86)
if (cpu_has_clflush) {
unsigned long i;
mb();
for (i = 0; i < num_pages; ++i)
drm_clflush_page(*pages++);
mb();
drm_cache_flush_clflush(pages, num_pages);
return;
}
wbinvd();
if (on_each_cpu(drm_clflush_ipi_handler, NULL, 1) != 0)
printk(KERN_ERR "Timed out waiting for cache flush.\n");
#elif defined(__powerpc__)
unsigned long i;
for (i = 0; i < num_pages; i++) {
struct page *page = pages[i];
void *page_virtual;
if (unlikely(page == NULL))
continue;
page_virtual = kmap_atomic(page, KM_USER0);
flush_dcache_range((unsigned long)page_virtual,
(unsigned long)page_virtual + PAGE_SIZE);
kunmap_atomic(page_virtual, KM_USER0);
}
#else
printk(KERN_ERR "Architecture has no drm_cache.c support\n");
WARN_ON_ONCE(1);
#endif
}
EXPORT_SYMBOL(drm_clflush_pages);
......@@ -68,10 +68,10 @@ DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
*/
static struct drm_prop_enum_list drm_scaling_mode_enum_list[] =
{
{ DRM_MODE_SCALE_NON_GPU, "Non-GPU" },
{ DRM_MODE_SCALE_FULLSCREEN, "Fullscreen" },
{ DRM_MODE_SCALE_NO_SCALE, "No scale" },
{ DRM_MODE_SCALE_ASPECT, "Aspect" },
{ DRM_MODE_SCALE_NONE, "None" },
{ DRM_MODE_SCALE_FULLSCREEN, "Full" },
{ DRM_MODE_SCALE_CENTER, "Center" },
{ DRM_MODE_SCALE_ASPECT, "Full aspect" },
};
static struct drm_prop_enum_list drm_dithering_mode_enum_list[] =
......@@ -108,6 +108,7 @@ static struct drm_prop_enum_list drm_tv_select_enum_list[] =
{ DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
{ DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */
{ DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
{ DRM_MODE_SUBCONNECTOR_SCART, "SCART" }, /* TV-out */
};
DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list)
......@@ -118,6 +119,7 @@ static struct drm_prop_enum_list drm_tv_subconnector_enum_list[] =
{ DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
{ DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */
{ DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
{ DRM_MODE_SUBCONNECTOR_SCART, "SCART" }, /* TV-out */
};
DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
......@@ -146,6 +148,7 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] =
{ DRM_MODE_CONNECTOR_DisplayPort, "DisplayPort", 0 },
{ DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A", 0 },
{ DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 },
{ DRM_MODE_CONNECTOR_TV, "TV", 0 },
};
static struct drm_prop_enum_list drm_encoder_enum_list[] =
......@@ -165,6 +168,7 @@ char *drm_get_encoder_name(struct drm_encoder *encoder)
encoder->base.id);
return buf;
}
EXPORT_SYMBOL(drm_get_encoder_name);
char *drm_get_connector_name(struct drm_connector *connector)
{
......@@ -699,6 +703,42 @@ int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes,
drm_property_add_enum(dev->mode_config.tv_mode_property, i,
i, modes[i]);
dev->mode_config.tv_brightness_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"brightness", 2);
dev->mode_config.tv_brightness_property->values[0] = 0;
dev->mode_config.tv_brightness_property->values[1] = 100;
dev->mode_config.tv_contrast_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"contrast", 2);
dev->mode_config.tv_contrast_property->values[0] = 0;
dev->mode_config.tv_contrast_property->values[1] = 100;
dev->mode_config.tv_flicker_reduction_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"flicker reduction", 2);
dev->mode_config.tv_flicker_reduction_property->values[0] = 0;
dev->mode_config.tv_flicker_reduction_property->values[1] = 100;
dev->mode_config.tv_overscan_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"overscan", 2);
dev->mode_config.tv_overscan_property->values[0] = 0;
dev->mode_config.tv_overscan_property->values[1] = 100;
dev->mode_config.tv_saturation_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"saturation", 2);
dev->mode_config.tv_saturation_property->values[0] = 0;
dev->mode_config.tv_saturation_property->values[1] = 100;
dev->mode_config.tv_hue_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"hue", 2);
dev->mode_config.tv_hue_property->values[0] = 0;
dev->mode_config.tv_hue_property->values[1] = 100;
return 0;
}
EXPORT_SYMBOL(drm_mode_create_tv_properties);
......@@ -1044,7 +1084,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
list_for_each_entry(crtc, &dev->mode_config.crtc_list,
head) {
DRM_DEBUG("CRTC ID is %d\n", crtc->base.id);
DRM_DEBUG_KMS("CRTC ID is %d\n", crtc->base.id);
if (put_user(crtc->base.id, crtc_id + copied)) {
ret = -EFAULT;
goto out;
......@@ -1072,7 +1112,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
list_for_each_entry(encoder,
&dev->mode_config.encoder_list,
head) {
DRM_DEBUG("ENCODER ID is %d\n",
DRM_DEBUG_KMS("ENCODER ID is %d\n",
encoder->base.id);
if (put_user(encoder->base.id, encoder_id +
copied)) {
......@@ -1103,7 +1143,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
list_for_each_entry(connector,
&dev->mode_config.connector_list,
head) {
DRM_DEBUG("CONNECTOR ID is %d\n",
DRM_DEBUG_KMS("CONNECTOR ID is %d\n",
connector->base.id);
if (put_user(connector->base.id,
connector_id + copied)) {
......@@ -1127,7 +1167,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
}
card_res->count_connectors = connector_count;
DRM_DEBUG("Counted %d %d %d\n", card_res->count_crtcs,
DRM_DEBUG_KMS("Counted %d %d %d\n", card_res->count_crtcs,
card_res->count_connectors, card_res->count_encoders);
out:
......@@ -1230,7 +1270,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
DRM_DEBUG("connector id %d:\n", out_resp->connector_id);
DRM_DEBUG_KMS("connector id %d:\n", out_resp->connector_id);
mutex_lock(&dev->mode_config.mutex);
......@@ -1406,7 +1446,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
obj = drm_mode_object_find(dev, crtc_req->crtc_id,
DRM_MODE_OBJECT_CRTC);
if (!obj) {
DRM_DEBUG("Unknown CRTC ID %d\n", crtc_req->crtc_id);
DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
ret = -EINVAL;
goto out;
}
......@@ -1419,7 +1459,8 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
list_for_each_entry(crtcfb,
&dev->mode_config.crtc_list, head) {
if (crtcfb == crtc) {
DRM_DEBUG("Using current fb for setmode\n");
DRM_DEBUG_KMS("Using current fb for "
"setmode\n");
fb = crtc->fb;
}
}
......@@ -1427,7 +1468,8 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
obj = drm_mode_object_find(dev, crtc_req->fb_id,
DRM_MODE_OBJECT_FB);
if (!obj) {
DRM_DEBUG("Unknown FB ID%d\n", crtc_req->fb_id);
DRM_DEBUG_KMS("Unknown FB ID%d\n",
crtc_req->fb_id);
ret = -EINVAL;
goto out;
}
......@@ -1440,13 +1482,13 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
}
if (crtc_req->count_connectors == 0 && mode) {
DRM_DEBUG("Count connectors is 0 but mode set\n");
DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");
ret = -EINVAL;
goto out;
}
if (crtc_req->count_connectors > 0 && (!mode || !fb)) {
DRM_DEBUG("Count connectors is %d but no mode or fb set\n",
DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n",
crtc_req->count_connectors);
ret = -EINVAL;
goto out;
......@@ -1479,7 +1521,8 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
obj = drm_mode_object_find(dev, out_id,
DRM_MODE_OBJECT_CONNECTOR);
if (!obj) {
DRM_DEBUG("Connector id %d unknown\n", out_id);
DRM_DEBUG_KMS("Connector id %d unknown\n",
out_id);
ret = -EINVAL;
goto out;
}
......@@ -1512,7 +1555,7 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,
struct drm_crtc *crtc;
int ret = 0;
DRM_DEBUG("\n");
DRM_DEBUG_KMS("\n");
if (!req->flags) {
DRM_ERROR("no operation set\n");
......@@ -1522,7 +1565,7 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,
mutex_lock(&dev->mode_config.mutex);
obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC);
if (!obj) {
DRM_DEBUG("Unknown CRTC ID %d\n", req->crtc_id);
DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id);
ret = -EINVAL;
goto out;
}
......
This diff is collapsed.
......@@ -63,12 +63,12 @@ static struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, 0),
DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, 0),
DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, 0),
DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER),
DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER),
DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH),
......
This diff is collapsed.
/*
* Copyright (C) 2009 Francisco Jerez.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "drm_encoder_slave.h"
/**
* drm_i2c_encoder_init - Initialize an I2C slave encoder
* @dev: DRM device.
* @encoder: Encoder to be attached to the I2C device. You aren't
* required to have called drm_encoder_init() before.
* @adap: I2C adapter that will be used to communicate with
* the device.
* @info: Information that will be used to create the I2C device.
* Required fields are @addr and @type.
*
* Create an I2C device on the specified bus (the module containing its
* driver is transparently loaded) and attach it to the specified
* &drm_encoder_slave. The @slave_funcs field will be initialized with
* the hooks provided by the slave driver.
*
* Returns 0 on success or a negative errno on failure, in particular,
* -ENODEV is returned when no matching driver is found.
*/
int drm_i2c_encoder_init(struct drm_device *dev,
struct drm_encoder_slave *encoder,
struct i2c_adapter *adap,
const struct i2c_board_info *info)
{
char modalias[sizeof(I2C_MODULE_PREFIX)
+ I2C_NAME_SIZE];
struct module *module = NULL;
struct i2c_client *client;
struct drm_i2c_encoder_driver *encoder_drv;
int err = 0;
snprintf(modalias, sizeof(modalias),
"%s%s", I2C_MODULE_PREFIX, info->type);
request_module(modalias);
client = i2c_new_device(adap, info);
if (!client) {
err = -ENOMEM;
goto fail;
}
if (!client->driver) {
err = -ENODEV;
goto fail_unregister;
}
module = client->driver->driver.owner;
if (!try_module_get(module)) {
err = -ENODEV;
goto fail_unregister;
}
encoder->bus_priv = client;
encoder_drv = to_drm_i2c_encoder_driver(client->driver);
err = encoder_drv->encoder_init(client, dev, encoder);
if (err)
goto fail_unregister;
return 0;
fail_unregister:
i2c_unregister_device(client);
module_put(module);
fail:
return err;
}
EXPORT_SYMBOL(drm_i2c_encoder_init);
/**
* drm_i2c_encoder_destroy - Unregister the I2C device backing an encoder
* @drm_encoder: Encoder to be unregistered.
*
* This should be called from the @destroy method of an I2C slave
* encoder driver once I2C access is no longer needed.
*/
void drm_i2c_encoder_destroy(struct drm_encoder *drm_encoder)
{
struct drm_encoder_slave *encoder = to_encoder_slave(drm_encoder);
struct i2c_client *client = drm_i2c_encoder_get_client(drm_encoder);
struct module *module = client->driver->driver.owner;
i2c_unregister_device(client);
encoder->bus_priv = NULL;
module_put(module);
}
EXPORT_SYMBOL(drm_i2c_encoder_destroy);
This diff is collapsed.
......@@ -164,7 +164,7 @@ EXPORT_SYMBOL(drm_gem_object_alloc);
* Removes the mapping from handle to filp for this object.
*/
static int
drm_gem_handle_delete(struct drm_file *filp, int handle)
drm_gem_handle_delete(struct drm_file *filp, u32 handle)
{
struct drm_device *dev;
struct drm_gem_object *obj;
......@@ -207,7 +207,7 @@ drm_gem_handle_delete(struct drm_file *filp, int handle)
int
drm_gem_handle_create(struct drm_file *file_priv,
struct drm_gem_object *obj,
int *handlep)
u32 *handlep)
{
int ret;
......@@ -221,7 +221,7 @@ drm_gem_handle_create(struct drm_file *file_priv,
/* do the allocation under our spinlock */
spin_lock(&file_priv->table_lock);
ret = idr_get_new_above(&file_priv->object_idr, obj, 1, handlep);
ret = idr_get_new_above(&file_priv->object_idr, obj, 1, (int *)handlep);
spin_unlock(&file_priv->table_lock);
if (ret == -EAGAIN)
goto again;
......@@ -237,7 +237,7 @@ EXPORT_SYMBOL(drm_gem_handle_create);
/** Returns a reference to the object named by the handle. */
struct drm_gem_object *
drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp,
int handle)
u32 handle)
{
struct drm_gem_object *obj;
......@@ -344,7 +344,7 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data,
struct drm_gem_open *args = data;
struct drm_gem_object *obj;
int ret;
int handle;
u32 handle;
if (!(dev->driver->driver_features & DRIVER_GEM))
return -ENODEV;
......@@ -539,7 +539,6 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND;
vma->vm_ops = obj->dev->driver->gem_vm_ops;
vma->vm_private_data = map->handle;
/* FIXME: use pgprot_writecombine when available */
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
/* Take a ref for this mapping of the object, so that the fault
......
......@@ -37,6 +37,7 @@
#include <linux/interrupt.h> /* For task queue support */
#include <linux/vgaarb.h>
/**
* Get interrupt from bus id.
*
......@@ -171,6 +172,26 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
}
EXPORT_SYMBOL(drm_vblank_init);
static void drm_irq_vgaarb_nokms(void *cookie, bool state)
{
struct drm_device *dev = cookie;
if (dev->driver->vgaarb_irq) {
dev->driver->vgaarb_irq(dev, state);
return;
}
if (!dev->irq_enabled)
return;
if (state)
dev->driver->irq_uninstall(dev);
else {
dev->driver->irq_preinstall(dev);
dev->driver->irq_postinstall(dev);
}
}
/**
* Install IRQ handler.
*
......@@ -231,6 +252,9 @@ int drm_irq_install(struct drm_device *dev)
return ret;
}
if (!drm_core_check_feature(dev, DRIVER_MODESET))
vga_client_register(dev->pdev, (void *)dev, drm_irq_vgaarb_nokms, NULL);
/* After installing handler */
ret = dev->driver->irq_postinstall(dev);
if (ret < 0) {
......@@ -279,6 +303,9 @@ int drm_irq_uninstall(struct drm_device * dev)
DRM_DEBUG("irq=%d\n", dev->pdev->irq);
if (!drm_core_check_feature(dev, DRIVER_MODESET))
vga_client_register(dev->pdev, NULL, NULL, NULL);
dev->driver->irq_uninstall(dev);
free_irq(dev->pdev->irq, dev);
......
......@@ -44,6 +44,7 @@
#include "drmP.h"
#include "drm_mm.h"
#include <linux/slab.h>
#include <linux/seq_file.h>
#define MM_UNUSED_TARGET 4
......@@ -370,3 +371,23 @@ void drm_mm_takedown(struct drm_mm * mm)
BUG_ON(mm->num_unused != 0);
}
EXPORT_SYMBOL(drm_mm_takedown);
#if defined(CONFIG_DEBUG_FS)
int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm)
{
struct drm_mm_node *entry;
int total_used = 0, total_free = 0, total = 0;
list_for_each_entry(entry, &mm->ml_entry, ml_entry) {
seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: %s\n", entry->start, entry->start + entry->size, entry->size, entry->free ? "free" : "used");
total += entry->size;
if (entry->free)
total_free += entry->size;
else
total_used += entry->size;
}
seq_printf(m, "total: %d, used %d free %d\n", total, total_free, total_used);
return 0;
}
EXPORT_SYMBOL(drm_mm_dump_table);
#endif
This diff is collapsed.
......@@ -106,20 +106,25 @@ int drm_proc_create_files(struct drm_info_list *files, int count,
continue;
tmp = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL);
ent = create_proc_entry(files[i].name, S_IFREG | S_IRUGO, root);
if (tmp == NULL) {
ret = -1;
goto fail;
}
tmp->minor = minor;
tmp->info_ent = &files[i];
list_add(&tmp->list, &minor->proc_nodes.list);
ent = proc_create_data(files[i].name, S_IRUGO, root,
&drm_proc_fops, tmp);
if (!ent) {
DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
name, files[i].name);
list_del(&tmp->list);
kfree(tmp);
ret = -1;
goto fail;
}
ent->proc_fops = &drm_proc_fops;
ent->data = tmp;
tmp->minor = minor;
tmp->info_ent = &files[i];
list_add(&(tmp->list), &(minor->proc_nodes.list));
}
return 0;
......
......@@ -16,6 +16,7 @@
#include <linux/kdev_t.h>
#include <linux/err.h>
#include "drm_sysfs.h"
#include "drm_core.h"
#include "drmP.h"
......@@ -253,6 +254,7 @@ static ssize_t subconnector_show(struct device *device,
case DRM_MODE_CONNECTOR_Composite:
case DRM_MODE_CONNECTOR_SVIDEO:
case DRM_MODE_CONNECTOR_Component:
case DRM_MODE_CONNECTOR_TV:
prop = dev->mode_config.tv_subconnector_property;
is_tv = 1;
break;
......@@ -293,6 +295,7 @@ static ssize_t select_subconnector_show(struct device *device,
case DRM_MODE_CONNECTOR_Composite:
case DRM_MODE_CONNECTOR_SVIDEO:
case DRM_MODE_CONNECTOR_Component:
case DRM_MODE_CONNECTOR_TV:
prop = dev->mode_config.tv_select_subconnector_property;
is_tv = 1;
break;
......@@ -391,6 +394,7 @@ int drm_sysfs_connector_add(struct drm_connector *connector)
case DRM_MODE_CONNECTOR_Composite:
case DRM_MODE_CONNECTOR_SVIDEO:
case DRM_MODE_CONNECTOR_Component:
case DRM_MODE_CONNECTOR_TV:
for (i = 0; i < ARRAY_SIZE(connector_attrs_opt1); i++) {
ret = device_create_file(&connector->kdev, &connector_attrs_opt1[i]);
if (ret)
......@@ -519,3 +523,27 @@ void drm_sysfs_device_remove(struct drm_minor *minor)
{
device_unregister(&minor->kdev);
}
/**
* drm_class_device_register - Register a struct device in the drm class.
*
* @dev: pointer to struct device to register.
*
* @dev should have all relevant members pre-filled with the exception
* of the class member. In particular, the device_type member must
* be set.
*/
int drm_class_device_register(struct device *dev)
{
dev->class = drm_class;
return device_register(dev);
}
EXPORT_SYMBOL_GPL(drm_class_device_register);
void drm_class_device_unregister(struct device *dev)
{
return device_unregister(dev);
}
EXPORT_SYMBOL_GPL(drm_class_device_unregister);
......@@ -4,10 +4,10 @@
ccflags-y := -Iinclude/drm
i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \
i915_debugfs.o \
i915_suspend.o \
i915_gem.o \
i915_gem_debug.o \
i915_gem_debugfs.o \
i915_gem_tiling.o \
intel_display.o \
intel_crt.o \
......
......@@ -158,16 +158,37 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
struct drm_device *dev = node->minor->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
seq_printf(m, "Interrupt enable: %08x\n",
I915_READ(IER));
seq_printf(m, "Interrupt identity: %08x\n",
I915_READ(IIR));
seq_printf(m, "Interrupt mask: %08x\n",
I915_READ(IMR));
seq_printf(m, "Pipe A stat: %08x\n",
I915_READ(PIPEASTAT));
seq_printf(m, "Pipe B stat: %08x\n",
I915_READ(PIPEBSTAT));
if (!IS_IGDNG(dev)) {
seq_printf(m, "Interrupt enable: %08x\n",
I915_READ(IER));
seq_printf(m, "Interrupt identity: %08x\n",
I915_READ(IIR));
seq_printf(m, "Interrupt mask: %08x\n",
I915_READ(IMR));
seq_printf(m, "Pipe A stat: %08x\n",
I915_READ(PIPEASTAT));
seq_printf(m, "Pipe B stat: %08x\n",
I915_READ(PIPEBSTAT));
} else {
seq_printf(m, "North Display Interrupt enable: %08x\n",
I915_READ(DEIER));
seq_printf(m, "North Display Interrupt identity: %08x\n",
I915_READ(DEIIR));
seq_printf(m, "North Display Interrupt mask: %08x\n",
I915_READ(DEIMR));
seq_printf(m, "South Display Interrupt enable: %08x\n",
I915_READ(SDEIER));
seq_printf(m, "South Display Interrupt identity: %08x\n",
I915_READ(SDEIIR));
seq_printf(m, "South Display Interrupt mask: %08x\n",
I915_READ(SDEIMR));
seq_printf(m, "Graphics Interrupt enable: %08x\n",
I915_READ(GTIER));
seq_printf(m, "Graphics Interrupt identity: %08x\n",
I915_READ(GTIIR));
seq_printf(m, "Graphics Interrupt mask: %08x\n",
I915_READ(GTIMR));
}
seq_printf(m, "Interrupts received: %d\n",
atomic_read(&dev_priv->irq_received));
if (dev_priv->hw_status_page != NULL) {
......@@ -312,15 +333,13 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data)
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
unsigned int head, tail, mask;
unsigned int head, tail;
head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
mask = dev_priv->ring.tail_mask;
seq_printf(m, "RingHead : %08x\n", head);
seq_printf(m, "RingTail : %08x\n", tail);
seq_printf(m, "RingMask : %08x\n", mask);
seq_printf(m, "RingSize : %08lx\n", dev_priv->ring.Size);
seq_printf(m, "Acthd : %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD));
......@@ -363,7 +382,37 @@ static int i915_error_state(struct seq_file *m, void *unused)
return 0;
}
static struct drm_info_list i915_gem_debugfs_list[] = {
static int i915_registers_info(struct seq_file *m, void *data) {
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
uint32_t reg;
#define DUMP_RANGE(start, end) \
for (reg=start; reg < end; reg += 4) \
seq_printf(m, "%08x\t%08x\n", reg, I915_READ(reg));
DUMP_RANGE(0x00000, 0x00fff); /* VGA registers */
DUMP_RANGE(0x02000, 0x02fff); /* instruction, memory, interrupt control registers */
DUMP_RANGE(0x03000, 0x031ff); /* FENCE and PPGTT control registers */
DUMP_RANGE(0x03200, 0x03fff); /* frame buffer compression registers */
DUMP_RANGE(0x05000, 0x05fff); /* I/O control registers */
DUMP_RANGE(0x06000, 0x06fff); /* clock control registers */
DUMP_RANGE(0x07000, 0x07fff); /* 3D internal debug registers */
DUMP_RANGE(0x07400, 0x088ff); /* GPE debug registers */
DUMP_RANGE(0x0a000, 0x0afff); /* display palette registers */
DUMP_RANGE(0x10000, 0x13fff); /* MMIO MCHBAR */
DUMP_RANGE(0x30000, 0x3ffff); /* overlay registers */
DUMP_RANGE(0x60000, 0x6ffff); /* display engine pipeline registers */
DUMP_RANGE(0x70000, 0x72fff); /* display and cursor registers */
DUMP_RANGE(0x73000, 0x73fff); /* performance counters */
return 0;
}
static struct drm_info_list i915_debugfs_list[] = {
{"i915_regs", i915_registers_info, 0},
{"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST},
{"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST},
{"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST},
......@@ -377,19 +426,19 @@ static struct drm_info_list i915_gem_debugfs_list[] = {
{"i915_batchbuffers", i915_batchbuffer_info, 0},
{"i915_error_state", i915_error_state, 0},
};
#define I915_GEM_DEBUGFS_ENTRIES ARRAY_SIZE(i915_gem_debugfs_list)
#define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
int i915_gem_debugfs_init(struct drm_minor *minor)
int i915_debugfs_init(struct drm_minor *minor)
{
return drm_debugfs_create_files(i915_gem_debugfs_list,
I915_GEM_DEBUGFS_ENTRIES,
return drm_debugfs_create_files(i915_debugfs_list,
I915_DEBUGFS_ENTRIES,
minor->debugfs_root, minor);
}
void i915_gem_debugfs_cleanup(struct drm_minor *minor)
void i915_debugfs_cleanup(struct drm_minor *minor)
{
drm_debugfs_remove_files(i915_gem_debugfs_list,
I915_GEM_DEBUGFS_ENTRIES, minor);
drm_debugfs_remove_files(i915_debugfs_list,
I915_DEBUGFS_ENTRIES, minor);
}
#endif /* CONFIG_DEBUG_FS */
......
......@@ -29,11 +29,11 @@
#include "drmP.h"
#include "drm.h"
#include "drm_crtc_helper.h"
#include "drm_fb_helper.h"
#include "intel_drv.h"
#include "i915_drm.h"
#include "i915_drv.h"
#define I915_DRV "i915_drv"
#include <linux/vgaarb.h>
/* Really want an OS-independent resettable timer. Would like to have
* this loop run for (eg) 3 sec, but have the timer reset every time
......@@ -80,6 +80,34 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
return -EBUSY;
}
/* As a ringbuffer is only allowed to wrap between instructions, fill
* the tail with NOOPs.
*/
int i915_wrap_ring(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
volatile unsigned int *virt;
int rem;
rem = dev_priv->ring.Size - dev_priv->ring.tail;
if (dev_priv->ring.space < rem) {
int ret = i915_wait_ring(dev, rem, __func__);
if (ret)
return ret;
}
dev_priv->ring.space -= rem;
virt = (unsigned int *)
(dev_priv->ring.virtual_start + dev_priv->ring.tail);
rem /= 4;
while (rem--)
*virt++ = MI_NOOP;
dev_priv->ring.tail = 0;
return 0;
}
/**
* Sets up the hardware status page for devices that need a physical address
* in the register.
......@@ -101,7 +129,7 @@ static int i915_init_phys_hws(struct drm_device *dev)
memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
DRM_DEBUG_DRIVER(I915_DRV, "Enabled hardware status page\n");
DRM_DEBUG_DRIVER("Enabled hardware status page\n");
return 0;
}
......@@ -187,8 +215,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
master_priv->sarea_priv = (drm_i915_sarea_t *)
((u8 *)master_priv->sarea->handle + init->sarea_priv_offset);
} else {
DRM_DEBUG_DRIVER(I915_DRV,
"sarea not found assuming DRI2 userspace\n");
DRM_DEBUG_DRIVER("sarea not found assuming DRI2 userspace\n");
}
if (init->ring_size != 0) {
......@@ -200,7 +227,6 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
}
dev_priv->ring.Size = init->ring_size;
dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
dev_priv->ring.map.offset = init->ring_start;
dev_priv->ring.map.size = init->ring_size;
......@@ -238,7 +264,7 @@ static int i915_dma_resume(struct drm_device * dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
DRM_DEBUG_DRIVER(I915_DRV, "%s\n", __func__);
DRM_DEBUG_DRIVER("%s\n", __func__);
if (dev_priv->ring.map.handle == NULL) {
DRM_ERROR("can not ioremap virtual address for"
......@@ -251,14 +277,14 @@ static int i915_dma_resume(struct drm_device * dev)
DRM_ERROR("Can not find hardware status page\n");
return -EINVAL;
}
DRM_DEBUG_DRIVER(I915_DRV, "hw status page @ %p\n",
DRM_DEBUG_DRIVER("hw status page @ %p\n",
dev_priv->hw_status_page);
if (dev_priv->status_gfx_addr != 0)
I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
else
I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
DRM_DEBUG_DRIVER(I915_DRV, "Enabled hardware status page\n");
DRM_DEBUG_DRIVER("Enabled hardware status page\n");
return 0;
}
......@@ -552,7 +578,7 @@ static int i915_dispatch_flip(struct drm_device * dev)
if (!master_priv->sarea_priv)
return -EINVAL;
DRM_DEBUG_DRIVER(I915_DRV, "%s: page=%d pfCurrentPage=%d\n",
DRM_DEBUG_DRIVER("%s: page=%d pfCurrentPage=%d\n",
__func__,
dev_priv->current_page,
master_priv->sarea_priv->pf_current_page);
......@@ -633,8 +659,7 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
return -EINVAL;
}
DRM_DEBUG_DRIVER(I915_DRV,
"i915 batchbuffer, start %x used %d cliprects %d\n",
DRM_DEBUG_DRIVER("i915 batchbuffer, start %x used %d cliprects %d\n",
batch->start, batch->used, batch->num_cliprects);
RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
......@@ -681,8 +706,7 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
void *batch_data;
int ret;
DRM_DEBUG_DRIVER(I915_DRV,
"i915 cmdbuffer, buf %p sz %d cliprects %d\n",
DRM_DEBUG_DRIVER("i915 cmdbuffer, buf %p sz %d cliprects %d\n",
cmdbuf->buf, cmdbuf->sz, cmdbuf->num_cliprects);
RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
......@@ -735,7 +759,7 @@ static int i915_flip_bufs(struct drm_device *dev, void *data,
{
int ret;
DRM_DEBUG_DRIVER(I915_DRV, "%s\n", __func__);
DRM_DEBUG_DRIVER("%s\n", __func__);
RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
......@@ -778,7 +802,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
value = dev_priv->num_fence_regs - dev_priv->fence_reg_start;
break;
default:
DRM_DEBUG_DRIVER(I915_DRV, "Unknown parameter %d\n",
DRM_DEBUG_DRIVER("Unknown parameter %d\n",
param->param);
return -EINVAL;
}
......@@ -819,7 +843,7 @@ static int i915_setparam(struct drm_device *dev, void *data,
dev_priv->fence_reg_start = param->value;
break;
default:
DRM_DEBUG_DRIVER(I915_DRV, "unknown parameter %d\n",
DRM_DEBUG_DRIVER("unknown parameter %d\n",
param->param);
return -EINVAL;
}
......@@ -846,7 +870,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
return 0;
}
DRM_DEBUG("set status page addr 0x%08x\n", (u32)hws->addr);
DRM_DEBUG_DRIVER("set status page addr 0x%08x\n", (u32)hws->addr);
dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12);
......@@ -868,13 +892,25 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
DRM_DEBUG_DRIVER(I915_DRV, "load hws HWS_PGA with gfx mem 0x%x\n",
DRM_DEBUG_DRIVER("load hws HWS_PGA with gfx mem 0x%x\n",
dev_priv->status_gfx_addr);
DRM_DEBUG_DRIVER(I915_DRV, "load hws at %p\n",
DRM_DEBUG_DRIVER("load hws at %p\n",
dev_priv->hw_status_page);
return 0;
}
static int i915_get_bridge_dev(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
dev_priv->bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
if (!dev_priv->bridge_dev) {
DRM_ERROR("bridge device not found\n");
return -1;
}
return 0;
}
/**
* i915_probe_agp - get AGP bootup configuration
* @pdev: PCI device
......@@ -888,20 +924,13 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
static int i915_probe_agp(struct drm_device *dev, uint32_t *aperture_size,
uint32_t *preallocated_size)
{
struct pci_dev *bridge_dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u16 tmp = 0;
unsigned long overhead;
unsigned long stolen;
bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
if (!bridge_dev) {
DRM_ERROR("bridge device not found\n");
return -1;
}
/* Get the fb aperture size and "stolen" memory amount. */
pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp);
pci_dev_put(bridge_dev);
pci_read_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, &tmp);
*aperture_size = 1024 * 1024;
*preallocated_size = 1024 * 1024;
......@@ -984,6 +1013,19 @@ static int i915_probe_agp(struct drm_device *dev, uint32_t *aperture_size,
return 0;
}
/* true = enable decode, false = disable decoder */
static unsigned int i915_vga_set_decode(void *cookie, bool state)
{
struct drm_device *dev = cookie;
intel_modeset_vga_set_state(dev, state);
if (state)
return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
else
return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
}
static int i915_load_modeset_init(struct drm_device *dev,
unsigned long prealloc_size,
unsigned long agp_size)
......@@ -1029,6 +1071,11 @@ static int i915_load_modeset_init(struct drm_device *dev,
if (ret)
DRM_INFO("failed to find VBIOS tables\n");
/* if we have > 1 VGA cards, then disable the radeon VGA resources */
ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode);
if (ret)
goto destroy_ringbuffer;
ret = drm_irq_install(dev);
if (ret)
goto destroy_ringbuffer;
......@@ -1153,11 +1200,16 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
base = drm_get_resource_start(dev, mmio_bar);
size = drm_get_resource_len(dev, mmio_bar);
if (i915_get_bridge_dev(dev)) {
ret = -EIO;
goto free_priv;
}
dev_priv->regs = ioremap(base, size);
if (!dev_priv->regs) {
DRM_ERROR("failed to map registers\n");
ret = -EIO;
goto free_priv;
goto put_bridge;
}
dev_priv->mm.gtt_mapping =
......@@ -1269,6 +1321,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
io_mapping_free(dev_priv->mm.gtt_mapping);
out_rmmap:
iounmap(dev_priv->regs);
put_bridge:
pci_dev_put(dev_priv->bridge_dev);
free_priv:
kfree(dev_priv);
return ret;
......@@ -1289,6 +1343,7 @@ int i915_driver_unload(struct drm_device *dev)
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
drm_irq_uninstall(dev);
vga_client_register(dev->pdev, NULL, NULL, NULL);
}
if (dev->pdev->msi_enabled)
......@@ -1312,6 +1367,7 @@ int i915_driver_unload(struct drm_device *dev)
i915_gem_lastclose(dev);
}
pci_dev_put(dev_priv->bridge_dev);
kfree(dev->dev_private);
return 0;
......@@ -1321,7 +1377,7 @@ int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv)
{
struct drm_i915_file_private *i915_file_priv;
DRM_DEBUG_DRIVER(I915_DRV, "\n");
DRM_DEBUG_DRIVER("\n");
i915_file_priv = (struct drm_i915_file_private *)
kmalloc(sizeof(*i915_file_priv), GFP_KERNEL);
......@@ -1352,7 +1408,7 @@ void i915_driver_lastclose(struct drm_device * dev)
drm_i915_private_t *dev_priv = dev->dev_private;
if (!dev_priv || drm_core_check_feature(dev, DRIVER_MODESET)) {
intelfb_restore();
drm_fb_helper_restore();
return;
}
......
......@@ -37,12 +37,15 @@
#include <linux/console.h>
#include "drm_crtc_helper.h"
static unsigned int i915_modeset = -1;
static int i915_modeset = -1;
module_param_named(modeset, i915_modeset, int, 0400);
unsigned int i915_fbpercrtc = 0;
module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400);
unsigned int i915_powersave = 1;
module_param_named(powersave, i915_powersave, int, 0400);
static struct drm_driver driver;
static struct pci_device_id pciidlist[] = {
......@@ -188,8 +191,8 @@ static struct drm_driver driver = {
.master_create = i915_master_create,
.master_destroy = i915_master_destroy,
#if defined(CONFIG_DEBUG_FS)
.debugfs_init = i915_gem_debugfs_init,
.debugfs_cleanup = i915_gem_debugfs_cleanup,
.debugfs_init = i915_debugfs_init,
.debugfs_cleanup = i915_debugfs_cleanup,
#endif
.gem_init_object = i915_gem_init_object,
.gem_free_object = i915_gem_free_object,
......
......@@ -85,7 +85,6 @@ struct drm_i915_gem_phys_object {
};
typedef struct _drm_i915_ring_buffer {
int tail_mask;
unsigned long Size;
u8 *virtual_start;
int head;
......@@ -156,6 +155,7 @@ typedef struct drm_i915_private {
void __iomem *regs;
struct pci_dev *bridge_dev;
drm_i915_ring_buffer_t ring;
drm_dma_handle_t *status_page_dmah;
......@@ -311,7 +311,7 @@ typedef struct drm_i915_private {
u32 saveIMR;
u32 saveCACHE_MODE_0;
u32 saveD_STATE;
u32 saveCG_2D_DIS;
u32 saveDSPCLK_GATE_D;
u32 saveMI_ARB_STATE;
u32 saveSWF0[16];
u32 saveSWF1[16];
......@@ -443,6 +443,14 @@ typedef struct drm_i915_private {
struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT];
} mm;
struct sdvo_device_mapping sdvo_mappings[2];
/* Reclocking support */
bool render_reclock_avail;
bool lvds_downclock_avail;
struct work_struct idle_work;
struct timer_list idle_timer;
bool busy;
u16 orig_clock;
} drm_i915_private_t;
/** driver private structure attached to each drm_gem_object */
......@@ -575,6 +583,7 @@ enum intel_chip_family {
extern struct drm_ioctl_desc i915_ioctls[];
extern int i915_max_ioctl;
extern unsigned int i915_fbpercrtc;
extern unsigned int i915_powersave;
extern int i915_master_create(struct drm_device *dev, struct drm_master *master);
extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master);
......@@ -730,8 +739,8 @@ void i915_gem_dump_object(struct drm_gem_object *obj, int len,
void i915_dump_lru(struct drm_device *dev, const char *where);
/* i915_debugfs.c */
int i915_gem_debugfs_init(struct drm_minor *minor);
void i915_gem_debugfs_cleanup(struct drm_minor *minor);
int i915_debugfs_init(struct drm_minor *minor);
void i915_debugfs_cleanup(struct drm_minor *minor);
/* i915_suspend.c */
extern int i915_save_state(struct drm_device *dev);
......@@ -757,6 +766,7 @@ static inline void opregion_enable_asle(struct drm_device *dev) { return; }
/* modesetting */
extern void intel_modeset_init(struct drm_device *dev);
extern void intel_modeset_cleanup(struct drm_device *dev);
extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
/**
* Lock test for when it's just for synchronization of ring access.
......@@ -781,33 +791,32 @@ extern void intel_modeset_cleanup(struct drm_device *dev);
#define I915_VERBOSE 0
#define RING_LOCALS unsigned int outring, ringmask, outcount; \
volatile char *virt;
#define BEGIN_LP_RING(n) do { \
if (I915_VERBOSE) \
DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n)); \
if (dev_priv->ring.space < (n)*4) \
i915_wait_ring(dev, (n)*4, __func__); \
outcount = 0; \
outring = dev_priv->ring.tail; \
ringmask = dev_priv->ring.tail_mask; \
virt = dev_priv->ring.virtual_start; \
#define RING_LOCALS volatile unsigned int *ring_virt__;
#define BEGIN_LP_RING(n) do { \
int bytes__ = 4*(n); \
if (I915_VERBOSE) DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n)); \
/* a wrap must occur between instructions so pad beforehand */ \
if (unlikely (dev_priv->ring.tail + bytes__ > dev_priv->ring.Size)) \
i915_wrap_ring(dev); \
if (unlikely (dev_priv->ring.space < bytes__)) \
i915_wait_ring(dev, bytes__, __func__); \
ring_virt__ = (unsigned int *) \
(dev_priv->ring.virtual_start + dev_priv->ring.tail); \
dev_priv->ring.tail += bytes__; \
dev_priv->ring.tail &= dev_priv->ring.Size - 1; \
dev_priv->ring.space -= bytes__; \
} while (0)
#define OUT_RING(n) do { \
#define OUT_RING(n) do { \
if (I915_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \
*(volatile unsigned int *)(virt + outring) = (n); \
outcount++; \
outring += 4; \
outring &= ringmask; \
*ring_virt__++ = (n); \
} while (0)
#define ADVANCE_LP_RING() do { \
if (I915_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING %x\n", outring); \
dev_priv->ring.tail = outring; \
dev_priv->ring.space -= outcount * 4; \
I915_WRITE(PRB0_TAIL, outring); \
if (I915_VERBOSE) \
DRM_DEBUG("ADVANCE_LP_RING %x\n", dev_priv->ring.tail); \
I915_WRITE(PRB0_TAIL, dev_priv->ring.tail); \
} while(0)
/**
......@@ -830,6 +839,7 @@ extern void intel_modeset_cleanup(struct drm_device *dev);
#define I915_GEM_HWS_INDEX 0x20
#define I915_BREADCRUMB_INDEX 0x21
extern int i915_wrap_ring(struct drm_device * dev);
extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define IS_I830(dev) ((dev)->pci_device == 0x3577)
......@@ -903,6 +913,9 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
/* dsparb controlled by hw only */
#define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev))
#define HAS_FW_BLC(dev) (IS_I9XX(dev) || IS_G4X(dev) || IS_IGDNG(dev))
#define HAS_PIPE_CXSR(dev) (IS_G4X(dev) || IS_IGDNG(dev))
#define PRIMARY_RINGBUFFER_SIZE (128*1024)
#endif
......@@ -29,6 +29,7 @@
#include "drm.h"
#include "i915_drm.h"
#include "i915_drv.h"
#include "intel_drv.h"
#include <linux/swap.h>
#include <linux/pci.h>
......@@ -111,7 +112,8 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
{
struct drm_i915_gem_create *args = data;
struct drm_gem_object *obj;
int handle, ret;
int ret;
u32 handle;
args->size = roundup(args->size, PAGE_SIZE);
......@@ -981,6 +983,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_gem_set_domain *args = data;
struct drm_gem_object *obj;
struct drm_i915_gem_object *obj_priv;
uint32_t read_domains = args->read_domains;
uint32_t write_domain = args->write_domain;
int ret;
......@@ -1004,15 +1007,17 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
obj = drm_gem_object_lookup(dev, file_priv, args->handle);
if (obj == NULL)
return -EBADF;
obj_priv = obj->driver_private;
mutex_lock(&dev->struct_mutex);
intel_mark_busy(dev, obj);
#if WATCH_BUF
DRM_INFO("set_domain_ioctl %p(%zd), %08x %08x\n",
obj, obj->size, read_domains, write_domain);
#endif
if (read_domains & I915_GEM_DOMAIN_GTT) {
struct drm_i915_gem_object *obj_priv = obj->driver_private;
ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0);
/* Update the LRU on the fence for the CPU access that's
......@@ -2776,6 +2781,8 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
BUG_ON(obj->pending_read_domains & I915_GEM_DOMAIN_CPU);
BUG_ON(obj->pending_write_domain == I915_GEM_DOMAIN_CPU);
intel_mark_busy(dev, obj);
#if WATCH_BUF
DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n",
__func__, obj,
......@@ -4093,7 +4100,6 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
/* Set up the kernel mapping for the ring. */
ring->Size = obj->size;
ring->tail_mask = obj->size - 1;
ring->map.offset = dev->agp->base + obj_priv->gtt_offset;
ring->map.size = obj->size;
......
......@@ -94,23 +94,15 @@
static int
intel_alloc_mchbar_resource(struct drm_device *dev)
{
struct pci_dev *bridge_dev;
drm_i915_private_t *dev_priv = dev->dev_private;
int reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915;
u32 temp_lo, temp_hi = 0;
u64 mchbar_addr;
int ret = 0;
bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
if (!bridge_dev) {
DRM_DEBUG("no bridge dev?!\n");
ret = -ENODEV;
goto out;
}
if (IS_I965G(dev))
pci_read_config_dword(bridge_dev, reg + 4, &temp_hi);
pci_read_config_dword(bridge_dev, reg, &temp_lo);
pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi);
pci_read_config_dword(dev_priv->bridge_dev, reg, &temp_lo);
mchbar_addr = ((u64)temp_hi << 32) | temp_lo;
/* If ACPI doesn't have it, assume we need to allocate it ourselves */
......@@ -118,30 +110,28 @@ intel_alloc_mchbar_resource(struct drm_device *dev)
if (mchbar_addr &&
pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) {
ret = 0;
goto out_put;
goto out;
}
#endif
/* Get some space for it */
ret = pci_bus_alloc_resource(bridge_dev->bus, &dev_priv->mch_res,
ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus, &dev_priv->mch_res,
MCHBAR_SIZE, MCHBAR_SIZE,
PCIBIOS_MIN_MEM,
0, pcibios_align_resource,
bridge_dev);
dev_priv->bridge_dev);
if (ret) {
DRM_DEBUG("failed bus alloc: %d\n", ret);
dev_priv->mch_res.start = 0;
goto out_put;
goto out;
}
if (IS_I965G(dev))
pci_write_config_dword(bridge_dev, reg + 4,
pci_write_config_dword(dev_priv->bridge_dev, reg + 4,
upper_32_bits(dev_priv->mch_res.start));
pci_write_config_dword(bridge_dev, reg,
pci_write_config_dword(dev_priv->bridge_dev, reg,
lower_32_bits(dev_priv->mch_res.start));
out_put:
pci_dev_put(bridge_dev);
out:
return ret;
}
......@@ -150,44 +140,36 @@ intel_alloc_mchbar_resource(struct drm_device *dev)
static bool
intel_setup_mchbar(struct drm_device *dev)
{
struct pci_dev *bridge_dev;
drm_i915_private_t *dev_priv = dev->dev_private;
int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915;
u32 temp;
bool need_disable = false, enabled;
bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
if (!bridge_dev) {
DRM_DEBUG("no bridge dev?!\n");
goto out;
}
if (IS_I915G(dev) || IS_I915GM(dev)) {
pci_read_config_dword(bridge_dev, DEVEN_REG, &temp);
pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp);
enabled = !!(temp & DEVEN_MCHBAR_EN);
} else {
pci_read_config_dword(bridge_dev, mchbar_reg, &temp);
pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
enabled = temp & 1;
}
/* If it's already enabled, don't have to do anything */
if (enabled)
goto out_put;
goto out;
if (intel_alloc_mchbar_resource(dev))
goto out_put;
goto out;
need_disable = true;
/* Space is allocated or reserved, so enable it. */
if (IS_I915G(dev) || IS_I915GM(dev)) {
pci_write_config_dword(bridge_dev, DEVEN_REG,
pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG,
temp | DEVEN_MCHBAR_EN);
} else {
pci_read_config_dword(bridge_dev, mchbar_reg, &temp);
pci_write_config_dword(bridge_dev, mchbar_reg, temp | 1);
pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp | 1);
}
out_put:
pci_dev_put(bridge_dev);
out:
return need_disable;
}
......@@ -196,25 +178,18 @@ static void
intel_teardown_mchbar(struct drm_device *dev, bool disable)
{
drm_i915_private_t *dev_priv = dev->dev_private;
struct pci_dev *bridge_dev;
int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915;
u32 temp;
bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
if (!bridge_dev) {
DRM_DEBUG("no bridge dev?!\n");
return;
}
if (disable) {
if (IS_I915G(dev) || IS_I915GM(dev)) {
pci_read_config_dword(bridge_dev, DEVEN_REG, &temp);
pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp);
temp &= ~DEVEN_MCHBAR_EN;
pci_write_config_dword(bridge_dev, DEVEN_REG, temp);
pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG, temp);
} else {
pci_read_config_dword(bridge_dev, mchbar_reg, &temp);
pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
temp &= ~1;
pci_write_config_dword(bridge_dev, mchbar_reg, temp);
pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp);
}
}
......@@ -234,7 +209,13 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
bool need_disable;
if (!IS_I9XX(dev)) {
if (IS_IGDNG(dev)) {
/* On IGDNG whatever DRAM config, GPU always do
* same swizzling setup.
*/
swizzle_x = I915_BIT_6_SWIZZLE_9_10;
swizzle_y = I915_BIT_6_SWIZZLE_9;
} else if (!IS_I9XX(dev)) {
/* As far as we know, the 865 doesn't have these bit 6
* swizzling issues.
*/
......@@ -317,13 +298,6 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
}
}
/* FIXME: check with memory config on IGDNG */
if (IS_IGDNG(dev)) {
DRM_ERROR("disable tiling on IGDNG...\n");
swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
}
dev_priv->mm.bit_6_swizzle_x = swizzle_x;
dev_priv->mm.bit_6_swizzle_y = swizzle_y;
}
......
......@@ -565,6 +565,27 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
I915_READ(PORT_HOTPLUG_STAT);
/* EOS interrupts occurs */
if (IS_IGD(dev) &&
(hotplug_status & CRT_EOS_INT_STATUS)) {
u32 temp;
DRM_DEBUG("EOS interrupt occurs\n");
/* status is already cleared */
temp = I915_READ(ADPA);
temp &= ~ADPA_DAC_ENABLE;
I915_WRITE(ADPA, temp);
temp = I915_READ(PORT_HOTPLUG_EN);
temp &= ~CRT_EOS_INT_EN;
I915_WRITE(PORT_HOTPLUG_EN, temp);
temp = I915_READ(PORT_HOTPLUG_STAT);
if (temp & CRT_EOS_INT_STATUS)
I915_WRITE(PORT_HOTPLUG_STAT,
CRT_EOS_INT_STATUS);
}
}
I915_WRITE(IIR, iir);
......
......@@ -30,6 +30,7 @@
* fb aperture size and the amount of pre-reserved memory.
*/
#define INTEL_GMCH_CTRL 0x52
#define INTEL_GMCH_VGA_DISABLE (1 << 1)
#define INTEL_GMCH_ENABLED 0x4
#define INTEL_GMCH_MEM_MASK 0x1
#define INTEL_GMCH_MEM_64M 0x1
......@@ -55,7 +56,7 @@
/* PCI config space */
#define HPLLCC 0xc0 /* 855 only */
#define GC_CLOCK_CONTROL_MASK (3 << 0)
#define GC_CLOCK_CONTROL_MASK (0xf << 0)
#define GC_CLOCK_133_200 (0 << 0)
#define GC_CLOCK_100_200 (1 << 0)
#define GC_CLOCK_100_133 (2 << 0)
......@@ -65,6 +66,25 @@
#define GC_DISPLAY_CLOCK_190_200_MHZ (0 << 4)
#define GC_DISPLAY_CLOCK_333_MHZ (4 << 4)
#define GC_DISPLAY_CLOCK_MASK (7 << 4)
#define GM45_GC_RENDER_CLOCK_MASK (0xf << 0)
#define GM45_GC_RENDER_CLOCK_266_MHZ (8 << 0)
#define GM45_GC_RENDER_CLOCK_320_MHZ (9 << 0)
#define GM45_GC_RENDER_CLOCK_400_MHZ (0xb << 0)
#define GM45_GC_RENDER_CLOCK_533_MHZ (0xc << 0)
#define I965_GC_RENDER_CLOCK_MASK (0xf << 0)
#define I965_GC_RENDER_CLOCK_267_MHZ (2 << 0)
#define I965_GC_RENDER_CLOCK_333_MHZ (3 << 0)
#define I965_GC_RENDER_CLOCK_444_MHZ (4 << 0)
#define I965_GC_RENDER_CLOCK_533_MHZ (5 << 0)
#define I945_GC_RENDER_CLOCK_MASK (7 << 0)
#define I945_GC_RENDER_CLOCK_166_MHZ (0 << 0)
#define I945_GC_RENDER_CLOCK_200_MHZ (1 << 0)
#define I945_GC_RENDER_CLOCK_250_MHZ (3 << 0)
#define I945_GC_RENDER_CLOCK_400_MHZ (5 << 0)
#define I915_GC_RENDER_CLOCK_MASK (7 << 0)
#define I915_GC_RENDER_CLOCK_166_MHZ (0 << 0)
#define I915_GC_RENDER_CLOCK_200_MHZ (1 << 0)
#define I915_GC_RENDER_CLOCK_333_MHZ (4 << 0)
#define LBB 0xf4
/* VGA stuff */
......@@ -553,9 +573,118 @@
#define DPLLA_TEST_M_BYPASS (1 << 2)
#define DPLLA_INPUT_BUFFER_ENABLE (1 << 0)
#define D_STATE 0x6104
#define CG_2D_DIS 0x6200
#define DPCUNIT_CLOCK_GATE_DISABLE (1 << 24)
#define CG_3D_DIS 0x6204
#define DSTATE_PLL_D3_OFF (1<<3)
#define DSTATE_GFX_CLOCK_GATING (1<<1)
#define DSTATE_DOT_CLOCK_GATING (1<<0)
#define DSPCLK_GATE_D 0x6200
# define DPUNIT_B_CLOCK_GATE_DISABLE (1 << 30) /* 965 */
# define VSUNIT_CLOCK_GATE_DISABLE (1 << 29) /* 965 */
# define VRHUNIT_CLOCK_GATE_DISABLE (1 << 28) /* 965 */
# define VRDUNIT_CLOCK_GATE_DISABLE (1 << 27) /* 965 */
# define AUDUNIT_CLOCK_GATE_DISABLE (1 << 26) /* 965 */
# define DPUNIT_A_CLOCK_GATE_DISABLE (1 << 25) /* 965 */
# define DPCUNIT_CLOCK_GATE_DISABLE (1 << 24) /* 965 */
# define TVRUNIT_CLOCK_GATE_DISABLE (1 << 23) /* 915-945 */
# define TVCUNIT_CLOCK_GATE_DISABLE (1 << 22) /* 915-945 */
# define TVFUNIT_CLOCK_GATE_DISABLE (1 << 21) /* 915-945 */
# define TVEUNIT_CLOCK_GATE_DISABLE (1 << 20) /* 915-945 */
# define DVSUNIT_CLOCK_GATE_DISABLE (1 << 19) /* 915-945 */
# define DSSUNIT_CLOCK_GATE_DISABLE (1 << 18) /* 915-945 */
# define DDBUNIT_CLOCK_GATE_DISABLE (1 << 17) /* 915-945 */
# define DPRUNIT_CLOCK_GATE_DISABLE (1 << 16) /* 915-945 */
# define DPFUNIT_CLOCK_GATE_DISABLE (1 << 15) /* 915-945 */
# define DPBMUNIT_CLOCK_GATE_DISABLE (1 << 14) /* 915-945 */
# define DPLSUNIT_CLOCK_GATE_DISABLE (1 << 13) /* 915-945 */
# define DPLUNIT_CLOCK_GATE_DISABLE (1 << 12) /* 915-945 */
# define DPOUNIT_CLOCK_GATE_DISABLE (1 << 11)
# define DPBUNIT_CLOCK_GATE_DISABLE (1 << 10)
# define DCUNIT_CLOCK_GATE_DISABLE (1 << 9)
# define DPUNIT_CLOCK_GATE_DISABLE (1 << 8)
# define VRUNIT_CLOCK_GATE_DISABLE (1 << 7) /* 915+: reserved */
# define OVHUNIT_CLOCK_GATE_DISABLE (1 << 6) /* 830-865 */
# define DPIOUNIT_CLOCK_GATE_DISABLE (1 << 6) /* 915-945 */
# define OVFUNIT_CLOCK_GATE_DISABLE (1 << 5)
# define OVBUNIT_CLOCK_GATE_DISABLE (1 << 4)
/**
* This bit must be set on the 830 to prevent hangs when turning off the
* overlay scaler.
*/
# define OVRUNIT_CLOCK_GATE_DISABLE (1 << 3)
# define OVCUNIT_CLOCK_GATE_DISABLE (1 << 2)
# define OVUUNIT_CLOCK_GATE_DISABLE (1 << 1)
# define ZVUNIT_CLOCK_GATE_DISABLE (1 << 0) /* 830 */
# define OVLUNIT_CLOCK_GATE_DISABLE (1 << 0) /* 845,865 */
#define RENCLK_GATE_D1 0x6204
# define BLITTER_CLOCK_GATE_DISABLE (1 << 13) /* 945GM only */
# define MPEG_CLOCK_GATE_DISABLE (1 << 12) /* 945GM only */
# define PC_FE_CLOCK_GATE_DISABLE (1 << 11)
# define PC_BE_CLOCK_GATE_DISABLE (1 << 10)
# define WINDOWER_CLOCK_GATE_DISABLE (1 << 9)
# define INTERPOLATOR_CLOCK_GATE_DISABLE (1 << 8)
# define COLOR_CALCULATOR_CLOCK_GATE_DISABLE (1 << 7)
# define MOTION_COMP_CLOCK_GATE_DISABLE (1 << 6)
# define MAG_CLOCK_GATE_DISABLE (1 << 5)
/** This bit must be unset on 855,865 */
# define MECI_CLOCK_GATE_DISABLE (1 << 4)
# define DCMP_CLOCK_GATE_DISABLE (1 << 3)
# define MEC_CLOCK_GATE_DISABLE (1 << 2)
# define MECO_CLOCK_GATE_DISABLE (1 << 1)
/** This bit must be set on 855,865. */
# define SV_CLOCK_GATE_DISABLE (1 << 0)
# define I915_MPEG_CLOCK_GATE_DISABLE (1 << 16)
# define I915_VLD_IP_PR_CLOCK_GATE_DISABLE (1 << 15)
# define I915_MOTION_COMP_CLOCK_GATE_DISABLE (1 << 14)
# define I915_BD_BF_CLOCK_GATE_DISABLE (1 << 13)
# define I915_SF_SE_CLOCK_GATE_DISABLE (1 << 12)
# define I915_WM_CLOCK_GATE_DISABLE (1 << 11)
# define I915_IZ_CLOCK_GATE_DISABLE (1 << 10)
# define I915_PI_CLOCK_GATE_DISABLE (1 << 9)
# define I915_DI_CLOCK_GATE_DISABLE (1 << 8)
# define I915_SH_SV_CLOCK_GATE_DISABLE (1 << 7)
# define I915_PL_DG_QC_FT_CLOCK_GATE_DISABLE (1 << 6)
# define I915_SC_CLOCK_GATE_DISABLE (1 << 5)
# define I915_FL_CLOCK_GATE_DISABLE (1 << 4)
# define I915_DM_CLOCK_GATE_DISABLE (1 << 3)
# define I915_PS_CLOCK_GATE_DISABLE (1 << 2)
# define I915_CC_CLOCK_GATE_DISABLE (1 << 1)
# define I915_BY_CLOCK_GATE_DISABLE (1 << 0)
# define I965_RCZ_CLOCK_GATE_DISABLE (1 << 30)
/** This bit must always be set on 965G/965GM */
# define I965_RCC_CLOCK_GATE_DISABLE (1 << 29)
# define I965_RCPB_CLOCK_GATE_DISABLE (1 << 28)
# define I965_DAP_CLOCK_GATE_DISABLE (1 << 27)
# define I965_ROC_CLOCK_GATE_DISABLE (1 << 26)
# define I965_GW_CLOCK_GATE_DISABLE (1 << 25)
# define I965_TD_CLOCK_GATE_DISABLE (1 << 24)
/** This bit must always be set on 965G */
# define I965_ISC_CLOCK_GATE_DISABLE (1 << 23)
# define I965_IC_CLOCK_GATE_DISABLE (1 << 22)
# define I965_EU_CLOCK_GATE_DISABLE (1 << 21)
# define I965_IF_CLOCK_GATE_DISABLE (1 << 20)
# define I965_TC_CLOCK_GATE_DISABLE (1 << 19)
# define I965_SO_CLOCK_GATE_DISABLE (1 << 17)
# define I965_FBC_CLOCK_GATE_DISABLE (1 << 16)
# define I965_MARI_CLOCK_GATE_DISABLE (1 << 15)
# define I965_MASF_CLOCK_GATE_DISABLE (1 << 14)
# define I965_MAWB_CLOCK_GATE_DISABLE (1 << 13)
# define I965_EM_CLOCK_GATE_DISABLE (1 << 12)
# define I965_UC_CLOCK_GATE_DISABLE (1 << 11)
# define I965_SI_CLOCK_GATE_DISABLE (1 << 6)
# define I965_MT_CLOCK_GATE_DISABLE (1 << 5)
# define I965_PL_CLOCK_GATE_DISABLE (1 << 4)
# define I965_DG_CLOCK_GATE_DISABLE (1 << 3)
# define I965_QC_CLOCK_GATE_DISABLE (1 << 2)
# define I965_FT_CLOCK_GATE_DISABLE (1 << 1)
# define I965_DM_CLOCK_GATE_DISABLE (1 << 0)
#define RENCLK_GATE_D2 0x6208
#define VF_UNIT_CLOCK_GATE_DISABLE (1 << 9)
#define GS_UNIT_CLOCK_GATE_DISABLE (1 << 7)
#define CL_UNIT_CLOCK_GATE_DISABLE (1 << 6)
#define RAMCLK_GATE_D 0x6210 /* CRL only */
#define DEUC 0x6214 /* CRL only */
/*
* Palette regs
......@@ -683,6 +812,7 @@
#define SDVOB_HOTPLUG_INT_EN (1 << 26)
#define SDVOC_HOTPLUG_INT_EN (1 << 25)
#define TV_HOTPLUG_INT_EN (1 << 18)
#define CRT_EOS_INT_EN (1 << 10)
#define CRT_HOTPLUG_INT_EN (1 << 9)
#define CRT_HOTPLUG_FORCE_DETECT (1 << 3)
#define CRT_HOTPLUG_ACTIVATION_PERIOD_32 (0 << 8)
......@@ -717,6 +847,7 @@
#define DPC_HOTPLUG_INT_STATUS (1 << 28)
#define HDMID_HOTPLUG_INT_STATUS (1 << 27)
#define DPD_HOTPLUG_INT_STATUS (1 << 27)
#define CRT_EOS_INT_STATUS (1 << 12)
#define CRT_HOTPLUG_INT_STATUS (1 << 11)
#define TV_HOTPLUG_INT_STATUS (1 << 10)
#define CRT_HOTPLUG_MONITOR_MASK (3 << 8)
......@@ -1586,6 +1717,7 @@
#define PIPECONF_PROGRESSIVE (0 << 21)
#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21)
#define PIPECONF_CXSR_DOWNCLOCK (1<<16)
#define PIPEASTAT 0x70024
#define PIPE_FIFO_UNDERRUN_STATUS (1UL<<31)
#define PIPE_CRC_ERROR_ENABLE (1UL<<29)
......@@ -1733,6 +1865,7 @@
#define DISPPLANE_NO_LINE_DOUBLE 0
#define DISPPLANE_STEREO_POLARITY_FIRST 0
#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
#define DISPPLANE_TRICKLE_FEED_DISABLE (1<<14) /* IGDNG */
#define DISPPLANE_TILED (1<<10)
#define DSPAADDR 0x70184
#define DSPASTRIDE 0x70188
......@@ -1913,6 +2046,9 @@
#define GTIIR 0x44018
#define GTIER 0x4401c
#define DISP_ARB_CTL 0x45000
#define DISP_TILE_SURFACE_SWIZZLING (1<<13)
/* PCH */
/* south display engine interrupt */
......
......@@ -461,7 +461,7 @@ int i915_save_state(struct drm_device *dev)
/* Clock gating state */
dev_priv->saveD_STATE = I915_READ(D_STATE);
dev_priv->saveCG_2D_DIS = I915_READ(CG_2D_DIS);
dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D);
/* Cache mode state */
dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
......@@ -588,7 +588,7 @@ int i915_restore_state(struct drm_device *dev)
/* Clock gating state */
I915_WRITE (D_STATE, dev_priv->saveD_STATE);
I915_WRITE (CG_2D_DIS, dev_priv->saveCG_2D_DIS);
I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D);
/* Cache mode state */
I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
......
......@@ -355,8 +355,14 @@ parse_driver_features(struct drm_i915_private *dev_priv,
}
driver = find_section(bdb, BDB_DRIVER_FEATURES);
if (driver && driver->lvds_config == BDB_DRIVER_FEATURE_EDP)
if (!driver)
return;
if (driver->lvds_config == BDB_DRIVER_FEATURE_EDP)
dev_priv->edp_support = 1;
if (driver->dual_frequency)
dev_priv->render_reclock_avail = true;
}
/**
......
......@@ -64,6 +64,34 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
}
I915_WRITE(reg, temp);
if (IS_IGD(dev)) {
if (mode == DRM_MODE_DPMS_OFF) {
/* turn off DAC */
temp = I915_READ(PORT_HOTPLUG_EN);
temp &= ~CRT_EOS_INT_EN;
I915_WRITE(PORT_HOTPLUG_EN, temp);
temp = I915_READ(PORT_HOTPLUG_STAT);
if (temp & CRT_EOS_INT_STATUS)
I915_WRITE(PORT_HOTPLUG_STAT,
CRT_EOS_INT_STATUS);
} else {
/* turn on DAC. EOS interrupt must be enabled after DAC
* is enabled, so it sounds not good to enable it in
* i915_driver_irq_postinstall()
* wait 12.5ms after DAC is enabled
*/
msleep(13);
temp = I915_READ(PORT_HOTPLUG_STAT);
if (temp & CRT_EOS_INT_STATUS)
I915_WRITE(PORT_HOTPLUG_STAT,
CRT_EOS_INT_STATUS);
temp = I915_READ(PORT_HOTPLUG_EN);
temp |= CRT_EOS_INT_EN;
I915_WRITE(PORT_HOTPLUG_EN, temp);
}
}
}
static int intel_crt_mode_valid(struct drm_connector *connector,
......
This diff is collapsed.
......@@ -117,9 +117,9 @@ struct intel_crtc {
uint32_t cursor_addr;
u8 lut_r[256], lut_g[256], lut_b[256];
int dpms_mode;
struct intel_framebuffer *fbdev_fb;
/* a mode_set for fbdev users on this crtc */
struct drm_mode_set mode_set;
bool busy; /* is scanout buffer being updated frequently? */
struct timer_list idle_timer;
bool lowfreq_avail;
};
#define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
......@@ -138,6 +138,7 @@ extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg);
extern bool intel_sdvo_init(struct drm_device *dev, int output_device);
extern void intel_dvo_init(struct drm_device *dev);
extern void intel_tv_init(struct drm_device *dev);
extern void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj);
extern void intel_lvds_init(struct drm_device *dev);
extern void intel_dp_init(struct drm_device *dev, int dp_reg);
void
......@@ -178,4 +179,5 @@ extern int intel_framebuffer_create(struct drm_device *dev,
struct drm_mode_fb_cmd *mode_cmd,
struct drm_framebuffer **fb,
struct drm_gem_object *obj);
#endif /* __INTEL_DRV_H__ */
This diff is collapsed.
......@@ -42,11 +42,11 @@ void intel_i2c_quirk_set(struct drm_device *dev, bool enable)
if (!IS_IGD(dev))
return;
if (enable)
I915_WRITE(CG_2D_DIS,
I915_READ(CG_2D_DIS) | DPCUNIT_CLOCK_GATE_DISABLE);
I915_WRITE(DSPCLK_GATE_D,
I915_READ(DSPCLK_GATE_D) | DPCUNIT_CLOCK_GATE_DISABLE);
else
I915_WRITE(CG_2D_DIS,
I915_READ(CG_2D_DIS) & (~DPCUNIT_CLOCK_GATE_DISABLE));
I915_WRITE(DSPCLK_GATE_D,
I915_READ(DSPCLK_GATE_D) & (~DPCUNIT_CLOCK_GATE_DISABLE));
}
/*
......
......@@ -38,16 +38,6 @@
#include "i915_drv.h"
#include <linux/acpi.h>
#define I915_LVDS "i915_lvds"
/*
* the following four scaling options are defined.
* #define DRM_MODE_SCALE_NON_GPU 0
* #define DRM_MODE_SCALE_FULLSCREEN 1
* #define DRM_MODE_SCALE_NO_SCALE 2
* #define DRM_MODE_SCALE_ASPECT 3
*/
/* Private structure for the integrated LVDS support */
struct intel_lvds_priv {
int fitting_mode;
......@@ -336,7 +326,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
I915_WRITE(BCLRPAT_B, 0);
switch (lvds_priv->fitting_mode) {
case DRM_MODE_SCALE_NO_SCALE:
case DRM_MODE_SCALE_CENTER:
/*
* For centered modes, we have to calculate border widths &
* heights and modify the values programmed into the CRTC.
......@@ -672,9 +662,8 @@ static int intel_lvds_set_property(struct drm_connector *connector,
connector->encoder) {
struct drm_crtc *crtc = connector->encoder->crtc;
struct intel_lvds_priv *lvds_priv = intel_output->dev_priv;
if (value == DRM_MODE_SCALE_NON_GPU) {
DRM_DEBUG_KMS(I915_LVDS,
"non_GPU property is unsupported\n");
if (value == DRM_MODE_SCALE_NONE) {
DRM_DEBUG_KMS("no scaling not supported\n");
return 0;
}
if (lvds_priv->fitting_mode == value) {
......@@ -731,8 +720,7 @@ static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id)
{
DRM_DEBUG_KMS(I915_LVDS,
"Skipping LVDS initialization for %s\n", id->ident);
DRM_DEBUG_KMS("Skipping LVDS initialization for %s\n", id->ident);
return 1;
}
......@@ -1027,7 +1015,7 @@ void intel_lvds_init(struct drm_device *dev)
return;
failed:
DRM_DEBUG_KMS(I915_LVDS, "No LVDS modes found, disabling.\n");
DRM_DEBUG_KMS("No LVDS modes found, disabling.\n");
if (intel_output->ddc_bus)
intel_i2c_destroy(intel_output->ddc_bus);
drm_connector_cleanup(connector);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment