#define PCI_DEVICE_ID_INTEL_82965GME_IG 0x2A12
#define PCI_DEVICE_ID_INTEL_82945GME_HB 0x27AC
#define PCI_DEVICE_ID_INTEL_82945GME_IG 0x27AE
- #define PCI_DEVICE_ID_INTEL_IGDGM_HB 0xA010
- #define PCI_DEVICE_ID_INTEL_IGDGM_IG 0xA011
- #define PCI_DEVICE_ID_INTEL_IGDG_HB 0xA000
- #define PCI_DEVICE_ID_INTEL_IGDG_IG 0xA001
+ #define PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB 0xA010
+ #define PCI_DEVICE_ID_INTEL_PINEVIEW_M_IG 0xA011
+ #define PCI_DEVICE_ID_INTEL_PINEVIEW_HB 0xA000
+ #define PCI_DEVICE_ID_INTEL_PINEVIEW_IG 0xA001
#define PCI_DEVICE_ID_INTEL_G33_HB 0x29C0
#define PCI_DEVICE_ID_INTEL_G33_IG 0x29C2
#define PCI_DEVICE_ID_INTEL_Q35_HB 0x29B0
#define PCI_DEVICE_ID_INTEL_B43_IG 0x2E42
#define PCI_DEVICE_ID_INTEL_GM45_HB 0x2A40
#define PCI_DEVICE_ID_INTEL_GM45_IG 0x2A42
- #define PCI_DEVICE_ID_INTEL_IGD_E_HB 0x2E00
- #define PCI_DEVICE_ID_INTEL_IGD_E_IG 0x2E02
+ #define PCI_DEVICE_ID_INTEL_EAGLELAKE_HB 0x2E00
+ #define PCI_DEVICE_ID_INTEL_EAGLELAKE_IG 0x2E02
#define PCI_DEVICE_ID_INTEL_Q45_HB 0x2E10
#define PCI_DEVICE_ID_INTEL_Q45_IG 0x2E12
#define PCI_DEVICE_ID_INTEL_G45_HB 0x2E20
#define PCI_DEVICE_ID_INTEL_G45_IG 0x2E22
#define PCI_DEVICE_ID_INTEL_G41_HB 0x2E30
#define PCI_DEVICE_ID_INTEL_G41_IG 0x2E32
- #define PCI_DEVICE_ID_INTEL_IGDNG_D_HB 0x0040
- #define PCI_DEVICE_ID_INTEL_IGDNG_D_IG 0x0042
- #define PCI_DEVICE_ID_INTEL_IGDNG_M_HB 0x0044
- #define PCI_DEVICE_ID_INTEL_IGDNG_MA_HB 0x0062
- #define PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB 0x006a
- #define PCI_DEVICE_ID_INTEL_IGDNG_M_IG 0x0046
+ #define PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB 0x0040
+ #define PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG 0x0042
+ #define PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB 0x0044
+ #define PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB 0x0062
++#define PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB 0x006a
+ #define PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG 0x0046
/* cover 915 and 945 variants */
#define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \
#define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q33_HB || \
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDGM_HB || \
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDG_HB)
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_HB)
- #define IS_IGD (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDGM_HB || \
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDG_HB)
+ #define IS_PINEVIEW (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_HB)
- #define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_E_HB || \
+ #define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_EAGLELAKE_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G41_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_B43_HB || \
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_D_HB || \
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB || \
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MA_HB || \
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB)
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB || \
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB)
++ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB || \
++ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB)
extern int agp_memory_reserved;
size = 512;
}
size += 4; /* add in BIOS popup space */
- } else if (IS_G33 && !IS_IGD) {
+ } else if (IS_G33 && !IS_PINEVIEW) {
/* G33's GTT size defined in gmch_ctrl */
switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) {
case G33_PGETBL_SIZE_1M:
size = 512;
}
size += 4;
- } else if (IS_G4X || IS_IGD) {
+ } else if (IS_G4X || IS_PINEVIEW) {
/* On 4 series hardware, GTT stolen is separate from graphics
* stolen, ignore it in stolen gtt entries counting. However,
* 4KB of the stolen memory doesn't get mapped to the GTT.
intel_i9xx_setup_flush();
-#ifdef USE_PCI_DMA_API
- if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(36)))
- dev_err(&intel_private.pcidev->dev,
- "set gfx device dma mask 36bit failed!\n");
-#endif
-
return 0;
}
{
switch (agp_bridge->dev->device) {
case PCI_DEVICE_ID_INTEL_GM45_HB:
- case PCI_DEVICE_ID_INTEL_IGD_E_HB:
+ case PCI_DEVICE_ID_INTEL_EAGLELAKE_HB:
case PCI_DEVICE_ID_INTEL_Q45_HB:
case PCI_DEVICE_ID_INTEL_G45_HB:
case PCI_DEVICE_ID_INTEL_G41_HB:
case PCI_DEVICE_ID_INTEL_B43_HB:
- case PCI_DEVICE_ID_INTEL_IGDNG_D_HB:
- case PCI_DEVICE_ID_INTEL_IGDNG_M_HB:
- case PCI_DEVICE_ID_INTEL_IGDNG_MA_HB:
- case PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB:
+ case PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB:
+ case PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB:
+ case PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB:
++ case PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB:
*gtt_offset = *gtt_size = MB(2);
break;
default:
NULL, &intel_g33_driver },
{ PCI_DEVICE_ID_INTEL_Q33_HB, PCI_DEVICE_ID_INTEL_Q33_IG, 0, "Q33",
NULL, &intel_g33_driver },
- { PCI_DEVICE_ID_INTEL_IGDGM_HB, PCI_DEVICE_ID_INTEL_IGDGM_IG, 0, "IGD",
+ { PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB, PCI_DEVICE_ID_INTEL_PINEVIEW_M_IG, 0, "Pineview",
NULL, &intel_g33_driver },
- { PCI_DEVICE_ID_INTEL_IGDG_HB, PCI_DEVICE_ID_INTEL_IGDG_IG, 0, "IGD",
+ { PCI_DEVICE_ID_INTEL_PINEVIEW_HB, PCI_DEVICE_ID_INTEL_PINEVIEW_IG, 0, "Pineview",
NULL, &intel_g33_driver },
{ PCI_DEVICE_ID_INTEL_GM45_HB, PCI_DEVICE_ID_INTEL_GM45_IG, 0,
- "Mobile IntelĀ® GM45 Express", NULL, &intel_i965_driver },
- { PCI_DEVICE_ID_INTEL_IGD_E_HB, PCI_DEVICE_ID_INTEL_IGD_E_IG, 0,
- "Intel Integrated Graphics Device", NULL, &intel_i965_driver },
+ "GM45", NULL, &intel_i965_driver },
+ { PCI_DEVICE_ID_INTEL_EAGLELAKE_HB, PCI_DEVICE_ID_INTEL_EAGLELAKE_IG, 0,
+ "Eaglelake", NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_Q45_HB, PCI_DEVICE_ID_INTEL_Q45_IG, 0,
"Q45/Q43", NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_G45_HB, PCI_DEVICE_ID_INTEL_G45_IG, 0,
"B43", NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_G41_HB, PCI_DEVICE_ID_INTEL_G41_IG, 0,
"G41", NULL, &intel_i965_driver },
- { PCI_DEVICE_ID_INTEL_IGDNG_D_HB, PCI_DEVICE_ID_INTEL_IGDNG_D_IG, 0,
- "IGDNG/D", NULL, &intel_i965_driver },
- { PCI_DEVICE_ID_INTEL_IGDNG_M_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
- "IGDNG/M", NULL, &intel_i965_driver },
- { PCI_DEVICE_ID_INTEL_IGDNG_MA_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
- "IGDNG/MA", NULL, &intel_i965_driver },
- { PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
- "IGDNG/MC2", NULL, &intel_i965_driver },
+ { PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG, 0,
+ "Ironlake/D", NULL, &intel_i965_driver },
+ { PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, 0,
+ "Ironlake/M", NULL, &intel_i965_driver },
+ { PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, 0,
+ "Ironlake/MA", NULL, &intel_i965_driver },
++ { PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, 0,
++ "Ironlake/MC2", NULL, &intel_i965_driver },
{ 0, 0, 0, NULL, NULL, NULL }
};
&bridge->mode);
}
+ if (bridge->driver->mask_memory == intel_i965_mask_memory)
+ if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(36)))
+ dev_err(&intel_private.pcidev->dev,
+ "set gfx device dma mask 36bit failed!\n");
+
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
}
ID(PCI_DEVICE_ID_INTEL_82945G_HB),
ID(PCI_DEVICE_ID_INTEL_82945GM_HB),
ID(PCI_DEVICE_ID_INTEL_82945GME_HB),
- ID(PCI_DEVICE_ID_INTEL_IGDGM_HB),
- ID(PCI_DEVICE_ID_INTEL_IGDG_HB),
+ ID(PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB),
+ ID(PCI_DEVICE_ID_INTEL_PINEVIEW_HB),
ID(PCI_DEVICE_ID_INTEL_82946GZ_HB),
ID(PCI_DEVICE_ID_INTEL_82G35_HB),
ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
ID(PCI_DEVICE_ID_INTEL_Q35_HB),
ID(PCI_DEVICE_ID_INTEL_Q33_HB),
ID(PCI_DEVICE_ID_INTEL_GM45_HB),
- ID(PCI_DEVICE_ID_INTEL_IGD_E_HB),
+ ID(PCI_DEVICE_ID_INTEL_EAGLELAKE_HB),
ID(PCI_DEVICE_ID_INTEL_Q45_HB),
ID(PCI_DEVICE_ID_INTEL_G45_HB),
ID(PCI_DEVICE_ID_INTEL_G41_HB),
ID(PCI_DEVICE_ID_INTEL_B43_HB),
- ID(PCI_DEVICE_ID_INTEL_IGDNG_D_HB),
- ID(PCI_DEVICE_ID_INTEL_IGDNG_M_HB),
- ID(PCI_DEVICE_ID_INTEL_IGDNG_MA_HB),
- ID(PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB),
+ ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB),
+ ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB),
+ ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB),
++ ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB),
{ }
};
DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
drm_tv_subconnector_enum_list)
+static struct drm_prop_enum_list drm_dirty_info_enum_list[] = {
+ { DRM_MODE_DIRTY_OFF, "Off" },
+ { DRM_MODE_DIRTY_ON, "On" },
+ { DRM_MODE_DIRTY_ANNOTATE, "Annotate" },
+};
+
+DRM_ENUM_NAME_FN(drm_get_dirty_info_name,
+ drm_dirty_info_enum_list)
+
struct drm_conn_prop_enum_list {
int type;
char *name;
mutex_unlock(&dev->mode_config.idr_mutex);
}
- void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type)
+ struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
+ uint32_t id, uint32_t type)
{
struct drm_mode_object *obj = NULL;
}
EXPORT_SYMBOL(drm_mode_create_dithering_property);
+/**
+ * drm_mode_create_dirty_property - create dirty property
+ * @dev: DRM device
+ *
+ * Called by a driver the first time it's needed, must be attached to desired
+ * connectors.
+ */
+int drm_mode_create_dirty_info_property(struct drm_device *dev)
+{
+ struct drm_property *dirty_info;
+ int i;
+
+ if (dev->mode_config.dirty_info_property)
+ return 0;
+
+ dirty_info =
+ drm_property_create(dev, DRM_MODE_PROP_ENUM |
+ DRM_MODE_PROP_IMMUTABLE,
+ "dirty",
+ ARRAY_SIZE(drm_dirty_info_enum_list));
+ for (i = 0; i < ARRAY_SIZE(drm_dirty_info_enum_list); i++)
+ drm_property_add_enum(dirty_info, i,
+ drm_dirty_info_enum_list[i].type,
+ drm_dirty_info_enum_list[i].name);
+ dev->mode_config.dirty_info_property = dirty_info;
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_mode_create_dirty_info_property);
+
/**
* drm_mode_config_init - initialize DRM mode_configuration structure
* @dev: DRM device
return ret;
}
+int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv)
+{
+ struct drm_clip_rect __user *clips_ptr;
+ struct drm_clip_rect *clips = NULL;
+ struct drm_mode_fb_dirty_cmd *r = data;
+ struct drm_mode_object *obj;
+ struct drm_framebuffer *fb;
+ unsigned flags;
+ int num_clips;
+ int ret = 0;
+
+ mutex_lock(&dev->mode_config.mutex);
+ obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB);
+ if (!obj) {
+ DRM_ERROR("invalid framebuffer id\n");
+ ret = -EINVAL;
+ goto out_err1;
+ }
+ fb = obj_to_fb(obj);
+
+ num_clips = r->num_clips;
+ clips_ptr = (struct drm_clip_rect *)(unsigned long)r->clips_ptr;
+
+ if (!num_clips != !clips_ptr) {
+ ret = -EINVAL;
+ goto out_err1;
+ }
+
+ flags = DRM_MODE_FB_DIRTY_FLAGS & r->flags;
+
+ /* If userspace annotates copy, clips must come in pairs */
+ if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY && (num_clips % 2)) {
+ ret = -EINVAL;
+ goto out_err1;
+ }
+
+ if (num_clips && clips_ptr) {
+ clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL);
+ if (!clips) {
+ ret = -ENOMEM;
+ goto out_err1;
+ }
+
+ ret = copy_from_user(clips, clips_ptr,
+ num_clips * sizeof(*clips));
+ if (ret)
+ goto out_err2;
+ }
+
+ if (fb->funcs->dirty) {
+ ret = fb->funcs->dirty(fb, flags, r->color, clips, num_clips);
+ } else {
+ ret = -ENOSYS;
+ goto out_err2;
+ }
+
+out_err2:
+ kfree(clips);
+out_err1:
+ mutex_unlock(&dev->mode_config.mutex);
+ return ret;
+}
+
+
/**
* drm_fb_release - remove and free the FBs on this file
* @filp: file * from the ioctl
goto out;
}
- e->event.base.type = DRM_EVENT_VBLANK;
+ e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
e->event.base.length = sizeof e->event;
e->event.user_data = page_flip->user_data;
e->base.event = &e->event.base;
--- /dev/null
- DRM_DEBUG("dp_aux_xfer return %d\n", ret);
+/*
+ * Copyright Ā© 2009 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/i2c.h>
+#include "drm_dp_helper.h"
+#include "drmP.h"
+
+/* Run a single AUX_CH I2C transaction, writing/reading data as necessary */
+static int
+i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode,
+ uint8_t write_byte, uint8_t *read_byte)
+{
+ struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
+ int ret;
+
+ ret = (*algo_data->aux_ch)(adapter, mode,
+ write_byte, read_byte);
+ return ret;
+}
+
+/*
+ * I2C over AUX CH
+ */
+
+/*
+ * Send the address. If the I2C link is running, this 'restarts'
+ * the connection with the new address, this is used for doing
+ * a write followed by a read (as needed for DDC)
+ */
+static int
+i2c_algo_dp_aux_address(struct i2c_adapter *adapter, u16 address, bool reading)
+{
+ struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
+ int mode = MODE_I2C_START;
+ int ret;
+
+ if (reading)
+ mode |= MODE_I2C_READ;
+ else
+ mode |= MODE_I2C_WRITE;
+ algo_data->address = address;
+ algo_data->running = true;
+ ret = i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL);
+ return ret;
+}
+
+/*
+ * Stop the I2C transaction. This closes out the link, sending
+ * a bare address packet with the MOT bit turned off
+ */
+static void
+i2c_algo_dp_aux_stop(struct i2c_adapter *adapter, bool reading)
+{
+ struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
+ int mode = MODE_I2C_STOP;
+
+ if (reading)
+ mode |= MODE_I2C_READ;
+ else
+ mode |= MODE_I2C_WRITE;
+ if (algo_data->running) {
+ (void) i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL);
+ algo_data->running = false;
+ }
+}
+
+/*
+ * Write a single byte to the current I2C address, the
+ * the I2C link must be running or this returns -EIO
+ */
+static int
+i2c_algo_dp_aux_put_byte(struct i2c_adapter *adapter, u8 byte)
+{
+ struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
+ int ret;
+
+ if (!algo_data->running)
+ return -EIO;
+
+ ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_WRITE, byte, NULL);
+ return ret;
+}
+
+/*
+ * Read a single byte from the current I2C address, the
+ * I2C link must be running or this returns -EIO
+ */
+static int
+i2c_algo_dp_aux_get_byte(struct i2c_adapter *adapter, u8 *byte_ret)
+{
+ struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
+ int ret;
+
+ if (!algo_data->running)
+ return -EIO;
+
+ ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_READ, 0, byte_ret);
+ return ret;
+}
+
+static int
+i2c_algo_dp_aux_xfer(struct i2c_adapter *adapter,
+ struct i2c_msg *msgs,
+ int num)
+{
+ int ret = 0;
+ bool reading = false;
+ int m;
+ int b;
+
+ for (m = 0; m < num; m++) {
+ u16 len = msgs[m].len;
+ u8 *buf = msgs[m].buf;
+ reading = (msgs[m].flags & I2C_M_RD) != 0;
+ ret = i2c_algo_dp_aux_address(adapter, msgs[m].addr, reading);
+ if (ret < 0)
+ break;
+ if (reading) {
+ for (b = 0; b < len; b++) {
+ ret = i2c_algo_dp_aux_get_byte(adapter, &buf[b]);
+ if (ret < 0)
+ break;
+ }
+ } else {
+ for (b = 0; b < len; b++) {
+ ret = i2c_algo_dp_aux_put_byte(adapter, buf[b]);
+ if (ret < 0)
+ break;
+ }
+ }
+ if (ret < 0)
+ break;
+ }
+ if (ret >= 0)
+ ret = num;
+ i2c_algo_dp_aux_stop(adapter, reading);
++ DRM_DEBUG_KMS("dp_aux_xfer return %d\n", ret);
+ return ret;
+}
+
+static u32
+i2c_algo_dp_aux_functionality(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
+ I2C_FUNC_SMBUS_READ_BLOCK_DATA |
+ I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
+ I2C_FUNC_10BIT_ADDR;
+}
+
+static const struct i2c_algorithm i2c_dp_aux_algo = {
+ .master_xfer = i2c_algo_dp_aux_xfer,
+ .functionality = i2c_algo_dp_aux_functionality,
+};
+
+static void
+i2c_dp_aux_reset_bus(struct i2c_adapter *adapter)
+{
+ (void) i2c_algo_dp_aux_address(adapter, 0, false);
+ (void) i2c_algo_dp_aux_stop(adapter, false);
+
+}
+
+static int
+i2c_dp_aux_prepare_bus(struct i2c_adapter *adapter)
+{
+ adapter->algo = &i2c_dp_aux_algo;
+ adapter->retries = 3;
+ i2c_dp_aux_reset_bus(adapter);
+ return 0;
+}
+
+int
+i2c_dp_aux_add_bus(struct i2c_adapter *adapter)
+{
+ int error;
+
+ error = i2c_dp_aux_prepare_bus(adapter);
+ if (error)
+ return error;
+ error = i2c_add_adapter(adapter);
+ return error;
+}
+EXPORT_SYMBOL(i2c_dp_aux_add_bus);
intel_lvds.o \
intel_bios.o \
intel_dp.o \
- intel_dp_i2c.o \
intel_hdmi.o \
intel_sdvo.o \
intel_modes.o \
intel_fb.o \
intel_tv.o \
intel_dvo.o \
+ intel_overlay.o \
dvo_ch7xxx.o \
dvo_ch7017.o \
dvo_ivch.o \
/* clock gating init */
};
+ struct intel_overlay;
+
typedef struct drm_i915_private {
struct drm_device *dev;
unsigned int status_gfx_addr;
drm_local_map_t hws_map;
struct drm_gem_object *hws_obj;
+ struct drm_gem_object *pwrctx;
struct resource mch_res;
/** Cached value of IMR to avoid reads in updating the bitfield */
u32 irq_mask_reg;
u32 pipestat[2];
- /** splitted irq regs for graphics and display engine on IGDNG,
+ /** splitted irq regs for graphics and display engine on Ironlake,
irq_mask_reg is still used for display irq. */
u32 gt_irq_mask_reg;
u32 gt_irq_enable_reg;
u32 de_irq_enable_reg;
+ u32 pch_irq_mask_reg;
+ u32 pch_irq_enable_reg;
u32 hotplug_supported_mask;
struct work_struct hotplug_work;
struct intel_opregion opregion;
+ /* overlay */
+ struct intel_overlay *overlay;
+
/* LVDS info */
int backlight_duty_cycle; /* restore backlight to this value */
bool panel_wants_dither;
struct notifier_block lid_notifier;
- int crt_ddc_bus; /* -1 = unknown, else GPIO to use for CRT DDC */
+ int crt_ddc_bus; /* 0 = unknown, else GPIO to use for CRT DDC */
struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */
int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */
int num_fence_regs; /* 8 on pre-965, 16 otherwise */
u32 saveDSPBCNTR;
u32 saveDSPARB;
u32 saveRENDERSTANDBY;
+ u32 savePWRCTXA;
u32 saveHWS;
u32 savePIPEACONF;
u32 savePIPEBCONF;
u32 saveVBLANK_A;
u32 saveVSYNC_A;
u32 saveBCLRPAT_A;
+ u32 saveTRANSACONF;
u32 saveTRANS_HTOTAL_A;
u32 saveTRANS_HBLANK_A;
u32 saveTRANS_HSYNC_A;
u32 saveVBLANK_B;
u32 saveVSYNC_B;
u32 saveBCLRPAT_B;
+ u32 saveTRANSBCONF;
u32 saveTRANS_HTOTAL_B;
u32 saveTRANS_HBLANK_B;
u32 saveTRANS_HSYNC_B;
u32 savePFB_WIN_SZ;
u32 savePFA_WIN_POS;
u32 savePFB_WIN_POS;
+ u32 savePCH_DREF_CONTROL;
+ u32 saveDISP_ARB_CTL;
+ u32 savePIPEA_DATA_M1;
+ u32 savePIPEA_DATA_N1;
+ u32 savePIPEA_LINK_M1;
+ u32 savePIPEA_LINK_N1;
+ u32 savePIPEB_DATA_M1;
+ u32 savePIPEB_DATA_N1;
+ u32 savePIPEB_LINK_M1;
+ u32 savePIPEB_LINK_N1;
struct {
struct drm_mm gtt_space;
/* indicate whether the LVDS_BORDER should be enabled or not */
unsigned int lvds_border_bits;
+ struct drm_crtc *plane_to_crtc_mapping[2];
+ struct drm_crtc *pipe_to_crtc_mapping[2];
+ wait_queue_head_t pending_flip_queue;
+
/* Reclocking support */
bool render_reclock_avail;
bool lvds_downclock_avail;
+ /* indicates the reduced downclock for LVDS*/
+ int lvds_downclock;
struct work_struct idle_work;
struct timer_list idle_timer;
bool busy;
u16 orig_clock;
+ int child_dev_num;
+ struct child_device_config *child_dev;
} drm_i915_private_t;
/** driver private structure attached to each drm_gem_object */
* Advice: are the backing pages purgeable?
*/
int madv;
+
+ /**
+ * Number of crtcs where this object is currently the fb, but
+ * will be page flipped away on the next vblank. When it
+ * reaches 0, dev_priv->pending_flip_queue will be woken up.
+ */
+ atomic_t pending_flip;
};
/**
void
i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
+ void intel_enable_asle (struct drm_device *dev);
+
/* i915_mem.c */
extern int i915_mem_alloc(struct drm_device *dev, void *data,
int i915_gem_do_init(struct drm_device *dev, unsigned long start,
unsigned long end);
int i915_gem_idle(struct drm_device *dev);
+ uint32_t i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
+ uint32_t flush_domains);
+ int i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible);
int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj,
int write);
int i915_gem_object_get_pages(struct drm_gem_object *obj);
void i915_gem_object_put_pages(struct drm_gem_object *obj);
void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv);
+ void i915_gem_object_flush_write_domain(struct drm_gem_object *obj);
void i915_gem_shrinker_init(void);
void i915_gem_shrinker_exit(void);
extern int intel_opregion_init(struct drm_device *dev, int resume);
extern void intel_opregion_free(struct drm_device *dev, int suspend);
extern void opregion_asle_intr(struct drm_device *dev);
+ extern void ironlake_opregion_gse_intr(struct drm_device *dev);
extern void opregion_enable_asle(struct drm_device *dev);
#else
static inline int intel_opregion_init(struct drm_device *dev, int resume) { return 0; }
static inline void intel_opregion_free(struct drm_device *dev, int suspend) { return; }
static inline void opregion_asle_intr(struct drm_device *dev) { return; }
+ static inline void ironlake_opregion_gse_intr(struct drm_device *dev) { return; }
static inline void opregion_enable_asle(struct drm_device *dev) { return; }
#endif
#define IS_I830(dev) ((dev)->pci_device == 0x3577)
#define IS_845G(dev) ((dev)->pci_device == 0x2562)
#define IS_I85X(dev) ((dev)->pci_device == 0x3582)
- #define IS_I855(dev) ((dev)->pci_device == 0x3582)
#define IS_I865G(dev) ((dev)->pci_device == 0x2572)
+ #define IS_I8XX(dev) (IS_I830(dev) || IS_845G(dev) || IS_I85X(dev) || IS_I865G(dev))
#define IS_I915G(dev) ((dev)->pci_device == 0x2582 || (dev)->pci_device == 0x258a)
#define IS_I915GM(dev) ((dev)->pci_device == 0x2592)
(dev)->pci_device == 0x2E42 || \
IS_GM45(dev))
- #define IS_IGDG(dev) ((dev)->pci_device == 0xa001)
- #define IS_IGDGM(dev) ((dev)->pci_device == 0xa011)
- #define IS_IGD(dev) (IS_IGDG(dev) || IS_IGDGM(dev))
+ #define IS_PINEVIEW_G(dev) ((dev)->pci_device == 0xa001)
+ #define IS_PINEVIEW_M(dev) ((dev)->pci_device == 0xa011)
+ #define IS_PINEVIEW(dev) (IS_PINEVIEW_G(dev) || IS_PINEVIEW_M(dev))
#define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \
(dev)->pci_device == 0x29B2 || \
(dev)->pci_device == 0x29D2 || \
- (IS_IGD(dev)))
+ (IS_PINEVIEW(dev)))
- #define IS_IGDNG_D(dev) ((dev)->pci_device == 0x0042)
- #define IS_IGDNG_M(dev) ((dev)->pci_device == 0x0046)
- #define IS_IGDNG(dev) (IS_IGDNG_D(dev) || IS_IGDNG_M(dev))
+ #define IS_IRONLAKE_D(dev) ((dev)->pci_device == 0x0042)
+ #define IS_IRONLAKE_M(dev) ((dev)->pci_device == 0x0046)
+ #define IS_IRONLAKE(dev) (IS_IRONLAKE_D(dev) || IS_IRONLAKE_M(dev))
#define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \
IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev) || \
- IS_IGDNG(dev))
+ IS_IRONLAKE(dev))
#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \
IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev) || \
- IS_IGD(dev) || IS_IGDNG_M(dev))
+ IS_PINEVIEW(dev) || IS_IRONLAKE_M(dev))
#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev) || \
- IS_IGDNG(dev))
+ IS_IRONLAKE(dev))
/* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte
* rows, which changed the alignment requirements and fence programming.
*/
#define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) && !(IS_I915G(dev) || \
IS_I915GM(dev)))
- #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IGDNG(dev))
- #define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IGDNG(dev))
- #define SUPPORTS_EDP(dev) (IS_IGDNG_M(dev))
+ #define SUPPORTS_DIGITAL_OUTPUTS(dev) (IS_I9XX(dev) && !IS_PINEVIEW(dev))
+ #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IRONLAKE(dev))
+ #define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IRONLAKE(dev))
+ #define SUPPORTS_EDP(dev) (IS_IRONLAKE_M(dev))
+ #define SUPPORTS_TV(dev) (IS_I9XX(dev) && IS_MOBILE(dev) && \
+ !IS_IRONLAKE(dev) && !IS_PINEVIEW(dev))
#define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev) || IS_I965G(dev))
/* dsparb controlled by hw only */
- #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev))
+ #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IRONLAKE(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 HAS_FW_BLC(dev) (IS_I9XX(dev) || IS_G4X(dev) || IS_IRONLAKE(dev))
+ #define HAS_PIPE_CXSR(dev) (IS_G4X(dev) || IS_IRONLAKE(dev))
#define I915_HAS_FBC(dev) (IS_MOBILE(dev) && \
(IS_I9XX(dev) || IS_GM45(dev)) && \
- !IS_IGD(dev) && \
- !IS_IGDNG(dev))
+ !IS_PINEVIEW(dev) && \
+ !IS_IRONLAKE(dev))
+ #define I915_HAS_RC6(dev) (IS_I965GM(dev) || IS_GM45(dev) || IS_IRONLAKE_M(dev))
#define PRIMARY_RINGBUFFER_SIZE (128*1024)
* we leave them always unmasked in IMR and then control enabling them through
* PIPESTAT alone.
*/
- #define I915_INTERRUPT_ENABLE_FIX (I915_ASLE_INTERRUPT | \
- I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
- I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | \
- I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
+ #define I915_INTERRUPT_ENABLE_FIX \
+ (I915_ASLE_INTERRUPT | \
+ I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
+ I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | \
+ I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | \
+ I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT | \
+ I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
/** Interrupts that we mask and unmask at runtime. */
#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT)
DRM_I915_VBLANK_PIPE_B)
void
- igdng_enable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask)
+ ironlake_enable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask)
{
if ((dev_priv->gt_irq_mask_reg & mask) != 0) {
dev_priv->gt_irq_mask_reg &= ~mask;
}
static inline void
- igdng_disable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask)
+ ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask)
{
if ((dev_priv->gt_irq_mask_reg & mask) != mask) {
dev_priv->gt_irq_mask_reg |= mask;
/* For display hotplug interrupt */
void
- igdng_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
+ ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
{
if ((dev_priv->irq_mask_reg & mask) != 0) {
dev_priv->irq_mask_reg &= ~mask;
}
static inline void
- igdng_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
+ ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
{
if ((dev_priv->irq_mask_reg & mask) != mask) {
dev_priv->irq_mask_reg |= mask;
}
}
+ /**
+ * intel_enable_asle - enable ASLE interrupt for OpRegion
+ */
+ void intel_enable_asle (struct drm_device *dev)
+ {
+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+
+ if (IS_IRONLAKE(dev))
+ ironlake_enable_display_irq(dev_priv, DE_GSE);
+ else
+ i915_enable_pipestat(dev_priv, 1,
+ I915_LEGACY_BLC_EVENT_ENABLE);
+ }
+
/**
* i915_pipe_enabled - check if a pipe is enabled
* @dev: DRM device
low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
if (!i915_pipe_enabled(dev, pipe)) {
- DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", pipe);
+ DRM_DEBUG_DRIVER("trying to get vblank count for disabled "
+ "pipe %d\n", pipe);
return 0;
}
int reg = pipe ? PIPEB_FRMCOUNT_GM45 : PIPEA_FRMCOUNT_GM45;
if (!i915_pipe_enabled(dev, pipe)) {
- DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", pipe);
+ DRM_DEBUG_DRIVER("trying to get vblank count for disabled "
+ "pipe %d\n", pipe);
return 0;
}
drm_sysfs_hotplug_event(dev);
}
- irqreturn_t igdng_irq_handler(struct drm_device *dev)
+ irqreturn_t ironlake_irq_handler(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
int ret = IRQ_NONE;
- u32 de_iir, gt_iir, de_ier;
- u32 new_de_iir, new_gt_iir;
- u32 de_iir, gt_iir, pch_iir;
++ u32 de_iir, gt_iir, de_ier, pch_iir;
+ u32 new_de_iir, new_gt_iir, new_pch_iir;
struct drm_i915_master_private *master_priv;
+ /* disable master interrupt before clearing iir */
+ de_ier = I915_READ(DEIER);
+ I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL);
+ (void)I915_READ(DEIER);
+
de_iir = I915_READ(DEIIR);
gt_iir = I915_READ(GTIIR);
+ pch_iir = I915_READ(SDEIIR);
for (;;) {
- if (de_iir == 0 && gt_iir == 0)
+ if (de_iir == 0 && gt_iir == 0 && pch_iir == 0)
break;
ret = IRQ_HANDLED;
+ /* should clear PCH hotplug event before clear CPU irq */
+ I915_WRITE(SDEIIR, pch_iir);
+ new_pch_iir = I915_READ(SDEIIR);
+
I915_WRITE(DEIIR, de_iir);
new_de_iir = I915_READ(DEIIR);
I915_WRITE(GTIIR, gt_iir);
DRM_WAKEUP(&dev_priv->irq_queue);
}
+ if (de_iir & DE_GSE)
+ ironlake_opregion_gse_intr(dev);
+
+ /* check event from PCH */
+ if ((de_iir & DE_PCH_EVENT) &&
+ (pch_iir & SDE_HOTPLUG_MASK)) {
+ queue_work(dev_priv->wq, &dev_priv->hotplug_work);
+ }
+
de_iir = new_de_iir;
gt_iir = new_gt_iir;
+ pch_iir = new_pch_iir;
}
+ I915_WRITE(DEIER, de_ier);
+ (void)I915_READ(DEIER);
+
return ret;
}
char *reset_event[] = { "RESET=1", NULL };
char *reset_done_event[] = { "ERROR=0", NULL };
- DRM_DEBUG("generating error event\n");
+ DRM_DEBUG_DRIVER("generating error event\n");
kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, error_event);
if (atomic_read(&dev_priv->mm.wedged)) {
if (IS_I965G(dev)) {
- DRM_DEBUG("resetting chip\n");
+ DRM_DEBUG_DRIVER("resetting chip\n");
kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_event);
if (!i965_reset(dev, GDRST_RENDER)) {
atomic_set(&dev_priv->mm.wedged, 0);
kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_done_event);
}
} else {
- printk("reboot required\n");
+ DRM_DEBUG_DRIVER("reboot required\n");
}
}
}
error = kmalloc(sizeof(*error), GFP_ATOMIC);
if (!error) {
- DRM_DEBUG("out ot memory, not capturing error state\n");
+ DRM_DEBUG_DRIVER("out ot memory, not capturing error state\n");
goto out;
}
atomic_inc(&dev_priv->irq_received);
- if (IS_IGDNG(dev))
- return igdng_irq_handler(dev);
+ if (IS_IRONLAKE(dev))
+ return ironlake_irq_handler(dev);
iir = I915_READ(IIR);
*/
if (pipea_stats & 0x8000ffff) {
if (pipea_stats & PIPE_FIFO_UNDERRUN_STATUS)
- DRM_DEBUG("pipe a underrun\n");
+ DRM_DEBUG_DRIVER("pipe a underrun\n");
I915_WRITE(PIPEASTAT, pipea_stats);
irq_received = 1;
}
if (pipeb_stats & 0x8000ffff) {
if (pipeb_stats & PIPE_FIFO_UNDERRUN_STATUS)
- DRM_DEBUG("pipe b underrun\n");
+ DRM_DEBUG_DRIVER("pipe b underrun\n");
I915_WRITE(PIPEBSTAT, pipeb_stats);
irq_received = 1;
}
(iir & I915_DISPLAY_PORT_INTERRUPT)) {
u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT);
- DRM_DEBUG("hotplug event received, stat 0x%08x\n",
+ DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n",
hotplug_status);
if (hotplug_status & dev_priv->hotplug_supported_mask)
queue_work(dev_priv->wq,
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);
mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
}
+ if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT)
+ intel_prepare_page_flip(dev, 0);
+
+ if (iir & I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT)
+ intel_prepare_page_flip(dev, 1);
+
if (pipea_stats & vblank_status) {
vblank++;
drm_handle_vblank(dev, 0);
+ intel_finish_page_flip(dev, 0);
}
if (pipeb_stats & vblank_status) {
vblank++;
drm_handle_vblank(dev, 1);
+ intel_finish_page_flip(dev, 1);
}
if ((pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS) ||
i915_kernel_lost_context(dev);
- DRM_DEBUG("\n");
+ DRM_DEBUG_DRIVER("\n");
dev_priv->counter++;
if (dev_priv->counter > 0x7FFFFFFFUL)
spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) {
- if (IS_IGDNG(dev))
- igdng_enable_graphics_irq(dev_priv, GT_USER_INTERRUPT);
+ if (IS_IRONLAKE(dev))
+ ironlake_enable_graphics_irq(dev_priv, GT_USER_INTERRUPT);
else
i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
}
spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0);
if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) {
- if (IS_IGDNG(dev))
- igdng_disable_graphics_irq(dev_priv, GT_USER_INTERRUPT);
+ if (IS_IRONLAKE(dev))
+ ironlake_disable_graphics_irq(dev_priv, GT_USER_INTERRUPT);
else
i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
}
struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
int ret = 0;
- DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr,
+ DRM_DEBUG_DRIVER("irq_nr=%d breadcrumb=%d\n", irq_nr,
READ_BREADCRUMB(dev_priv));
if (READ_BREADCRUMB(dev_priv) >= irq_nr) {
if (!(pipeconf & PIPEACONF_ENABLE))
return -EINVAL;
- if (IS_IGDNG(dev))
+ if (IS_IRONLAKE(dev))
return 0;
spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
unsigned long irqflags;
- if (IS_IGDNG(dev))
+ if (IS_IRONLAKE(dev))
return;
spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
{
struct drm_i915_private *dev_priv = dev->dev_private;
- if (!IS_IGDNG(dev))
+ if (!IS_IRONLAKE(dev))
opregion_enable_asle(dev);
dev_priv->irq_enabled = 1;
}
/* drm_dma.h hooks
*/
- static void igdng_irq_preinstall(struct drm_device *dev)
+ static void ironlake_irq_preinstall(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
I915_WRITE(GTIMR, 0xffffffff);
I915_WRITE(GTIER, 0x0);
(void) I915_READ(GTIER);
+
+ /* south display irq */
+ I915_WRITE(SDEIMR, 0xffffffff);
+ I915_WRITE(SDEIER, 0x0);
+ (void) I915_READ(SDEIER);
}
- static int igdng_irq_postinstall(struct drm_device *dev)
+ static int ironlake_irq_postinstall(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
/* enable kind of interrupts always enabled */
- u32 display_mask = DE_MASTER_IRQ_CONTROL /*| DE_PCH_EVENT */;
+ u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT;
u32 render_mask = GT_USER_INTERRUPT;
+ u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG |
+ SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG;
dev_priv->irq_mask_reg = ~display_mask;
dev_priv->de_irq_enable_reg = display_mask;
I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg);
(void) I915_READ(GTIER);
+ dev_priv->pch_irq_mask_reg = ~hotplug_mask;
+ dev_priv->pch_irq_enable_reg = hotplug_mask;
+
+ I915_WRITE(SDEIIR, I915_READ(SDEIIR));
+ I915_WRITE(SDEIMR, dev_priv->pch_irq_mask_reg);
+ I915_WRITE(SDEIER, dev_priv->pch_irq_enable_reg);
+ (void) I915_READ(SDEIER);
+
return 0;
}
INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func);
INIT_WORK(&dev_priv->error_work, i915_error_work_func);
- if (IS_IGDNG(dev)) {
- igdng_irq_preinstall(dev);
+ if (IS_IRONLAKE(dev)) {
+ ironlake_irq_preinstall(dev);
return;
}
dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
- if (IS_IGDNG(dev))
- return igdng_irq_postinstall(dev);
+ if (IS_IRONLAKE(dev))
+ return ironlake_irq_postinstall(dev);
/* Unmask the interrupts that we always want on. */
dev_priv->irq_mask_reg = ~I915_INTERRUPT_ENABLE_FIX;
return 0;
}
- static void igdng_irq_uninstall(struct drm_device *dev)
+ static void ironlake_irq_uninstall(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
I915_WRITE(HWSTAM, 0xffffffff);
dev_priv->vblank_pipe = 0;
- if (IS_IGDNG(dev)) {
- igdng_irq_uninstall(dev);
+ if (IS_IRONLAKE(dev)) {
+ ironlake_irq_uninstall(dev);
return;
}
#include "drmP.h"
#include "drm.h"
#include "i915_drm.h"
- #include "i915_drv.h"
+ #include "intel_drv.h"
static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 dpll_reg;
- if (IS_IGDNG(dev)) {
+ if (IS_IRONLAKE(dev)) {
dpll_reg = (pipe == PIPE_A) ? PCH_DPLL_A: PCH_DPLL_B;
} else {
dpll_reg = (pipe == PIPE_A) ? DPLL_A: DPLL_B;
if (!i915_pipe_enabled(dev, pipe))
return;
- if (IS_IGDNG(dev))
+ if (IS_IRONLAKE(dev))
reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B;
if (pipe == PIPE_A)
if (!i915_pipe_enabled(dev, pipe))
return;
- if (IS_IGDNG(dev))
+ if (IS_IRONLAKE(dev))
reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B;
if (pipe == PIPE_A)
if (drm_core_check_feature(dev, DRIVER_MODESET))
return;
- if (IS_IGDNG(dev)) {
++ if (IS_IRONLAKE(dev)) {
+ dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL);
+ dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL);
+ }
+
/* Pipe & plane A info */
dev_priv->savePIPEACONF = I915_READ(PIPEACONF);
dev_priv->savePIPEASRC = I915_READ(PIPEASRC);
- if (IS_IGDNG(dev)) {
+ if (IS_IRONLAKE(dev)) {
dev_priv->saveFPA0 = I915_READ(PCH_FPA0);
dev_priv->saveFPA1 = I915_READ(PCH_FPA1);
dev_priv->saveDPLL_A = I915_READ(PCH_DPLL_A);
dev_priv->saveFPA1 = I915_READ(FPA1);
dev_priv->saveDPLL_A = I915_READ(DPLL_A);
}
- if (IS_I965G(dev) && !IS_IGDNG(dev))
+ if (IS_I965G(dev) && !IS_IRONLAKE(dev))
dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD);
dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A);
dev_priv->saveHBLANK_A = I915_READ(HBLANK_A);
dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A);
dev_priv->saveVBLANK_A = I915_READ(VBLANK_A);
dev_priv->saveVSYNC_A = I915_READ(VSYNC_A);
- if (!IS_IGDNG(dev))
+ if (!IS_IRONLAKE(dev))
dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
- if (IS_IGDNG(dev)) {
+ if (IS_IRONLAKE(dev)) {
+ dev_priv->savePIPEA_DATA_M1 = I915_READ(PIPEA_DATA_M1);
+ dev_priv->savePIPEA_DATA_N1 = I915_READ(PIPEA_DATA_N1);
+ dev_priv->savePIPEA_LINK_M1 = I915_READ(PIPEA_LINK_M1);
+ dev_priv->savePIPEA_LINK_N1 = I915_READ(PIPEA_LINK_N1);
+
dev_priv->saveFDI_TXA_CTL = I915_READ(FDI_TXA_CTL);
dev_priv->saveFDI_RXA_CTL = I915_READ(FDI_RXA_CTL);
dev_priv->savePFA_WIN_SZ = I915_READ(PFA_WIN_SZ);
dev_priv->savePFA_WIN_POS = I915_READ(PFA_WIN_POS);
+ dev_priv->saveTRANSACONF = I915_READ(TRANSACONF);
dev_priv->saveTRANS_HTOTAL_A = I915_READ(TRANS_HTOTAL_A);
dev_priv->saveTRANS_HBLANK_A = I915_READ(TRANS_HBLANK_A);
dev_priv->saveTRANS_HSYNC_A = I915_READ(TRANS_HSYNC_A);
/* Pipe & plane B info */
dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC);
- if (IS_IGDNG(dev)) {
+ if (IS_IRONLAKE(dev)) {
dev_priv->saveFPB0 = I915_READ(PCH_FPB0);
dev_priv->saveFPB1 = I915_READ(PCH_FPB1);
dev_priv->saveDPLL_B = I915_READ(PCH_DPLL_B);
dev_priv->saveFPB1 = I915_READ(FPB1);
dev_priv->saveDPLL_B = I915_READ(DPLL_B);
}
- if (IS_I965G(dev) && !IS_IGDNG(dev))
+ if (IS_I965G(dev) && !IS_IRONLAKE(dev))
dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD);
dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B);
dev_priv->saveHBLANK_B = I915_READ(HBLANK_B);
dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B);
dev_priv->saveVBLANK_B = I915_READ(VBLANK_B);
dev_priv->saveVSYNC_B = I915_READ(VSYNC_B);
- if (!IS_IGDNG(dev))
+ if (!IS_IRONLAKE(dev))
dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B);
- if (IS_IGDNG(dev)) {
+ if (IS_IRONLAKE(dev)) {
+ dev_priv->savePIPEB_DATA_M1 = I915_READ(PIPEB_DATA_M1);
+ dev_priv->savePIPEB_DATA_N1 = I915_READ(PIPEB_DATA_N1);
+ dev_priv->savePIPEB_LINK_M1 = I915_READ(PIPEB_LINK_M1);
+ dev_priv->savePIPEB_LINK_N1 = I915_READ(PIPEB_LINK_N1);
+
dev_priv->saveFDI_TXB_CTL = I915_READ(FDI_TXB_CTL);
dev_priv->saveFDI_RXB_CTL = I915_READ(FDI_RXB_CTL);
dev_priv->savePFB_WIN_SZ = I915_READ(PFB_WIN_SZ);
dev_priv->savePFB_WIN_POS = I915_READ(PFB_WIN_POS);
+ dev_priv->saveTRANSBCONF = I915_READ(TRANSBCONF);
dev_priv->saveTRANS_HTOTAL_B = I915_READ(TRANS_HTOTAL_B);
dev_priv->saveTRANS_HBLANK_B = I915_READ(TRANS_HBLANK_B);
dev_priv->saveTRANS_HSYNC_B = I915_READ(TRANS_HSYNC_B);
if (drm_core_check_feature(dev, DRIVER_MODESET))
return;
- if (IS_IGDNG(dev)) {
+ if (IS_IRONLAKE(dev)) {
dpll_a_reg = PCH_DPLL_A;
dpll_b_reg = PCH_DPLL_B;
fpa0_reg = PCH_FPA0;
fpb1_reg = FPB1;
}
- if (IS_IGDNG(dev)) {
++ if (IS_IRONLAKE(dev)) {
+ I915_WRITE(PCH_DREF_CONTROL, dev_priv->savePCH_DREF_CONTROL);
+ I915_WRITE(DISP_ARB_CTL, dev_priv->saveDISP_ARB_CTL);
+ }
+
/* Pipe & plane A info */
/* Prime the clock */
if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) {
/* Actually enable it */
I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A);
DRM_UDELAY(150);
- if (IS_I965G(dev) && !IS_IGDNG(dev))
+ if (IS_I965G(dev) && !IS_IRONLAKE(dev))
I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD);
DRM_UDELAY(150);
I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A);
I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A);
I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A);
- if (!IS_IGDNG(dev))
+ if (!IS_IRONLAKE(dev))
I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A);
- if (IS_IGDNG(dev)) {
+ if (IS_IRONLAKE(dev)) {
+ I915_WRITE(PIPEA_DATA_M1, dev_priv->savePIPEA_DATA_M1);
+ I915_WRITE(PIPEA_DATA_N1, dev_priv->savePIPEA_DATA_N1);
+ I915_WRITE(PIPEA_LINK_M1, dev_priv->savePIPEA_LINK_M1);
+ I915_WRITE(PIPEA_LINK_N1, dev_priv->savePIPEA_LINK_N1);
+
I915_WRITE(FDI_RXA_CTL, dev_priv->saveFDI_RXA_CTL);
I915_WRITE(FDI_TXA_CTL, dev_priv->saveFDI_TXA_CTL);
I915_WRITE(PFA_WIN_SZ, dev_priv->savePFA_WIN_SZ);
I915_WRITE(PFA_WIN_POS, dev_priv->savePFA_WIN_POS);
+ I915_WRITE(TRANSACONF, dev_priv->saveTRANSACONF);
I915_WRITE(TRANS_HTOTAL_A, dev_priv->saveTRANS_HTOTAL_A);
I915_WRITE(TRANS_HBLANK_A, dev_priv->saveTRANS_HBLANK_A);
I915_WRITE(TRANS_HSYNC_A, dev_priv->saveTRANS_HSYNC_A);
/* Actually enable it */
I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B);
DRM_UDELAY(150);
- if (IS_I965G(dev) && !IS_IGDNG(dev))
- if (IS_I965G(dev))
++ if (IS_I965G(dev) && !IS_IRONLAKE(dev))
I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD);
DRM_UDELAY(150);
I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B);
I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B);
I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B);
- if (!IS_IGDNG(dev))
+ if (!IS_IRONLAKE(dev))
I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B);
- if (IS_IGDNG(dev)) {
+ if (IS_IRONLAKE(dev)) {
+ I915_WRITE(PIPEB_DATA_M1, dev_priv->savePIPEB_DATA_M1);
+ I915_WRITE(PIPEB_DATA_N1, dev_priv->savePIPEB_DATA_N1);
+ I915_WRITE(PIPEB_LINK_M1, dev_priv->savePIPEB_LINK_M1);
+ I915_WRITE(PIPEB_LINK_N1, dev_priv->savePIPEB_LINK_N1);
+
I915_WRITE(FDI_RXB_CTL, dev_priv->saveFDI_RXB_CTL);
I915_WRITE(FDI_TXB_CTL, dev_priv->saveFDI_TXB_CTL);
I915_WRITE(PFB_WIN_SZ, dev_priv->savePFB_WIN_SZ);
I915_WRITE(PFB_WIN_POS, dev_priv->savePFB_WIN_POS);
+ I915_WRITE(TRANSBCONF, dev_priv->saveTRANSBCONF);
I915_WRITE(TRANS_HTOTAL_B, dev_priv->saveTRANS_HTOTAL_B);
I915_WRITE(TRANS_HBLANK_B, dev_priv->saveTRANS_HBLANK_B);
I915_WRITE(TRANS_HSYNC_B, dev_priv->saveTRANS_HSYNC_B);
dev_priv->saveCURSIZE = I915_READ(CURSIZE);
/* CRT state */
- if (IS_IGDNG(dev)) {
+ if (IS_IRONLAKE(dev)) {
dev_priv->saveADPA = I915_READ(PCH_ADPA);
} else {
dev_priv->saveADPA = I915_READ(ADPA);
}
/* LVDS state */
- if (IS_IGDNG(dev)) {
+ if (IS_IRONLAKE(dev)) {
dev_priv->savePP_CONTROL = I915_READ(PCH_PP_CONTROL);
dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1);
dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2);
dev_priv->saveLVDS = I915_READ(LVDS);
}
- if (!IS_I830(dev) && !IS_845G(dev) && !IS_IGDNG(dev))
+ if (!IS_I830(dev) && !IS_845G(dev) && !IS_IRONLAKE(dev))
dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
- if (IS_IGDNG(dev)) {
+ if (IS_IRONLAKE(dev)) {
dev_priv->savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS);
dev_priv->savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS);
dev_priv->savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR);
dev_priv->saveVGA0 = I915_READ(VGA0);
dev_priv->saveVGA1 = I915_READ(VGA1);
dev_priv->saveVGA_PD = I915_READ(VGA_PD);
- if (IS_IGDNG(dev))
+ if (IS_IRONLAKE(dev))
dev_priv->saveVGACNTRL = I915_READ(CPU_VGACNTRL);
else
dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
I915_WRITE(CURSIZE, dev_priv->saveCURSIZE);
/* CRT state */
- if (IS_IGDNG(dev))
+ if (IS_IRONLAKE(dev))
I915_WRITE(PCH_ADPA, dev_priv->saveADPA);
else
I915_WRITE(ADPA, dev_priv->saveADPA);
/* LVDS state */
- if (IS_I965G(dev) && !IS_IGDNG(dev))
+ if (IS_I965G(dev) && !IS_IRONLAKE(dev))
I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2);
- if (IS_IGDNG(dev)) {
+ if (IS_IRONLAKE(dev)) {
I915_WRITE(PCH_LVDS, dev_priv->saveLVDS);
} else if (IS_MOBILE(dev) && !IS_I830(dev))
I915_WRITE(LVDS, dev_priv->saveLVDS);
- if (!IS_I830(dev) && !IS_845G(dev) && !IS_IGDNG(dev))
+ if (!IS_I830(dev) && !IS_845G(dev) && !IS_IRONLAKE(dev))
I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL);
- if (IS_IGDNG(dev)) {
+ if (IS_IRONLAKE(dev)) {
I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL);
I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2);
I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL);
}
/* VGA state */
- if (IS_IGDNG(dev))
+ if (IS_IRONLAKE(dev))
I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL);
else
I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB);
/* Render Standby */
- if (IS_I965G(dev) && IS_MOBILE(dev))
+ if (I915_HAS_RC6(dev)) {
dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY);
+ dev_priv->savePWRCTXA = I915_READ(PWRCTXA);
+ }
/* Hardware status page */
dev_priv->saveHWS = I915_READ(HWS_PGA);
i915_save_display(dev);
/* Interrupt state */
- if (IS_IGDNG(dev)) {
+ if (IS_IRONLAKE(dev)) {
dev_priv->saveDEIER = I915_READ(DEIER);
dev_priv->saveDEIMR = I915_READ(DEIMR);
dev_priv->saveGTIER = I915_READ(GTIER);
pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB);
/* Render Standby */
- if (IS_I965G(dev) && IS_MOBILE(dev))
+ if (I915_HAS_RC6(dev)) {
I915_WRITE(MCHBAR_RENDER_STANDBY, dev_priv->saveRENDERSTANDBY);
+ I915_WRITE(PWRCTXA, dev_priv->savePWRCTXA);
+ }
/* Hardware status page */
I915_WRITE(HWS_PGA, dev_priv->saveHWS);
i915_restore_display(dev);
/* Interrupt state */
- if (IS_IGDNG(dev)) {
+ if (IS_IRONLAKE(dev)) {
I915_WRITE(DEIER, dev_priv->saveDEIER);
I915_WRITE(DEIMR, dev_priv->saveDEIMR);
I915_WRITE(GTIER, dev_priv->saveGTIER);
for (i = 0; i < 3; i++)
I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]);
+ /* I2C state */
+ intel_i2c_reset_gmbus(dev);
+
return 0;
}
struct drm_i915_private *dev_priv = dev->dev_private;
u32 temp, reg;
- if (IS_IGDNG(dev))
+ if (IS_IRONLAKE(dev))
reg = PCH_ADPA;
else
reg = ADPA;
}
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,
else
dpll_md_reg = DPLL_B_MD;
- if (IS_IGDNG(dev))
+ if (IS_IRONLAKE(dev))
adpa_reg = PCH_ADPA;
else
adpa_reg = ADPA;
* Disable separate mode multiplier used when cloning SDVO to CRT
* XXX this needs to be adjusted when we really are cloning
*/
- if (IS_I965G(dev) && !IS_IGDNG(dev)) {
+ if (IS_I965G(dev) && !IS_IRONLAKE(dev)) {
dpll_md = I915_READ(dpll_md_reg);
I915_WRITE(dpll_md_reg,
dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK);
if (intel_crtc->pipe == 0) {
adpa |= ADPA_PIPE_A_SELECT;
- if (!IS_IGDNG(dev))
+ if (!IS_IRONLAKE(dev))
I915_WRITE(BCLRPAT_A, 0);
} else {
adpa |= ADPA_PIPE_B_SELECT;
- if (!IS_IGDNG(dev))
+ if (!IS_IRONLAKE(dev))
I915_WRITE(BCLRPAT_B, 0);
}
I915_WRITE(adpa_reg, adpa);
}
- static bool intel_igdng_crt_detect_hotplug(struct drm_connector *connector)
+ static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
ADPA_CRT_HOTPLUG_ENABLE |
ADPA_CRT_HOTPLUG_FORCE_TRIGGER);
- DRM_DEBUG("pch crt adpa 0x%x", adpa);
+ DRM_DEBUG_KMS("pch crt adpa 0x%x", adpa);
I915_WRITE(PCH_ADPA, adpa);
while ((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) != 0)
u32 hotplug_en;
int i, tries = 0;
- if (IS_IGDNG(dev))
- return intel_igdng_crt_detect_hotplug(connector);
+ if (IS_IRONLAKE(dev))
+ return intel_ironlake_crt_detect_hotplug(connector);
/*
* On 4 series desktop, CRT detect sequence need to be done twice
} while (time_after(timeout, jiffies));
}
- if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) ==
- CRT_HOTPLUG_MONITOR_COLOR)
+ if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) !=
+ CRT_HOTPLUG_MONITOR_NONE)
return true;
return false;
&intel_output->enc);
/* Set up the DDC bus. */
- if (IS_IGDNG(dev))
+ if (IS_IRONLAKE(dev))
i2c_reg = PCH_GPIOA;
else {
i2c_reg = GPIOA;
/* Use VBT information for CRT DDC if available */
- if (dev_priv->crt_ddc_bus != -1)
+ if (dev_priv->crt_ddc_bus != 0)
i2c_reg = dev_priv->crt_ddc_bus;
}
intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A");
#include "intel_drv.h"
#include "i915_drm.h"
#include "i915_drv.h"
-#include "intel_dp.h"
+#include "drm_dp_helper.h"
#include "drm_crtc_helper.h"
#define I9XX_DOT_MAX 400000
#define I9XX_VCO_MIN 1400000
#define I9XX_VCO_MAX 2800000
- #define IGD_VCO_MIN 1700000
- #define IGD_VCO_MAX 3500000
+ #define PINEVIEW_VCO_MIN 1700000
+ #define PINEVIEW_VCO_MAX 3500000
#define I9XX_N_MIN 1
#define I9XX_N_MAX 6
- /* IGD's Ncounter is a ring counter */
- #define IGD_N_MIN 3
- #define IGD_N_MAX 6
+ /* Pineview's Ncounter is a ring counter */
+ #define PINEVIEW_N_MIN 3
+ #define PINEVIEW_N_MAX 6
#define I9XX_M_MIN 70
#define I9XX_M_MAX 120
- #define IGD_M_MIN 2
- #define IGD_M_MAX 256
+ #define PINEVIEW_M_MIN 2
+ #define PINEVIEW_M_MAX 256
#define I9XX_M1_MIN 10
#define I9XX_M1_MAX 22
#define I9XX_M2_MIN 5
#define I9XX_M2_MAX 9
- /* IGD M1 is reserved, and must be 0 */
- #define IGD_M1_MIN 0
- #define IGD_M1_MAX 0
- #define IGD_M2_MIN 0
- #define IGD_M2_MAX 254
+ /* Pineview M1 is reserved, and must be 0 */
+ #define PINEVIEW_M1_MIN 0
+ #define PINEVIEW_M1_MAX 0
+ #define PINEVIEW_M2_MIN 0
+ #define PINEVIEW_M2_MAX 254
#define I9XX_P_SDVO_DAC_MIN 5
#define I9XX_P_SDVO_DAC_MAX 80
#define I9XX_P_LVDS_MIN 7
#define I9XX_P_LVDS_MAX 98
- #define IGD_P_LVDS_MIN 7
- #define IGD_P_LVDS_MAX 112
+ #define PINEVIEW_P_LVDS_MIN 7
+ #define PINEVIEW_P_LVDS_MAX 112
#define I9XX_P1_MIN 1
#define I9XX_P1_MAX 8
#define I9XX_P2_SDVO_DAC_SLOW 10
#define G4X_P2_DISPLAY_PORT_FAST 10
#define G4X_P2_DISPLAY_PORT_LIMIT 0
- /* IGDNG */
+ /* Ironlake */
/* as we calculate clock using (register_value + 2) for
N/M1/M2, so here the range value for them is (actual_value-2).
*/
- #define IGDNG_DOT_MIN 25000
- #define IGDNG_DOT_MAX 350000
- #define IGDNG_VCO_MIN 1760000
- #define IGDNG_VCO_MAX 3510000
- #define IGDNG_N_MIN 1
- #define IGDNG_N_MAX 5
- #define IGDNG_M_MIN 79
- #define IGDNG_M_MAX 118
- #define IGDNG_M1_MIN 12
- #define IGDNG_M1_MAX 23
- #define IGDNG_M2_MIN 5
- #define IGDNG_M2_MAX 9
- #define IGDNG_P_SDVO_DAC_MIN 5
- #define IGDNG_P_SDVO_DAC_MAX 80
- #define IGDNG_P_LVDS_MIN 28
- #define IGDNG_P_LVDS_MAX 112
- #define IGDNG_P1_MIN 1
- #define IGDNG_P1_MAX 8
- #define IGDNG_P2_SDVO_DAC_SLOW 10
- #define IGDNG_P2_SDVO_DAC_FAST 5
- #define IGDNG_P2_LVDS_SLOW 14 /* single channel */
- #define IGDNG_P2_LVDS_FAST 7 /* double channel */
- #define IGDNG_P2_DOT_LIMIT 225000 /* 225Mhz */
+ #define IRONLAKE_DOT_MIN 25000
+ #define IRONLAKE_DOT_MAX 350000
+ #define IRONLAKE_VCO_MIN 1760000
+ #define IRONLAKE_VCO_MAX 3510000
+ #define IRONLAKE_N_MIN 1
+ #define IRONLAKE_N_MAX 5
+ #define IRONLAKE_M_MIN 79
+ #define IRONLAKE_M_MAX 118
+ #define IRONLAKE_M1_MIN 12
+ #define IRONLAKE_M1_MAX 23
+ #define IRONLAKE_M2_MIN 5
+ #define IRONLAKE_M2_MAX 9
+ #define IRONLAKE_P_SDVO_DAC_MIN 5
+ #define IRONLAKE_P_SDVO_DAC_MAX 80
+ #define IRONLAKE_P_LVDS_MIN 28
+ #define IRONLAKE_P_LVDS_MAX 112
+ #define IRONLAKE_P1_MIN 1
+ #define IRONLAKE_P1_MAX 8
+ #define IRONLAKE_P2_SDVO_DAC_SLOW 10
+ #define IRONLAKE_P2_SDVO_DAC_FAST 5
+ #define IRONLAKE_P2_LVDS_SLOW 14 /* single channel */
+ #define IRONLAKE_P2_LVDS_FAST 7 /* double channel */
+ #define IRONLAKE_P2_DOT_LIMIT 225000 /* 225Mhz */
static bool
intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
int target, int refclk, intel_clock_t *best_clock);
static bool
- intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
- int target, int refclk, intel_clock_t *best_clock);
+ intel_ironlake_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
+ int target, int refclk, intel_clock_t *best_clock);
static bool
intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc,
int target, int refclk, intel_clock_t *best_clock);
static bool
- intel_find_pll_igdng_dp(const intel_limit_t *, struct drm_crtc *crtc,
- int target, int refclk, intel_clock_t *best_clock);
+ intel_find_pll_ironlake_dp(const intel_limit_t *, struct drm_crtc *crtc,
+ int target, int refclk, intel_clock_t *best_clock);
static const intel_limit_t intel_limits_i8xx_dvo = {
.dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX },
.find_pll = intel_find_pll_g4x_dp,
};
- static const intel_limit_t intel_limits_igd_sdvo = {
+ static const intel_limit_t intel_limits_pineview_sdvo = {
.dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX},
- .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX },
- .n = { .min = IGD_N_MIN, .max = IGD_N_MAX },
- .m = { .min = IGD_M_MIN, .max = IGD_M_MAX },
- .m1 = { .min = IGD_M1_MIN, .max = IGD_M1_MAX },
- .m2 = { .min = IGD_M2_MIN, .max = IGD_M2_MAX },
+ .vco = { .min = PINEVIEW_VCO_MIN, .max = PINEVIEW_VCO_MAX },
+ .n = { .min = PINEVIEW_N_MIN, .max = PINEVIEW_N_MAX },
+ .m = { .min = PINEVIEW_M_MIN, .max = PINEVIEW_M_MAX },
+ .m1 = { .min = PINEVIEW_M1_MIN, .max = PINEVIEW_M1_MAX },
+ .m2 = { .min = PINEVIEW_M2_MIN, .max = PINEVIEW_M2_MAX },
.p = { .min = I9XX_P_SDVO_DAC_MIN, .max = I9XX_P_SDVO_DAC_MAX },
.p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX },
.p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
.find_reduced_pll = intel_find_best_reduced_PLL,
};
- static const intel_limit_t intel_limits_igd_lvds = {
+ static const intel_limit_t intel_limits_pineview_lvds = {
.dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX },
- .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX },
- .n = { .min = IGD_N_MIN, .max = IGD_N_MAX },
- .m = { .min = IGD_M_MIN, .max = IGD_M_MAX },
- .m1 = { .min = IGD_M1_MIN, .max = IGD_M1_MAX },
- .m2 = { .min = IGD_M2_MIN, .max = IGD_M2_MAX },
- .p = { .min = IGD_P_LVDS_MIN, .max = IGD_P_LVDS_MAX },
+ .vco = { .min = PINEVIEW_VCO_MIN, .max = PINEVIEW_VCO_MAX },
+ .n = { .min = PINEVIEW_N_MIN, .max = PINEVIEW_N_MAX },
+ .m = { .min = PINEVIEW_M_MIN, .max = PINEVIEW_M_MAX },
+ .m1 = { .min = PINEVIEW_M1_MIN, .max = PINEVIEW_M1_MAX },
+ .m2 = { .min = PINEVIEW_M2_MIN, .max = PINEVIEW_M2_MAX },
+ .p = { .min = PINEVIEW_P_LVDS_MIN, .max = PINEVIEW_P_LVDS_MAX },
.p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX },
- /* IGD only supports single-channel mode. */
+ /* Pineview only supports single-channel mode. */
.p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
.p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW },
.find_pll = intel_find_best_PLL,
.find_reduced_pll = intel_find_best_reduced_PLL,
};
- static const intel_limit_t intel_limits_igdng_sdvo = {
- .dot = { .min = IGDNG_DOT_MIN, .max = IGDNG_DOT_MAX },
- .vco = { .min = IGDNG_VCO_MIN, .max = IGDNG_VCO_MAX },
- .n = { .min = IGDNG_N_MIN, .max = IGDNG_N_MAX },
- .m = { .min = IGDNG_M_MIN, .max = IGDNG_M_MAX },
- .m1 = { .min = IGDNG_M1_MIN, .max = IGDNG_M1_MAX },
- .m2 = { .min = IGDNG_M2_MIN, .max = IGDNG_M2_MAX },
- .p = { .min = IGDNG_P_SDVO_DAC_MIN, .max = IGDNG_P_SDVO_DAC_MAX },
- .p1 = { .min = IGDNG_P1_MIN, .max = IGDNG_P1_MAX },
- .p2 = { .dot_limit = IGDNG_P2_DOT_LIMIT,
- .p2_slow = IGDNG_P2_SDVO_DAC_SLOW,
- .p2_fast = IGDNG_P2_SDVO_DAC_FAST },
- .find_pll = intel_igdng_find_best_PLL,
+ static const intel_limit_t intel_limits_ironlake_sdvo = {
+ .dot = { .min = IRONLAKE_DOT_MIN, .max = IRONLAKE_DOT_MAX },
+ .vco = { .min = IRONLAKE_VCO_MIN, .max = IRONLAKE_VCO_MAX },
+ .n = { .min = IRONLAKE_N_MIN, .max = IRONLAKE_N_MAX },
+ .m = { .min = IRONLAKE_M_MIN, .max = IRONLAKE_M_MAX },
+ .m1 = { .min = IRONLAKE_M1_MIN, .max = IRONLAKE_M1_MAX },
+ .m2 = { .min = IRONLAKE_M2_MIN, .max = IRONLAKE_M2_MAX },
+ .p = { .min = IRONLAKE_P_SDVO_DAC_MIN, .max = IRONLAKE_P_SDVO_DAC_MAX },
+ .p1 = { .min = IRONLAKE_P1_MIN, .max = IRONLAKE_P1_MAX },
+ .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT,
+ .p2_slow = IRONLAKE_P2_SDVO_DAC_SLOW,
+ .p2_fast = IRONLAKE_P2_SDVO_DAC_FAST },
+ .find_pll = intel_ironlake_find_best_PLL,
};
- static const intel_limit_t intel_limits_igdng_lvds = {
- .dot = { .min = IGDNG_DOT_MIN, .max = IGDNG_DOT_MAX },
- .vco = { .min = IGDNG_VCO_MIN, .max = IGDNG_VCO_MAX },
- .n = { .min = IGDNG_N_MIN, .max = IGDNG_N_MAX },
- .m = { .min = IGDNG_M_MIN, .max = IGDNG_M_MAX },
- .m1 = { .min = IGDNG_M1_MIN, .max = IGDNG_M1_MAX },
- .m2 = { .min = IGDNG_M2_MIN, .max = IGDNG_M2_MAX },
- .p = { .min = IGDNG_P_LVDS_MIN, .max = IGDNG_P_LVDS_MAX },
- .p1 = { .min = IGDNG_P1_MIN, .max = IGDNG_P1_MAX },
- .p2 = { .dot_limit = IGDNG_P2_DOT_LIMIT,
- .p2_slow = IGDNG_P2_LVDS_SLOW,
- .p2_fast = IGDNG_P2_LVDS_FAST },
- .find_pll = intel_igdng_find_best_PLL,
+ static const intel_limit_t intel_limits_ironlake_lvds = {
+ .dot = { .min = IRONLAKE_DOT_MIN, .max = IRONLAKE_DOT_MAX },
+ .vco = { .min = IRONLAKE_VCO_MIN, .max = IRONLAKE_VCO_MAX },
+ .n = { .min = IRONLAKE_N_MIN, .max = IRONLAKE_N_MAX },
+ .m = { .min = IRONLAKE_M_MIN, .max = IRONLAKE_M_MAX },
+ .m1 = { .min = IRONLAKE_M1_MIN, .max = IRONLAKE_M1_MAX },
+ .m2 = { .min = IRONLAKE_M2_MIN, .max = IRONLAKE_M2_MAX },
+ .p = { .min = IRONLAKE_P_LVDS_MIN, .max = IRONLAKE_P_LVDS_MAX },
+ .p1 = { .min = IRONLAKE_P1_MIN, .max = IRONLAKE_P1_MAX },
+ .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT,
+ .p2_slow = IRONLAKE_P2_LVDS_SLOW,
+ .p2_fast = IRONLAKE_P2_LVDS_FAST },
+ .find_pll = intel_ironlake_find_best_PLL,
};
- static const intel_limit_t *intel_igdng_limit(struct drm_crtc *crtc)
+ static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc)
{
const intel_limit_t *limit;
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
- limit = &intel_limits_igdng_lvds;
+ limit = &intel_limits_ironlake_lvds;
else
- limit = &intel_limits_igdng_sdvo;
+ limit = &intel_limits_ironlake_sdvo;
return limit;
}
struct drm_device *dev = crtc->dev;
const intel_limit_t *limit;
- if (IS_IGDNG(dev))
- limit = intel_igdng_limit(crtc);
+ if (IS_IRONLAKE(dev))
+ limit = intel_ironlake_limit(crtc);
else if (IS_G4X(dev)) {
limit = intel_g4x_limit(crtc);
- } else if (IS_I9XX(dev) && !IS_IGD(dev)) {
+ } else if (IS_I9XX(dev) && !IS_PINEVIEW(dev)) {
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
limit = &intel_limits_i9xx_lvds;
else
limit = &intel_limits_i9xx_sdvo;
- } else if (IS_IGD(dev)) {
+ } else if (IS_PINEVIEW(dev)) {
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
- limit = &intel_limits_igd_lvds;
+ limit = &intel_limits_pineview_lvds;
else
- limit = &intel_limits_igd_sdvo;
+ limit = &intel_limits_pineview_sdvo;
} else {
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
limit = &intel_limits_i8xx_lvds;
return limit;
}
- /* m1 is reserved as 0 in IGD, n is a ring counter */
- static void igd_clock(int refclk, intel_clock_t *clock)
+ /* m1 is reserved as 0 in Pineview, n is a ring counter */
+ static void pineview_clock(int refclk, intel_clock_t *clock)
{
clock->m = clock->m2 + 2;
clock->p = clock->p1 * clock->p2;
static void intel_clock(struct drm_device *dev, int refclk, intel_clock_t *clock)
{
- if (IS_IGD(dev)) {
- igd_clock(refclk, clock);
+ if (IS_PINEVIEW(dev)) {
+ pineview_clock(refclk, clock);
return;
}
clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
INTELPllInvalid ("m2 out of range\n");
if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1)
INTELPllInvalid ("m1 out of range\n");
- if (clock->m1 <= clock->m2 && !IS_IGD(dev))
+ if (clock->m1 <= clock->m2 && !IS_PINEVIEW(dev))
INTELPllInvalid ("m1 <= m2\n");
if (clock->m < limit->m.min || limit->m.max < clock->m)
INTELPllInvalid ("m out of range\n");
memset (best_clock, 0, sizeof (*best_clock));
- for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
- for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max;
- clock.m1++) {
- for (clock.m2 = limit->m2.min;
- clock.m2 <= limit->m2.max; clock.m2++) {
- /* m1 is always 0 in IGD */
- if (clock.m2 >= clock.m1 && !IS_IGD(dev))
- break;
- for (clock.n = limit->n.min;
- clock.n <= limit->n.max; clock.n++) {
+ for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max;
+ clock.m1++) {
+ for (clock.m2 = limit->m2.min;
+ clock.m2 <= limit->m2.max; clock.m2++) {
+ /* m1 is always 0 in Pineview */
+ if (clock.m2 >= clock.m1 && !IS_PINEVIEW(dev))
+ break;
+ for (clock.n = limit->n.min;
+ clock.n <= limit->n.max; clock.n++) {
+ for (clock.p1 = limit->p1.min;
+ clock.p1 <= limit->p1.max; clock.p1++) {
int this_err;
intel_clock(dev, refclk, &clock);
for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) {
for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; clock.m2++) {
- /* m1 is always 0 in IGD */
- if (clock.m2 >= clock.m1 && !IS_IGD(dev))
+ /* m1 is always 0 in Pineview */
+ if (clock.m2 >= clock.m1 && !IS_PINEVIEW(dev))
break;
for (clock.n = limit->n.min; clock.n <= limit->n.max;
clock.n++) {
}
static bool
- intel_find_pll_igdng_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
- int target, int refclk, intel_clock_t *best_clock)
+ intel_find_pll_ironlake_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
+ int target, int refclk, intel_clock_t *best_clock)
{
struct drm_device *dev = crtc->dev;
intel_clock_t clock;
}
static bool
- intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
- int target, int refclk, intel_clock_t *best_clock)
+ intel_ironlake_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
+ int target, int refclk, intel_clock_t *best_clock)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
return true;
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT))
- return intel_find_pll_igdng_dp(limit, crtc, target,
+ return intel_find_pll_ironlake_dp(limit, crtc, target,
refclk, best_clock);
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
intel_wait_for_vblank(struct drm_device *dev)
{
/* Wait for 20ms, i.e. one cycle at 50hz. */
- mdelay(20);
+ msleep(20);
}
/* Parameters have changed, update FBC info */
fbc_ctl |= dev_priv->cfb_fence;
I915_WRITE(FBC_CONTROL, fbc_ctl);
- DRM_DEBUG("enabled FBC, pitch %ld, yoff %d, plane %d, ",
+ DRM_DEBUG_KMS("enabled FBC, pitch %ld, yoff %d, plane %d, ",
dev_priv->cfb_pitch, crtc->y, dev_priv->cfb_plane);
}
intel_wait_for_vblank(dev);
- DRM_DEBUG("disabled FBC\n");
+ DRM_DEBUG_KMS("disabled FBC\n");
}
static bool i8xx_fbc_enabled(struct drm_crtc *crtc)
/* enable it... */
I915_WRITE(DPFC_CONTROL, I915_READ(DPFC_CONTROL) | DPFC_CTL_EN);
- DRM_DEBUG("enabled fbc on plane %d\n", intel_crtc->plane);
+ DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane);
}
void g4x_disable_fbc(struct drm_device *dev)
I915_WRITE(DPFC_CONTROL, dpfc_ctl);
intel_wait_for_vblank(dev);
- DRM_DEBUG("disabled FBC\n");
+ DRM_DEBUG_KMS("disabled FBC\n");
}
static bool g4x_fbc_enabled(struct drm_crtc *crtc)
* - going to an unsupported config (interlace, pixel multiply, etc.)
*/
if (intel_fb->obj->size > dev_priv->cfb_size) {
- DRM_DEBUG("framebuffer too large, disabling compression\n");
+ DRM_DEBUG_KMS("framebuffer too large, disabling "
+ "compression\n");
goto out_disable;
}
if ((mode->flags & DRM_MODE_FLAG_INTERLACE) ||
(mode->flags & DRM_MODE_FLAG_DBLSCAN)) {
- DRM_DEBUG("mode incompatible with compression, disabling\n");
+ DRM_DEBUG_KMS("mode incompatible with compression, "
+ "disabling\n");
goto out_disable;
}
if ((mode->hdisplay > 2048) ||
(mode->vdisplay > 1536)) {
- DRM_DEBUG("mode too large for compression, disabling\n");
+ DRM_DEBUG_KMS("mode too large for compression, disabling\n");
goto out_disable;
}
if ((IS_I915GM(dev) || IS_I945GM(dev)) && plane != 0) {
- DRM_DEBUG("plane not 0, disabling compression\n");
+ DRM_DEBUG_KMS("plane not 0, disabling compression\n");
goto out_disable;
}
if (obj_priv->tiling_mode != I915_TILING_X) {
- DRM_DEBUG("framebuffer not tiled, disabling compression\n");
+ DRM_DEBUG_KMS("framebuffer not tiled, disabling compression\n");
goto out_disable;
}
return;
out_disable:
- DRM_DEBUG("unsupported config, disabling FBC\n");
+ DRM_DEBUG_KMS("unsupported config, disabling FBC\n");
/* Multiple disables should be harmless */
if (dev_priv->display.fbc_enabled(crtc))
dev_priv->display.disable_fbc(dev);
}
+ static int
+ intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj)
+ {
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ u32 alignment;
+ int ret;
+
+ switch (obj_priv->tiling_mode) {
+ case I915_TILING_NONE:
+ alignment = 64 * 1024;
+ break;
+ case I915_TILING_X:
+ /* pin() will align the object as required by fence */
+ alignment = 0;
+ break;
+ case I915_TILING_Y:
+ /* FIXME: Is this true? */
+ DRM_ERROR("Y tiled not allowed for scan out buffers\n");
+ return -EINVAL;
+ default:
+ BUG();
+ }
+
+ ret = i915_gem_object_pin(obj, alignment);
+ if (ret != 0)
+ return ret;
+
+ /* Install a fence for tiled scan-out. Pre-i965 always needs a
+ * fence, whereas 965+ only requires a fence if using
+ * framebuffer compression. For simplicity, we always install
+ * a fence as the cost is not that onerous.
+ */
+ if (obj_priv->fence_reg == I915_FENCE_REG_NONE &&
+ obj_priv->tiling_mode != I915_TILING_NONE) {
+ ret = i915_gem_object_get_fence_reg(obj);
+ if (ret != 0) {
+ i915_gem_object_unpin(obj);
+ return ret;
+ }
+ }
+
+ return 0;
+ }
+
static int
intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
struct drm_framebuffer *old_fb)
int dspstride = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE;
int dsptileoff = (plane == 0 ? DSPATILEOFF : DSPBTILEOFF);
int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR;
- u32 dspcntr, alignment;
+ u32 dspcntr;
int ret;
/* no fb bound */
if (!crtc->fb) {
- DRM_DEBUG("No FB bound\n");
+ DRM_DEBUG_KMS("No FB bound\n");
return 0;
}
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:
- /* pin() will align the object as required by fence */
- alignment = 0;
- break;
- case I915_TILING_Y:
- /* FIXME: Is this true? */
- DRM_ERROR("Y tiled not allowed for scan out buffers\n");
- return -EINVAL;
- default:
- BUG();
- }
-
mutex_lock(&dev->struct_mutex);
- ret = i915_gem_object_pin(obj, alignment);
+ ret = intel_pin_and_fence_fb_obj(dev, obj);
if (ret != 0) {
mutex_unlock(&dev->struct_mutex);
return ret;
return ret;
}
- /* Install a fence for tiled scan-out. Pre-i965 always needs a fence,
- * whereas 965+ only requires a fence if using framebuffer compression.
- * For simplicity, we always install a fence as the cost is not that onerous.
- */
- if (obj_priv->fence_reg == I915_FENCE_REG_NONE &&
- obj_priv->tiling_mode != I915_TILING_NONE) {
- ret = i915_gem_object_get_fence_reg(obj);
- if (ret != 0) {
- i915_gem_object_unpin(obj);
- mutex_unlock(&dev->struct_mutex);
- return ret;
- }
- }
-
dspcntr = I915_READ(dspcntr_reg);
/* Mask out pixel format bits in case we change it */
dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
break;
case 24:
case 32:
- dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
+ if (crtc->fb->depth == 30)
+ dspcntr |= DISPPLANE_32BPP_30BIT_NO_ALPHA;
+ else
+ dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
break;
default:
DRM_ERROR("Unknown color depth\n");
dspcntr &= ~DISPPLANE_TILED;
}
- if (IS_IGDNG(dev))
+ if (IS_IRONLAKE(dev))
/* must disable */
dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
Start = obj_priv->gtt_offset;
Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
- DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
+ DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
I915_WRITE(dspstride, crtc->fb->pitch);
if (IS_I965G(dev)) {
I915_WRITE(dspbase, Offset);
u8 sr1;
u32 vga_reg;
- if (IS_IGDNG(dev))
+ if (IS_IRONLAKE(dev))
vga_reg = CPU_VGACNTRL;
else
vga_reg = VGACNTRL;
I915_WRITE(vga_reg, VGA_DISP_DISABLE);
}
- static void igdng_disable_pll_edp (struct drm_crtc *crtc)
+ static void ironlake_disable_pll_edp (struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 dpa_ctl;
- DRM_DEBUG("\n");
+ DRM_DEBUG_KMS("\n");
dpa_ctl = I915_READ(DP_A);
dpa_ctl &= ~DP_PLL_ENABLE;
I915_WRITE(DP_A, dpa_ctl);
}
- static void igdng_enable_pll_edp (struct drm_crtc *crtc)
+ static void ironlake_enable_pll_edp (struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
}
- static void igdng_set_pll_edp (struct drm_crtc *crtc, int clock)
+ static void ironlake_set_pll_edp (struct drm_crtc *crtc, int clock)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 dpa_ctl;
- DRM_DEBUG("eDP PLL enable for clock %d\n", clock);
+ DRM_DEBUG_KMS("eDP PLL enable for clock %d\n", clock);
dpa_ctl = I915_READ(DP_A);
dpa_ctl &= ~DP_PLL_FREQ_MASK;
udelay(500);
}
- static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
+ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
case DRM_MODE_DPMS_ON:
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
- DRM_DEBUG("crtc %d dpms on\n", pipe);
+ DRM_DEBUG_KMS("crtc %d dpms on\n", pipe);
+
+ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
+ temp = I915_READ(PCH_LVDS);
+ if ((temp & LVDS_PORT_EN) == 0) {
+ I915_WRITE(PCH_LVDS, temp | LVDS_PORT_EN);
+ POSTING_READ(PCH_LVDS);
+ }
+ }
+
if (HAS_eDP) {
/* enable eDP PLL */
- igdng_enable_pll_edp(crtc);
+ ironlake_enable_pll_edp(crtc);
} else {
/* enable PCH DPLL */
temp = I915_READ(pch_dpll_reg);
I915_READ(fdi_rx_reg);
udelay(200);
- /* Enable CPU FDI TX PLL, always on for IGDNG */
+ /* Enable CPU FDI TX PLL, always on for Ironlake */
temp = I915_READ(fdi_tx_reg);
if ((temp & FDI_TX_PLL_ENABLE) == 0) {
I915_WRITE(fdi_tx_reg, temp | FDI_TX_PLL_ENABLE);
udelay(150);
temp = I915_READ(fdi_rx_iir_reg);
- DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp);
+ DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp);
if ((temp & FDI_RX_BIT_LOCK) == 0) {
for (j = 0; j < tries; j++) {
temp = I915_READ(fdi_rx_iir_reg);
- DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp);
+ DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n",
+ temp);
if (temp & FDI_RX_BIT_LOCK)
break;
udelay(200);
I915_WRITE(fdi_rx_iir_reg,
temp | FDI_RX_BIT_LOCK);
else
- DRM_DEBUG("train 1 fail\n");
+ DRM_DEBUG_KMS("train 1 fail\n");
} else {
I915_WRITE(fdi_rx_iir_reg,
temp | FDI_RX_BIT_LOCK);
- DRM_DEBUG("train 1 ok 2!\n");
+ DRM_DEBUG_KMS("train 1 ok 2!\n");
}
temp = I915_READ(fdi_tx_reg);
temp &= ~FDI_LINK_TRAIN_NONE;
udelay(150);
temp = I915_READ(fdi_rx_iir_reg);
- DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp);
+ DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp);
if ((temp & FDI_RX_SYMBOL_LOCK) == 0) {
for (j = 0; j < tries; j++) {
temp = I915_READ(fdi_rx_iir_reg);
- DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp);
+ DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n",
+ temp);
if (temp & FDI_RX_SYMBOL_LOCK)
break;
udelay(200);
if (j != tries) {
I915_WRITE(fdi_rx_iir_reg,
temp | FDI_RX_SYMBOL_LOCK);
- DRM_DEBUG("train 2 ok 1!\n");
+ DRM_DEBUG_KMS("train 2 ok 1!\n");
} else
- DRM_DEBUG("train 2 fail\n");
+ DRM_DEBUG_KMS("train 2 fail\n");
} else {
I915_WRITE(fdi_rx_iir_reg,
temp | FDI_RX_SYMBOL_LOCK);
- DRM_DEBUG("train 2 ok 2!\n");
+ DRM_DEBUG_KMS("train 2 ok 2!\n");
}
- DRM_DEBUG("train done\n");
+ DRM_DEBUG_KMS("train done\n");
/* set transcoder timing */
I915_WRITE(trans_htot_reg, I915_READ(cpu_htot_reg));
break;
case DRM_MODE_DPMS_OFF:
- DRM_DEBUG("crtc %d dpms off\n", pipe);
-
- i915_disable_vga(dev);
+ DRM_DEBUG_KMS("crtc %d dpms off\n", pipe);
/* Disable display plane */
temp = I915_READ(dspcntr_reg);
I915_READ(dspbase_reg);
}
+ i915_disable_vga(dev);
+
/* disable cpu pipe, disable after all planes disabled */
temp = I915_READ(pipeconf_reg);
if ((temp & PIPEACONF_ENABLE) != 0) {
udelay(500);
continue;
} else {
- DRM_DEBUG("pipe %d off delay\n", pipe);
+ DRM_DEBUG_KMS("pipe %d off delay\n",
+ pipe);
break;
}
}
} else
- DRM_DEBUG("crtc %d is disabled\n", pipe);
+ DRM_DEBUG_KMS("crtc %d is disabled\n", pipe);
- if (HAS_eDP) {
- igdng_disable_pll_edp(crtc);
+ udelay(100);
+
+ /* Disable PF */
+ temp = I915_READ(pf_ctl_reg);
+ if ((temp & PF_ENABLE) != 0) {
+ I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE);
+ I915_READ(pf_ctl_reg);
}
+ I915_WRITE(pf_win_size, 0);
/* disable CPU FDI tx and PCH FDI rx */
temp = I915_READ(fdi_tx_reg);
udelay(100);
+ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
+ temp = I915_READ(PCH_LVDS);
+ I915_WRITE(PCH_LVDS, temp & ~LVDS_PORT_EN);
+ I915_READ(PCH_LVDS);
+ udelay(100);
+ }
+
/* disable PCH transcoder */
temp = I915_READ(transconf_reg);
if ((temp & TRANS_ENABLE) != 0) {
udelay(500);
continue;
} else {
- DRM_DEBUG("transcoder %d off delay\n", pipe);
+ DRM_DEBUG_KMS("transcoder %d off "
+ "delay\n", pipe);
break;
}
}
}
+ udelay(100);
+
/* disable PCH DPLL */
temp = I915_READ(pch_dpll_reg);
if ((temp & DPLL_VCO_ENABLE) != 0) {
I915_READ(pch_dpll_reg);
}
- temp = I915_READ(fdi_rx_reg);
- if ((temp & FDI_RX_PLL_ENABLE) != 0) {
- temp &= ~FDI_SEL_PCDCLK;
- temp &= ~FDI_RX_PLL_ENABLE;
- I915_WRITE(fdi_rx_reg, temp);
- I915_READ(fdi_rx_reg);
+ if (HAS_eDP) {
+ ironlake_disable_pll_edp(crtc);
}
+ temp = I915_READ(fdi_rx_reg);
+ temp &= ~FDI_SEL_PCDCLK;
+ I915_WRITE(fdi_rx_reg, temp);
+ I915_READ(fdi_rx_reg);
+
+ temp = I915_READ(fdi_rx_reg);
+ temp &= ~FDI_RX_PLL_ENABLE;
+ I915_WRITE(fdi_rx_reg, temp);
+ I915_READ(fdi_rx_reg);
+
/* Disable CPU FDI TX PLL */
temp = I915_READ(fdi_tx_reg);
if ((temp & FDI_TX_PLL_ENABLE) != 0) {
udelay(100);
}
- /* Disable PF */
- temp = I915_READ(pf_ctl_reg);
- if ((temp & PF_ENABLE) != 0) {
- I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE);
- I915_READ(pf_ctl_reg);
- }
- I915_WRITE(pf_win_size, 0);
-
/* Wait for the clocks to turn off. */
- udelay(150);
+ udelay(100);
break;
}
}
+ static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable)
+ {
+ struct intel_overlay *overlay;
+ int ret;
+
+ if (!enable && intel_crtc->overlay) {
+ overlay = intel_crtc->overlay;
+ mutex_lock(&overlay->dev->struct_mutex);
+ for (;;) {
+ ret = intel_overlay_switch_off(overlay);
+ if (ret == 0)
+ break;
+
+ ret = intel_overlay_recover_from_interrupt(overlay, 0);
+ if (ret != 0) {
+ /* overlay doesn't react anymore. Usually
+ * results in a black screen and an unkillable
+ * X server. */
+ BUG();
+ overlay->hw_wedged = HW_WEDGED;
+ break;
+ }
+ }
+ mutex_unlock(&overlay->dev->struct_mutex);
+ }
+ /* Let userspace switch the overlay on again. In most cases userspace
+ * has to recompute where to put it anyway. */
+
+ return;
+ }
+
static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
{
struct drm_device *dev = crtc->dev;
intel_update_fbc(crtc, &crtc->mode);
/* Give the overlay scaler a chance to enable if it's on this pipe */
- //intel_crtc_dpms_video(crtc, true); TODO
+ intel_crtc_dpms_overlay(intel_crtc, true);
break;
case DRM_MODE_DPMS_OFF:
intel_update_watermarks(dev);
+
/* Give the overlay scaler a chance to disable if it's on this pipe */
- //intel_crtc_dpms_video(crtc, FALSE); TODO
+ intel_crtc_dpms_overlay(intel_crtc, false);
+ drm_vblank_off(dev, pipe);
if (dev_priv->cfb_plane == plane &&
dev_priv->display.disable_fbc)
struct drm_display_mode *adjusted_mode)
{
struct drm_device *dev = crtc->dev;
- if (IS_IGDNG(dev)) {
+ if (IS_IRONLAKE(dev)) {
/* FDI link clock is fixed at 2.7G */
if (mode->clock * 3 > 27000 * 4)
return MODE_CLOCK_HIGH;
* Return the pipe currently connected to the panel fitter,
* or -1 if the panel fitter is not present or not in use
*/
- static int intel_panel_fitter_pipe (struct drm_device *dev)
+ int intel_panel_fitter_pipe (struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 pfit_control;
#define LINK_N 0x80000
static void
- igdng_compute_m_n(int bits_per_pixel, int nlanes,
- int pixel_clock, int link_clock,
- struct fdi_m_n *m_n)
+ ironlake_compute_m_n(int bits_per_pixel, int nlanes, int pixel_clock,
+ int link_clock, struct fdi_m_n *m_n)
{
u64 temp;
unsigned long cacheline_size;
};
- /* IGD has different values for various configs */
- static struct intel_watermark_params igd_display_wm = {
- IGD_DISPLAY_FIFO,
- IGD_MAX_WM,
- IGD_DFT_WM,
- IGD_GUARD_WM,
- IGD_FIFO_LINE_SIZE
+ /* Pineview has different values for various configs */
+ static struct intel_watermark_params pineview_display_wm = {
+ PINEVIEW_DISPLAY_FIFO,
+ PINEVIEW_MAX_WM,
+ PINEVIEW_DFT_WM,
+ PINEVIEW_GUARD_WM,
+ PINEVIEW_FIFO_LINE_SIZE
};
- static struct intel_watermark_params igd_display_hplloff_wm = {
- IGD_DISPLAY_FIFO,
- IGD_MAX_WM,
- IGD_DFT_HPLLOFF_WM,
- IGD_GUARD_WM,
- IGD_FIFO_LINE_SIZE
+ static struct intel_watermark_params pineview_display_hplloff_wm = {
+ PINEVIEW_DISPLAY_FIFO,
+ PINEVIEW_MAX_WM,
+ PINEVIEW_DFT_HPLLOFF_WM,
+ PINEVIEW_GUARD_WM,
+ PINEVIEW_FIFO_LINE_SIZE
};
- static struct intel_watermark_params igd_cursor_wm = {
- IGD_CURSOR_FIFO,
- IGD_CURSOR_MAX_WM,
- IGD_CURSOR_DFT_WM,
- IGD_CURSOR_GUARD_WM,
- IGD_FIFO_LINE_SIZE,
+ static struct intel_watermark_params pineview_cursor_wm = {
+ PINEVIEW_CURSOR_FIFO,
+ PINEVIEW_CURSOR_MAX_WM,
+ PINEVIEW_CURSOR_DFT_WM,
+ PINEVIEW_CURSOR_GUARD_WM,
+ PINEVIEW_FIFO_LINE_SIZE,
};
- static struct intel_watermark_params igd_cursor_hplloff_wm = {
- IGD_CURSOR_FIFO,
- IGD_CURSOR_MAX_WM,
- IGD_CURSOR_DFT_WM,
- IGD_CURSOR_GUARD_WM,
- IGD_FIFO_LINE_SIZE
+ static struct intel_watermark_params pineview_cursor_hplloff_wm = {
+ PINEVIEW_CURSOR_FIFO,
+ PINEVIEW_CURSOR_MAX_WM,
+ PINEVIEW_CURSOR_DFT_WM,
+ PINEVIEW_CURSOR_GUARD_WM,
+ PINEVIEW_FIFO_LINE_SIZE
};
static struct intel_watermark_params g4x_wm_info = {
G4X_FIFO_SIZE,
1000;
entries_required /= wm->cacheline_size;
- DRM_DEBUG("FIFO entries required for mode: %d\n", entries_required);
+ DRM_DEBUG_KMS("FIFO entries required for mode: %d\n", entries_required);
wm_size = wm->fifo_size - (entries_required + wm->guard_size);
- DRM_DEBUG("FIFO watermark level: %d\n", wm_size);
+ DRM_DEBUG_KMS("FIFO watermark level: %d\n", wm_size);
/* Don't promote wm_size to unsigned... */
if (wm_size > (long)wm->max_wm)
return latency;
}
- DRM_DEBUG("Unknown FSB/MEM found, disable CxSR\n");
+ DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n");
return NULL;
}
- static void igd_disable_cxsr(struct drm_device *dev)
+ static void pineview_disable_cxsr(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 reg;
/* deactivate cxsr */
reg = I915_READ(DSPFW3);
- reg &= ~(IGD_SELF_REFRESH_EN);
+ reg &= ~(PINEVIEW_SELF_REFRESH_EN);
I915_WRITE(DSPFW3, reg);
DRM_INFO("Big FIFO is disabled\n");
}
- static void igd_enable_cxsr(struct drm_device *dev, unsigned long clock,
- int pixel_size)
+ static void pineview_enable_cxsr(struct drm_device *dev, unsigned long clock,
+ int pixel_size)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 reg;
unsigned long wm;
struct cxsr_latency *latency;
- latency = intel_get_cxsr_latency(IS_IGDG(dev), dev_priv->fsb_freq,
+ latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->fsb_freq,
dev_priv->mem_freq);
if (!latency) {
- DRM_DEBUG("Unknown FSB/MEM found, disable CxSR\n");
- igd_disable_cxsr(dev);
+ DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n");
+ pineview_disable_cxsr(dev);
return;
}
/* Display SR */
- wm = intel_calculate_wm(clock, &igd_display_wm, pixel_size,
+ wm = intel_calculate_wm(clock, &pineview_display_wm, pixel_size,
latency->display_sr);
reg = I915_READ(DSPFW1);
reg &= 0x7fffff;
reg |= wm << 23;
I915_WRITE(DSPFW1, reg);
- DRM_DEBUG("DSPFW1 register is %x\n", reg);
+ DRM_DEBUG_KMS("DSPFW1 register is %x\n", reg);
/* cursor SR */
- wm = intel_calculate_wm(clock, &igd_cursor_wm, pixel_size,
+ wm = intel_calculate_wm(clock, &pineview_cursor_wm, pixel_size,
latency->cursor_sr);
reg = I915_READ(DSPFW3);
reg &= ~(0x3f << 24);
I915_WRITE(DSPFW3, reg);
/* Display HPLL off SR */
- wm = intel_calculate_wm(clock, &igd_display_hplloff_wm,
+ wm = intel_calculate_wm(clock, &pineview_display_hplloff_wm,
latency->display_hpll_disable, I915_FIFO_LINE_SIZE);
reg = I915_READ(DSPFW3);
reg &= 0xfffffe00;
I915_WRITE(DSPFW3, reg);
/* cursor HPLL off SR */
- wm = intel_calculate_wm(clock, &igd_cursor_hplloff_wm, pixel_size,
+ wm = intel_calculate_wm(clock, &pineview_cursor_hplloff_wm, pixel_size,
latency->cursor_hpll_disable);
reg = I915_READ(DSPFW3);
reg &= ~(0x3f << 16);
reg |= (wm & 0x3f) << 16;
I915_WRITE(DSPFW3, reg);
- DRM_DEBUG("DSPFW3 register is %x\n", reg);
+ DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg);
/* activate cxsr */
reg = I915_READ(DSPFW3);
- reg |= IGD_SELF_REFRESH_EN;
+ reg |= PINEVIEW_SELF_REFRESH_EN;
I915_WRITE(DSPFW3, reg);
DRM_INFO("Big FIFO is enabled\n");
size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) -
(dsparb & 0x7f);
- DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A",
- size);
+ DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb,
+ plane ? "B" : "A", size);
return size;
}
(dsparb & 0x1ff);
size >>= 1; /* Convert to cachelines */
- DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A",
- size);
+ DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb,
+ plane ? "B" : "A", size);
return size;
}
size = dsparb & 0x7f;
size >>= 2; /* Convert to cachelines */
- DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A",
+ DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb,
+ plane ? "B" : "A",
size);
return size;
size = dsparb & 0x7f;
size >>= 1; /* Convert to cachelines */
- DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A",
- size);
+ DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb,
+ plane ? "B" : "A", size);
return size;
}
(cursor_sr << DSPFW_CURSOR_SR_SHIFT));
}
- static void i965_update_wm(struct drm_device *dev, int unused, int unused2,
- int unused3, int unused4)
+ static void i965_update_wm(struct drm_device *dev, int planea_clock,
+ int planeb_clock, int sr_hdisplay, int pixel_size)
{
struct drm_i915_private *dev_priv = dev->dev_private;
+ unsigned long line_time_us;
+ int sr_clock, sr_entries, srwm = 1;
+
+ /* Calc sr entries for one plane configs */
+ if (sr_hdisplay && (!planea_clock || !planeb_clock)) {
+ /* self-refresh has much higher latency */
+ const static int sr_latency_ns = 12000;
+
+ sr_clock = planea_clock ? planea_clock : planeb_clock;
+ line_time_us = ((sr_hdisplay * 1000) / sr_clock);
+
+ /* Use ns/us then divide to preserve precision */
+ sr_entries = (((sr_latency_ns / line_time_us) + 1) *
+ pixel_size * sr_hdisplay) / 1000;
+ sr_entries = roundup(sr_entries / I915_FIFO_LINE_SIZE, 1);
+ DRM_DEBUG("self-refresh entries: %d\n", sr_entries);
+ srwm = I945_FIFO_SIZE - sr_entries;
+ if (srwm < 0)
+ srwm = 1;
+ srwm &= 0x3f;
+ I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN);
+ }
- DRM_DEBUG("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR 8\n");
+ DRM_DEBUG_KMS("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n",
+ srwm);
/* 965 has limitations... */
- I915_WRITE(DSPFW1, (8 << 16) | (8 << 8) | (8 << 0));
+ I915_WRITE(DSPFW1, (srwm << DSPFW_SR_SHIFT) | (8 << 16) | (8 << 8) |
+ (8 << 0));
I915_WRITE(DSPFW2, (8 << 8) | (8 << 0));
}
pixel_size, latency_ns);
planeb_wm = intel_calculate_wm(planeb_clock, &planeb_params,
pixel_size, latency_ns);
- DRM_DEBUG("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm);
+ DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm);
/*
* Overlay gets an aggressive default since video jitter is bad.
sr_entries = (((sr_latency_ns / line_time_us) + 1) *
pixel_size * sr_hdisplay) / 1000;
sr_entries = roundup(sr_entries / cacheline_size, 1);
- DRM_DEBUG("self-refresh entries: %d\n", sr_entries);
+ DRM_DEBUG_KMS("self-refresh entries: %d\n", sr_entries);
srwm = total_size - sr_entries;
if (srwm < 0)
srwm = 1;
I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN | (srwm & 0x3f));
}
- DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n",
+ DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n",
planea_wm, planeb_wm, cwm, srwm);
fwater_lo = ((planeb_wm & 0x3f) << 16) | (planea_wm & 0x3f);
pixel_size, latency_ns);
fwater_lo |= (3<<8) | planea_wm;
- DRM_DEBUG("Setting FIFO watermarks - A: %d\n", planea_wm);
+ DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d\n", planea_wm);
I915_WRITE(FW_BLC, fwater_lo);
}
if (crtc->enabled) {
enabled++;
if (intel_crtc->plane == 0) {
- DRM_DEBUG("plane A (pipe %d) clock: %d\n",
+ DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n",
intel_crtc->pipe, crtc->mode.clock);
planea_clock = crtc->mode.clock;
} else {
- DRM_DEBUG("plane B (pipe %d) clock: %d\n",
+ DRM_DEBUG_KMS("plane B (pipe %d) clock: %d\n",
intel_crtc->pipe, crtc->mode.clock);
planeb_clock = crtc->mode.clock;
}
return;
/* Single plane configs can enable self refresh */
- if (enabled == 1 && IS_IGD(dev))
- igd_enable_cxsr(dev, sr_clock, pixel_size);
- else if (IS_IGD(dev))
- igd_disable_cxsr(dev);
+ if (enabled == 1 && IS_PINEVIEW(dev))
+ pineview_enable_cxsr(dev, sr_clock, pixel_size);
+ else if (IS_PINEVIEW(dev))
+ pineview_disable_cxsr(dev);
dev_priv->display.update_wm(dev, planea_clock, planeb_clock,
sr_hdisplay, pixel_size);
if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2) {
refclk = dev_priv->lvds_ssc_freq * 1000;
- DRM_DEBUG("using SSC reference clock of %d MHz\n", refclk / 1000);
+ DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n",
+ refclk / 1000);
} else if (IS_I9XX(dev)) {
refclk = 96000;
- if (IS_IGDNG(dev))
+ if (IS_IRONLAKE(dev))
refclk = 120000; /* 120Mhz refclk */
} else {
refclk = 48000;
return -EINVAL;
}
- if (limit->find_reduced_pll && dev_priv->lvds_downclock_avail) {
+ if (is_lvds && limit->find_reduced_pll &&
+ dev_priv->lvds_downclock_avail) {
memcpy(&reduced_clock, &clock, sizeof(intel_clock_t));
has_reduced_clock = limit->find_reduced_pll(limit, crtc,
- (adjusted_mode->clock*3/4),
+ dev_priv->lvds_downclock,
refclk,
&reduced_clock);
+ if (has_reduced_clock && (clock.p != reduced_clock.p)) {
+ /*
+ * If the different P is found, it means that we can't
+ * switch the display clock by using the FP0/FP1.
+ * In such case we will disable the LVDS downclock
+ * feature.
+ */
+ DRM_DEBUG_KMS("Different P is found for "
+ "LVDS clock/downclock\n");
+ has_reduced_clock = 0;
+ }
}
-
/* SDVO TV has fixed PLL values depend on its clock range,
this mirrors vbios setting. */
if (is_sdvo && is_tv) {
}
/* FDI link */
- if (IS_IGDNG(dev)) {
+ if (IS_IRONLAKE(dev)) {
int lane, link_bw, bpp;
/* eDP doesn't require FDI link, so just set DP M/N
according to current link config */
bpp = 24;
}
- igdng_compute_m_n(bpp, lane, target_clock,
- link_bw, &m_n);
+ ironlake_compute_m_n(bpp, lane, target_clock, link_bw, &m_n);
}
/* Ironlake: try to setup display ref clock before DPLL
* PCH B stepping, previous chipset stepping should be
* ignoring this setting.
*/
- if (IS_IGDNG(dev)) {
+ if (IS_IRONLAKE(dev)) {
temp = I915_READ(PCH_DREF_CONTROL);
/* Always enable nonspread source */
temp &= ~DREF_NONSPREAD_SOURCE_MASK;
}
}
- if (IS_IGD(dev)) {
+ if (IS_PINEVIEW(dev)) {
fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2;
if (has_reduced_clock)
fp2 = (1 << reduced_clock.n) << 16 |
reduced_clock.m2;
}
- if (!IS_IGDNG(dev))
+ if (!IS_IRONLAKE(dev))
dpll = DPLL_VGA_MODE_DIS;
if (IS_I9XX(dev)) {
sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
- else if (IS_IGDNG(dev))
+ else if (IS_IRONLAKE(dev))
dpll |= (sdvo_pixel_multiply - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
}
if (is_dp)
dpll |= DPLL_DVO_HIGH_SPEED;
/* compute bitmask from p1 value */
- if (IS_IGD(dev))
- dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_IGD;
+ if (IS_PINEVIEW(dev))
+ dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW;
else {
dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
/* also FPA1 */
- if (IS_IGDNG(dev))
+ if (IS_IRONLAKE(dev))
dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
if (IS_G4X(dev) && has_reduced_clock)
dpll |= (1 << (reduced_clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
break;
}
- if (IS_I965G(dev) && !IS_IGDNG(dev))
+ if (IS_I965G(dev) && !IS_IRONLAKE(dev))
dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
} else {
if (is_lvds) {
/* Set up the display plane register */
dspcntr = DISPPLANE_GAMMA_ENABLE;
- /* IGDNG's plane is forced to pipe, bit 24 is to
+ /* Ironlake's plane is forced to pipe, bit 24 is to
enable color space conversion */
- if (!IS_IGDNG(dev)) {
+ if (!IS_IRONLAKE(dev)) {
if (pipe == 0)
dspcntr &= ~DISPPLANE_SEL_PIPE_MASK;
else
/* Disable the panel fitter if it was on our pipe */
- if (!IS_IGDNG(dev) && intel_panel_fitter_pipe(dev) == pipe)
+ if (!IS_IRONLAKE(dev) && intel_panel_fitter_pipe(dev) == pipe)
I915_WRITE(PFIT_CONTROL, 0);
- DRM_DEBUG("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
+ DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
drm_mode_debug_printmodeline(mode);
- /* assign to IGDNG registers */
- if (IS_IGDNG(dev)) {
+ /* assign to Ironlake registers */
+ if (IS_IRONLAKE(dev)) {
fp_reg = pch_fp_reg;
dpll_reg = pch_dpll_reg;
}
if (is_edp) {
- igdng_disable_pll_edp(crtc);
+ ironlake_disable_pll_edp(crtc);
} else if ((dpll & DPLL_VCO_ENABLE)) {
I915_WRITE(fp_reg, fp);
I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
if (is_lvds) {
u32 lvds;
- if (IS_IGDNG(dev))
+ if (IS_IRONLAKE(dev))
lvds_reg = PCH_LVDS;
lvds = I915_READ(lvds_reg);
/* Wait for the clocks to stabilize. */
udelay(150);
- if (IS_I965G(dev) && !IS_IGDNG(dev)) {
+ if (IS_I965G(dev) && !IS_IRONLAKE(dev)) {
if (is_sdvo) {
sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
I915_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) |
I915_WRITE(fp_reg + 4, fp2);
intel_crtc->lowfreq_avail = true;
if (HAS_PIPE_CXSR(dev)) {
- DRM_DEBUG("enabling CxSR downclocking\n");
+ DRM_DEBUG_KMS("enabling CxSR downclocking\n");
pipeconf |= PIPECONF_CXSR_DOWNCLOCK;
}
} else {
I915_WRITE(fp_reg + 4, fp);
intel_crtc->lowfreq_avail = false;
if (HAS_PIPE_CXSR(dev)) {
- DRM_DEBUG("disabling CxSR downclocking\n");
+ DRM_DEBUG_KMS("disabling CxSR downclocking\n");
pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK;
}
}
/* pipesrc and dspsize control the size that is scaled from, which should
* always be the user's requested size.
*/
- if (!IS_IGDNG(dev)) {
+ if (!IS_IRONLAKE(dev)) {
I915_WRITE(dspsize_reg, ((mode->vdisplay - 1) << 16) |
(mode->hdisplay - 1));
I915_WRITE(dsppos_reg, 0);
}
I915_WRITE(pipesrc_reg, ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
- if (IS_IGDNG(dev)) {
+ if (IS_IRONLAKE(dev)) {
I915_WRITE(data_m1_reg, TU_SIZE(m_n.tu) | m_n.gmch_m);
I915_WRITE(data_n1_reg, TU_SIZE(m_n.tu) | m_n.gmch_n);
I915_WRITE(link_m1_reg, m_n.link_m);
I915_WRITE(link_n1_reg, m_n.link_n);
if (is_edp) {
- igdng_set_pll_edp(crtc, adjusted_mode->clock);
+ ironlake_set_pll_edp(crtc, adjusted_mode->clock);
} else {
/* enable FDI RX PLL too */
temp = I915_READ(fdi_rx_reg);
intel_wait_for_vblank(dev);
- if (IS_IGDNG(dev)) {
+ if (IS_IRONLAKE(dev)) {
/* enable address swizzle for tiling buffer */
temp = I915_READ(DISP_ARB_CTL);
I915_WRITE(DISP_ARB_CTL, temp | DISP_TILE_SURFACE_SWIZZLING);
if (!crtc->enabled)
return;
- /* use legacy palette for IGDNG */
- if (IS_IGDNG(dev))
+ /* use legacy palette for Ironlake */
+ if (IS_IRONLAKE(dev))
palreg = (intel_crtc->pipe == 0) ? LGC_PALETTE_A :
LGC_PALETTE_B;
size_t addr;
int ret;
- DRM_DEBUG("\n");
+ DRM_DEBUG_KMS("\n");
/* if we want to turn off the cursor ignore width and height */
if (!handle) {
- DRM_DEBUG("cursor off\n");
+ DRM_DEBUG_KMS("cursor off\n");
if (IS_MOBILE(dev) || IS_I9XX(dev)) {
temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
temp |= CURSOR_MODE_DISABLE;
fp = I915_READ((pipe == 0) ? FPA1 : FPB1);
clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
- if (IS_IGD(dev)) {
- clock.n = ffs((fp & FP_N_IGD_DIV_MASK) >> FP_N_DIV_SHIFT) - 1;
- clock.m2 = (fp & FP_M2_IGD_DIV_MASK) >> FP_M2_DIV_SHIFT;
+ if (IS_PINEVIEW(dev)) {
+ clock.n = ffs((fp & FP_N_PINEVIEW_DIV_MASK) >> FP_N_DIV_SHIFT) - 1;
+ clock.m2 = (fp & FP_M2_PINEVIEW_DIV_MASK) >> FP_M2_DIV_SHIFT;
} else {
clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
}
if (IS_I9XX(dev)) {
- if (IS_IGD(dev))
- clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_IGD) >>
- DPLL_FPA01_P1_POST_DIV_SHIFT_IGD);
+ if (IS_PINEVIEW(dev))
+ clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW) >>
+ DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW);
else
clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >>
DPLL_FPA01_P1_POST_DIV_SHIFT);
7 : 14;
break;
default:
- DRM_DEBUG("Unknown DPLL mode %08x in programmed "
+ DRM_DEBUG_KMS("Unknown DPLL mode %08x in programmed "
"mode\n", (int)(dpll & DPLL_MODE_MASK));
return 0;
}
struct drm_device *dev = (struct drm_device *)arg;
drm_i915_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG("idle timer fired, downclocking\n");
+ DRM_DEBUG_DRIVER("idle timer fired, downclocking\n");
dev_priv->busy = false;
{
drm_i915_private_t *dev_priv = dev->dev_private;
- if (IS_IGDNG(dev))
+ if (IS_IRONLAKE(dev))
return;
if (!dev_priv->render_reclock_avail) {
- DRM_DEBUG("not reclocking render clock\n");
+ DRM_DEBUG_DRIVER("not reclocking render clock\n");
return;
}
pci_write_config_word(dev->pdev, GCFGC, dev_priv->orig_clock);
else if (IS_I85X(dev))
pci_write_config_word(dev->pdev, HPLLCC, dev_priv->orig_clock);
- DRM_DEBUG("increasing render clock frequency\n");
+ DRM_DEBUG_DRIVER("increasing render clock frequency\n");
/* Schedule downclock */
if (schedule)
{
drm_i915_private_t *dev_priv = dev->dev_private;
- if (IS_IGDNG(dev))
+ if (IS_IRONLAKE(dev))
return;
if (!dev_priv->render_reclock_avail) {
- DRM_DEBUG("not reclocking render clock\n");
+ DRM_DEBUG_DRIVER("not reclocking render clock\n");
return;
}
pci_write_config_word(dev->pdev, HPLLCC, hpllcc);
}
- DRM_DEBUG("decreasing render clock frequency\n");
+ DRM_DEBUG_DRIVER("decreasing render clock frequency\n");
}
/* Note that no increase function is needed for this - increase_renderclock()
*/
void intel_decrease_displayclock(struct drm_device *dev)
{
- if (IS_IGDNG(dev))
+ if (IS_IRONLAKE(dev))
return;
if (IS_I945G(dev) || IS_I945GM(dev) || IS_I915G(dev) ||
struct drm_crtc *crtc = &intel_crtc->base;
drm_i915_private_t *dev_priv = crtc->dev->dev_private;
- DRM_DEBUG("idle timer fired, downclocking\n");
+ DRM_DEBUG_DRIVER("idle timer fired, downclocking\n");
intel_crtc->busy = false;
int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
int dpll = I915_READ(dpll_reg);
- if (IS_IGDNG(dev))
+ if (IS_IRONLAKE(dev))
return;
if (!dev_priv->lvds_downclock_avail)
return;
if (!HAS_PIPE_CXSR(dev) && (dpll & DISPLAY_RATE_SELECT_FPA1)) {
- DRM_DEBUG("upclocking LVDS\n");
+ DRM_DEBUG_DRIVER("upclocking LVDS\n");
/* Unlock panel regs */
I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | (0xabcd << 16));
intel_wait_for_vblank(dev);
dpll = I915_READ(dpll_reg);
if (dpll & DISPLAY_RATE_SELECT_FPA1)
- DRM_DEBUG("failed to upclock LVDS!\n");
+ DRM_DEBUG_DRIVER("failed to upclock LVDS!\n");
/* ...and lock them again */
I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) & 0x3);
int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
int dpll = I915_READ(dpll_reg);
- if (IS_IGDNG(dev))
+ if (IS_IRONLAKE(dev))
return;
if (!dev_priv->lvds_downclock_avail)
* the manual case.
*/
if (!HAS_PIPE_CXSR(dev) && intel_crtc->lowfreq_avail) {
- DRM_DEBUG("downclocking LVDS\n");
+ DRM_DEBUG_DRIVER("downclocking LVDS\n");
/* Unlock panel regs */
I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | (0xabcd << 16));
intel_wait_for_vblank(dev);
dpll = I915_READ(dpll_reg);
if (!(dpll & DISPLAY_RATE_SELECT_FPA1))
- DRM_DEBUG("failed to downclock LVDS!\n");
+ DRM_DEBUG_DRIVER("failed to downclock LVDS!\n");
/* ...and lock them again */
I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) & 0x3);
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return;
- dev_priv->busy = true;
- intel_increase_renderclock(dev, true);
+ if (!dev_priv->busy) {
+ dev_priv->busy = true;
+ intel_increase_renderclock(dev, true);
+ } else {
+ mod_timer(&dev_priv->idle_timer, jiffies +
+ msecs_to_jiffies(GPU_IDLE_TIMEOUT));
+ }
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
if (!crtc->fb)
kfree(intel_crtc);
}
+ struct intel_unpin_work {
+ struct work_struct work;
+ struct drm_device *dev;
+ struct drm_gem_object *obj;
+ struct drm_pending_vblank_event *event;
+ int pending;
+ };
+
+ static void intel_unpin_work_fn(struct work_struct *__work)
+ {
+ struct intel_unpin_work *work =
+ container_of(__work, struct intel_unpin_work, work);
+
+ mutex_lock(&work->dev->struct_mutex);
+ i915_gem_object_unpin(work->obj);
+ drm_gem_object_unreference(work->obj);
+ mutex_unlock(&work->dev->struct_mutex);
+ kfree(work);
+ }
+
+ void intel_finish_page_flip(struct drm_device *dev, int pipe)
+ {
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_unpin_work *work;
+ struct drm_i915_gem_object *obj_priv;
+ struct drm_pending_vblank_event *e;
+ struct timeval now;
+ unsigned long flags;
+
+ /* Ignore early vblank irqs */
+ if (intel_crtc == NULL)
+ return;
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ work = intel_crtc->unpin_work;
+ if (work == NULL || !work->pending) {
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ return;
+ }
+
+ intel_crtc->unpin_work = NULL;
+ drm_vblank_put(dev, intel_crtc->pipe);
+
+ if (work->event) {
+ e = work->event;
+ do_gettimeofday(&now);
+ e->event.sequence = drm_vblank_count(dev, intel_crtc->pipe);
+ e->event.tv_sec = now.tv_sec;
+ e->event.tv_usec = now.tv_usec;
+ list_add_tail(&e->base.link,
+ &e->base.file_priv->event_list);
+ wake_up_interruptible(&e->base.file_priv->event_wait);
+ }
+
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+
+ obj_priv = work->obj->driver_private;
+ if (atomic_dec_and_test(&obj_priv->pending_flip))
+ DRM_WAKEUP(&dev_priv->pending_flip_queue);
+ schedule_work(&work->work);
+ }
+
+ void intel_prepare_page_flip(struct drm_device *dev, int plane)
+ {
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc =
+ to_intel_crtc(dev_priv->plane_to_crtc_mapping[plane]);
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ if (intel_crtc->unpin_work)
+ intel_crtc->unpin_work->pending = 1;
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ }
+
+ static int intel_crtc_page_flip(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ struct drm_pending_vblank_event *event)
+ {
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_framebuffer *intel_fb;
+ struct drm_i915_gem_object *obj_priv;
+ struct drm_gem_object *obj;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_unpin_work *work;
+ unsigned long flags;
+ int ret;
+ RING_LOCALS;
+
+ work = kzalloc(sizeof *work, GFP_KERNEL);
+ if (work == NULL)
+ return -ENOMEM;
+
+ mutex_lock(&dev->struct_mutex);
+
+ work->event = event;
+ work->dev = crtc->dev;
+ intel_fb = to_intel_framebuffer(crtc->fb);
+ work->obj = intel_fb->obj;
+ INIT_WORK(&work->work, intel_unpin_work_fn);
+
+ /* We borrow the event spin lock for protecting unpin_work */
+ spin_lock_irqsave(&dev->event_lock, flags);
+ if (intel_crtc->unpin_work) {
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ kfree(work);
+ mutex_unlock(&dev->struct_mutex);
+ return -EBUSY;
+ }
+ intel_crtc->unpin_work = work;
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+
+ intel_fb = to_intel_framebuffer(fb);
+ obj = intel_fb->obj;
+
+ ret = intel_pin_and_fence_fb_obj(dev, obj);
+ if (ret != 0) {
+ kfree(work);
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+ }
+
+ /* Reference the old fb object for the scheduled work. */
+ drm_gem_object_reference(work->obj);
+
+ crtc->fb = fb;
+ i915_gem_object_flush_write_domain(obj);
+ drm_vblank_get(dev, intel_crtc->pipe);
+ obj_priv = obj->driver_private;
+ atomic_inc(&obj_priv->pending_flip);
+
+ BEGIN_LP_RING(4);
+ OUT_RING(MI_DISPLAY_FLIP |
+ MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
+ OUT_RING(fb->pitch);
+ if (IS_I965G(dev)) {
+ OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode);
+ OUT_RING((fb->width << 16) | fb->height);
+ } else {
+ OUT_RING(obj_priv->gtt_offset);
+ OUT_RING(MI_NOOP);
+ }
+ ADVANCE_LP_RING();
+
+ mutex_unlock(&dev->struct_mutex);
+
+ return 0;
+ }
+
static const struct drm_crtc_helper_funcs intel_helper_funcs = {
.dpms = intel_crtc_dpms,
.mode_fixup = intel_crtc_mode_fixup,
.gamma_set = intel_crtc_gamma_set,
.set_config = drm_crtc_helper_set_config,
.destroy = intel_crtc_destroy,
+ .page_flip = intel_crtc_page_flip,
};
static void intel_crtc_init(struct drm_device *dev, int pipe)
{
+ drm_i915_private_t *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc;
int i;
intel_crtc->pipe = pipe;
intel_crtc->plane = pipe;
if (IS_MOBILE(dev) && (IS_I9XX(dev) && !IS_I965G(dev))) {
- DRM_DEBUG("swapping pipes & planes for FBC\n");
+ DRM_DEBUG_KMS("swapping pipes & planes for FBC\n");
intel_crtc->plane = ((pipe == 0) ? 1 : 0);
}
+ BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) ||
+ dev_priv->plane_to_crtc_mapping[intel_crtc->plane] != NULL);
+ dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base;
+ dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base;
+
intel_crtc->cursor_addr = 0;
intel_crtc->dpms_mode = DRM_MODE_DPMS_OFF;
drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
if (IS_MOBILE(dev) && !IS_I830(dev))
intel_lvds_init(dev);
- if (IS_IGDNG(dev)) {
+ if (IS_IRONLAKE(dev)) {
int found;
if (IS_MOBILE(dev) && (I915_READ(DP_A) & DP_DETECTED))
if (I915_READ(PCH_DP_D) & DP_DETECTED)
intel_dp_init(dev, PCH_DP_D);
- } else if (IS_I9XX(dev)) {
+ } else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) {
bool found = false;
if (I915_READ(SDVOB) & SDVO_DETECTED) {
if (SUPPORTS_INTEGRATED_DP(dev) && (I915_READ(DP_D) & DP_DETECTED))
intel_dp_init(dev, DP_D);
- } else
+ } else if (IS_I8XX(dev))
intel_dvo_init(dev);
- if (IS_I9XX(dev) && IS_MOBILE(dev) && !IS_IGDNG(dev))
+ if (SUPPORTS_TV(dev))
intel_tv_init(dev);
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
* Disable clock gating reported to work incorrectly according to the
* specs, but enable as much else as we can.
*/
- if (IS_IGDNG(dev)) {
+ if (IS_IRONLAKE(dev)) {
return;
} else if (IS_G4X(dev)) {
uint32_t dspclk_gate;
dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING |
DSTATE_DOT_CLOCK_GATING;
I915_WRITE(D_STATE, dstate);
- } else if (IS_I855(dev) || IS_I865G(dev)) {
+ } else if (IS_I85X(dev) || IS_I865G(dev)) {
I915_WRITE(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE);
} else if (IS_I830(dev)) {
I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE);
}
+
+ /*
+ * GPU can automatically power down the render unit if given a page
+ * to save state.
+ */
+ if (I915_HAS_RC6(dev)) {
+ struct drm_gem_object *pwrctx;
+ struct drm_i915_gem_object *obj_priv;
+ int ret;
+
+ pwrctx = drm_gem_object_alloc(dev, 4096);
+ if (!pwrctx) {
+ DRM_DEBUG("failed to alloc power context, RC6 disabled\n");
+ goto out;
+ }
+
+ ret = i915_gem_object_pin(pwrctx, 4096);
+ if (ret) {
+ DRM_ERROR("failed to pin power context: %d\n", ret);
+ drm_gem_object_unreference(pwrctx);
+ goto out;
+ }
+
+ i915_gem_object_set_to_gtt_domain(pwrctx, 1);
+
+ obj_priv = pwrctx->driver_private;
+
+ I915_WRITE(PWRCTXA, obj_priv->gtt_offset | PWRCTX_EN);
+ I915_WRITE(MCHBAR_RENDER_STANDBY,
+ I915_READ(MCHBAR_RENDER_STANDBY) & ~RCX_SW_EXIT);
+
+ dev_priv->pwrctx = pwrctx;
+ }
+
+ out:
+ return;
}
/* Set up chip specific display functions */
struct drm_i915_private *dev_priv = dev->dev_private;
/* We always want a DPMS function */
- if (IS_IGDNG(dev))
- dev_priv->display.dpms = igdng_crtc_dpms;
+ if (IS_IRONLAKE(dev))
+ dev_priv->display.dpms = ironlake_crtc_dpms;
else
dev_priv->display.dpms = i9xx_crtc_dpms;
}
/* Returns the core display clock speed */
- if (IS_I945G(dev))
+ if (IS_I945G(dev) || (IS_G33(dev) && ! IS_PINEVIEW_M(dev)))
dev_priv->display.get_display_clock_speed =
i945_get_display_clock_speed;
else if (IS_I915G(dev))
dev_priv->display.get_display_clock_speed =
i915_get_display_clock_speed;
- else if (IS_I945GM(dev) || IS_845G(dev) || IS_IGDGM(dev))
+ else if (IS_I945GM(dev) || IS_845G(dev) || IS_PINEVIEW_M(dev))
dev_priv->display.get_display_clock_speed =
i9xx_misc_get_display_clock_speed;
else if (IS_I915GM(dev))
else if (IS_I865G(dev))
dev_priv->display.get_display_clock_speed =
i865_get_display_clock_speed;
- else if (IS_I855(dev))
+ else if (IS_I85X(dev))
dev_priv->display.get_display_clock_speed =
i855_get_display_clock_speed;
else /* 852, 830 */
i830_get_display_clock_speed;
/* For FIFO watermark updates */
- if (IS_IGDNG(dev))
+ if (IS_IRONLAKE(dev))
dev_priv->display.update_wm = NULL;
else if (IS_G4X(dev))
dev_priv->display.update_wm = g4x_update_wm;
num_pipe = 2;
else
num_pipe = 1;
- DRM_DEBUG("%d display pipe%s available.\n",
+ DRM_DEBUG_KMS("%d display pipe%s available.\n",
num_pipe, num_pipe > 1 ? "s" : "");
if (IS_I85X(dev))
INIT_WORK(&dev_priv->idle_work, intel_idle_update);
setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer,
(unsigned long)dev);
+
+ intel_setup_overlay(dev);
+
+ if (IS_PINEVIEW(dev) && !intel_get_cxsr_latency(IS_PINEVIEW_G(dev),
+ dev_priv->fsb_freq,
+ dev_priv->mem_freq))
+ DRM_INFO("failed to find known CxSR latency "
+ "(found fsb freq %d, mem freq %d), disabling CxSR\n",
+ dev_priv->fsb_freq, dev_priv->mem_freq);
}
void intel_modeset_cleanup(struct drm_device *dev)
intel_increase_renderclock(dev, false);
del_timer_sync(&dev_priv->idle_timer);
- mutex_unlock(&dev->struct_mutex);
-
if (dev_priv->display.disable_fbc)
dev_priv->display.disable_fbc(dev);
+ if (dev_priv->pwrctx) {
+ struct drm_i915_gem_object *obj_priv;
+
+ obj_priv = dev_priv->pwrctx->driver_private;
+ I915_WRITE(PWRCTXA, obj_priv->gtt_offset &~ PWRCTX_EN);
+ I915_READ(PWRCTXA);
+ i915_gem_object_unpin(dev_priv->pwrctx);
+ drm_gem_object_unreference(dev_priv->pwrctx);
+ }
+
+ mutex_unlock(&dev->struct_mutex);
+
drm_mode_config_cleanup(dev);
}
#include "intel_drv.h"
#include "i915_drm.h"
#include "i915_drv.h"
-#include "intel_dp.h"
+#include "drm_dp_helper.h"
+
#define DP_LINK_STATUS_SIZE 6
#define DP_LINK_CHECK_TIMEOUT (10 * 1000)
*/
if (IS_eDP(intel_output))
aux_clock_divider = 225; /* eDP input clock at 450Mhz */
- else if (IS_IGDNG(dev))
- aux_clock_divider = 62; /* IGDNG: input clock fixed at 125Mhz */
+ else if (IS_IRONLAKE(dev))
+ aux_clock_divider = 62; /* IRL input clock fixed at 125Mhz */
else
aux_clock_divider = intel_hrawclk(dev) / 2;
/* Timeouts occur when the device isn't connected, so they're
* "normal" -- don't fill the kernel log with these */
if (status & DP_AUX_CH_CTL_TIME_OUT_ERROR) {
- DRM_DEBUG("dp_aux_ch timeout status 0x%08x\n", status);
+ DRM_DEBUG_KMS("dp_aux_ch timeout status 0x%08x\n", status);
return -ETIMEDOUT;
}
}
static int
-intel_dp_i2c_aux_ch(struct i2c_adapter *adapter,
- uint8_t *send, int send_bytes,
- uint8_t *recv, int recv_bytes)
+intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
+ uint8_t write_byte, uint8_t *read_byte)
{
+ struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
struct intel_dp_priv *dp_priv = container_of(adapter,
struct intel_dp_priv,
adapter);
struct intel_output *intel_output = dp_priv->intel_output;
+ uint16_t address = algo_data->address;
+ uint8_t msg[5];
+ uint8_t reply[2];
+ int msg_bytes;
+ int reply_bytes;
+ int ret;
+
+ /* Set up the command byte */
+ if (mode & MODE_I2C_READ)
+ msg[0] = AUX_I2C_READ << 4;
+ else
+ msg[0] = AUX_I2C_WRITE << 4;
+
+ if (!(mode & MODE_I2C_STOP))
+ msg[0] |= AUX_I2C_MOT << 4;
- return intel_dp_aux_ch(intel_output,
- send, send_bytes, recv, recv_bytes);
+ msg[1] = address >> 8;
+ msg[2] = address;
+
+ switch (mode) {
+ case MODE_I2C_WRITE:
+ msg[3] = 0;
+ msg[4] = write_byte;
+ msg_bytes = 5;
+ reply_bytes = 1;
+ break;
+ case MODE_I2C_READ:
+ msg[3] = 0;
+ msg_bytes = 4;
+ reply_bytes = 2;
+ break;
+ default:
+ msg_bytes = 3;
+ reply_bytes = 1;
+ break;
+ }
+
+ for (;;) {
+ ret = intel_dp_aux_ch(intel_output,
+ msg, msg_bytes,
+ reply, reply_bytes);
+ if (ret < 0) {
- DRM_DEBUG("aux_ch failed %d\n", ret);
++ DRM_DEBUG_KMS("aux_ch failed %d\n", ret);
+ return ret;
+ }
+ switch (reply[0] & AUX_I2C_REPLY_MASK) {
+ case AUX_I2C_REPLY_ACK:
+ if (mode == MODE_I2C_READ) {
+ *read_byte = reply[1];
+ }
+ return reply_bytes - 1;
+ case AUX_I2C_REPLY_NACK:
- DRM_DEBUG("aux_ch nack\n");
++ DRM_DEBUG_KMS("aux_ch nack\n");
+ return -EREMOTEIO;
+ case AUX_I2C_REPLY_DEFER:
- DRM_DEBUG("aux_ch defer\n");
++ DRM_DEBUG_KMS("aux_ch defer\n");
+ udelay(100);
+ break;
+ default:
+ DRM_ERROR("aux_ch invalid reply 0x%02x\n", reply[0]);
+ return -EREMOTEIO;
+ }
+ }
}
static int
dp_priv->link_bw = bws[clock];
dp_priv->lane_count = lane_count;
adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw);
- DRM_DEBUG("Display port link bw %02x lane count %d clock %d\n",
+ DRM_DEBUG_KMS("Display port link bw %02x lane "
+ "count %d clock %d\n",
dp_priv->link_bw, dp_priv->lane_count,
adjusted_mode->clock);
return true;
intel_dp_compute_m_n(3, lane_count,
mode->clock, adjusted_mode->clock, &m_n);
- if (IS_IGDNG(dev)) {
+ if (IS_IRONLAKE(dev)) {
if (intel_crtc->pipe == 0) {
I915_WRITE(TRANSA_DATA_M1,
((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) |
}
}
- static void igdng_edp_backlight_on (struct drm_device *dev)
+ static void ironlake_edp_backlight_on (struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 pp;
- DRM_DEBUG("\n");
+ DRM_DEBUG_KMS("\n");
pp = I915_READ(PCH_PP_CONTROL);
pp |= EDP_BLC_ENABLE;
I915_WRITE(PCH_PP_CONTROL, pp);
}
- static void igdng_edp_backlight_off (struct drm_device *dev)
+ static void ironlake_edp_backlight_off (struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 pp;
- DRM_DEBUG("\n");
+ DRM_DEBUG_KMS("\n");
pp = I915_READ(PCH_PP_CONTROL);
pp &= ~EDP_BLC_ENABLE;
I915_WRITE(PCH_PP_CONTROL, pp);
if (dp_reg & DP_PORT_EN) {
intel_dp_link_down(intel_output, dp_priv->DP);
if (IS_eDP(intel_output))
- igdng_edp_backlight_off(dev);
+ ironlake_edp_backlight_off(dev);
}
} else {
if (!(dp_reg & DP_PORT_EN)) {
intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration);
if (IS_eDP(intel_output))
- igdng_edp_backlight_on(dev);
+ ironlake_edp_backlight_on(dev);
}
}
dp_priv->dpms_mode = mode;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_dp_priv *dp_priv = intel_output->dev_priv;
- DRM_DEBUG("\n");
+ DRM_DEBUG_KMS("\n");
if (IS_eDP(intel_output)) {
DP &= ~DP_PLL_ENABLE;
}
static enum drm_connector_status
- igdng_dp_detect(struct drm_connector *connector)
+ ironlake_dp_detect(struct drm_connector *connector)
{
struct intel_output *intel_output = to_intel_output(connector);
struct intel_dp_priv *dp_priv = intel_output->dev_priv;
dp_priv->has_audio = false;
- if (IS_IGDNG(dev))
- return igdng_dp_detect(connector);
+ if (IS_IRONLAKE(dev))
+ return ironlake_dp_detect(connector);
temp = I915_READ(PORT_HOTPLUG_EN);
if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON)
intel_dp_check_link_status(intel_output);
}
-
+ /*
+ * Enumerate the child dev array parsed from VBT to check whether
+ * the given DP is present.
+ * If it is present, return 1.
+ * If it is not present, return false.
+ * If no child dev is parsed from VBT, it is assumed that the given
+ * DP is present.
+ */
+ static int dp_is_present_in_vbt(struct drm_device *dev, int dp_reg)
+ {
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct child_device_config *p_child;
+ int i, dp_port, ret;
+
+ if (!dev_priv->child_dev_num)
+ return 1;
+
+ dp_port = 0;
+ if (dp_reg == DP_B || dp_reg == PCH_DP_B)
+ dp_port = PORT_IDPB;
+ else if (dp_reg == DP_C || dp_reg == PCH_DP_C)
+ dp_port = PORT_IDPC;
+ else if (dp_reg == DP_D || dp_reg == PCH_DP_D)
+ dp_port = PORT_IDPD;
+
+ ret = 0;
+ for (i = 0; i < dev_priv->child_dev_num; i++) {
+ p_child = dev_priv->child_dev + i;
+ /*
+ * If the device type is not DP, continue.
+ */
+ if (p_child->device_type != DEVICE_TYPE_DP &&
+ p_child->device_type != DEVICE_TYPE_eDP)
+ continue;
+ /* Find the eDP port */
+ if (dp_reg == DP_A && p_child->device_type == DEVICE_TYPE_eDP) {
+ ret = 1;
+ break;
+ }
+ /* Find the DP port */
+ if (p_child->dvo_port == dp_port) {
+ ret = 1;
+ break;
+ }
+ }
+ return ret;
+ }
void
intel_dp_init(struct drm_device *dev, int output_reg)
{
struct intel_dp_priv *dp_priv;
const char *name = NULL;
+ if (!dp_is_present_in_vbt(dev, output_reg)) {
+ DRM_DEBUG_KMS("DP is not present. Ignore it\n");
+ return;
+ }
intel_output = kcalloc(sizeof(struct intel_output) +
sizeof(struct intel_dp_priv), 1, GFP_KERNEL);
if (!intel_output)
else
intel_output->type = INTEL_OUTPUT_DISPLAYPORT;
- if (output_reg == DP_B)
+ if (output_reg == DP_B || output_reg == PCH_DP_B)
intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);
- else if (output_reg == DP_C)
+ else if (output_reg == DP_C || output_reg == PCH_DP_C)
intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT);
- else if (output_reg == DP_D)
+ else if (output_reg == DP_D || output_reg == PCH_DP_D)
intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
if (IS_eDP(intel_output)) {
#ifndef _DRM_H_
#define _DRM_H_
+#if defined(__linux__)
+
#include <linux/types.h>
-#include <asm/ioctl.h> /* For _IO* macros */
-#define DRM_IOCTL_NR(n) _IOC_NR(n)
-#define DRM_IOC_VOID _IOC_NONE
-#define DRM_IOC_READ _IOC_READ
-#define DRM_IOC_WRITE _IOC_WRITE
-#define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE
-#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
+#include <asm/ioctl.h>
+typedef unsigned int drm_handle_t;
+
+#else /* One of the BSDs */
-#define DRM_MAJOR 226
-#define DRM_MAX_MINOR 15
+#include <sys/ioccom.h>
+#include <sys/types.h>
+typedef int8_t __s8;
+typedef uint8_t __u8;
+typedef int16_t __s16;
+typedef uint16_t __u16;
+typedef int32_t __s32;
+typedef uint32_t __u32;
+typedef int64_t __s64;
+typedef uint64_t __u64;
+typedef unsigned long drm_handle_t;
+
+#endif
#define DRM_NAME "drm" /**< Name in kernel, /dev, and /proc */
#define DRM_MIN_ORDER 5 /**< At least 2^5 bytes = 32 bytes */
#define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT)
#define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT))
-typedef unsigned int drm_handle_t;
typedef unsigned int drm_context_t;
typedef unsigned int drm_drawable_t;
typedef unsigned int drm_magic_t;
#define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd)
#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, unsigned int)
#define DRM_IOCTL_MODE_PAGE_FLIP DRM_IOWR(0xB0, struct drm_mode_crtc_page_flip)
+#define DRM_IOCTL_MODE_DIRTYFB DRM_IOWR(0xB1, struct drm_mode_fb_dirty_cmd)
/**
* Device specific ioctls should only be in their respective headers
};
#define DRM_EVENT_VBLANK 0x01
+ #define DRM_EVENT_FLIP_COMPLETE 0x02
struct drm_event_vblank {
struct drm_event base;
typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,
unsigned long arg);
+#define DRM_IOCTL_NR(n) _IOC_NR(n)
+#define DRM_MAJOR 226
+
#define DRM_AUTH 0x1
#define DRM_MASTER 0x2
#define DRM_ROOT_ONLY 0x4
/* Master routines */
int (*master_create)(struct drm_device *dev, struct drm_master *master);
void (*master_destroy)(struct drm_device *dev, struct drm_master *master);
+ /**
+ * master_set is called whenever the minor master is set.
+ * master_drop is called whenever the minor master is dropped.
+ */
+
+ int (*master_set)(struct drm_device *dev, struct drm_file *file_priv,
+ bool from_open);
+ void (*master_drop)(struct drm_device *dev, struct drm_file *file_priv,
+ bool from_release);
int (*proc_init)(struct drm_minor *minor);
void (*proc_cleanup)(struct drm_minor *minor);
extern void drm_handle_vblank(struct drm_device *dev, int crtc);
extern int drm_vblank_get(struct drm_device *dev, int crtc);
extern void drm_vblank_put(struct drm_device *dev, int crtc);
+ extern void drm_vblank_off(struct drm_device *dev, int crtc);
extern void drm_vblank_cleanup(struct drm_device *dev);
/* Modesetting support */
extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc);
static __inline__ void *drm_calloc_large(size_t nmemb, size_t size)
{
+ if (size != 0 && nmemb > ULONG_MAX / size)
+ return NULL;
+
if (size * nmemb <= PAGE_SIZE)
return kcalloc(nmemb, size, GFP_KERNEL);
+ return __vmalloc(size * nmemb,
+ GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
+ }
+
+ /* Modeled after cairo's malloc_ab, it's like calloc but without the zeroing. */
+ static __inline__ void *drm_malloc_ab(size_t nmemb, size_t size)
+ {
if (size != 0 && nmemb > ULONG_MAX / size)
return NULL;
+ if (size * nmemb <= PAGE_SIZE)
+ return kmalloc(nmemb * size, GFP_KERNEL);
+
return __vmalloc(size * nmemb,
- GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
+ GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);
}
static __inline void drm_free_large(void *ptr)
int type;
/* Proposed mode values */
- int clock;
+ int clock; /* in kHz */
int hdisplay;
int hsync_start;
int hsync_end;
int *private;
int private_flags;
- int vrefresh;
- float hsync;
+ int vrefresh; /* in Hz */
+ int hsync; /* in kHz */
};
enum drm_connector_status {
int (*create_handle)(struct drm_framebuffer *fb,
struct drm_file *file_priv,
unsigned int *handle);
+ /**
+ * Optinal callback for the dirty fb ioctl.
+ *
+ * Userspace can notify the driver via this callback
+ * that a area of the framebuffer has changed and should
+ * be flushed to the display hardware.
+ *
+ * See documentation in drm_mode.h for the struct
+ * drm_mode_fb_dirty_cmd for more information as all
+ * the semantics and arguments have a one to one mapping
+ * on this function.
+ */
+ int (*dirty)(struct drm_framebuffer *framebuffer, unsigned flags,
+ unsigned color, struct drm_clip_rect *clips,
+ unsigned num_clips);
};
struct drm_framebuffer {
unsigned int depth;
int bits_per_pixel;
int flags;
- void *fbdev;
+ struct fb_info *fbdev;
u32 pseudo_palette[17];
struct list_head filp_head;
/* if you are using the helper */
/* Optional properties */
struct drm_property *scaling_mode_property;
struct drm_property *dithering_mode_property;
+ struct drm_property *dirty_info_property;
};
#define obj_to_crtc(x) container_of(x, struct drm_crtc, base)
extern void drm_mode_prune_invalid(struct drm_device *dev,
struct list_head *mode_list, bool verbose);
extern void drm_mode_sort(struct list_head *mode_list);
+extern int drm_mode_hsync(struct drm_display_mode *mode);
extern int drm_mode_vrefresh(struct drm_display_mode *mode);
extern void drm_mode_set_crtcinfo(struct drm_display_mode *p,
int adjust_flags);
char *formats[]);
extern int drm_mode_create_scaling_mode_property(struct drm_device *dev);
extern int drm_mode_create_dithering_property(struct drm_device *dev);
+extern int drm_mode_create_dirty_info_property(struct drm_device *dev);
extern char *drm_get_encoder_name(struct drm_encoder *encoder);
extern int drm_mode_connector_attach_encoder(struct drm_connector *connector,
struct drm_encoder *encoder);
extern bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
int gamma_size);
- extern void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type);
+ extern struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
+ uint32_t id, uint32_t type);
/* IOCTLs */
extern int drm_mode_getresources(struct drm_device *dev,
void *data, struct drm_file *file_priv);
void *data, struct drm_file *file_priv);
extern int drm_mode_getfb(struct drm_device *dev,
void *data, struct drm_file *file_priv);
+extern int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
extern int drm_mode_addmode_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv);
extern int drm_mode_rmmode_ioctl(struct drm_device *dev,
#ifndef _I915_DRM_H_
#define _I915_DRM_H_
+#include "drm.h"
+
/* Please note that modifications to all structs defined here are
* subject to backwards-compatibility constraints.
*/
-#include <linux/types.h>
-#include "drm.h"
/* Each region is a minimum of 16k, and there are at most 255 of them.
*/
#define DRM_I915_GEM_MMAP_GTT 0x24
#define DRM_I915_GET_PIPE_FROM_CRTC_ID 0x25
#define DRM_I915_GEM_MADVISE 0x26
+ #define DRM_I915_OVERLAY_PUT_IMAGE 0x27
+ #define DRM_I915_OVERLAY_ATTRS 0x28
#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
#define DRM_IOCTL_I915_GEM_SET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling)
#define DRM_IOCTL_I915_GEM_GET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling)
#define DRM_IOCTL_I915_GEM_GET_APERTURE DRM_IOR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_APERTURE, struct drm_i915_gem_get_aperture)
- #define DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_PIPE_FROM_CRTC_ID, struct drm_intel_get_pipe_from_crtc_id)
+ #define DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_PIPE_FROM_CRTC_ID, struct drm_i915_get_pipe_from_crtc_id)
#define DRM_IOCTL_I915_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MADVISE, struct drm_i915_gem_madvise)
+ #define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE DRM_IOW(DRM_COMMAND_BASE + DRM_IOCTL_I915_OVERLAY_ATTRS, struct drm_intel_overlay_put_image)
+ #define DRM_IOCTL_I915_OVERLAY_ATTRS DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_OVERLAY_ATTRS, struct drm_intel_overlay_attrs)
/* Allow drivers to submit batchbuffers directly to hardware, relying
* on the security mechanisms provided by hardware.
#define I915_PARAM_CHIPSET_ID 4
#define I915_PARAM_HAS_GEM 5
#define I915_PARAM_NUM_FENCES_AVAIL 6
+ #define I915_PARAM_HAS_OVERLAY 7
+ #define I915_PARAM_HAS_PAGEFLIPPING 8
typedef struct drm_i915_getparam {
int param;
__u32 retained;
};
+ /* flags */
+ #define I915_OVERLAY_TYPE_MASK 0xff
+ #define I915_OVERLAY_YUV_PLANAR 0x01
+ #define I915_OVERLAY_YUV_PACKED 0x02
+ #define I915_OVERLAY_RGB 0x03
+
+ #define I915_OVERLAY_DEPTH_MASK 0xff00
+ #define I915_OVERLAY_RGB24 0x1000
+ #define I915_OVERLAY_RGB16 0x2000
+ #define I915_OVERLAY_RGB15 0x3000
+ #define I915_OVERLAY_YUV422 0x0100
+ #define I915_OVERLAY_YUV411 0x0200
+ #define I915_OVERLAY_YUV420 0x0300
+ #define I915_OVERLAY_YUV410 0x0400
+
+ #define I915_OVERLAY_SWAP_MASK 0xff0000
+ #define I915_OVERLAY_NO_SWAP 0x000000
+ #define I915_OVERLAY_UV_SWAP 0x010000
+ #define I915_OVERLAY_Y_SWAP 0x020000
+ #define I915_OVERLAY_Y_AND_UV_SWAP 0x030000
+
+ #define I915_OVERLAY_FLAGS_MASK 0xff000000
+ #define I915_OVERLAY_ENABLE 0x01000000
+
+ struct drm_intel_overlay_put_image {
+ /* various flags and src format description */
+ __u32 flags;
+ /* source picture description */
+ __u32 bo_handle;
+ /* stride values and offsets are in bytes, buffer relative */
+ __u16 stride_Y; /* stride for packed formats */
+ __u16 stride_UV;
+ __u32 offset_Y; /* offset for packet formats */
+ __u32 offset_U;
+ __u32 offset_V;
+ /* in pixels */
+ __u16 src_width;
+ __u16 src_height;
+ /* to compensate the scaling factors for partially covered surfaces */
+ __u16 src_scan_width;
+ __u16 src_scan_height;
+ /* output crtc description */
+ __u32 crtc_id;
+ __u16 dst_x;
+ __u16 dst_y;
+ __u16 dst_width;
+ __u16 dst_height;
+ };
+
+ /* flags */
+ #define I915_OVERLAY_UPDATE_ATTRS (1<<0)
+ #define I915_OVERLAY_UPDATE_GAMMA (1<<1)
+ struct drm_intel_overlay_attrs {
+ __u32 flags;
+ __u32 color_key;
+ __s32 brightness;
+ __u32 contrast;
+ __u32 saturation;
+ __u32 gamma0;
+ __u32 gamma1;
+ __u32 gamma2;
+ __u32 gamma3;
+ __u32 gamma4;
+ __u32 gamma5;
+ };
+
#endif /* _I915_DRM_H_ */