i915 preview #3
git-svn-id: svn://kolibrios.org@2342 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
5491cb4d99
commit
9566458ddb
@ -6,6 +6,16 @@
|
||||
#include "intel_drv.h"
|
||||
#include "bitmap.h"
|
||||
|
||||
void __attribute__((regparm(1))) destroy_bitmap(bitmap_t *bitmap)
|
||||
{
|
||||
/*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
__DestroyObject(bitmap);
|
||||
};
|
||||
|
||||
extern struct drm_device *main_device;
|
||||
|
||||
struct hman bm_man;
|
||||
@ -20,12 +30,14 @@ int init_bitmaps()
|
||||
};
|
||||
|
||||
|
||||
int create_bitmap(struct ubitmap *pbitmap, int width, int height)
|
||||
int create_bitmap(struct ubitmap *pbitmap)
|
||||
{
|
||||
struct drm_i915_gem_object *obj;
|
||||
|
||||
bitmap_t *bitmap;
|
||||
u32 handle;
|
||||
u32 width;
|
||||
u32 height;
|
||||
u32 size;
|
||||
u32 pitch;
|
||||
void *uaddr;
|
||||
@ -35,15 +47,24 @@ int create_bitmap(struct ubitmap *pbitmap, int width, int height)
|
||||
pbitmap->handle = 0;
|
||||
pbitmap->data = NULL;
|
||||
|
||||
width = pbitmap->width;
|
||||
height = pbitmap->height;
|
||||
|
||||
if((width==0)||(height==0)||(width>4096)||(height>4096))
|
||||
goto err1;
|
||||
|
||||
handle = alloc_handle(&bm_man);
|
||||
// printf("%s %d\n",__FUNCTION__, handle);
|
||||
|
||||
if(handle == 0)
|
||||
goto err1;
|
||||
|
||||
bitmap = CreateObject(GetPid(), sizeof(*bitmap));
|
||||
bitmap->handle = handle;
|
||||
bitmap->header.destroy = destroy_bitmap;
|
||||
bitmap->obj = NULL;
|
||||
|
||||
// printf("bitmap %x\n", bitmap);
|
||||
if( bitmap == NULL)
|
||||
goto err1;
|
||||
|
||||
@ -52,6 +73,7 @@ int create_bitmap(struct ubitmap *pbitmap, int width, int height)
|
||||
pitch = ALIGN(width*4,64);
|
||||
|
||||
size = roundup(pitch*height, PAGE_SIZE);
|
||||
// printf("pitch %d size %d\n", pitch, size);
|
||||
|
||||
obj = i915_gem_alloc_object(main_device, size);
|
||||
if (obj == NULL)
|
||||
@ -88,9 +110,15 @@ int create_bitmap(struct ubitmap *pbitmap, int width, int height)
|
||||
bitmap->gaddr = obj->gtt_offset;
|
||||
bitmap->uaddr = uaddr;
|
||||
bitmap->obj = obj;
|
||||
bitmap->header.destroy = destroy_bitmap;
|
||||
|
||||
pbitmap->pitch = pitch;
|
||||
pbitmap->handle = handle;
|
||||
pbitmap->data = uaddr;
|
||||
|
||||
// printf("%s handle %d pitch %d gpu %x user %x\n",
|
||||
// __FUNCTION__, handle, pitch, obj->gtt_offset, uaddr);
|
||||
|
||||
return 0;
|
||||
|
||||
err4:
|
||||
@ -99,74 +127,13 @@ err3:
|
||||
// drm_gem_object_unreference(&obj->base);
|
||||
err2:
|
||||
free_handle(&bm_man, handle);
|
||||
DestroyObject(bitmap);
|
||||
__DestroyObject(bitmap);
|
||||
err1:
|
||||
return -1;
|
||||
|
||||
};
|
||||
|
||||
|
||||
int create_video(int width, int height, u32_t *outp)
|
||||
{
|
||||
struct drm_i915_gem_object *obj;
|
||||
|
||||
size_t size;
|
||||
size_t pitch;
|
||||
void *uaddr;
|
||||
|
||||
int ret;
|
||||
|
||||
if((width==0)||(height==0)||(width>4096)||(height>4096))
|
||||
goto err1;
|
||||
|
||||
pitch = ALIGN(width*4,64);
|
||||
|
||||
size = roundup(pitch*height, PAGE_SIZE);
|
||||
|
||||
obj = i915_gem_alloc_object(main_device, size);
|
||||
if (obj == NULL)
|
||||
goto err2;
|
||||
|
||||
ret = i915_gem_object_pin(obj, 4096, true);
|
||||
if (ret)
|
||||
goto err3;
|
||||
|
||||
uaddr = UserAlloc(size);
|
||||
if( uaddr == NULL)
|
||||
goto err4;
|
||||
else
|
||||
{
|
||||
u32_t *src, *dst;
|
||||
int count;
|
||||
|
||||
#define page_tabs 0xFDC00000 /* really dirty hack */
|
||||
|
||||
src = (u32_t*)obj->pages;
|
||||
dst = &((u32_t*)page_tabs)[(u32_t)uaddr >> 12];
|
||||
count = size/4096;
|
||||
|
||||
while(count--)
|
||||
{
|
||||
*dst++ = (0xFFFFF000 & *src++) | 0x207 ; // map as shared page
|
||||
};
|
||||
}
|
||||
|
||||
outp[0] = obj->gtt_offset;
|
||||
outp[2] = (u32)uaddr;
|
||||
outp[3] = pitch;
|
||||
|
||||
return 0;
|
||||
|
||||
err4:
|
||||
// drm_gem_object_unpin;
|
||||
err3:
|
||||
// drm_gem_object_unreference(&obj->base);
|
||||
err2:
|
||||
err1:
|
||||
return -1;
|
||||
};
|
||||
|
||||
|
||||
int init_hman(struct hman *man, u32 count)
|
||||
{
|
||||
u32* data;
|
||||
|
@ -55,5 +55,6 @@ struct ubitmap
|
||||
void *data;
|
||||
};
|
||||
|
||||
int create_bitmap(struct ubitmap *pbitmap, int width, int height);
|
||||
int create_bitmap(struct ubitmap *pbitmap);
|
||||
int init_bitmaps();
|
||||
|
||||
|
@ -227,7 +227,7 @@ static bool ch7017_init(struct intel_dvo_device *dvo,
|
||||
default:
|
||||
DRM_DEBUG_KMS("ch701x not detected, got %d: from %s "
|
||||
"slave %d.\n",
|
||||
val, adapter->name,dvo->slave_addr);
|
||||
val, adapter->name, dvo->slave_addr);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -111,7 +111,7 @@ static char *ch7xxx_get_id(uint8_t vid)
|
||||
/** Reads an 8 bit register */
|
||||
static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
|
||||
{
|
||||
struct ch7xxx_priv *ch7xxx= dvo->dev_priv;
|
||||
struct ch7xxx_priv *ch7xxx = dvo->dev_priv;
|
||||
struct i2c_adapter *adapter = dvo->i2c_bus;
|
||||
u8 out_buf[2];
|
||||
u8 in_buf[2];
|
||||
@ -303,7 +303,7 @@ static void ch7xxx_dump_regs(struct intel_dvo_device *dvo)
|
||||
|
||||
for (i = 0; i < CH7xxx_NUM_REGS; i++) {
|
||||
uint8_t val;
|
||||
if ((i % 8) == 0 )
|
||||
if ((i % 8) == 0)
|
||||
DRM_LOG_KMS("\n %02X: ", i);
|
||||
ch7xxx_readb(dvo, i, &val);
|
||||
DRM_LOG_KMS("%02X ", val);
|
||||
|
@ -344,8 +344,8 @@ static void ivch_mode_set(struct intel_dvo_device *dvo,
|
||||
(adjusted_mode->hdisplay - 1)) >> 2;
|
||||
y_ratio = (((mode->vdisplay - 1) << 16) /
|
||||
(adjusted_mode->vdisplay - 1)) >> 2;
|
||||
ivch_write (dvo, VR42, x_ratio);
|
||||
ivch_write (dvo, VR41, y_ratio);
|
||||
ivch_write(dvo, VR42, x_ratio);
|
||||
ivch_write(dvo, VR41, y_ratio);
|
||||
} else {
|
||||
vr01 &= ~VR01_PANEL_FIT_ENABLE;
|
||||
vr40 &= ~VR40_CLOCK_GATING_ENABLE;
|
||||
@ -410,7 +410,7 @@ static void ivch_destroy(struct intel_dvo_device *dvo)
|
||||
}
|
||||
}
|
||||
|
||||
struct intel_dvo_dev_ops ivch_ops= {
|
||||
struct intel_dvo_dev_ops ivch_ops = {
|
||||
.init = ivch_init,
|
||||
.dpms = ivch_dpms,
|
||||
.mode_valid = ivch_mode_valid,
|
||||
|
@ -104,7 +104,7 @@ static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
|
||||
|
||||
static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
|
||||
{
|
||||
struct sil164_priv *sil= dvo->dev_priv;
|
||||
struct sil164_priv *sil = dvo->dev_priv;
|
||||
struct i2c_adapter *adapter = dvo->i2c_bus;
|
||||
uint8_t out_buf[2];
|
||||
struct i2c_msg msg = {
|
||||
|
@ -560,11 +560,14 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
|
||||
// if (!IS_I945G(dev) && !IS_I945GM(dev))
|
||||
// pci_enable_msi(dev->pdev);
|
||||
|
||||
spin_lock_init(&dev_priv->gt_lock);
|
||||
spin_lock_init(&dev_priv->irq_lock);
|
||||
spin_lock_init(&dev_priv->error_lock);
|
||||
spin_lock_init(&dev_priv->rps_lock);
|
||||
|
||||
if (IS_MOBILE(dev) || !IS_GEN2(dev))
|
||||
if (IS_IVYBRIDGE(dev))
|
||||
dev_priv->num_pipe = 3;
|
||||
else if (IS_MOBILE(dev) || !IS_GEN2(dev))
|
||||
dev_priv->num_pipe = 2;
|
||||
else
|
||||
dev_priv->num_pipe = 1;
|
||||
|
@ -198,6 +198,8 @@ typedef struct _drm_i915_sarea {
|
||||
#define DRM_I915_OVERLAY_PUT_IMAGE 0x27
|
||||
#define DRM_I915_OVERLAY_ATTRS 0x28
|
||||
#define DRM_I915_GEM_EXECBUFFER2 0x29
|
||||
#define DRM_I915_GET_SPRITE_COLORKEY 0x2a
|
||||
#define DRM_I915_SET_SPRITE_COLORKEY 0x2b
|
||||
|
||||
#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)
|
||||
@ -239,6 +241,8 @@ typedef struct _drm_i915_sarea {
|
||||
#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_I915_OVERLAY_PUT_IMAGE, 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)
|
||||
#define DRM_IOCTL_I915_SET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey)
|
||||
#define DRM_IOCTL_I915_GET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey)
|
||||
|
||||
/* Allow drivers to submit batchbuffers directly to hardware, relying
|
||||
* on the security mechanisms provided by hardware.
|
||||
@ -291,6 +295,7 @@ typedef struct drm_i915_irq_wait {
|
||||
#define I915_PARAM_HAS_COHERENT_RINGS 13
|
||||
#define I915_PARAM_HAS_EXEC_CONSTANTS 14
|
||||
#define I915_PARAM_HAS_RELAXED_DELTA 15
|
||||
#define I915_PARAM_HAS_GEN7_SOL_RESET 16
|
||||
|
||||
typedef struct drm_i915_getparam {
|
||||
int param;
|
||||
@ -653,6 +658,9 @@ struct drm_i915_gem_execbuffer2 {
|
||||
__u64 rsvd2;
|
||||
};
|
||||
|
||||
/** Resets the SO write offset registers for transform feedback on gen7. */
|
||||
#define I915_EXEC_GEN7_SOL_RESET (1<<8)
|
||||
|
||||
struct drm_i915_gem_pin {
|
||||
/** Handle of the buffer to be pinned. */
|
||||
__u32 handle;
|
||||
@ -844,4 +852,36 @@ struct drm_intel_overlay_attrs {
|
||||
__u32 gamma5;
|
||||
};
|
||||
|
||||
/*
|
||||
* Intel sprite handling
|
||||
*
|
||||
* Color keying works with a min/mask/max tuple. Both source and destination
|
||||
* color keying is allowed.
|
||||
*
|
||||
* Source keying:
|
||||
* Sprite pixels within the min & max values, masked against the color channels
|
||||
* specified in the mask field, will be transparent. All other pixels will
|
||||
* be displayed on top of the primary plane. For RGB surfaces, only the min
|
||||
* and mask fields will be used; ranged compares are not allowed.
|
||||
*
|
||||
* Destination keying:
|
||||
* Primary plane pixels that match the min value, masked against the color
|
||||
* channels specified in the mask field, will be replaced by corresponding
|
||||
* pixels from the sprite plane.
|
||||
*
|
||||
* Note that source & destination keying are exclusive; only one can be
|
||||
* active on a given plane.
|
||||
*/
|
||||
|
||||
#define I915_SET_COLORKEY_NONE (1<<0) /* disable color key matching */
|
||||
#define I915_SET_COLORKEY_DESTINATION (1<<1)
|
||||
#define I915_SET_COLORKEY_SOURCE (1<<2)
|
||||
struct drm_intel_sprite_colorkey {
|
||||
__u32 plane_id;
|
||||
__u32 min_value;
|
||||
__u32 channel_mask;
|
||||
__u32 max_value;
|
||||
__u32 flags;
|
||||
};
|
||||
|
||||
#endif /* _I915_DRM_H_ */
|
||||
|
@ -53,7 +53,7 @@ int i915_panel_ignore_lid __read_mostly = 0;
|
||||
|
||||
unsigned int i915_powersave __read_mostly = 0;
|
||||
|
||||
unsigned int i915_enable_rc6 __read_mostly = 0;
|
||||
unsigned int i915_enable_rc6 __read_mostly = -1;
|
||||
|
||||
unsigned int i915_enable_fbc __read_mostly = 0;
|
||||
|
||||
@ -66,7 +66,7 @@ int i915_vbt_sdvo_panel_type __read_mostly = -1;
|
||||
#define PCI_VENDOR_ID_INTEL 0x8086
|
||||
|
||||
#define INTEL_VGA_DEVICE(id, info) { \
|
||||
.class = PCI_CLASS_DISPLAY_VGA << 8, \
|
||||
.class = PCI_BASE_CLASS_DISPLAY << 16, \
|
||||
.class_mask = 0xff0000, \
|
||||
.vendor = 0x8086, \
|
||||
.device = id, \
|
||||
@ -245,7 +245,7 @@ static const struct pci_device_id pciidlist[] = { /* aka */
|
||||
#define INTEL_PCH_CPT_DEVICE_ID_TYPE 0x1c00
|
||||
#define INTEL_PCH_PPT_DEVICE_ID_TYPE 0x1e00
|
||||
|
||||
void intel_detect_pch (struct drm_device *dev)
|
||||
void intel_detect_pch(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct pci_dev *pch;
|
||||
@ -277,7 +277,7 @@ void intel_detect_pch (struct drm_device *dev)
|
||||
}
|
||||
}
|
||||
|
||||
static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
|
||||
void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
int count;
|
||||
|
||||
@ -293,6 +293,22 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
int count;
|
||||
|
||||
count = 0;
|
||||
while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1))
|
||||
udelay(10);
|
||||
|
||||
I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<16) | 1);
|
||||
POSTING_READ(FORCEWAKE_MT);
|
||||
|
||||
count = 0;
|
||||
while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1) == 0)
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generally this is called implicitly by the register read function. However,
|
||||
* if some sequence requires the GT to not power down then this function should
|
||||
@ -301,33 +317,42 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
|
||||
*/
|
||||
void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
// WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
|
||||
unsigned long irqflags;
|
||||
|
||||
/* Forcewake is atomic in case we get in here without the lock */
|
||||
if (atomic_add_return(1, &dev_priv->forcewake_count) == 1)
|
||||
__gen6_gt_force_wake_get(dev_priv);
|
||||
spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
|
||||
if (dev_priv->forcewake_count++ == 0)
|
||||
dev_priv->display.force_wake_get(dev_priv);
|
||||
spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
|
||||
}
|
||||
|
||||
static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
|
||||
void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
I915_WRITE_NOTRACE(FORCEWAKE, 0);
|
||||
POSTING_READ(FORCEWAKE);
|
||||
}
|
||||
|
||||
void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<16) | 0);
|
||||
POSTING_READ(FORCEWAKE_MT);
|
||||
}
|
||||
|
||||
/*
|
||||
* see gen6_gt_force_wake_get()
|
||||
*/
|
||||
void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
// WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
|
||||
unsigned long irqflags;
|
||||
|
||||
if (atomic_dec_and_test(&dev_priv->forcewake_count))
|
||||
__gen6_gt_force_wake_put(dev_priv);
|
||||
spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
|
||||
if (--dev_priv->forcewake_count == 0)
|
||||
dev_priv->display.force_wake_put(dev_priv);
|
||||
spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
|
||||
}
|
||||
|
||||
void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
if (dev_priv->gt_fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES ) {
|
||||
if (dev_priv->gt_fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) {
|
||||
int loop = 500;
|
||||
u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
|
||||
while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) {
|
||||
@ -441,3 +466,39 @@ err_g4:
|
||||
}
|
||||
|
||||
|
||||
#define __i915_read(x, y) \
|
||||
u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
|
||||
u##x val = 0; \
|
||||
if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
|
||||
unsigned long irqflags; \
|
||||
spin_lock_irqsave(&dev_priv->gt_lock, irqflags); \
|
||||
if (dev_priv->forcewake_count == 0) \
|
||||
dev_priv->display.force_wake_get(dev_priv); \
|
||||
val = read##y(dev_priv->regs + reg); \
|
||||
if (dev_priv->forcewake_count == 0) \
|
||||
dev_priv->display.force_wake_put(dev_priv); \
|
||||
spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \
|
||||
} else { \
|
||||
val = read##y(dev_priv->regs + reg); \
|
||||
} \
|
||||
return val; \
|
||||
}
|
||||
|
||||
__i915_read(8, b)
|
||||
__i915_read(16, w)
|
||||
__i915_read(32, l)
|
||||
__i915_read(64, q)
|
||||
#undef __i915_read
|
||||
|
||||
#define __i915_write(x, y) \
|
||||
void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \
|
||||
if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
|
||||
__gen6_gt_wait_for_fifo(dev_priv); \
|
||||
} \
|
||||
write##y(val, dev_priv->regs + reg); \
|
||||
}
|
||||
__i915_write(8, b)
|
||||
__i915_write(16, w)
|
||||
__i915_write(32, l)
|
||||
__i915_write(64, q)
|
||||
#undef __i915_write
|
||||
|
@ -105,6 +105,7 @@ struct opregion_header;
|
||||
struct opregion_acpi;
|
||||
struct opregion_swsci;
|
||||
struct opregion_asle;
|
||||
struct drm_i915_private;
|
||||
|
||||
struct intel_opregion {
|
||||
struct opregion_header *header;
|
||||
@ -124,6 +125,9 @@ struct drm_i915_master_private {
|
||||
struct _drm_i915_sarea *sarea_priv;
|
||||
};
|
||||
#define I915_FENCE_REG_NONE -1
|
||||
#define I915_MAX_NUM_FENCES 16
|
||||
/* 16 fences + sign bit for FENCE_REG_NONE */
|
||||
#define I915_MAX_NUM_FENCE_BITS 5
|
||||
|
||||
struct drm_i915_fence_reg {
|
||||
struct list_head lru_list;
|
||||
@ -137,7 +141,6 @@ struct sdvo_device_mapping {
|
||||
u8 slave_addr;
|
||||
u8 dvo_wiring;
|
||||
u8 i2c_pin;
|
||||
u8 i2c_speed;
|
||||
u8 ddc_pin;
|
||||
};
|
||||
|
||||
@ -167,7 +170,7 @@ struct drm_i915_error_state {
|
||||
u32 instdone1;
|
||||
u32 seqno;
|
||||
u64 bbaddr;
|
||||
u64 fence[16];
|
||||
u64 fence[I915_MAX_NUM_FENCES];
|
||||
struct timeval time;
|
||||
struct drm_i915_error_object {
|
||||
int page_count;
|
||||
@ -181,7 +184,7 @@ struct drm_i915_error_state {
|
||||
u32 gtt_offset;
|
||||
u32 read_domains;
|
||||
u32 write_domain;
|
||||
s32 fence_reg:5;
|
||||
s32 fence_reg:I915_MAX_NUM_FENCE_BITS;
|
||||
s32 pinned:2;
|
||||
u32 tiling:2;
|
||||
u32 dirty:1;
|
||||
@ -202,11 +205,15 @@ struct drm_i915_display_funcs {
|
||||
int (*get_display_clock_speed)(struct drm_device *dev);
|
||||
int (*get_fifo_size)(struct drm_device *dev, int plane);
|
||||
void (*update_wm)(struct drm_device *dev);
|
||||
void (*update_sprite_wm)(struct drm_device *dev, int pipe,
|
||||
uint32_t sprite_width, int pixel_size);
|
||||
int (*crtc_mode_set)(struct drm_crtc *crtc,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode,
|
||||
int x, int y,
|
||||
struct drm_framebuffer *old_fb);
|
||||
void (*write_eld)(struct drm_connector *connector,
|
||||
struct drm_crtc *crtc);
|
||||
void (*fdi_link_train)(struct drm_crtc *crtc);
|
||||
void (*init_clock_gating)(struct drm_device *dev);
|
||||
void (*init_pch_clock_gating)(struct drm_device *dev);
|
||||
@ -215,6 +222,8 @@ struct drm_i915_display_funcs {
|
||||
struct drm_i915_gem_object *obj);
|
||||
int (*update_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb,
|
||||
int x, int y);
|
||||
void (*force_wake_get)(struct drm_i915_private *dev_priv);
|
||||
void (*force_wake_put)(struct drm_i915_private *dev_priv);
|
||||
/* clock updates for mode set */
|
||||
/* cursor updates */
|
||||
/* render clock increase/decrease */
|
||||
@ -224,26 +233,26 @@ struct drm_i915_display_funcs {
|
||||
|
||||
struct intel_device_info {
|
||||
u8 gen;
|
||||
u8 is_mobile : 1;
|
||||
u8 is_i85x : 1;
|
||||
u8 is_i915g : 1;
|
||||
u8 is_i945gm : 1;
|
||||
u8 is_g33 : 1;
|
||||
u8 need_gfx_hws : 1;
|
||||
u8 is_g4x : 1;
|
||||
u8 is_pineview : 1;
|
||||
u8 is_broadwater : 1;
|
||||
u8 is_crestline : 1;
|
||||
u8 is_ivybridge : 1;
|
||||
u8 has_fbc : 1;
|
||||
u8 has_pipe_cxsr : 1;
|
||||
u8 has_hotplug : 1;
|
||||
u8 cursor_needs_physical : 1;
|
||||
u8 has_overlay : 1;
|
||||
u8 overlay_needs_physical : 1;
|
||||
u8 supports_tv : 1;
|
||||
u8 has_bsd_ring : 1;
|
||||
u8 has_blt_ring : 1;
|
||||
u8 is_mobile:1;
|
||||
u8 is_i85x:1;
|
||||
u8 is_i915g:1;
|
||||
u8 is_i945gm:1;
|
||||
u8 is_g33:1;
|
||||
u8 need_gfx_hws:1;
|
||||
u8 is_g4x:1;
|
||||
u8 is_pineview:1;
|
||||
u8 is_broadwater:1;
|
||||
u8 is_crestline:1;
|
||||
u8 is_ivybridge:1;
|
||||
u8 has_fbc:1;
|
||||
u8 has_pipe_cxsr:1;
|
||||
u8 has_hotplug:1;
|
||||
u8 cursor_needs_physical:1;
|
||||
u8 has_overlay:1;
|
||||
u8 overlay_needs_physical:1;
|
||||
u8 supports_tv:1;
|
||||
u8 has_bsd_ring:1;
|
||||
u8 has_blt_ring:1;
|
||||
};
|
||||
|
||||
enum no_fbc_reason {
|
||||
@ -277,7 +286,13 @@ typedef struct drm_i915_private {
|
||||
int relative_constants_mode;
|
||||
|
||||
void __iomem *regs;
|
||||
u32 gt_fifo_count;
|
||||
/** gt_fifo_count and the subsequent register write are synchronized
|
||||
* with dev->struct_mutex. */
|
||||
unsigned gt_fifo_count;
|
||||
/** forcewake_count is protected by gt_lock */
|
||||
unsigned forcewake_count;
|
||||
/** gt_lock is also taken in irq contexts. */
|
||||
spinlock_t gt_lock;
|
||||
|
||||
struct intel_gmbus {
|
||||
struct i2c_adapter adapter;
|
||||
@ -328,6 +343,8 @@ typedef struct drm_i915_private {
|
||||
struct timer_list hangcheck_timer;
|
||||
int hangcheck_count;
|
||||
uint32_t last_acthd;
|
||||
uint32_t last_acthd_bsd;
|
||||
uint32_t last_acthd_blt;
|
||||
uint32_t last_instdone;
|
||||
uint32_t last_instdone1;
|
||||
|
||||
@ -341,11 +358,11 @@ typedef struct drm_i915_private {
|
||||
|
||||
/* overlay */
|
||||
// struct intel_overlay *overlay;
|
||||
bool sprite_scaling_enabled;
|
||||
|
||||
/* LVDS info */
|
||||
int backlight_level; /* restore backlight to this value */
|
||||
bool backlight_enabled;
|
||||
struct drm_display_mode *panel_fixed_mode;
|
||||
struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */
|
||||
struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */
|
||||
|
||||
@ -355,6 +372,7 @@ typedef struct drm_i915_private {
|
||||
unsigned int lvds_vbt:1;
|
||||
unsigned int int_crt_support:1;
|
||||
unsigned int lvds_use_ssc:1;
|
||||
unsigned int display_clock_mode:1;
|
||||
int lvds_ssc_freq;
|
||||
struct {
|
||||
int rate;
|
||||
@ -372,7 +390,7 @@ typedef struct drm_i915_private {
|
||||
// struct notifier_block lid_notifier;
|
||||
|
||||
int crt_ddc_pin;
|
||||
struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */
|
||||
struct drm_i915_fence_reg fence_regs[I915_MAX_NUM_FENCES]; /* 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 */
|
||||
|
||||
@ -503,7 +521,7 @@ typedef struct drm_i915_private {
|
||||
u8 saveAR[21];
|
||||
u8 saveDACMASK;
|
||||
u8 saveCR[37];
|
||||
uint64_t saveFENCE[16];
|
||||
uint64_t saveFENCE[I915_MAX_NUM_FENCES];
|
||||
u32 saveCURACNTR;
|
||||
u32 saveCURAPOS;
|
||||
u32 saveCURABASE;
|
||||
@ -670,10 +688,9 @@ typedef struct drm_i915_private {
|
||||
unsigned int lvds_border_bits;
|
||||
/* Panel fitter placement and size for Ironlake+ */
|
||||
u32 pch_pf_pos, pch_pf_size;
|
||||
int panel_t3, panel_t12;
|
||||
|
||||
struct drm_crtc *plane_to_crtc_mapping[2];
|
||||
struct drm_crtc *pipe_to_crtc_mapping[2];
|
||||
struct drm_crtc *plane_to_crtc_mapping[3];
|
||||
struct drm_crtc *pipe_to_crtc_mapping[3];
|
||||
// wait_queue_head_t pending_flip_queue;
|
||||
bool flip_pending_is_done;
|
||||
|
||||
@ -705,6 +722,7 @@ typedef struct drm_i915_private {
|
||||
|
||||
u64 last_count1;
|
||||
unsigned long last_time1;
|
||||
unsigned long chipset_power;
|
||||
u64 last_count2;
|
||||
struct timespec last_time2;
|
||||
unsigned long gfx_power;
|
||||
@ -727,8 +745,6 @@ typedef struct drm_i915_private {
|
||||
|
||||
// struct drm_property *broadcast_rgb_property;
|
||||
// struct drm_property *force_audio_property;
|
||||
|
||||
atomic_t forcewake_count;
|
||||
} drm_i915_private_t;
|
||||
|
||||
enum i915_cache_level {
|
||||
@ -757,39 +773,37 @@ struct drm_i915_gem_object {
|
||||
* (has pending rendering), and is not set if it's on inactive (ready
|
||||
* to be unbound).
|
||||
*/
|
||||
unsigned int active : 1;
|
||||
unsigned int active:1;
|
||||
|
||||
/**
|
||||
* This is set if the object has been written to since last bound
|
||||
* to the GTT
|
||||
*/
|
||||
unsigned int dirty : 1;
|
||||
unsigned int dirty:1;
|
||||
|
||||
/**
|
||||
* This is set if the object has been written to since the last
|
||||
* GPU flush.
|
||||
*/
|
||||
unsigned int pending_gpu_write : 1;
|
||||
unsigned int pending_gpu_write:1;
|
||||
|
||||
/**
|
||||
* Fence register bits (if any) for this object. Will be set
|
||||
* as needed when mapped into the GTT.
|
||||
* Protected by dev->struct_mutex.
|
||||
*
|
||||
* Size: 4 bits for 16 fences + sign (for FENCE_REG_NONE)
|
||||
*/
|
||||
signed int fence_reg : 5;
|
||||
signed int fence_reg:I915_MAX_NUM_FENCE_BITS;
|
||||
|
||||
/**
|
||||
* Advice: are the backing pages purgeable?
|
||||
*/
|
||||
unsigned int madv : 2;
|
||||
unsigned int madv:2;
|
||||
|
||||
/**
|
||||
* Current tiling mode for the object.
|
||||
*/
|
||||
unsigned int tiling_mode : 2;
|
||||
unsigned int tiling_changed : 1;
|
||||
unsigned int tiling_mode:2;
|
||||
unsigned int tiling_changed:1;
|
||||
|
||||
/** How many users have pinned this object in GTT space. The following
|
||||
* users can each hold at most one reference: pwrite/pread, pin_ioctl
|
||||
@ -800,22 +814,22 @@ struct drm_i915_gem_object {
|
||||
*
|
||||
* In the worst case this is 1 + 1 + 1 + 2*2 = 7. That would fit into 3
|
||||
* bits with absolutely no headroom. So use 4 bits. */
|
||||
unsigned int pin_count : 4;
|
||||
unsigned int pin_count:4;
|
||||
#define DRM_I915_GEM_OBJECT_MAX_PIN_COUNT 0xf
|
||||
|
||||
/**
|
||||
* Is the object at the current location in the gtt mappable and
|
||||
* fenceable? Used to avoid costly recalculations.
|
||||
*/
|
||||
unsigned int map_and_fenceable : 1;
|
||||
unsigned int map_and_fenceable:1;
|
||||
|
||||
/**
|
||||
* Whether the current gtt mapping needs to be mappable (and isn't just
|
||||
* mappable by accident). Track pin and fault separate for a more
|
||||
* accurate mappable working set.
|
||||
*/
|
||||
unsigned int fault_mappable : 1;
|
||||
unsigned int pin_mappable : 1;
|
||||
unsigned int fault_mappable:1;
|
||||
unsigned int pin_mappable:1;
|
||||
|
||||
/*
|
||||
* Is the GPU currently using a fence to access this buffer,
|
||||
@ -915,7 +929,7 @@ struct drm_i915_gem_request {
|
||||
|
||||
struct drm_i915_file_private {
|
||||
struct {
|
||||
// struct spinlock lock;
|
||||
spinlock_t lock;
|
||||
struct list_head request_list;
|
||||
} mm;
|
||||
};
|
||||
@ -1052,7 +1066,7 @@ i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
|
||||
void
|
||||
i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
|
||||
|
||||
void intel_enable_asle (struct drm_device *dev);
|
||||
void intel_enable_asle(struct drm_device *dev);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
extern void i915_destroy_error_state(struct drm_device *dev);
|
||||
@ -1159,6 +1173,9 @@ i915_gem_next_request_seqno(struct intel_ring_buffer *ring)
|
||||
return ring->outstanding_lazy_request = dev_priv->next_seqno;
|
||||
}
|
||||
|
||||
int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj,
|
||||
struct intel_ring_buffer *pipelined);
|
||||
int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj);
|
||||
|
||||
void i915_gem_retire_requests(struct drm_device *dev);
|
||||
void i915_gem_reset(struct drm_device *dev);
|
||||
@ -1255,12 +1272,10 @@ extern int intel_setup_gmbus(struct drm_device *dev);
|
||||
extern void intel_teardown_gmbus(struct drm_device *dev);
|
||||
extern void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed);
|
||||
extern void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit);
|
||||
|
||||
//extern inline bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter)
|
||||
//{
|
||||
// return container_of(adapter, struct intel_gmbus, adapter)->force_bit;
|
||||
//}
|
||||
|
||||
extern inline bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter)
|
||||
{
|
||||
return container_of(adapter, struct intel_gmbus, adapter)->force_bit;
|
||||
}
|
||||
extern void intel_i2c_reset(struct drm_device *dev);
|
||||
|
||||
/* intel_opregion.c */
|
||||
@ -1296,10 +1311,16 @@ extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
|
||||
extern bool intel_fbc_enabled(struct drm_device *dev);
|
||||
extern void intel_disable_fbc(struct drm_device *dev);
|
||||
extern bool ironlake_set_drps(struct drm_device *dev, u8 val);
|
||||
extern void ironlake_init_pch_refclk(struct drm_device *dev);
|
||||
extern void ironlake_enable_rc6(struct drm_device *dev);
|
||||
extern void gen6_set_rps(struct drm_device *dev, u8 val);
|
||||
extern void intel_detect_pch (struct drm_device *dev);
|
||||
extern int intel_trans_dp_port_sel (struct drm_crtc *crtc);
|
||||
extern void intel_detect_pch(struct drm_device *dev);
|
||||
extern int intel_trans_dp_port_sel(struct drm_crtc *crtc);
|
||||
|
||||
extern void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv);
|
||||
extern void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv);
|
||||
extern void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv);
|
||||
extern void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv);
|
||||
|
||||
/* overlay */
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
@ -1349,18 +1370,7 @@ void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv);
|
||||
((reg) != FORCEWAKE))
|
||||
|
||||
#define __i915_read(x, y) \
|
||||
static inline u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
|
||||
u##x val = 0; \
|
||||
if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
|
||||
gen6_gt_force_wake_get(dev_priv); \
|
||||
val = read##y(dev_priv->regs + reg); \
|
||||
gen6_gt_force_wake_put(dev_priv); \
|
||||
} else { \
|
||||
val = read##y(dev_priv->regs + reg); \
|
||||
} \
|
||||
/* trace_i915_reg_rw(false, reg, val, sizeof(val)); */\
|
||||
return val; \
|
||||
}
|
||||
u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg);
|
||||
|
||||
__i915_read(8, b)
|
||||
__i915_read(16, w)
|
||||
@ -1369,13 +1379,8 @@ __i915_read(64, q)
|
||||
#undef __i915_read
|
||||
|
||||
#define __i915_write(x, y) \
|
||||
static inline void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \
|
||||
/* trace_i915_reg_rw(true, reg, val, sizeof(val));*/ \
|
||||
if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
|
||||
__gen6_gt_wait_for_fifo(dev_priv); \
|
||||
} \
|
||||
write##y(val, dev_priv->regs + reg); \
|
||||
}
|
||||
void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val);
|
||||
|
||||
__i915_write(8, b)
|
||||
__i915_write(16, w)
|
||||
__i915_write(32, l)
|
||||
|
@ -230,7 +230,7 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
||||
args->aper_size = dev_priv->mm.gtt_total;
|
||||
args->aper_available_size = args->aper_size -pinned;
|
||||
args->aper_available_size = args->aper_size - pinned;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -246,6 +246,8 @@ i915_gem_create(struct drm_file *file,
|
||||
u32 handle;
|
||||
|
||||
size = roundup(size, PAGE_SIZE);
|
||||
if (size == 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* Allocate the new object */
|
||||
obj = i915_gem_alloc_object(dev, size);
|
||||
@ -1186,7 +1188,7 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
|
||||
|
||||
fenceable =
|
||||
obj->gtt_space->size == fence_size &&
|
||||
(obj->gtt_space->start & (fence_alignment -1)) == 0;
|
||||
(obj->gtt_space->start & (fence_alignment - 1)) == 0;
|
||||
|
||||
mappable =
|
||||
obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end;
|
||||
@ -1557,13 +1559,6 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj,
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1593,7 +1588,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
|
||||
obj->base.write_domain = I915_GEM_DOMAIN_CPU;
|
||||
obj->base.read_domains = I915_GEM_DOMAIN_CPU;
|
||||
|
||||
if (IS_GEN6(dev)) {
|
||||
if (IS_GEN6(dev) || IS_GEN7(dev)) {
|
||||
/* On Gen6, we can have the GPU use the LLC (the CPU
|
||||
* cache) for about a 10% performance improvement
|
||||
* compared to uncached. Graphics requests other than
|
||||
@ -1787,7 +1782,7 @@ i915_gem_load(struct drm_device *dev)
|
||||
INIT_LIST_HEAD(&dev_priv->mm.gtt_list);
|
||||
for (i = 0; i < I915_NUM_RINGS; i++)
|
||||
init_ring_lists(&dev_priv->ring[i]);
|
||||
for (i = 0; i < 16; i++)
|
||||
for (i = 0; i < I915_MAX_NUM_FENCES; i++)
|
||||
INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list);
|
||||
// INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
|
||||
// i915_gem_retire_work_handler);
|
||||
|
@ -110,7 +110,10 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
|
||||
uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
|
||||
uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
|
||||
|
||||
if (INTEL_INFO(dev)->gen >= 5) {
|
||||
if (INTEL_INFO(dev)->gen >= 6) {
|
||||
swizzle_x = I915_BIT_6_SWIZZLE_NONE;
|
||||
swizzle_y = I915_BIT_6_SWIZZLE_NONE;
|
||||
} else if (IS_GEN5(dev)) {
|
||||
/* On Ironlake whatever DRAM config, GPU always do
|
||||
* same swizzling setup.
|
||||
*/
|
||||
@ -459,14 +462,9 @@ i915_gem_swizzle_page(struct page *page)
|
||||
void
|
||||
i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj)
|
||||
{
|
||||
struct drm_device *dev = obj->base.dev;
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
int page_count = obj->base.size >> PAGE_SHIFT;
|
||||
int i;
|
||||
|
||||
if (dev_priv->mm.bit_6_swizzle_x != I915_BIT_6_SWIZZLE_9_10_17)
|
||||
return;
|
||||
|
||||
if (obj->bit_17 == NULL)
|
||||
return;
|
||||
|
||||
@ -483,14 +481,9 @@ i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj)
|
||||
void
|
||||
i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj)
|
||||
{
|
||||
struct drm_device *dev = obj->base.dev;
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
int page_count = obj->base.size >> PAGE_SHIFT;
|
||||
int i;
|
||||
|
||||
if (dev_priv->mm.bit_6_swizzle_x != I915_BIT_6_SWIZZLE_9_10_17)
|
||||
return;
|
||||
|
||||
if (obj->bit_17 == NULL) {
|
||||
obj->bit_17 = kmalloc(BITS_TO_LONGS(page_count) *
|
||||
sizeof(long), GFP_KERNEL);
|
||||
|
@ -156,7 +156,7 @@
|
||||
#define MI_SUSPEND_FLUSH MI_INSTR(0x0b, 0)
|
||||
#define MI_SUSPEND_FLUSH_EN (1<<0)
|
||||
#define MI_REPORT_HEAD MI_INSTR(0x07, 0)
|
||||
#define MI_OVERLAY_FLIP MI_INSTR(0x11,0)
|
||||
#define MI_OVERLAY_FLIP MI_INSTR(0x11, 0)
|
||||
#define MI_OVERLAY_CONTINUE (0x0<<21)
|
||||
#define MI_OVERLAY_ON (0x1<<21)
|
||||
#define MI_OVERLAY_OFF (0x2<<21)
|
||||
@ -194,6 +194,13 @@
|
||||
#define MI_SEMAPHORE_UPDATE (1<<21)
|
||||
#define MI_SEMAPHORE_COMPARE (1<<20)
|
||||
#define MI_SEMAPHORE_REGISTER (1<<18)
|
||||
#define MI_SEMAPHORE_SYNC_RV (2<<16)
|
||||
#define MI_SEMAPHORE_SYNC_RB (0<<16)
|
||||
#define MI_SEMAPHORE_SYNC_VR (0<<16)
|
||||
#define MI_SEMAPHORE_SYNC_VB (2<<16)
|
||||
#define MI_SEMAPHORE_SYNC_BR (2<<16)
|
||||
#define MI_SEMAPHORE_SYNC_BV (0<<16)
|
||||
#define MI_SEMAPHORE_SYNC_INVALID (1<<0)
|
||||
/*
|
||||
* 3D instructions used by the kernel
|
||||
*/
|
||||
@ -235,16 +242,22 @@
|
||||
#define ASYNC_FLIP (1<<22)
|
||||
#define DISPLAY_PLANE_A (0<<20)
|
||||
#define DISPLAY_PLANE_B (1<<20)
|
||||
#define GFX_OP_PIPE_CONTROL ((0x3<<29)|(0x3<<27)|(0x2<<24)|2)
|
||||
#define GFX_OP_PIPE_CONTROL(len) ((0x3<<29)|(0x3<<27)|(0x2<<24)|(len-2))
|
||||
#define PIPE_CONTROL_CS_STALL (1<<20)
|
||||
#define PIPE_CONTROL_QW_WRITE (1<<14)
|
||||
#define PIPE_CONTROL_DEPTH_STALL (1<<13)
|
||||
#define PIPE_CONTROL_WC_FLUSH (1<<12)
|
||||
#define PIPE_CONTROL_IS_FLUSH (1<<11) /* MBZ on Ironlake */
|
||||
#define PIPE_CONTROL_TC_FLUSH (1<<10) /* GM45+ only */
|
||||
#define PIPE_CONTROL_ISP_DIS (1<<9)
|
||||
#define PIPE_CONTROL_WRITE_FLUSH (1<<12)
|
||||
#define PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH (1<<12) /* gen6+ */
|
||||
#define PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE (1<<11) /* MBZ on Ironlake */
|
||||
#define PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE (1<<10) /* GM45+ only */
|
||||
#define PIPE_CONTROL_INDIRECT_STATE_DISABLE (1<<9)
|
||||
#define PIPE_CONTROL_NOTIFY (1<<8)
|
||||
#define PIPE_CONTROL_VF_CACHE_INVALIDATE (1<<4)
|
||||
#define PIPE_CONTROL_CONST_CACHE_INVALIDATE (1<<3)
|
||||
#define PIPE_CONTROL_STATE_CACHE_INVALIDATE (1<<2)
|
||||
#define PIPE_CONTROL_STALL_AT_SCOREBOARD (1<<1)
|
||||
#define PIPE_CONTROL_DEPTH_CACHE_FLUSH (1<<0)
|
||||
#define PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */
|
||||
#define PIPE_CONTROL_STALL_EN (1<<1) /* in addr word, Ironlake+ only */
|
||||
|
||||
|
||||
/*
|
||||
@ -296,6 +309,12 @@
|
||||
#define RING_CTL(base) ((base)+0x3c)
|
||||
#define RING_SYNC_0(base) ((base)+0x40)
|
||||
#define RING_SYNC_1(base) ((base)+0x44)
|
||||
#define GEN6_RVSYNC (RING_SYNC_0(RENDER_RING_BASE))
|
||||
#define GEN6_RBSYNC (RING_SYNC_1(RENDER_RING_BASE))
|
||||
#define GEN6_VRSYNC (RING_SYNC_1(GEN6_BSD_RING_BASE))
|
||||
#define GEN6_VBSYNC (RING_SYNC_0(GEN6_BSD_RING_BASE))
|
||||
#define GEN6_BRSYNC (RING_SYNC_0(BLT_RING_BASE))
|
||||
#define GEN6_BVSYNC (RING_SYNC_1(BLT_RING_BASE))
|
||||
#define RING_MAX_IDLE(base) ((base)+0x54)
|
||||
#define RING_HWS_PGA(base) ((base)+0x80)
|
||||
#define RING_HWS_PGA_GEN6(base) ((base)+0x2080)
|
||||
@ -423,6 +442,7 @@
|
||||
#define INSTPM_AGPBUSY_DIS (1<<11) /* gen3: when disabled, pending interrupts
|
||||
will not assert AGPBUSY# and will only
|
||||
be delivered when out of C3. */
|
||||
#define INSTPM_FORCE_ORDERING (1<<7) /* GEN6+ */
|
||||
#define ACTHD 0x020c8
|
||||
#define FW_BLC 0x020d8
|
||||
#define FW_BLC2 0x020dc
|
||||
@ -1534,12 +1554,21 @@
|
||||
*/
|
||||
#define PP_READY (1 << 30)
|
||||
#define PP_SEQUENCE_NONE (0 << 28)
|
||||
#define PP_SEQUENCE_ON (1 << 28)
|
||||
#define PP_SEQUENCE_OFF (2 << 28)
|
||||
#define PP_SEQUENCE_MASK 0x30000000
|
||||
#define PP_SEQUENCE_POWER_UP (1 << 28)
|
||||
#define PP_SEQUENCE_POWER_DOWN (2 << 28)
|
||||
#define PP_SEQUENCE_MASK (3 << 28)
|
||||
#define PP_SEQUENCE_SHIFT 28
|
||||
#define PP_CYCLE_DELAY_ACTIVE (1 << 27)
|
||||
#define PP_SEQUENCE_STATE_ON_IDLE (1 << 3)
|
||||
#define PP_SEQUENCE_STATE_MASK 0x0000000f
|
||||
#define PP_SEQUENCE_STATE_OFF_IDLE (0x0 << 0)
|
||||
#define PP_SEQUENCE_STATE_OFF_S0_1 (0x1 << 0)
|
||||
#define PP_SEQUENCE_STATE_OFF_S0_2 (0x2 << 0)
|
||||
#define PP_SEQUENCE_STATE_OFF_S0_3 (0x3 << 0)
|
||||
#define PP_SEQUENCE_STATE_ON_IDLE (0x8 << 0)
|
||||
#define PP_SEQUENCE_STATE_ON_S1_0 (0x9 << 0)
|
||||
#define PP_SEQUENCE_STATE_ON_S1_2 (0xa << 0)
|
||||
#define PP_SEQUENCE_STATE_ON_S1_3 (0xb << 0)
|
||||
#define PP_SEQUENCE_STATE_RESET (0xf << 0)
|
||||
#define PP_CONTROL 0x61204
|
||||
#define POWER_TARGET_ON (1 << 0)
|
||||
#define PP_ON_DELAYS 0x61208
|
||||
@ -2293,6 +2322,7 @@
|
||||
#define PIPECONF_PROGRESSIVE (0 << 21)
|
||||
#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
|
||||
#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21)
|
||||
#define PIPECONF_INTERLACE_MASK (7 << 21)
|
||||
#define PIPECONF_CXSR_DOWNCLOCK (1<<16)
|
||||
#define PIPECONF_BPP_MASK (0x000000e0)
|
||||
#define PIPECONF_BPP_8 (0<<5)
|
||||
@ -2416,6 +2446,7 @@
|
||||
#define WM0_PIPE_CURSOR_MASK (0x1f)
|
||||
|
||||
#define WM0_PIPEB_ILK 0x45104
|
||||
#define WM0_PIPEC_IVB 0x45200
|
||||
#define WM1_LP_ILK 0x45108
|
||||
#define WM1_LP_SR_EN (1<<31)
|
||||
#define WM1_LP_LATENCY_SHIFT 24
|
||||
@ -2430,6 +2461,8 @@
|
||||
#define WM3_LP_ILK 0x45110
|
||||
#define WM3_LP_EN (1<<31)
|
||||
#define WM1S_LP_ILK 0x45120
|
||||
#define WM2S_LP_IVB 0x45124
|
||||
#define WM3S_LP_IVB 0x45128
|
||||
#define WM1S_LP_EN (1<<31)
|
||||
|
||||
/* Memory latency timer register */
|
||||
@ -2554,10 +2587,18 @@
|
||||
#define _CURBBASE 0x700c4
|
||||
#define _CURBPOS 0x700c8
|
||||
|
||||
#define _CURBCNTR_IVB 0x71080
|
||||
#define _CURBBASE_IVB 0x71084
|
||||
#define _CURBPOS_IVB 0x71088
|
||||
|
||||
#define CURCNTR(pipe) _PIPE(pipe, _CURACNTR, _CURBCNTR)
|
||||
#define CURBASE(pipe) _PIPE(pipe, _CURABASE, _CURBBASE)
|
||||
#define CURPOS(pipe) _PIPE(pipe, _CURAPOS, _CURBPOS)
|
||||
|
||||
#define CURCNTR_IVB(pipe) _PIPE(pipe, _CURACNTR, _CURBCNTR_IVB)
|
||||
#define CURBASE_IVB(pipe) _PIPE(pipe, _CURABASE, _CURBBASE_IVB)
|
||||
#define CURPOS_IVB(pipe) _PIPE(pipe, _CURAPOS, _CURBPOS_IVB)
|
||||
|
||||
/* Display A control */
|
||||
#define _DSPACNTR 0x70180
|
||||
#define DISPLAY_PLANE_ENABLE (1<<31)
|
||||
@ -2638,6 +2679,140 @@
|
||||
#define _DSPBSURF 0x7119C
|
||||
#define _DSPBTILEOFF 0x711A4
|
||||
|
||||
/* Sprite A control */
|
||||
#define _DVSACNTR 0x72180
|
||||
#define DVS_ENABLE (1<<31)
|
||||
#define DVS_GAMMA_ENABLE (1<<30)
|
||||
#define DVS_PIXFORMAT_MASK (3<<25)
|
||||
#define DVS_FORMAT_YUV422 (0<<25)
|
||||
#define DVS_FORMAT_RGBX101010 (1<<25)
|
||||
#define DVS_FORMAT_RGBX888 (2<<25)
|
||||
#define DVS_FORMAT_RGBX161616 (3<<25)
|
||||
#define DVS_SOURCE_KEY (1<<22)
|
||||
#define DVS_RGB_ORDER_RGBX (1<<20)
|
||||
#define DVS_YUV_BYTE_ORDER_MASK (3<<16)
|
||||
#define DVS_YUV_ORDER_YUYV (0<<16)
|
||||
#define DVS_YUV_ORDER_UYVY (1<<16)
|
||||
#define DVS_YUV_ORDER_YVYU (2<<16)
|
||||
#define DVS_YUV_ORDER_VYUY (3<<16)
|
||||
#define DVS_DEST_KEY (1<<2)
|
||||
#define DVS_TRICKLE_FEED_DISABLE (1<<14)
|
||||
#define DVS_TILED (1<<10)
|
||||
#define _DVSALINOFF 0x72184
|
||||
#define _DVSASTRIDE 0x72188
|
||||
#define _DVSAPOS 0x7218c
|
||||
#define _DVSASIZE 0x72190
|
||||
#define _DVSAKEYVAL 0x72194
|
||||
#define _DVSAKEYMSK 0x72198
|
||||
#define _DVSASURF 0x7219c
|
||||
#define _DVSAKEYMAXVAL 0x721a0
|
||||
#define _DVSATILEOFF 0x721a4
|
||||
#define _DVSASURFLIVE 0x721ac
|
||||
#define _DVSASCALE 0x72204
|
||||
#define DVS_SCALE_ENABLE (1<<31)
|
||||
#define DVS_FILTER_MASK (3<<29)
|
||||
#define DVS_FILTER_MEDIUM (0<<29)
|
||||
#define DVS_FILTER_ENHANCING (1<<29)
|
||||
#define DVS_FILTER_SOFTENING (2<<29)
|
||||
#define DVS_VERTICAL_OFFSET_HALF (1<<28) /* must be enabled below */
|
||||
#define DVS_VERTICAL_OFFSET_ENABLE (1<<27)
|
||||
#define _DVSAGAMC 0x72300
|
||||
|
||||
#define _DVSBCNTR 0x73180
|
||||
#define _DVSBLINOFF 0x73184
|
||||
#define _DVSBSTRIDE 0x73188
|
||||
#define _DVSBPOS 0x7318c
|
||||
#define _DVSBSIZE 0x73190
|
||||
#define _DVSBKEYVAL 0x73194
|
||||
#define _DVSBKEYMSK 0x73198
|
||||
#define _DVSBSURF 0x7319c
|
||||
#define _DVSBKEYMAXVAL 0x731a0
|
||||
#define _DVSBTILEOFF 0x731a4
|
||||
#define _DVSBSURFLIVE 0x731ac
|
||||
#define _DVSBSCALE 0x73204
|
||||
#define _DVSBGAMC 0x73300
|
||||
|
||||
#define DVSCNTR(pipe) _PIPE(pipe, _DVSACNTR, _DVSBCNTR)
|
||||
#define DVSLINOFF(pipe) _PIPE(pipe, _DVSALINOFF, _DVSBLINOFF)
|
||||
#define DVSSTRIDE(pipe) _PIPE(pipe, _DVSASTRIDE, _DVSBSTRIDE)
|
||||
#define DVSPOS(pipe) _PIPE(pipe, _DVSAPOS, _DVSBPOS)
|
||||
#define DVSSURF(pipe) _PIPE(pipe, _DVSASURF, _DVSBSURF)
|
||||
#define DVSKEYMAX(pipe) _PIPE(pipe, _DVSAKEYMAXVAL, _DVSBKEYMAXVAL)
|
||||
#define DVSSIZE(pipe) _PIPE(pipe, _DVSASIZE, _DVSBSIZE)
|
||||
#define DVSSCALE(pipe) _PIPE(pipe, _DVSASCALE, _DVSBSCALE)
|
||||
#define DVSTILEOFF(pipe) _PIPE(pipe, _DVSATILEOFF, _DVSBTILEOFF)
|
||||
#define DVSKEYVAL(pipe) _PIPE(pipe, _DVSAKEYVAL, _DVSBKEYVAL)
|
||||
#define DVSKEYMSK(pipe) _PIPE(pipe, _DVSAKEYMSK, _DVSBKEYMSK)
|
||||
|
||||
#define _SPRA_CTL 0x70280
|
||||
#define SPRITE_ENABLE (1<<31)
|
||||
#define SPRITE_GAMMA_ENABLE (1<<30)
|
||||
#define SPRITE_PIXFORMAT_MASK (7<<25)
|
||||
#define SPRITE_FORMAT_YUV422 (0<<25)
|
||||
#define SPRITE_FORMAT_RGBX101010 (1<<25)
|
||||
#define SPRITE_FORMAT_RGBX888 (2<<25)
|
||||
#define SPRITE_FORMAT_RGBX161616 (3<<25)
|
||||
#define SPRITE_FORMAT_YUV444 (4<<25)
|
||||
#define SPRITE_FORMAT_XR_BGR101010 (5<<25) /* Extended range */
|
||||
#define SPRITE_CSC_ENABLE (1<<24)
|
||||
#define SPRITE_SOURCE_KEY (1<<22)
|
||||
#define SPRITE_RGB_ORDER_RGBX (1<<20) /* only for 888 and 161616 */
|
||||
#define SPRITE_YUV_TO_RGB_CSC_DISABLE (1<<19)
|
||||
#define SPRITE_YUV_CSC_FORMAT_BT709 (1<<18) /* 0 is BT601 */
|
||||
#define SPRITE_YUV_BYTE_ORDER_MASK (3<<16)
|
||||
#define SPRITE_YUV_ORDER_YUYV (0<<16)
|
||||
#define SPRITE_YUV_ORDER_UYVY (1<<16)
|
||||
#define SPRITE_YUV_ORDER_YVYU (2<<16)
|
||||
#define SPRITE_YUV_ORDER_VYUY (3<<16)
|
||||
#define SPRITE_TRICKLE_FEED_DISABLE (1<<14)
|
||||
#define SPRITE_INT_GAMMA_ENABLE (1<<13)
|
||||
#define SPRITE_TILED (1<<10)
|
||||
#define SPRITE_DEST_KEY (1<<2)
|
||||
#define _SPRA_LINOFF 0x70284
|
||||
#define _SPRA_STRIDE 0x70288
|
||||
#define _SPRA_POS 0x7028c
|
||||
#define _SPRA_SIZE 0x70290
|
||||
#define _SPRA_KEYVAL 0x70294
|
||||
#define _SPRA_KEYMSK 0x70298
|
||||
#define _SPRA_SURF 0x7029c
|
||||
#define _SPRA_KEYMAX 0x702a0
|
||||
#define _SPRA_TILEOFF 0x702a4
|
||||
#define _SPRA_SCALE 0x70304
|
||||
#define SPRITE_SCALE_ENABLE (1<<31)
|
||||
#define SPRITE_FILTER_MASK (3<<29)
|
||||
#define SPRITE_FILTER_MEDIUM (0<<29)
|
||||
#define SPRITE_FILTER_ENHANCING (1<<29)
|
||||
#define SPRITE_FILTER_SOFTENING (2<<29)
|
||||
#define SPRITE_VERTICAL_OFFSET_HALF (1<<28) /* must be enabled below */
|
||||
#define SPRITE_VERTICAL_OFFSET_ENABLE (1<<27)
|
||||
#define _SPRA_GAMC 0x70400
|
||||
|
||||
#define _SPRB_CTL 0x71280
|
||||
#define _SPRB_LINOFF 0x71284
|
||||
#define _SPRB_STRIDE 0x71288
|
||||
#define _SPRB_POS 0x7128c
|
||||
#define _SPRB_SIZE 0x71290
|
||||
#define _SPRB_KEYVAL 0x71294
|
||||
#define _SPRB_KEYMSK 0x71298
|
||||
#define _SPRB_SURF 0x7129c
|
||||
#define _SPRB_KEYMAX 0x712a0
|
||||
#define _SPRB_TILEOFF 0x712a4
|
||||
#define _SPRB_SCALE 0x71304
|
||||
#define _SPRB_GAMC 0x71400
|
||||
|
||||
#define SPRCTL(pipe) _PIPE(pipe, _SPRA_CTL, _SPRB_CTL)
|
||||
#define SPRLINOFF(pipe) _PIPE(pipe, _SPRA_LINOFF, _SPRB_LINOFF)
|
||||
#define SPRSTRIDE(pipe) _PIPE(pipe, _SPRA_STRIDE, _SPRB_STRIDE)
|
||||
#define SPRPOS(pipe) _PIPE(pipe, _SPRA_POS, _SPRB_POS)
|
||||
#define SPRSIZE(pipe) _PIPE(pipe, _SPRA_SIZE, _SPRB_SIZE)
|
||||
#define SPRKEYVAL(pipe) _PIPE(pipe, _SPRA_KEYVAL, _SPRB_KEYVAL)
|
||||
#define SPRKEYMSK(pipe) _PIPE(pipe, _SPRA_KEYMSK, _SPRB_KEYMSK)
|
||||
#define SPRSURF(pipe) _PIPE(pipe, _SPRA_SURF, _SPRB_SURF)
|
||||
#define SPRKEYMAX(pipe) _PIPE(pipe, _SPRA_KEYMAX, _SPRB_KEYMAX)
|
||||
#define SPRTILEOFF(pipe) _PIPE(pipe, _SPRA_TILEOFF, _SPRB_TILEOFF)
|
||||
#define SPRSCALE(pipe) _PIPE(pipe, _SPRA_SCALE, _SPRB_SCALE)
|
||||
#define SPRGAMC(pipe) _PIPE(pipe, _SPRA_GAMC, _SPRB_GAMC)
|
||||
|
||||
/* VBIOS regs */
|
||||
#define VGACNTRL 0x71400
|
||||
# define VGA_DISP_DISABLE (1 << 31)
|
||||
@ -2845,6 +3020,10 @@
|
||||
#define ILK_DPFC_DIS1 (1<<8)
|
||||
#define ILK_DPFC_DIS2 (1<<9)
|
||||
|
||||
#define IVB_CHICKEN3 0x4200c
|
||||
# define CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE (1 << 5)
|
||||
# define CHICKEN3_DGMG_DONE_FIX_DISABLE (1 << 2)
|
||||
|
||||
#define DISP_ARB_CTL 0x45000
|
||||
#define DISP_TILE_SURFACE_SWIZZLING (1<<13)
|
||||
#define DISP_FBC_WM_DIS (1<<15)
|
||||
@ -2903,12 +3082,13 @@
|
||||
#define SDEIER 0xc400c
|
||||
|
||||
/* digital port hotplug */
|
||||
#define PCH_PORT_HOTPLUG 0xc4030
|
||||
#define PCH_PORT_HOTPLUG 0xc4030 /* SHOTPLUG_CTL */
|
||||
#define PORTD_HOTPLUG_ENABLE (1 << 20)
|
||||
#define PORTD_PULSE_DURATION_2ms (0)
|
||||
#define PORTD_PULSE_DURATION_4_5ms (1 << 18)
|
||||
#define PORTD_PULSE_DURATION_6ms (2 << 18)
|
||||
#define PORTD_PULSE_DURATION_100ms (3 << 18)
|
||||
#define PORTD_PULSE_DURATION_MASK (3 << 18)
|
||||
#define PORTD_HOTPLUG_NO_DETECT (0)
|
||||
#define PORTD_HOTPLUG_SHORT_DETECT (1 << 16)
|
||||
#define PORTD_HOTPLUG_LONG_DETECT (1 << 17)
|
||||
@ -2917,6 +3097,7 @@
|
||||
#define PORTC_PULSE_DURATION_4_5ms (1 << 10)
|
||||
#define PORTC_PULSE_DURATION_6ms (2 << 10)
|
||||
#define PORTC_PULSE_DURATION_100ms (3 << 10)
|
||||
#define PORTC_PULSE_DURATION_MASK (3 << 10)
|
||||
#define PORTC_HOTPLUG_NO_DETECT (0)
|
||||
#define PORTC_HOTPLUG_SHORT_DETECT (1 << 8)
|
||||
#define PORTC_HOTPLUG_LONG_DETECT (1 << 9)
|
||||
@ -2925,6 +3106,7 @@
|
||||
#define PORTB_PULSE_DURATION_4_5ms (1 << 2)
|
||||
#define PORTB_PULSE_DURATION_6ms (2 << 2)
|
||||
#define PORTB_PULSE_DURATION_100ms (3 << 2)
|
||||
#define PORTB_PULSE_DURATION_MASK (3 << 2)
|
||||
#define PORTB_HOTPLUG_NO_DETECT (0)
|
||||
#define PORTB_HOTPLUG_SHORT_DETECT (1 << 0)
|
||||
#define PORTB_HOTPLUG_LONG_DETECT (1 << 1)
|
||||
@ -2945,15 +3127,15 @@
|
||||
|
||||
#define _PCH_DPLL_A 0xc6014
|
||||
#define _PCH_DPLL_B 0xc6018
|
||||
#define PCH_DPLL(pipe) _PIPE(pipe, _PCH_DPLL_A, _PCH_DPLL_B)
|
||||
#define PCH_DPLL(pipe) (pipe == 0 ? _PCH_DPLL_A : _PCH_DPLL_B)
|
||||
|
||||
#define _PCH_FPA0 0xc6040
|
||||
#define FP_CB_TUNE (0x3<<22)
|
||||
#define _PCH_FPA1 0xc6044
|
||||
#define _PCH_FPB0 0xc6048
|
||||
#define _PCH_FPB1 0xc604c
|
||||
#define PCH_FP0(pipe) _PIPE(pipe, _PCH_FPA0, _PCH_FPB0)
|
||||
#define PCH_FP1(pipe) _PIPE(pipe, _PCH_FPA1, _PCH_FPB1)
|
||||
#define PCH_FP0(pipe) (pipe == 0 ? _PCH_FPA0 : _PCH_FPB0)
|
||||
#define PCH_FP1(pipe) (pipe == 0 ? _PCH_FPA1 : _PCH_FPB1)
|
||||
|
||||
#define PCH_DPLL_TEST 0xc606c
|
||||
|
||||
@ -3167,6 +3349,7 @@
|
||||
#define FDI_LINK_TRAIN_NONE_IVB (3<<8)
|
||||
|
||||
/* both Tx and Rx */
|
||||
#define FDI_COMPOSITE_SYNC (1<<11)
|
||||
#define FDI_LINK_TRAIN_AUTO (1<<10)
|
||||
#define FDI_SCRAMBLING_ENABLE (0<<7)
|
||||
#define FDI_SCRAMBLING_DISABLE (1<<7)
|
||||
@ -3262,10 +3445,10 @@
|
||||
/* or SDVOB */
|
||||
#define HDMIB 0xe1140
|
||||
#define PORT_ENABLE (1 << 31)
|
||||
#define TRANSCODER_A (0)
|
||||
#define TRANSCODER_B (1 << 30)
|
||||
#define TRANSCODER(pipe) ((pipe) << 30)
|
||||
#define TRANSCODER_CPT(pipe) ((pipe) << 29)
|
||||
#define TRANSCODER_MASK (1 << 30)
|
||||
#define TRANSCODER_MASK_CPT (3 << 29)
|
||||
#define COLOR_FORMAT_8bpc (0)
|
||||
#define COLOR_FORMAT_12bpc (3 << 26)
|
||||
#define SDVOB_HOTPLUG_ENABLE (1 << 23)
|
||||
@ -3308,15 +3491,35 @@
|
||||
#define PCH_PP_STATUS 0xc7200
|
||||
#define PCH_PP_CONTROL 0xc7204
|
||||
#define PANEL_UNLOCK_REGS (0xabcd << 16)
|
||||
#define PANEL_UNLOCK_MASK (0xffff << 16)
|
||||
#define EDP_FORCE_VDD (1 << 3)
|
||||
#define EDP_BLC_ENABLE (1 << 2)
|
||||
#define PANEL_POWER_RESET (1 << 1)
|
||||
#define PANEL_POWER_OFF (0 << 0)
|
||||
#define PANEL_POWER_ON (1 << 0)
|
||||
#define PCH_PP_ON_DELAYS 0xc7208
|
||||
#define PANEL_PORT_SELECT_MASK (3 << 30)
|
||||
#define PANEL_PORT_SELECT_LVDS (0 << 30)
|
||||
#define PANEL_PORT_SELECT_DPA (1 << 30)
|
||||
#define EDP_PANEL (1 << 30)
|
||||
#define PANEL_PORT_SELECT_DPC (2 << 30)
|
||||
#define PANEL_PORT_SELECT_DPD (3 << 30)
|
||||
#define PANEL_POWER_UP_DELAY_MASK (0x1fff0000)
|
||||
#define PANEL_POWER_UP_DELAY_SHIFT 16
|
||||
#define PANEL_LIGHT_ON_DELAY_MASK (0x1fff)
|
||||
#define PANEL_LIGHT_ON_DELAY_SHIFT 0
|
||||
|
||||
#define PCH_PP_OFF_DELAYS 0xc720c
|
||||
#define PANEL_POWER_DOWN_DELAY_MASK (0x1fff0000)
|
||||
#define PANEL_POWER_DOWN_DELAY_SHIFT 16
|
||||
#define PANEL_LIGHT_OFF_DELAY_MASK (0x1fff)
|
||||
#define PANEL_LIGHT_OFF_DELAY_SHIFT 0
|
||||
|
||||
#define PCH_PP_DIVISOR 0xc7210
|
||||
#define PP_REFERENCE_DIVIDER_MASK (0xffffff00)
|
||||
#define PP_REFERENCE_DIVIDER_SHIFT 8
|
||||
#define PANEL_POWER_CYCLE_DELAY_MASK (0x1f)
|
||||
#define PANEL_POWER_CYCLE_DELAY_SHIFT 0
|
||||
|
||||
#define PCH_DP_B 0xe4100
|
||||
#define PCH_DPB_AUX_CH_CTL 0xe4110
|
||||
@ -3386,12 +3589,38 @@
|
||||
#define EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B (0x38<<22)
|
||||
#define EDP_LINK_TRAIN_VOL_EMP_MASK_SNB (0x3f<<22)
|
||||
|
||||
/* IVB */
|
||||
#define EDP_LINK_TRAIN_400MV_0DB_IVB (0x24 <<22)
|
||||
#define EDP_LINK_TRAIN_400MV_3_5DB_IVB (0x2a <<22)
|
||||
#define EDP_LINK_TRAIN_400MV_6DB_IVB (0x2f <<22)
|
||||
#define EDP_LINK_TRAIN_600MV_0DB_IVB (0x30 <<22)
|
||||
#define EDP_LINK_TRAIN_600MV_3_5DB_IVB (0x36 <<22)
|
||||
#define EDP_LINK_TRAIN_800MV_0DB_IVB (0x38 <<22)
|
||||
#define EDP_LINK_TRAIN_800MV_3_5DB_IVB (0x33 <<22)
|
||||
|
||||
/* legacy values */
|
||||
#define EDP_LINK_TRAIN_500MV_0DB_IVB (0x00 <<22)
|
||||
#define EDP_LINK_TRAIN_1000MV_0DB_IVB (0x20 <<22)
|
||||
#define EDP_LINK_TRAIN_500MV_3_5DB_IVB (0x02 <<22)
|
||||
#define EDP_LINK_TRAIN_1000MV_3_5DB_IVB (0x22 <<22)
|
||||
#define EDP_LINK_TRAIN_1000MV_6DB_IVB (0x23 <<22)
|
||||
|
||||
#define EDP_LINK_TRAIN_VOL_EMP_MASK_IVB (0x3f<<22)
|
||||
|
||||
#define FORCEWAKE 0xA18C
|
||||
#define FORCEWAKE_ACK 0x130090
|
||||
#define FORCEWAKE_MT 0xa188 /* multi-threaded */
|
||||
#define FORCEWAKE_MT_ACK 0x130040
|
||||
#define ECOBUS 0xa180
|
||||
#define FORCEWAKE_MT_ENABLE (1<<5)
|
||||
|
||||
#define GT_FIFO_FREE_ENTRIES 0x120008
|
||||
#define GT_FIFO_NUM_RESERVED_ENTRIES 20
|
||||
|
||||
#define GEN6_UCGCTL2 0x9404
|
||||
# define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE (1 << 12)
|
||||
# define GEN6_RCCUNIT_CLOCK_GATE_DISABLE (1 << 11)
|
||||
|
||||
#define GEN6_RPNSWREQ 0xA008
|
||||
#define GEN6_TURBO_DISABLE (1<<31)
|
||||
#define GEN6_FREQUENCY(x) ((x)<<25)
|
||||
@ -3413,7 +3642,11 @@
|
||||
#define GEN6_CAGF_MASK (0x7f << GEN6_CAGF_SHIFT)
|
||||
#define GEN6_RP_CONTROL 0xA024
|
||||
#define GEN6_RP_MEDIA_TURBO (1<<11)
|
||||
#define GEN6_RP_USE_NORMAL_FREQ (1<<9)
|
||||
#define GEN6_RP_MEDIA_MODE_MASK (3<<9)
|
||||
#define GEN6_RP_MEDIA_HW_TURBO_MODE (3<<9)
|
||||
#define GEN6_RP_MEDIA_HW_NORMAL_MODE (2<<9)
|
||||
#define GEN6_RP_MEDIA_HW_MODE (1<<9)
|
||||
#define GEN6_RP_MEDIA_SW_MODE (0<<9)
|
||||
#define GEN6_RP_MEDIA_IS_GFX (1<<8)
|
||||
#define GEN6_RP_ENABLE (1<<7)
|
||||
#define GEN6_RP_UP_IDLE_MIN (0x1<<3)
|
||||
@ -3470,4 +3703,43 @@
|
||||
#define GEN6_PCODE_DATA 0x138128
|
||||
#define GEN6_PCODE_FREQ_IA_RATIO_SHIFT 8
|
||||
|
||||
#define GEN6_GT_CORE_STATUS 0x138060
|
||||
#define GEN6_CORE_CPD_STATE_MASK (7<<4)
|
||||
#define GEN6_RCn_MASK 7
|
||||
#define GEN6_RC0 0
|
||||
#define GEN6_RC3 2
|
||||
#define GEN6_RC6 3
|
||||
#define GEN6_RC7 4
|
||||
|
||||
#define G4X_AUD_VID_DID 0x62020
|
||||
#define INTEL_AUDIO_DEVCL 0x808629FB
|
||||
#define INTEL_AUDIO_DEVBLC 0x80862801
|
||||
#define INTEL_AUDIO_DEVCTG 0x80862802
|
||||
|
||||
#define G4X_AUD_CNTL_ST 0x620B4
|
||||
#define G4X_ELDV_DEVCL_DEVBLC (1 << 13)
|
||||
#define G4X_ELDV_DEVCTG (1 << 14)
|
||||
#define G4X_ELD_ADDR (0xf << 5)
|
||||
#define G4X_ELD_ACK (1 << 4)
|
||||
#define G4X_HDMIW_HDMIEDID 0x6210C
|
||||
|
||||
#define IBX_HDMIW_HDMIEDID_A 0xE2050
|
||||
#define IBX_AUD_CNTL_ST_A 0xE20B4
|
||||
#define IBX_ELD_BUFFER_SIZE (0x1f << 10)
|
||||
#define IBX_ELD_ADDRESS (0x1f << 5)
|
||||
#define IBX_ELD_ACK (1 << 4)
|
||||
#define IBX_AUD_CNTL_ST2 0xE20C0
|
||||
#define IBX_ELD_VALIDB (1 << 0)
|
||||
#define IBX_CP_READYB (1 << 1)
|
||||
|
||||
#define CPT_HDMIW_HDMIEDID_A 0xE5050
|
||||
#define CPT_AUD_CNTL_ST_A 0xE50B4
|
||||
#define CPT_AUD_CNTRL_ST2 0xE50C0
|
||||
|
||||
/* These are the 4 32-bit write offset registers for each stream
|
||||
* output buffer. It determines the offset from the
|
||||
* 3DSTATE_SO_BUFFERs that the next streamed vertex output goes to.
|
||||
*/
|
||||
#define GEN7_SO_WRITE_OFFSET(n) (0x5280 + (n) * 4)
|
||||
|
||||
#endif /* _I915_REG_H_ */
|
||||
|
@ -309,6 +309,13 @@ parse_general_features(struct drm_i915_private *dev_priv,
|
||||
dev_priv->lvds_use_ssc = general->enable_ssc;
|
||||
dev_priv->lvds_ssc_freq =
|
||||
intel_bios_ssc_frequency(dev, general->ssc_freq);
|
||||
dev_priv->display_clock_mode = general->display_clock_mode;
|
||||
DRM_DEBUG_KMS("BDB_GENERAL_FEATURES int_tv_support %d int_crt_support %d lvds_use_ssc %d lvds_ssc_freq %d display_clock_mode %d\n",
|
||||
dev_priv->int_tv_support,
|
||||
dev_priv->int_crt_support,
|
||||
dev_priv->lvds_use_ssc,
|
||||
dev_priv->lvds_ssc_freq,
|
||||
dev_priv->display_clock_mode);
|
||||
}
|
||||
}
|
||||
|
||||
@ -381,7 +388,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
|
||||
if (p_child->dvo_port != DEVICE_PORT_DVOB &&
|
||||
p_child->dvo_port != DEVICE_PORT_DVOC) {
|
||||
/* skip the incorrect SDVO port */
|
||||
DRM_DEBUG_KMS("Incorrect SDVO port. Skip it \n");
|
||||
DRM_DEBUG_KMS("Incorrect SDVO port. Skip it\n");
|
||||
continue;
|
||||
}
|
||||
DRM_DEBUG_KMS("the SDVO device with slave addr %2x is found on"
|
||||
@ -396,15 +403,13 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
|
||||
p_mapping->dvo_wiring = p_child->dvo_wiring;
|
||||
p_mapping->ddc_pin = p_child->ddc_pin;
|
||||
p_mapping->i2c_pin = p_child->i2c_pin;
|
||||
p_mapping->i2c_speed = p_child->i2c_speed;
|
||||
p_mapping->initialized = 1;
|
||||
DRM_DEBUG_KMS("SDVO device: dvo=%x, addr=%x, wiring=%d, ddc_pin=%d, i2c_pin=%d, i2c_speed=%d\n",
|
||||
DRM_DEBUG_KMS("SDVO device: dvo=%x, addr=%x, wiring=%d, ddc_pin=%d, i2c_pin=%d\n",
|
||||
p_mapping->dvo_port,
|
||||
p_mapping->slave_addr,
|
||||
p_mapping->dvo_wiring,
|
||||
p_mapping->ddc_pin,
|
||||
p_mapping->i2c_pin,
|
||||
p_mapping->i2c_speed);
|
||||
p_mapping->i2c_pin);
|
||||
} else {
|
||||
DRM_DEBUG_KMS("Maybe one SDVO port is shared by "
|
||||
"two SDVO device.\n");
|
||||
@ -564,7 +569,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
|
||||
count++;
|
||||
}
|
||||
if (!count) {
|
||||
DRM_DEBUG_KMS("no child dev is parsed from VBT \n");
|
||||
DRM_DEBUG_KMS("no child dev is parsed from VBT\n");
|
||||
return;
|
||||
}
|
||||
dev_priv->child_dev = kzalloc(sizeof(*p_child) * count, GFP_KERNEL);
|
||||
@ -610,7 +615,7 @@ init_vbt_defaults(struct drm_i915_private *dev_priv)
|
||||
/* Default to using SSC */
|
||||
dev_priv->lvds_use_ssc = 1;
|
||||
dev_priv->lvds_ssc_freq = intel_bios_ssc_frequency(dev, 1);
|
||||
DRM_DEBUG("Set default to SSC at %dMHz\n", dev_priv->lvds_ssc_freq);
|
||||
DRM_DEBUG_KMS("Set default to SSC at %dMHz\n", dev_priv->lvds_ssc_freq);
|
||||
|
||||
/* eDP data */
|
||||
dev_priv->edp.bpp = 18;
|
||||
@ -639,7 +644,7 @@ intel_parse_bios(struct drm_device *dev)
|
||||
if (dev_priv->opregion.vbt) {
|
||||
struct vbt_header *vbt = dev_priv->opregion.vbt;
|
||||
if (memcmp(vbt->signature, "$VBT", 4) == 0) {
|
||||
DRM_DEBUG_DRIVER("Using VBT from OpRegion: %20s\n",
|
||||
DRM_DEBUG_KMS("Using VBT from OpRegion: %20s\n",
|
||||
vbt->signature);
|
||||
bdb = (struct bdb_header *)((char *)vbt + vbt->bdb_offset);
|
||||
} else
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -69,7 +69,7 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
|
||||
temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
|
||||
temp &= ~ADPA_DAC_ENABLE;
|
||||
|
||||
switch(mode) {
|
||||
switch (mode) {
|
||||
case DRM_MODE_DPMS_ON:
|
||||
temp |= ADPA_DAC_ENABLE;
|
||||
break;
|
||||
@ -152,17 +152,13 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
|
||||
adpa |= ADPA_VSYNC_ACTIVE_HIGH;
|
||||
|
||||
if (intel_crtc->pipe == 0) {
|
||||
/* For CPT allow 3 pipe config, for others just use A or B */
|
||||
if (HAS_PCH_CPT(dev))
|
||||
adpa |= PORT_TRANS_A_SEL_CPT;
|
||||
else
|
||||
adpa |= PORT_TRANS_SEL_CPT(intel_crtc->pipe);
|
||||
else if (intel_crtc->pipe == 0)
|
||||
adpa |= ADPA_PIPE_A_SELECT;
|
||||
} else {
|
||||
if (HAS_PCH_CPT(dev))
|
||||
adpa |= PORT_TRANS_B_SEL_CPT;
|
||||
else
|
||||
adpa |= ADPA_PIPE_B_SELECT;
|
||||
}
|
||||
|
||||
if (!HAS_PCH_SPLIT(dev))
|
||||
I915_WRITE(BCLRPAT(intel_crtc->pipe), 0);
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -26,6 +26,7 @@
|
||||
#define __INTEL_DRV_H__
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include "i915_drm.h"
|
||||
#include "i915_drv.h"
|
||||
#include "drm_crtc.h"
|
||||
#include "drm_crtc_helper.h"
|
||||
@ -35,7 +36,7 @@
|
||||
#define _wait_for(COND, MS, W) ({ \
|
||||
unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \
|
||||
int ret__ = 0; \
|
||||
while (! (COND)) { \
|
||||
while (!(COND)) { \
|
||||
if (time_after(jiffies, timeout__)) { \
|
||||
ret__ = -ETIMEDOUT; \
|
||||
break; \
|
||||
@ -111,6 +112,7 @@
|
||||
/* drm_display_mode->private_flags */
|
||||
#define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0)
|
||||
#define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT)
|
||||
#define INTEL_MODE_DP_FORCE_6BPC (0x10)
|
||||
|
||||
static inline void
|
||||
intel_mode_set_pixel_multiplier(struct drm_display_mode *mode,
|
||||
@ -172,12 +174,37 @@ struct intel_crtc {
|
||||
int16_t cursor_width, cursor_height;
|
||||
bool cursor_visible;
|
||||
unsigned int bpp;
|
||||
|
||||
bool no_pll; /* tertiary pipe for IVB */
|
||||
bool use_pll_a;
|
||||
};
|
||||
|
||||
struct intel_plane {
|
||||
struct drm_plane base;
|
||||
enum pipe pipe;
|
||||
struct drm_i915_gem_object *obj;
|
||||
bool primary_disabled;
|
||||
int max_downscale;
|
||||
u32 lut_r[1024], lut_g[1024], lut_b[1024];
|
||||
void (*update_plane)(struct drm_plane *plane,
|
||||
struct drm_framebuffer *fb,
|
||||
struct drm_i915_gem_object *obj,
|
||||
int crtc_x, int crtc_y,
|
||||
unsigned int crtc_w, unsigned int crtc_h,
|
||||
uint32_t x, uint32_t y,
|
||||
uint32_t src_w, uint32_t src_h);
|
||||
void (*disable_plane)(struct drm_plane *plane);
|
||||
int (*update_colorkey)(struct drm_plane *plane,
|
||||
struct drm_intel_sprite_colorkey *key);
|
||||
void (*get_colorkey)(struct drm_plane *plane,
|
||||
struct drm_intel_sprite_colorkey *key);
|
||||
};
|
||||
|
||||
#define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
|
||||
#define to_intel_connector(x) container_of(x, struct intel_connector, base)
|
||||
#define to_intel_encoder(x) container_of(x, struct intel_encoder, base)
|
||||
#define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)
|
||||
#define to_intel_plane(x) container_of(x, struct intel_plane, base)
|
||||
|
||||
#define DIP_HEADER_SIZE 5
|
||||
|
||||
@ -185,7 +212,7 @@ struct intel_crtc {
|
||||
#define DIP_VERSION_AVI 0x2
|
||||
#define DIP_LEN_AVI 13
|
||||
|
||||
#define DIP_TYPE_SPD 0x3
|
||||
#define DIP_TYPE_SPD 0x83
|
||||
#define DIP_VERSION_SPD 0x1
|
||||
#define DIP_LEN_SPD 25
|
||||
#define DIP_SPD_UNKNOWN 0
|
||||
@ -285,8 +312,9 @@ void
|
||||
intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode);
|
||||
extern bool intel_dpd_is_edp(struct drm_device *dev);
|
||||
extern void intel_edp_link_config (struct intel_encoder *, int *, int *);
|
||||
extern void intel_edp_link_config(struct intel_encoder *, int *, int *);
|
||||
extern bool intel_encoder_is_pch_edp(struct drm_encoder *encoder);
|
||||
extern int intel_plane_init(struct drm_device *dev, enum pipe pipe);
|
||||
|
||||
/* intel_panel.c */
|
||||
extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,
|
||||
@ -305,8 +333,8 @@ extern void intel_panel_destroy_backlight(struct drm_device *dev);
|
||||
extern enum drm_connector_status intel_panel_detect(struct drm_device *dev);
|
||||
|
||||
extern void intel_crtc_load_lut(struct drm_crtc *crtc);
|
||||
extern void intel_encoder_prepare (struct drm_encoder *encoder);
|
||||
extern void intel_encoder_commit (struct drm_encoder *encoder);
|
||||
extern void intel_encoder_prepare(struct drm_encoder *encoder);
|
||||
extern void intel_encoder_commit(struct drm_encoder *encoder);
|
||||
extern void intel_encoder_destroy(struct drm_encoder *encoder);
|
||||
|
||||
static inline struct intel_encoder *intel_attached_encoder(struct drm_connector *connector)
|
||||
@ -338,9 +366,6 @@ extern void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder,
|
||||
struct drm_connector *connector,
|
||||
struct intel_load_detect_pipe *old);
|
||||
|
||||
extern struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB);
|
||||
extern int intel_sdvo_supports_hotplug(struct drm_connector *connector);
|
||||
extern void intel_sdvo_set_hotplug(struct drm_connector *connector, int enable);
|
||||
extern void intelfb_restore(void);
|
||||
extern void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
|
||||
u16 blue, int regno);
|
||||
@ -360,7 +385,7 @@ extern int intel_pin_and_fence_fb_obj(struct drm_device *dev,
|
||||
|
||||
extern int intel_framebuffer_init(struct drm_device *dev,
|
||||
struct intel_framebuffer *ifb,
|
||||
struct drm_mode_fb_cmd *mode_cmd,
|
||||
struct drm_mode_fb_cmd2 *mode_cmd,
|
||||
struct drm_i915_gem_object *obj);
|
||||
extern int intel_fbdev_init(struct drm_device *dev);
|
||||
extern void intel_fbdev_fini(struct drm_device *dev);
|
||||
@ -380,5 +405,25 @@ extern int intel_overlay_attrs(struct drm_device *dev, void *data,
|
||||
extern void intel_fb_output_poll_changed(struct drm_device *dev);
|
||||
extern void intel_fb_restore_mode(struct drm_device *dev);
|
||||
|
||||
extern void assert_pipe(struct drm_i915_private *dev_priv, enum pipe pipe,
|
||||
bool state);
|
||||
#define assert_pipe_enabled(d, p) assert_pipe(d, p, true)
|
||||
#define assert_pipe_disabled(d, p) assert_pipe(d, p, false)
|
||||
|
||||
extern void intel_init_clock_gating(struct drm_device *dev);
|
||||
extern void intel_write_eld(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode);
|
||||
extern void intel_cpt_verify_modeset(struct drm_device *dev, int pipe);
|
||||
|
||||
/* For use by IVB LP watermark workaround in intel_sprite.c */
|
||||
extern void sandybridge_update_wm(struct drm_device *dev);
|
||||
extern void intel_update_sprite_watermarks(struct drm_device *dev, int pipe,
|
||||
uint32_t sprite_width,
|
||||
int pixel_size);
|
||||
|
||||
extern int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
extern int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
|
||||
#endif /* __INTEL_DRV_H__ */
|
||||
|
@ -93,7 +93,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct fb_info *info;
|
||||
struct drm_framebuffer *fb;
|
||||
struct drm_mode_fb_cmd mode_cmd;
|
||||
struct drm_mode_fb_cmd2 mode_cmd;
|
||||
struct drm_i915_gem_object *obj;
|
||||
struct device *device = &dev->pdev->dev;
|
||||
int size, ret;
|
||||
@ -105,11 +105,12 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
|
||||
mode_cmd.width = sizes->surface_width;
|
||||
mode_cmd.height = sizes->surface_height;
|
||||
|
||||
mode_cmd.bpp = sizes->surface_bpp;
|
||||
mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 7) / 8), 64);
|
||||
mode_cmd.depth = sizes->surface_depth;
|
||||
mode_cmd.pitches[0] = ALIGN(mode_cmd.width * ((sizes->surface_bpp + 7) /
|
||||
8), 64);
|
||||
mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
|
||||
sizes->surface_depth);
|
||||
|
||||
size = mode_cmd.pitch * mode_cmd.height;
|
||||
size = mode_cmd.pitches[0] * mode_cmd.height;
|
||||
size = ALIGN(size, PAGE_SIZE);
|
||||
obj = i915_gem_alloc_object(dev, size);
|
||||
if (!obj) {
|
||||
@ -186,7 +187,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
|
||||
|
||||
// memset(info->screen_base, 0, size);
|
||||
|
||||
drm_fb_helper_fill_fix(info, fb->pitch, fb->depth);
|
||||
drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
|
||||
drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height);
|
||||
|
||||
DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x, bo %p\n",
|
||||
@ -206,6 +207,7 @@ out_unref:
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int intel_fb_find_or_create_single(struct drm_fb_helper *helper,
|
||||
struct drm_fb_helper_surface_size *sizes)
|
||||
{
|
||||
|
@ -69,8 +69,7 @@ void intel_dip_infoframe_csum(struct dip_infoframe *frame)
|
||||
frame->checksum = 0;
|
||||
frame->ecc = 0;
|
||||
|
||||
/* Header isn't part of the checksum */
|
||||
for (i = 5; i < frame->len; i++)
|
||||
for (i = 0; i < frame->len + DIP_HEADER_SIZE; i++)
|
||||
sum += data[i];
|
||||
|
||||
frame->checksum = 0x100 - sum;
|
||||
@ -104,7 +103,7 @@ static u32 intel_infoframe_flags(struct dip_infoframe *frame)
|
||||
flags |= VIDEO_DIP_ENABLE_AVI | VIDEO_DIP_FREQ_VSYNC;
|
||||
break;
|
||||
case DIP_TYPE_SPD:
|
||||
flags |= VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_FREQ_2VSYNC;
|
||||
flags |= VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_FREQ_VSYNC;
|
||||
break;
|
||||
default:
|
||||
DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type);
|
||||
@ -165,9 +164,9 @@ static void ironlake_write_infoframe(struct drm_encoder *encoder,
|
||||
|
||||
flags = intel_infoframe_index(frame);
|
||||
|
||||
val &= ~VIDEO_DIP_SELECT_MASK;
|
||||
val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
|
||||
|
||||
I915_WRITE(reg, val | flags);
|
||||
I915_WRITE(reg, VIDEO_DIP_ENABLE | val | flags);
|
||||
|
||||
for (i = 0; i < len; i += 4) {
|
||||
I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data);
|
||||
@ -245,16 +244,17 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder,
|
||||
sdvox |= HDMI_MODE_SELECT;
|
||||
|
||||
if (intel_hdmi->has_audio) {
|
||||
DRM_DEBUG_DRIVER("Enabling HDMI audio on pipe %c\n",
|
||||
pipe_name(intel_crtc->pipe));
|
||||
sdvox |= SDVO_AUDIO_ENABLE;
|
||||
sdvox |= SDVO_NULL_PACKETS_DURING_VSYNC;
|
||||
intel_write_eld(encoder, adjusted_mode);
|
||||
}
|
||||
|
||||
if (intel_crtc->pipe == 1) {
|
||||
if (HAS_PCH_CPT(dev))
|
||||
sdvox |= PORT_TRANS_B_SEL_CPT;
|
||||
else
|
||||
sdvox |= PORT_TRANS_SEL_CPT(intel_crtc->pipe);
|
||||
else if (intel_crtc->pipe == 1)
|
||||
sdvox |= SDVO_PIPE_B_SELECT;
|
||||
}
|
||||
|
||||
I915_WRITE(intel_hdmi->sdvox_reg, sdvox);
|
||||
POSTING_READ(intel_hdmi->sdvox_reg);
|
||||
@ -269,6 +269,10 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
|
||||
u32 temp;
|
||||
u32 enable_bits = SDVO_ENABLE;
|
||||
|
||||
if (intel_hdmi->has_audio)
|
||||
enable_bits |= SDVO_AUDIO_ENABLE;
|
||||
|
||||
temp = I915_READ(intel_hdmi->sdvox_reg);
|
||||
|
||||
@ -281,9 +285,9 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
|
||||
}
|
||||
|
||||
if (mode != DRM_MODE_DPMS_ON) {
|
||||
temp &= ~SDVO_ENABLE;
|
||||
temp &= ~enable_bits;
|
||||
} else {
|
||||
temp |= SDVO_ENABLE;
|
||||
temp |= enable_bits;
|
||||
}
|
||||
|
||||
I915_WRITE(intel_hdmi->sdvox_reg, temp);
|
||||
@ -486,6 +490,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
|
||||
struct intel_encoder *intel_encoder;
|
||||
struct intel_connector *intel_connector;
|
||||
struct intel_hdmi *intel_hdmi;
|
||||
int i;
|
||||
|
||||
intel_hdmi = kzalloc(sizeof(struct intel_hdmi), GFP_KERNEL);
|
||||
if (!intel_hdmi)
|
||||
@ -511,7 +516,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
|
||||
connector->polled = DRM_CONNECTOR_POLL_HPD;
|
||||
connector->interlace_allowed = 0;
|
||||
connector->doublescan_allowed = 0;
|
||||
intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
|
||||
intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
|
||||
|
||||
/* Set up the DDC bus. */
|
||||
if (sdvox_reg == SDVOB) {
|
||||
@ -538,10 +543,14 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
|
||||
|
||||
intel_hdmi->sdvox_reg = sdvox_reg;
|
||||
|
||||
if (!HAS_PCH_SPLIT(dev))
|
||||
if (!HAS_PCH_SPLIT(dev)) {
|
||||
intel_hdmi->write_infoframe = i9xx_write_infoframe;
|
||||
else
|
||||
I915_WRITE(VIDEO_DIP_CTL, 0);
|
||||
} else {
|
||||
intel_hdmi->write_infoframe = ironlake_write_infoframe;
|
||||
for_each_pipe(i)
|
||||
I915_WRITE(TVIDEO_DIP_CTL(i), 0);
|
||||
}
|
||||
|
||||
drm_encoder_helper_add(&intel_encoder->base, &intel_hdmi_helper_funcs);
|
||||
|
||||
|
@ -550,13 +550,7 @@ void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed)
|
||||
{
|
||||
struct intel_gmbus *bus = to_intel_gmbus(adapter);
|
||||
|
||||
/* speed:
|
||||
* 0x0 = 100 KHz
|
||||
* 0x1 = 50 KHz
|
||||
* 0x2 = 400 KHz
|
||||
* 0x3 = 1000 Khz
|
||||
*/
|
||||
bus->reg0 = (bus->reg0 & ~(0x3 << 8)) | (speed << 8);
|
||||
bus->reg0 = (bus->reg0 & ~(0x3 << 8)) | speed;
|
||||
}
|
||||
|
||||
void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit)
|
||||
|
@ -710,6 +710,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = intel_no_lvds_dmi_callback,
|
||||
.ident = "Clientron E830",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Clientron"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "E830"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = intel_no_lvds_dmi_callback,
|
||||
.ident = "Asus EeeBox PC EB1007",
|
||||
.matches = {
|
||||
@ -717,6 +725,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "EB1007"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = intel_no_lvds_dmi_callback,
|
||||
.ident = "Asus AT5NM10T-I",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "AT5NM10T-I"),
|
||||
},
|
||||
},
|
||||
|
||||
{ } /* terminating entry */
|
||||
};
|
||||
@ -890,9 +906,11 @@ bool intel_lvds_init(struct drm_device *dev)
|
||||
intel_encoder->type = INTEL_OUTPUT_LVDS;
|
||||
|
||||
intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT);
|
||||
if (HAS_PCH_SPLIT(dev))
|
||||
intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
|
||||
else
|
||||
intel_encoder->crtc_mask = (1 << 1);
|
||||
if (INTEL_INFO(dev)->gen >= 5)
|
||||
intel_encoder->crtc_mask |= (1 << 0);
|
||||
|
||||
drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs);
|
||||
drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
|
||||
connector->display_info.subpixel_order = SubPixelHorizontalRGB;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/fb.h>
|
||||
#include <drm/drm_edid.h>
|
||||
#include "drmP.h"
|
||||
#include "intel_drv.h"
|
||||
#include "i915_drv.h"
|
||||
@ -74,6 +75,7 @@ int intel_ddc_get_modes(struct drm_connector *connector,
|
||||
if (edid) {
|
||||
drm_mode_connector_update_edid_property(connector, edid);
|
||||
ret = drm_add_edid_modes(connector, edid);
|
||||
drm_edid_to_eld(connector, edid);
|
||||
connector->display_info.raw_edid = NULL;
|
||||
kfree(edid);
|
||||
}
|
||||
|
@ -193,13 +193,10 @@ u32 intel_panel_get_max_backlight(struct drm_device *dev)
|
||||
if (HAS_PCH_SPLIT(dev)) {
|
||||
max >>= 16;
|
||||
} else {
|
||||
if (IS_PINEVIEW(dev)) {
|
||||
if (INTEL_INFO(dev)->gen < 4)
|
||||
max >>= 17;
|
||||
} else {
|
||||
else
|
||||
max >>= 16;
|
||||
if (INTEL_INFO(dev)->gen < 4)
|
||||
max &= ~1;
|
||||
}
|
||||
|
||||
if (is_backlight_combination_mode(dev))
|
||||
max *= 0xff;
|
||||
@ -218,13 +215,12 @@ u32 intel_panel_get_backlight(struct drm_device *dev)
|
||||
val = I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
|
||||
} else {
|
||||
val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
|
||||
if (IS_PINEVIEW(dev))
|
||||
if (INTEL_INFO(dev)->gen < 4)
|
||||
val >>= 1;
|
||||
|
||||
if (is_backlight_combination_mode(dev)){
|
||||
if (is_backlight_combination_mode(dev)) {
|
||||
u8 lbpc;
|
||||
|
||||
val &= ~1;
|
||||
pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc);
|
||||
val *= lbpc;
|
||||
}
|
||||
@ -241,7 +237,7 @@ static void intel_pch_panel_set_backlight(struct drm_device *dev, u32 level)
|
||||
I915_WRITE(BLC_PWM_CPU_CTL, val | level);
|
||||
}
|
||||
|
||||
void intel_panel_set_backlight(struct drm_device *dev, u32 level)
|
||||
static void intel_panel_actually_set_backlight(struct drm_device *dev, u32 level)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u32 tmp;
|
||||
@ -251,7 +247,7 @@ void intel_panel_set_backlight(struct drm_device *dev, u32 level)
|
||||
if (HAS_PCH_SPLIT(dev))
|
||||
return intel_pch_panel_set_backlight(dev, level);
|
||||
|
||||
if (is_backlight_combination_mode(dev)){
|
||||
if (is_backlight_combination_mode(dev)) {
|
||||
u32 max = intel_panel_get_max_backlight(dev);
|
||||
u8 lbpc;
|
||||
|
||||
@ -261,24 +257,27 @@ void intel_panel_set_backlight(struct drm_device *dev, u32 level)
|
||||
}
|
||||
|
||||
tmp = I915_READ(BLC_PWM_CTL);
|
||||
if (IS_PINEVIEW(dev)) {
|
||||
tmp &= ~(BACKLIGHT_DUTY_CYCLE_MASK - 1);
|
||||
if (INTEL_INFO(dev)->gen < 4)
|
||||
level <<= 1;
|
||||
} else
|
||||
tmp &= ~BACKLIGHT_DUTY_CYCLE_MASK;
|
||||
I915_WRITE(BLC_PWM_CTL, tmp | level);
|
||||
}
|
||||
|
||||
void intel_panel_set_backlight(struct drm_device *dev, u32 level)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
dev_priv->backlight_level = level;
|
||||
if (dev_priv->backlight_enabled)
|
||||
intel_panel_actually_set_backlight(dev, level);
|
||||
}
|
||||
|
||||
void intel_panel_disable_backlight(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
if (dev_priv->backlight_enabled) {
|
||||
dev_priv->backlight_level = intel_panel_get_backlight(dev);
|
||||
dev_priv->backlight_enabled = false;
|
||||
}
|
||||
|
||||
intel_panel_set_backlight(dev, 0);
|
||||
intel_panel_actually_set_backlight(dev, 0);
|
||||
}
|
||||
|
||||
void intel_panel_enable_backlight(struct drm_device *dev)
|
||||
@ -288,8 +287,8 @@ void intel_panel_enable_backlight(struct drm_device *dev)
|
||||
if (dev_priv->backlight_level == 0)
|
||||
dev_priv->backlight_level = intel_panel_get_max_backlight(dev);
|
||||
|
||||
intel_panel_set_backlight(dev, dev_priv->backlight_level);
|
||||
dev_priv->backlight_enabled = true;
|
||||
intel_panel_actually_set_backlight(dev, dev_priv->backlight_level);
|
||||
}
|
||||
|
||||
static void intel_panel_init_backlight(struct drm_device *dev)
|
||||
@ -336,7 +335,8 @@ static int intel_panel_update_status(struct backlight_device *bd)
|
||||
static int intel_panel_get_brightness(struct backlight_device *bd)
|
||||
{
|
||||
struct drm_device *dev = bl_get_data(bd);
|
||||
return intel_panel_get_backlight(dev);
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
return dev_priv->backlight_level;
|
||||
}
|
||||
|
||||
static const struct backlight_ops intel_panel_bl_ops = {
|
||||
|
@ -36,6 +36,16 @@
|
||||
//#include "i915_trace.h"
|
||||
#include "intel_drv.h"
|
||||
|
||||
/*
|
||||
* 965+ support PIPE_CONTROL commands, which provide finer grained control
|
||||
* over cache flushing.
|
||||
*/
|
||||
struct pipe_control {
|
||||
struct drm_i915_gem_object *obj;
|
||||
volatile u32 *cpu_page;
|
||||
u32 gtt_offset;
|
||||
};
|
||||
|
||||
static inline int ring_space(struct intel_ring_buffer *ring)
|
||||
{
|
||||
int space = (ring->head & HEAD_ADDR) - (ring->tail + 8);
|
||||
@ -125,6 +135,118 @@ render_ring_flush(struct intel_ring_buffer *ring,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits a PIPE_CONTROL with a non-zero post-sync operation, for
|
||||
* implementing two workarounds on gen6. From section 1.4.7.1
|
||||
* "PIPE_CONTROL" of the Sandy Bridge PRM volume 2 part 1:
|
||||
*
|
||||
* [DevSNB-C+{W/A}] Before any depth stall flush (including those
|
||||
* produced by non-pipelined state commands), software needs to first
|
||||
* send a PIPE_CONTROL with no bits set except Post-Sync Operation !=
|
||||
* 0.
|
||||
*
|
||||
* [Dev-SNB{W/A}]: Before a PIPE_CONTROL with Write Cache Flush Enable
|
||||
* =1, a PIPE_CONTROL with any non-zero post-sync-op is required.
|
||||
*
|
||||
* And the workaround for these two requires this workaround first:
|
||||
*
|
||||
* [Dev-SNB{W/A}]: Pipe-control with CS-stall bit set must be sent
|
||||
* BEFORE the pipe-control with a post-sync op and no write-cache
|
||||
* flushes.
|
||||
*
|
||||
* And this last workaround is tricky because of the requirements on
|
||||
* that bit. From section 1.4.7.2.3 "Stall" of the Sandy Bridge PRM
|
||||
* volume 2 part 1:
|
||||
*
|
||||
* "1 of the following must also be set:
|
||||
* - Render Target Cache Flush Enable ([12] of DW1)
|
||||
* - Depth Cache Flush Enable ([0] of DW1)
|
||||
* - Stall at Pixel Scoreboard ([1] of DW1)
|
||||
* - Depth Stall ([13] of DW1)
|
||||
* - Post-Sync Operation ([13] of DW1)
|
||||
* - Notify Enable ([8] of DW1)"
|
||||
*
|
||||
* The cache flushes require the workaround flush that triggered this
|
||||
* one, so we can't use it. Depth stall would trigger the same.
|
||||
* Post-sync nonzero is what triggered this second workaround, so we
|
||||
* can't use that one either. Notify enable is IRQs, which aren't
|
||||
* really our business. That leaves only stall at scoreboard.
|
||||
*/
|
||||
static int
|
||||
intel_emit_post_sync_nonzero_flush(struct intel_ring_buffer *ring)
|
||||
{
|
||||
struct pipe_control *pc = ring->private;
|
||||
u32 scratch_addr = pc->gtt_offset + 128;
|
||||
int ret;
|
||||
|
||||
|
||||
ret = intel_ring_begin(ring, 6);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(5));
|
||||
intel_ring_emit(ring, PIPE_CONTROL_CS_STALL |
|
||||
PIPE_CONTROL_STALL_AT_SCOREBOARD);
|
||||
intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); /* address */
|
||||
intel_ring_emit(ring, 0); /* low dword */
|
||||
intel_ring_emit(ring, 0); /* high dword */
|
||||
intel_ring_emit(ring, MI_NOOP);
|
||||
intel_ring_advance(ring);
|
||||
|
||||
ret = intel_ring_begin(ring, 6);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(5));
|
||||
intel_ring_emit(ring, PIPE_CONTROL_QW_WRITE);
|
||||
intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); /* address */
|
||||
intel_ring_emit(ring, 0);
|
||||
intel_ring_emit(ring, 0);
|
||||
intel_ring_emit(ring, MI_NOOP);
|
||||
intel_ring_advance(ring);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
gen6_render_ring_flush(struct intel_ring_buffer *ring,
|
||||
u32 invalidate_domains, u32 flush_domains)
|
||||
{
|
||||
u32 flags = 0;
|
||||
struct pipe_control *pc = ring->private;
|
||||
u32 scratch_addr = pc->gtt_offset + 128;
|
||||
int ret;
|
||||
|
||||
/* Force SNB workarounds for PIPE_CONTROL flushes */
|
||||
intel_emit_post_sync_nonzero_flush(ring);
|
||||
|
||||
/* Just flush everything. Experiments have shown that reducing the
|
||||
* number of bits based on the write domains has little performance
|
||||
* impact.
|
||||
*/
|
||||
flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
|
||||
flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE;
|
||||
flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE;
|
||||
flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
|
||||
flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE;
|
||||
flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE;
|
||||
flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE;
|
||||
|
||||
ret = intel_ring_begin(ring, 6);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(5));
|
||||
intel_ring_emit(ring, flags);
|
||||
intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT);
|
||||
intel_ring_emit(ring, 0); /* lower dword */
|
||||
intel_ring_emit(ring, 0); /* uppwer dword */
|
||||
intel_ring_emit(ring, MI_NOOP);
|
||||
intel_ring_advance(ring);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ring_write_tail(struct intel_ring_buffer *ring,
|
||||
u32 value)
|
||||
{
|
||||
@ -205,16 +327,6 @@ static int init_ring_common(struct intel_ring_buffer *ring)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 965+ support PIPE_CONTROL commands, which provide finer grained control
|
||||
* over cache flushing.
|
||||
*/
|
||||
struct pipe_control {
|
||||
struct drm_i915_gem_object *obj;
|
||||
volatile u32 *cpu_page;
|
||||
u32 gtt_offset;
|
||||
};
|
||||
|
||||
static int
|
||||
init_pipe_control(struct intel_ring_buffer *ring)
|
||||
{
|
||||
@ -295,13 +407,17 @@ static int init_render_ring(struct intel_ring_buffer *ring)
|
||||
GFX_MODE_ENABLE(GFX_REPLAY_MODE));
|
||||
}
|
||||
|
||||
if (INTEL_INFO(dev)->gen >= 6) {
|
||||
} else if (IS_GEN5(dev)) {
|
||||
if (INTEL_INFO(dev)->gen >= 5) {
|
||||
ret = init_pipe_control(ring);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (INTEL_INFO(dev)->gen >= 6) {
|
||||
I915_WRITE(INSTPM,
|
||||
INSTPM_FORCE_ORDERING << 16 | INSTPM_FORCE_ORDERING);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -314,83 +430,131 @@ static void render_ring_cleanup(struct intel_ring_buffer *ring)
|
||||
}
|
||||
|
||||
static void
|
||||
update_semaphore(struct intel_ring_buffer *ring, int i, u32 seqno)
|
||||
update_mboxes(struct intel_ring_buffer *ring,
|
||||
u32 seqno,
|
||||
u32 mmio_offset)
|
||||
{
|
||||
struct drm_device *dev = ring->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int id;
|
||||
|
||||
/*
|
||||
* cs -> 1 = vcs, 0 = bcs
|
||||
* vcs -> 1 = bcs, 0 = cs,
|
||||
* bcs -> 1 = cs, 0 = vcs.
|
||||
*/
|
||||
id = ring - dev_priv->ring;
|
||||
id += 2 - i;
|
||||
id %= 3;
|
||||
|
||||
intel_ring_emit(ring,
|
||||
MI_SEMAPHORE_MBOX |
|
||||
intel_ring_emit(ring, MI_SEMAPHORE_MBOX |
|
||||
MI_SEMAPHORE_GLOBAL_GTT |
|
||||
MI_SEMAPHORE_REGISTER |
|
||||
MI_SEMAPHORE_UPDATE);
|
||||
intel_ring_emit(ring, seqno);
|
||||
intel_ring_emit(ring,
|
||||
RING_SYNC_0(dev_priv->ring[id].mmio_base) + 4*i);
|
||||
intel_ring_emit(ring, mmio_offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* gen6_add_request - Update the semaphore mailbox registers
|
||||
*
|
||||
* @ring - ring that is adding a request
|
||||
* @seqno - return seqno stuck into the ring
|
||||
*
|
||||
* Update the mailbox registers in the *other* rings with the current seqno.
|
||||
* This acts like a signal in the canonical semaphore.
|
||||
*/
|
||||
static int
|
||||
gen6_add_request(struct intel_ring_buffer *ring,
|
||||
u32 *result)
|
||||
u32 *seqno)
|
||||
{
|
||||
u32 seqno;
|
||||
u32 mbox1_reg;
|
||||
u32 mbox2_reg;
|
||||
int ret;
|
||||
|
||||
ret = intel_ring_begin(ring, 10);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
seqno = i915_gem_get_seqno(ring->dev);
|
||||
update_semaphore(ring, 0, seqno);
|
||||
update_semaphore(ring, 1, seqno);
|
||||
mbox1_reg = ring->signal_mbox[0];
|
||||
mbox2_reg = ring->signal_mbox[1];
|
||||
|
||||
*seqno = i915_gem_get_seqno(ring->dev);
|
||||
|
||||
update_mboxes(ring, *seqno, mbox1_reg);
|
||||
update_mboxes(ring, *seqno, mbox2_reg);
|
||||
intel_ring_emit(ring, MI_STORE_DWORD_INDEX);
|
||||
intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
|
||||
intel_ring_emit(ring, seqno);
|
||||
intel_ring_emit(ring, *seqno);
|
||||
intel_ring_emit(ring, MI_USER_INTERRUPT);
|
||||
intel_ring_advance(ring);
|
||||
|
||||
*result = seqno;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
intel_ring_sync(struct intel_ring_buffer *ring,
|
||||
struct intel_ring_buffer *to,
|
||||
/**
|
||||
* intel_ring_sync - sync the waiter to the signaller on seqno
|
||||
*
|
||||
* @waiter - ring that is waiting
|
||||
* @signaller - ring which has, or will signal
|
||||
* @seqno - seqno which the waiter will block on
|
||||
*/
|
||||
static int
|
||||
intel_ring_sync(struct intel_ring_buffer *waiter,
|
||||
struct intel_ring_buffer *signaller,
|
||||
int ring,
|
||||
u32 seqno)
|
||||
{
|
||||
int ret;
|
||||
u32 dw1 = MI_SEMAPHORE_MBOX |
|
||||
MI_SEMAPHORE_COMPARE |
|
||||
MI_SEMAPHORE_REGISTER;
|
||||
|
||||
ret = intel_ring_begin(ring, 4);
|
||||
ret = intel_ring_begin(waiter, 4);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
intel_ring_emit(ring,
|
||||
MI_SEMAPHORE_MBOX |
|
||||
MI_SEMAPHORE_REGISTER |
|
||||
intel_ring_sync_index(ring, to) << 17 |
|
||||
MI_SEMAPHORE_COMPARE);
|
||||
intel_ring_emit(ring, seqno);
|
||||
intel_ring_emit(ring, 0);
|
||||
intel_ring_emit(ring, MI_NOOP);
|
||||
intel_ring_advance(ring);
|
||||
intel_ring_emit(waiter, dw1 | signaller->semaphore_register[ring]);
|
||||
intel_ring_emit(waiter, seqno);
|
||||
intel_ring_emit(waiter, 0);
|
||||
intel_ring_emit(waiter, MI_NOOP);
|
||||
intel_ring_advance(waiter);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* VCS->RCS (RVSYNC) or BCS->RCS (RBSYNC) */
|
||||
int
|
||||
render_ring_sync_to(struct intel_ring_buffer *waiter,
|
||||
struct intel_ring_buffer *signaller,
|
||||
u32 seqno)
|
||||
{
|
||||
// WARN_ON(signaller->semaphore_register[RCS] == MI_SEMAPHORE_SYNC_INVALID);
|
||||
return intel_ring_sync(waiter,
|
||||
signaller,
|
||||
RCS,
|
||||
seqno);
|
||||
}
|
||||
|
||||
/* RCS->VCS (VRSYNC) or BCS->VCS (VBSYNC) */
|
||||
int
|
||||
gen6_bsd_ring_sync_to(struct intel_ring_buffer *waiter,
|
||||
struct intel_ring_buffer *signaller,
|
||||
u32 seqno)
|
||||
{
|
||||
// WARN_ON(signaller->semaphore_register[VCS] == MI_SEMAPHORE_SYNC_INVALID);
|
||||
return intel_ring_sync(waiter,
|
||||
signaller,
|
||||
VCS,
|
||||
seqno);
|
||||
}
|
||||
|
||||
/* RCS->BCS (BRSYNC) or VCS->BCS (BVSYNC) */
|
||||
int
|
||||
gen6_blt_ring_sync_to(struct intel_ring_buffer *waiter,
|
||||
struct intel_ring_buffer *signaller,
|
||||
u32 seqno)
|
||||
{
|
||||
// WARN_ON(signaller->semaphore_register[BCS] == MI_SEMAPHORE_SYNC_INVALID);
|
||||
return intel_ring_sync(waiter,
|
||||
signaller,
|
||||
BCS,
|
||||
seqno);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define PIPE_CONTROL_FLUSH(ring__, addr__) \
|
||||
do { \
|
||||
intel_ring_emit(ring__, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \
|
||||
PIPE_CONTROL_DEPTH_STALL | 2); \
|
||||
intel_ring_emit(ring__, GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE | \
|
||||
PIPE_CONTROL_DEPTH_STALL); \
|
||||
intel_ring_emit(ring__, (addr__) | PIPE_CONTROL_GLOBAL_GTT); \
|
||||
intel_ring_emit(ring__, 0); \
|
||||
intel_ring_emit(ring__, 0); \
|
||||
@ -418,8 +582,9 @@ pc_render_add_request(struct intel_ring_buffer *ring,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
|
||||
PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH);
|
||||
intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE |
|
||||
PIPE_CONTROL_WRITE_FLUSH |
|
||||
PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE);
|
||||
intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT);
|
||||
intel_ring_emit(ring, seqno);
|
||||
intel_ring_emit(ring, 0);
|
||||
@ -434,8 +599,9 @@ pc_render_add_request(struct intel_ring_buffer *ring,
|
||||
PIPE_CONTROL_FLUSH(ring, scratch_addr);
|
||||
scratch_addr += 128;
|
||||
PIPE_CONTROL_FLUSH(ring, scratch_addr);
|
||||
intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
|
||||
PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH |
|
||||
intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE |
|
||||
PIPE_CONTROL_WRITE_FLUSH |
|
||||
PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE |
|
||||
PIPE_CONTROL_NOTIFY);
|
||||
intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT);
|
||||
intel_ring_emit(ring, seqno);
|
||||
@ -468,6 +634,19 @@ render_ring_add_request(struct intel_ring_buffer *ring,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32
|
||||
gen6_ring_get_seqno(struct intel_ring_buffer *ring)
|
||||
{
|
||||
struct drm_device *dev = ring->dev;
|
||||
|
||||
/* Workaround to force correct ordering between irq and seqno writes on
|
||||
* ivb (and maybe also on snb) by reading from a CS register (like
|
||||
* ACTHD) before reading the status page. */
|
||||
if (IS_GEN7(dev))
|
||||
intel_ring_get_active_head(ring);
|
||||
return intel_read_status_page(ring, I915_GEM_HWS_INDEX);
|
||||
}
|
||||
|
||||
static u32
|
||||
ring_get_seqno(struct intel_ring_buffer *ring)
|
||||
{
|
||||
@ -513,7 +692,6 @@ i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask)
|
||||
POSTING_READ(IMR);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static bool
|
||||
render_ring_get_irq(struct intel_ring_buffer *ring)
|
||||
{
|
||||
@ -553,7 +731,6 @@ render_ring_put_irq(struct intel_ring_buffer *ring)
|
||||
}
|
||||
spin_unlock(&ring->irq_lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
void intel_ring_setup_status_page(struct intel_ring_buffer *ring)
|
||||
{
|
||||
@ -626,8 +803,6 @@ ring_add_request(struct intel_ring_buffer *ring,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
static bool
|
||||
gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag)
|
||||
{
|
||||
@ -637,6 +812,12 @@ gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag)
|
||||
if (!dev->irq_enabled)
|
||||
return false;
|
||||
|
||||
/* It looks like we need to prevent the gt from suspending while waiting
|
||||
* for an notifiy irq, otherwise irqs seem to get lost on at least the
|
||||
* blt/bsd rings on ivb. */
|
||||
if (IS_GEN7(dev))
|
||||
gen6_gt_force_wake_get(dev_priv);
|
||||
|
||||
spin_lock(&ring->irq_lock);
|
||||
if (ring->irq_refcount++ == 0) {
|
||||
ring->irq_mask &= ~rflag;
|
||||
@ -661,6 +842,9 @@ gen6_ring_put_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag)
|
||||
ironlake_disable_irq(dev_priv, gflag);
|
||||
}
|
||||
spin_unlock(&ring->irq_lock);
|
||||
|
||||
if (IS_GEN7(dev))
|
||||
gen6_gt_force_wake_put(dev_priv);
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -698,7 +882,6 @@ bsd_ring_put_irq(struct intel_ring_buffer *ring)
|
||||
}
|
||||
spin_unlock(&ring->irq_lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
ring_dispatch_execbuffer(struct intel_ring_buffer *ring, u32 offset, u32 length)
|
||||
@ -828,7 +1011,7 @@ int intel_init_ring_buffer(struct drm_device *dev,
|
||||
INIT_LIST_HEAD(&ring->gpu_write_list);
|
||||
|
||||
// init_waitqueue_head(&ring->irq_queue);
|
||||
// spin_lock_init(&ring->irq_lock);
|
||||
spin_lock_init(&ring->irq_lock);
|
||||
ring->irq_mask = ~0;
|
||||
|
||||
if (I915_NEED_GFX_HWS(dev)) {
|
||||
@ -1038,11 +1221,16 @@ static const struct intel_ring_buffer render_ring = {
|
||||
.write_tail = ring_write_tail,
|
||||
.flush = render_ring_flush,
|
||||
.add_request = render_ring_add_request,
|
||||
// .get_seqno = ring_get_seqno,
|
||||
// .irq_get = render_ring_get_irq,
|
||||
// .irq_put = render_ring_put_irq,
|
||||
.get_seqno = ring_get_seqno,
|
||||
.irq_get = render_ring_get_irq,
|
||||
.irq_put = render_ring_put_irq,
|
||||
.dispatch_execbuffer = render_ring_dispatch_execbuffer,
|
||||
// .cleanup = render_ring_cleanup,
|
||||
.sync_to = render_ring_sync_to,
|
||||
.semaphore_register = {MI_SEMAPHORE_SYNC_INVALID,
|
||||
MI_SEMAPHORE_SYNC_RV,
|
||||
MI_SEMAPHORE_SYNC_RB},
|
||||
.signal_mbox = {GEN6_VRSYNC, GEN6_BRSYNC},
|
||||
};
|
||||
|
||||
/* ring buffer for bit-stream decoder */
|
||||
@ -1056,9 +1244,9 @@ static const struct intel_ring_buffer bsd_ring = {
|
||||
.write_tail = ring_write_tail,
|
||||
.flush = bsd_ring_flush,
|
||||
.add_request = ring_add_request,
|
||||
// .get_seqno = ring_get_seqno,
|
||||
// .irq_get = bsd_ring_get_irq,
|
||||
// .irq_put = bsd_ring_put_irq,
|
||||
.get_seqno = ring_get_seqno,
|
||||
.irq_get = bsd_ring_get_irq,
|
||||
.irq_put = bsd_ring_put_irq,
|
||||
.dispatch_execbuffer = ring_dispatch_execbuffer,
|
||||
};
|
||||
|
||||
@ -1124,8 +1312,6 @@ gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
static bool
|
||||
gen6_render_ring_get_irq(struct intel_ring_buffer *ring)
|
||||
{
|
||||
@ -1158,8 +1344,6 @@ gen6_bsd_ring_put_irq(struct intel_ring_buffer *ring)
|
||||
GEN6_BSD_USER_INTERRUPT);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ring buffer for Video Codec for Gen6+ */
|
||||
static const struct intel_ring_buffer gen6_bsd_ring = {
|
||||
.name = "gen6 bsd ring",
|
||||
@ -1170,13 +1354,17 @@ static const struct intel_ring_buffer gen6_bsd_ring = {
|
||||
.write_tail = gen6_bsd_ring_write_tail,
|
||||
.flush = gen6_ring_flush,
|
||||
.add_request = gen6_add_request,
|
||||
// .get_seqno = ring_get_seqno,
|
||||
// .irq_get = gen6_bsd_ring_get_irq,
|
||||
// .irq_put = gen6_bsd_ring_put_irq,
|
||||
.get_seqno = gen6_ring_get_seqno,
|
||||
.irq_get = gen6_bsd_ring_get_irq,
|
||||
.irq_put = gen6_bsd_ring_put_irq,
|
||||
.dispatch_execbuffer = gen6_ring_dispatch_execbuffer,
|
||||
.sync_to = gen6_bsd_ring_sync_to,
|
||||
.semaphore_register = {MI_SEMAPHORE_SYNC_VR,
|
||||
MI_SEMAPHORE_SYNC_INVALID,
|
||||
MI_SEMAPHORE_SYNC_VB},
|
||||
.signal_mbox = {GEN6_RVSYNC, GEN6_BVSYNC},
|
||||
};
|
||||
|
||||
#if 0
|
||||
/* Blitter support (SandyBridge+) */
|
||||
|
||||
static bool
|
||||
@ -1194,7 +1382,6 @@ blt_ring_put_irq(struct intel_ring_buffer *ring)
|
||||
GT_BLT_USER_INTERRUPT,
|
||||
GEN6_BLITTER_USER_INTERRUPT);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Workaround for some stepping of SNB,
|
||||
@ -1302,11 +1489,16 @@ static const struct intel_ring_buffer gen6_blt_ring = {
|
||||
.write_tail = ring_write_tail,
|
||||
.flush = blt_ring_flush,
|
||||
.add_request = gen6_add_request,
|
||||
// .get_seqno = ring_get_seqno,
|
||||
// .irq_get = blt_ring_get_irq,
|
||||
// .irq_put = blt_ring_put_irq,
|
||||
.get_seqno = gen6_ring_get_seqno,
|
||||
.irq_get = blt_ring_get_irq,
|
||||
.irq_put = blt_ring_put_irq,
|
||||
.dispatch_execbuffer = gen6_ring_dispatch_execbuffer,
|
||||
// .cleanup = blt_ring_cleanup,
|
||||
.sync_to = gen6_blt_ring_sync_to,
|
||||
.semaphore_register = {MI_SEMAPHORE_SYNC_BR,
|
||||
MI_SEMAPHORE_SYNC_BV,
|
||||
MI_SEMAPHORE_SYNC_INVALID},
|
||||
.signal_mbox = {GEN6_RBSYNC, GEN6_VBSYNC},
|
||||
};
|
||||
|
||||
int intel_init_render_ring_buffer(struct drm_device *dev)
|
||||
@ -1317,11 +1509,13 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
|
||||
*ring = render_ring;
|
||||
if (INTEL_INFO(dev)->gen >= 6) {
|
||||
ring->add_request = gen6_add_request;
|
||||
// ring->irq_get = gen6_render_ring_get_irq;
|
||||
// ring->irq_put = gen6_render_ring_put_irq;
|
||||
ring->flush = gen6_render_ring_flush;
|
||||
ring->irq_get = gen6_render_ring_get_irq;
|
||||
ring->irq_put = gen6_render_ring_put_irq;
|
||||
ring->get_seqno = gen6_ring_get_seqno;
|
||||
} else if (IS_GEN5(dev)) {
|
||||
ring->add_request = pc_render_add_request;
|
||||
// ring->get_seqno = pc_render_get_seqno;
|
||||
ring->get_seqno = pc_render_get_seqno;
|
||||
}
|
||||
|
||||
if (!I915_NEED_GFX_HWS(dev)) {
|
||||
|
@ -75,7 +75,12 @@ struct intel_ring_buffer {
|
||||
int (*dispatch_execbuffer)(struct intel_ring_buffer *ring,
|
||||
u32 offset, u32 length);
|
||||
void (*cleanup)(struct intel_ring_buffer *ring);
|
||||
int (*sync_to)(struct intel_ring_buffer *ring,
|
||||
struct intel_ring_buffer *to,
|
||||
u32 seqno);
|
||||
|
||||
u32 semaphore_register[3]; /*our mbox written by others */
|
||||
u32 signal_mbox[2]; /* mboxes this ring signals to */
|
||||
/**
|
||||
* List of objects currently involved in rendering from the
|
||||
* ringbuffer.
|
||||
@ -180,9 +185,6 @@ static inline void intel_ring_emit(struct intel_ring_buffer *ring,
|
||||
void intel_ring_advance(struct intel_ring_buffer *ring);
|
||||
|
||||
u32 intel_ring_get_seqno(struct intel_ring_buffer *ring);
|
||||
int intel_ring_sync(struct intel_ring_buffer *ring,
|
||||
struct intel_ring_buffer *to,
|
||||
u32 seqno);
|
||||
|
||||
int intel_init_render_ring_buffer(struct drm_device *dev);
|
||||
int intel_init_bsd_ring_buffer(struct drm_device *dev);
|
||||
|
@ -58,6 +58,7 @@ unsigned int hweight16(unsigned int w)
|
||||
#define IS_TMDS(c) (c->output_flag & SDVO_TMDS_MASK)
|
||||
#define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK)
|
||||
#define IS_TV_OR_LVDS(c) (c->output_flag & (SDVO_TV_MASK | SDVO_LVDS_MASK))
|
||||
#define IS_DIGITAL(c) (c->output_flag & (SDVO_TMDS_MASK | SDVO_LVDS_MASK))
|
||||
|
||||
|
||||
static const char *tv_format_names[] = {
|
||||
@ -101,6 +102,11 @@ struct intel_sdvo {
|
||||
*/
|
||||
uint16_t attached_output;
|
||||
|
||||
/*
|
||||
* Hotplug activation bits for this device
|
||||
*/
|
||||
uint8_t hotplug_active[2];
|
||||
|
||||
/**
|
||||
* This is used to select the color range of RBG outputs in HDMI mode.
|
||||
* It is only valid when using TMDS encoding and 8 bit per color mode.
|
||||
@ -1068,15 +1074,13 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
|
||||
|
||||
/* Set the SDVO control regs. */
|
||||
if (INTEL_INFO(dev)->gen >= 4) {
|
||||
sdvox = 0;
|
||||
/* The real mode polarity is set by the SDVO commands, using
|
||||
* struct intel_sdvo_dtd. */
|
||||
sdvox = SDVO_VSYNC_ACTIVE_HIGH | SDVO_HSYNC_ACTIVE_HIGH;
|
||||
if (intel_sdvo->is_hdmi)
|
||||
sdvox |= intel_sdvo->color_range;
|
||||
if (INTEL_INFO(dev)->gen < 5)
|
||||
sdvox |= SDVO_BORDER_ENABLE;
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
|
||||
sdvox |= SDVO_VSYNC_ACTIVE_HIGH;
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
|
||||
sdvox |= SDVO_HSYNC_ACTIVE_HIGH;
|
||||
} else {
|
||||
sdvox = I915_READ(intel_sdvo->sdvo_reg);
|
||||
switch (intel_sdvo->sdvo_reg) {
|
||||
@ -1089,8 +1093,12 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
|
||||
}
|
||||
sdvox |= (9 << 19) | SDVO_BORDER_ENABLE;
|
||||
}
|
||||
if (intel_crtc->pipe == 1)
|
||||
sdvox |= SDVO_PIPE_B_SELECT;
|
||||
|
||||
if (INTEL_PCH_TYPE(dev) >= PCH_CPT)
|
||||
sdvox |= TRANSCODER_CPT(intel_crtc->pipe);
|
||||
else
|
||||
sdvox |= TRANSCODER(intel_crtc->pipe);
|
||||
|
||||
if (intel_sdvo->has_hdmi_audio)
|
||||
sdvox |= SDVO_AUDIO_ENABLE;
|
||||
|
||||
@ -1217,81 +1225,26 @@ static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct in
|
||||
return true;
|
||||
}
|
||||
|
||||
/* No use! */
|
||||
#if 0
|
||||
struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB)
|
||||
{
|
||||
struct drm_connector *connector = NULL;
|
||||
struct intel_sdvo *iout = NULL;
|
||||
struct intel_sdvo *sdvo;
|
||||
|
||||
/* find the sdvo connector */
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
iout = to_intel_sdvo(connector);
|
||||
|
||||
if (iout->type != INTEL_OUTPUT_SDVO)
|
||||
continue;
|
||||
|
||||
sdvo = iout->dev_priv;
|
||||
|
||||
if (sdvo->sdvo_reg == SDVOB && sdvoB)
|
||||
return connector;
|
||||
|
||||
if (sdvo->sdvo_reg == SDVOC && !sdvoB)
|
||||
return connector;
|
||||
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int intel_sdvo_supports_hotplug(struct drm_connector *connector)
|
||||
static int intel_sdvo_supports_hotplug(struct intel_sdvo *intel_sdvo)
|
||||
{
|
||||
u8 response[2];
|
||||
u8 status;
|
||||
struct intel_sdvo *intel_sdvo;
|
||||
DRM_DEBUG_KMS("\n");
|
||||
|
||||
if (!connector)
|
||||
return 0;
|
||||
|
||||
intel_sdvo = to_intel_sdvo(connector);
|
||||
|
||||
return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT,
|
||||
&response, 2) && response[0];
|
||||
}
|
||||
|
||||
void intel_sdvo_set_hotplug(struct drm_connector *connector, int on)
|
||||
static void intel_sdvo_enable_hotplug(struct intel_encoder *encoder)
|
||||
{
|
||||
u8 response[2];
|
||||
u8 status;
|
||||
struct intel_sdvo *intel_sdvo = to_intel_sdvo(connector);
|
||||
struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base);
|
||||
|
||||
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
|
||||
intel_sdvo_read_response(intel_sdvo, &response, 2);
|
||||
|
||||
if (on) {
|
||||
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
|
||||
status = intel_sdvo_read_response(intel_sdvo, &response, 2);
|
||||
|
||||
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
|
||||
} else {
|
||||
response[0] = 0;
|
||||
response[1] = 0;
|
||||
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
|
||||
}
|
||||
|
||||
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
|
||||
intel_sdvo_read_response(intel_sdvo, &response, 2);
|
||||
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &intel_sdvo->hotplug_active, 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool
|
||||
intel_sdvo_multifunc_encoder(struct intel_sdvo *intel_sdvo)
|
||||
{
|
||||
/* Is there more than one type of output? */
|
||||
int caps = intel_sdvo->caps.output_flags & 0xf;
|
||||
return caps & -caps;
|
||||
return hweight16(intel_sdvo->caps.output_flags) > 1;
|
||||
}
|
||||
|
||||
static struct edid *
|
||||
@ -1312,7 +1265,7 @@ intel_sdvo_get_analog_edid(struct drm_connector *connector)
|
||||
}
|
||||
|
||||
enum drm_connector_status
|
||||
intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
|
||||
intel_sdvo_tmds_sink_detect(struct drm_connector *connector)
|
||||
{
|
||||
struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
|
||||
enum drm_connector_status status;
|
||||
@ -1372,6 +1325,18 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
|
||||
return status;
|
||||
}
|
||||
|
||||
static bool
|
||||
intel_sdvo_connector_matches_edid(struct intel_sdvo_connector *sdvo,
|
||||
struct edid *edid)
|
||||
{
|
||||
bool monitor_is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL);
|
||||
bool connector_is_digital = !!IS_DIGITAL(sdvo);
|
||||
|
||||
DRM_DEBUG_KMS("connector_is_digital? %d, monitor_is_digital? %d\n",
|
||||
connector_is_digital, monitor_is_digital);
|
||||
return connector_is_digital == monitor_is_digital;
|
||||
}
|
||||
|
||||
static enum drm_connector_status
|
||||
intel_sdvo_detect(struct drm_connector *connector, bool force)
|
||||
{
|
||||
@ -1407,7 +1372,7 @@ intel_sdvo_detect(struct drm_connector *connector, bool force)
|
||||
if ((intel_sdvo_connector->output_flag & response) == 0)
|
||||
ret = connector_status_disconnected;
|
||||
else if (IS_TMDS(intel_sdvo_connector))
|
||||
ret = intel_sdvo_hdmi_sink_detect(connector);
|
||||
ret = intel_sdvo_tmds_sink_detect(connector);
|
||||
else {
|
||||
struct edid *edid;
|
||||
|
||||
@ -1416,10 +1381,12 @@ intel_sdvo_detect(struct drm_connector *connector, bool force)
|
||||
if (edid == NULL)
|
||||
edid = intel_sdvo_get_analog_edid(connector);
|
||||
if (edid != NULL) {
|
||||
if (edid->input & DRM_EDID_INPUT_DIGITAL)
|
||||
ret = connector_status_disconnected;
|
||||
else
|
||||
if (intel_sdvo_connector_matches_edid(intel_sdvo_connector,
|
||||
edid))
|
||||
ret = connector_status_connected;
|
||||
else
|
||||
ret = connector_status_disconnected;
|
||||
|
||||
connector->display_info.raw_edid = NULL;
|
||||
kfree(edid);
|
||||
} else
|
||||
@ -1460,11 +1427,8 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
|
||||
edid = intel_sdvo_get_analog_edid(connector);
|
||||
|
||||
if (edid != NULL) {
|
||||
struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
|
||||
bool monitor_is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL);
|
||||
bool connector_is_digital = !!IS_TMDS(intel_sdvo_connector);
|
||||
|
||||
if (connector_is_digital == monitor_is_digital) {
|
||||
if (intel_sdvo_connector_matches_edid(to_intel_sdvo_connector(connector),
|
||||
edid)) {
|
||||
drm_mode_connector_update_edid_property(connector, edid);
|
||||
drm_add_edid_modes(connector, edid);
|
||||
}
|
||||
@ -1944,7 +1908,7 @@ intel_sdvo_select_i2c_bus(struct drm_i915_private *dev_priv,
|
||||
struct intel_sdvo *sdvo, u32 reg)
|
||||
{
|
||||
struct sdvo_device_mapping *mapping;
|
||||
u8 pin, speed;
|
||||
u8 pin;
|
||||
|
||||
if (IS_SDVOB(reg))
|
||||
mapping = &dev_priv->sdvo_mappings[0];
|
||||
@ -1952,18 +1916,16 @@ intel_sdvo_select_i2c_bus(struct drm_i915_private *dev_priv,
|
||||
mapping = &dev_priv->sdvo_mappings[1];
|
||||
|
||||
pin = GMBUS_PORT_DPB;
|
||||
speed = GMBUS_RATE_1MHZ >> 8;
|
||||
if (mapping->initialized) {
|
||||
if (mapping->initialized)
|
||||
pin = mapping->i2c_pin;
|
||||
speed = mapping->i2c_speed;
|
||||
}
|
||||
|
||||
if (pin < GMBUS_NUM_PORTS) {
|
||||
sdvo->i2c = &dev_priv->gmbus[pin].adapter;
|
||||
intel_gmbus_set_speed(sdvo->i2c, speed);
|
||||
intel_gmbus_set_speed(sdvo->i2c, GMBUS_RATE_1MHZ);
|
||||
intel_gmbus_force_bit(sdvo->i2c, true);
|
||||
} else
|
||||
} else {
|
||||
sdvo->i2c = &dev_priv->gmbus[GMBUS_PORT_DPB].adapter;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -2044,6 +2006,7 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
|
||||
{
|
||||
struct drm_encoder *encoder = &intel_sdvo->base.base;
|
||||
struct drm_connector *connector;
|
||||
struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
|
||||
struct intel_connector *intel_connector;
|
||||
struct intel_sdvo_connector *intel_sdvo_connector;
|
||||
|
||||
@ -2061,6 +2024,16 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
|
||||
|
||||
intel_connector = &intel_sdvo_connector->base;
|
||||
connector = &intel_connector->base;
|
||||
if (intel_sdvo_supports_hotplug(intel_sdvo) & (1 << device)) {
|
||||
connector->polled = DRM_CONNECTOR_POLL_HPD;
|
||||
intel_sdvo->hotplug_active[0] |= 1 << device;
|
||||
/* Some SDVO devices have one-shot hotplug interrupts.
|
||||
* Ensure that they get re-enabled when an interrupt happens.
|
||||
*/
|
||||
intel_encoder->hot_plug = intel_sdvo_enable_hotplug;
|
||||
intel_sdvo_enable_hotplug(intel_encoder);
|
||||
}
|
||||
else
|
||||
connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
|
||||
encoder->encoder_type = DRM_MODE_ENCODER_TMDS;
|
||||
connector->connector_type = DRM_MODE_CONNECTOR_DVID;
|
||||
@ -2243,7 +2216,7 @@ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags)
|
||||
bytes[0], bytes[1]);
|
||||
return false;
|
||||
}
|
||||
intel_sdvo->base.crtc_mask = (1 << 0) | (1 << 1);
|
||||
intel_sdvo->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -2312,7 +2285,7 @@ static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo,
|
||||
DRM_DEBUG_KMS(#name ": max %d, default %d, current %d\n", \
|
||||
data_value[0], data_value[1], response); \
|
||||
} \
|
||||
} while(0)
|
||||
} while (0)
|
||||
|
||||
static bool
|
||||
intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo,
|
||||
@ -2479,7 +2452,7 @@ static bool intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo,
|
||||
|
||||
if (IS_TV(intel_sdvo_connector))
|
||||
return intel_sdvo_create_enhance_property_tv(intel_sdvo, intel_sdvo_connector, enhancements.reply);
|
||||
else if(IS_LVDS(intel_sdvo_connector))
|
||||
else if (IS_LVDS(intel_sdvo_connector))
|
||||
return intel_sdvo_create_enhance_property_lvds(intel_sdvo, intel_sdvo_connector, enhancements.reply);
|
||||
else
|
||||
return true;
|
||||
@ -2568,6 +2541,14 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
|
||||
if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps))
|
||||
goto err;
|
||||
|
||||
/* Set up hotplug command - note paranoia about contents of reply.
|
||||
* We assume that the hardware is in a sane state, and only touch
|
||||
* the bits we think we understand.
|
||||
*/
|
||||
intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG,
|
||||
&intel_sdvo->hotplug_active, 2);
|
||||
intel_sdvo->hotplug_active[0] &= ~0x3;
|
||||
|
||||
if (intel_sdvo_output_setup(intel_sdvo,
|
||||
intel_sdvo->caps.output_flags) != true) {
|
||||
DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n",
|
||||
|
File diff suppressed because it is too large
Load Diff
664
drivers/video/drm/i915/intel_sprite.c
Normal file
664
drivers/video/drm/i915/intel_sprite.c
Normal file
@ -0,0 +1,664 @@
|
||||
/*
|
||||
* Copyright © 2011 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Jesse Barnes <jbarnes@virtuousgeek.org>
|
||||
*
|
||||
* New plane/sprite handling.
|
||||
*
|
||||
* The older chips had a separate interface for programming plane related
|
||||
* registers; newer ones are much simpler and we can use the new DRM plane
|
||||
* support.
|
||||
*/
|
||||
#include "drmP.h"
|
||||
#include "drm_crtc.h"
|
||||
#include "drm_fourcc.h"
|
||||
#include "intel_drv.h"
|
||||
#include "i915_drm.h"
|
||||
#include "i915_drv.h"
|
||||
|
||||
static void
|
||||
ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
|
||||
struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
|
||||
unsigned int crtc_w, unsigned int crtc_h,
|
||||
uint32_t x, uint32_t y,
|
||||
uint32_t src_w, uint32_t src_h)
|
||||
{
|
||||
struct drm_device *dev = plane->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_plane *intel_plane = to_intel_plane(plane);
|
||||
int pipe = intel_plane->pipe;
|
||||
u32 sprctl, sprscale = 0;
|
||||
int pixel_size;
|
||||
|
||||
sprctl = I915_READ(SPRCTL(pipe));
|
||||
|
||||
/* Mask out pixel format bits in case we change it */
|
||||
sprctl &= ~SPRITE_PIXFORMAT_MASK;
|
||||
sprctl &= ~SPRITE_RGB_ORDER_RGBX;
|
||||
sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK;
|
||||
|
||||
switch (fb->pixel_format) {
|
||||
case DRM_FORMAT_XBGR8888:
|
||||
sprctl |= SPRITE_FORMAT_RGBX888;
|
||||
pixel_size = 4;
|
||||
break;
|
||||
case DRM_FORMAT_XRGB8888:
|
||||
sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
|
||||
pixel_size = 4;
|
||||
break;
|
||||
case DRM_FORMAT_YUYV:
|
||||
sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
|
||||
pixel_size = 2;
|
||||
break;
|
||||
case DRM_FORMAT_YVYU:
|
||||
sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
|
||||
pixel_size = 2;
|
||||
break;
|
||||
case DRM_FORMAT_UYVY:
|
||||
sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
|
||||
pixel_size = 2;
|
||||
break;
|
||||
case DRM_FORMAT_VYUY:
|
||||
sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
|
||||
pixel_size = 2;
|
||||
break;
|
||||
default:
|
||||
DRM_DEBUG_DRIVER("bad pixel format, assuming RGBX888\n");
|
||||
sprctl |= DVS_FORMAT_RGBX888;
|
||||
pixel_size = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
if (obj->tiling_mode != I915_TILING_NONE)
|
||||
sprctl |= SPRITE_TILED;
|
||||
|
||||
/* must disable */
|
||||
sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
|
||||
sprctl |= SPRITE_ENABLE;
|
||||
sprctl |= SPRITE_DEST_KEY;
|
||||
|
||||
/* Sizes are 0 based */
|
||||
src_w--;
|
||||
src_h--;
|
||||
crtc_w--;
|
||||
crtc_h--;
|
||||
|
||||
intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size);
|
||||
|
||||
/*
|
||||
* IVB workaround: must disable low power watermarks for at least
|
||||
* one frame before enabling scaling. LP watermarks can be re-enabled
|
||||
* when scaling is disabled.
|
||||
*/
|
||||
if (crtc_w != src_w || crtc_h != src_h) {
|
||||
dev_priv->sprite_scaling_enabled = true;
|
||||
sandybridge_update_wm(dev);
|
||||
intel_wait_for_vblank(dev, pipe);
|
||||
sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
|
||||
} else {
|
||||
dev_priv->sprite_scaling_enabled = false;
|
||||
/* potentially re-enable LP watermarks */
|
||||
sandybridge_update_wm(dev);
|
||||
}
|
||||
|
||||
I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]);
|
||||
I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
|
||||
if (obj->tiling_mode != I915_TILING_NONE) {
|
||||
I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x);
|
||||
} else {
|
||||
unsigned long offset;
|
||||
|
||||
offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
|
||||
I915_WRITE(SPRLINOFF(pipe), offset);
|
||||
}
|
||||
I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
|
||||
I915_WRITE(SPRSCALE(pipe), sprscale);
|
||||
I915_WRITE(SPRCTL(pipe), sprctl);
|
||||
I915_WRITE(SPRSURF(pipe), obj->gtt_offset);
|
||||
POSTING_READ(SPRSURF(pipe));
|
||||
}
|
||||
|
||||
static void
|
||||
ivb_disable_plane(struct drm_plane *plane)
|
||||
{
|
||||
struct drm_device *dev = plane->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_plane *intel_plane = to_intel_plane(plane);
|
||||
int pipe = intel_plane->pipe;
|
||||
|
||||
I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE);
|
||||
/* Can't leave the scaler enabled... */
|
||||
I915_WRITE(SPRSCALE(pipe), 0);
|
||||
/* Activate double buffered register update */
|
||||
I915_WRITE(SPRSURF(pipe), 0);
|
||||
POSTING_READ(SPRSURF(pipe));
|
||||
}
|
||||
|
||||
static int
|
||||
ivb_update_colorkey(struct drm_plane *plane,
|
||||
struct drm_intel_sprite_colorkey *key)
|
||||
{
|
||||
struct drm_device *dev = plane->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_plane *intel_plane;
|
||||
u32 sprctl;
|
||||
int ret = 0;
|
||||
|
||||
intel_plane = to_intel_plane(plane);
|
||||
|
||||
I915_WRITE(SPRKEYVAL(intel_plane->pipe), key->min_value);
|
||||
I915_WRITE(SPRKEYMAX(intel_plane->pipe), key->max_value);
|
||||
I915_WRITE(SPRKEYMSK(intel_plane->pipe), key->channel_mask);
|
||||
|
||||
sprctl = I915_READ(SPRCTL(intel_plane->pipe));
|
||||
sprctl &= ~(SPRITE_SOURCE_KEY | SPRITE_DEST_KEY);
|
||||
if (key->flags & I915_SET_COLORKEY_DESTINATION)
|
||||
sprctl |= SPRITE_DEST_KEY;
|
||||
else if (key->flags & I915_SET_COLORKEY_SOURCE)
|
||||
sprctl |= SPRITE_SOURCE_KEY;
|
||||
I915_WRITE(SPRCTL(intel_plane->pipe), sprctl);
|
||||
|
||||
POSTING_READ(SPRKEYMSK(intel_plane->pipe));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
ivb_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key)
|
||||
{
|
||||
struct drm_device *dev = plane->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_plane *intel_plane;
|
||||
u32 sprctl;
|
||||
|
||||
intel_plane = to_intel_plane(plane);
|
||||
|
||||
key->min_value = I915_READ(SPRKEYVAL(intel_plane->pipe));
|
||||
key->max_value = I915_READ(SPRKEYMAX(intel_plane->pipe));
|
||||
key->channel_mask = I915_READ(SPRKEYMSK(intel_plane->pipe));
|
||||
key->flags = 0;
|
||||
|
||||
sprctl = I915_READ(SPRCTL(intel_plane->pipe));
|
||||
|
||||
if (sprctl & SPRITE_DEST_KEY)
|
||||
key->flags = I915_SET_COLORKEY_DESTINATION;
|
||||
else if (sprctl & SPRITE_SOURCE_KEY)
|
||||
key->flags = I915_SET_COLORKEY_SOURCE;
|
||||
else
|
||||
key->flags = I915_SET_COLORKEY_NONE;
|
||||
}
|
||||
|
||||
static void
|
||||
snb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
|
||||
struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
|
||||
unsigned int crtc_w, unsigned int crtc_h,
|
||||
uint32_t x, uint32_t y,
|
||||
uint32_t src_w, uint32_t src_h)
|
||||
{
|
||||
struct drm_device *dev = plane->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_plane *intel_plane = to_intel_plane(plane);
|
||||
int pipe = intel_plane->pipe, pixel_size;
|
||||
u32 dvscntr, dvsscale = 0;
|
||||
|
||||
dvscntr = I915_READ(DVSCNTR(pipe));
|
||||
|
||||
/* Mask out pixel format bits in case we change it */
|
||||
dvscntr &= ~DVS_PIXFORMAT_MASK;
|
||||
dvscntr &= ~DVS_RGB_ORDER_RGBX;
|
||||
dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK;
|
||||
|
||||
switch (fb->pixel_format) {
|
||||
case DRM_FORMAT_XBGR8888:
|
||||
dvscntr |= DVS_FORMAT_RGBX888;
|
||||
pixel_size = 4;
|
||||
break;
|
||||
case DRM_FORMAT_XRGB8888:
|
||||
dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_RGBX;
|
||||
pixel_size = 4;
|
||||
break;
|
||||
case DRM_FORMAT_YUYV:
|
||||
dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
|
||||
pixel_size = 2;
|
||||
break;
|
||||
case DRM_FORMAT_YVYU:
|
||||
dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
|
||||
pixel_size = 2;
|
||||
break;
|
||||
case DRM_FORMAT_UYVY:
|
||||
dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
|
||||
pixel_size = 2;
|
||||
break;
|
||||
case DRM_FORMAT_VYUY:
|
||||
dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
|
||||
pixel_size = 2;
|
||||
break;
|
||||
default:
|
||||
DRM_DEBUG_DRIVER("bad pixel format, assuming RGBX888\n");
|
||||
dvscntr |= DVS_FORMAT_RGBX888;
|
||||
pixel_size = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
if (obj->tiling_mode != I915_TILING_NONE)
|
||||
dvscntr |= DVS_TILED;
|
||||
|
||||
/* must disable */
|
||||
dvscntr |= DVS_TRICKLE_FEED_DISABLE;
|
||||
dvscntr |= DVS_ENABLE;
|
||||
|
||||
/* Sizes are 0 based */
|
||||
src_w--;
|
||||
src_h--;
|
||||
crtc_w--;
|
||||
crtc_h--;
|
||||
|
||||
intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size);
|
||||
|
||||
if (crtc_w != src_w || crtc_h != src_h)
|
||||
dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
|
||||
|
||||
I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]);
|
||||
I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
|
||||
if (obj->tiling_mode != I915_TILING_NONE) {
|
||||
I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x);
|
||||
} else {
|
||||
unsigned long offset;
|
||||
|
||||
offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
|
||||
I915_WRITE(DVSLINOFF(pipe), offset);
|
||||
}
|
||||
I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
|
||||
I915_WRITE(DVSSCALE(pipe), dvsscale);
|
||||
I915_WRITE(DVSCNTR(pipe), dvscntr);
|
||||
I915_WRITE(DVSSURF(pipe), obj->gtt_offset);
|
||||
POSTING_READ(DVSSURF(pipe));
|
||||
}
|
||||
|
||||
static void
|
||||
snb_disable_plane(struct drm_plane *plane)
|
||||
{
|
||||
struct drm_device *dev = plane->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_plane *intel_plane = to_intel_plane(plane);
|
||||
int pipe = intel_plane->pipe;
|
||||
|
||||
I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE);
|
||||
/* Disable the scaler */
|
||||
I915_WRITE(DVSSCALE(pipe), 0);
|
||||
/* Flush double buffered register updates */
|
||||
I915_WRITE(DVSSURF(pipe), 0);
|
||||
POSTING_READ(DVSSURF(pipe));
|
||||
}
|
||||
|
||||
static void
|
||||
intel_enable_primary(struct drm_crtc *crtc)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
int reg = DSPCNTR(intel_crtc->plane);
|
||||
|
||||
I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE);
|
||||
}
|
||||
|
||||
static void
|
||||
intel_disable_primary(struct drm_crtc *crtc)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
int reg = DSPCNTR(intel_crtc->plane);
|
||||
|
||||
I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE);
|
||||
}
|
||||
|
||||
static int
|
||||
snb_update_colorkey(struct drm_plane *plane,
|
||||
struct drm_intel_sprite_colorkey *key)
|
||||
{
|
||||
struct drm_device *dev = plane->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_plane *intel_plane;
|
||||
u32 dvscntr;
|
||||
int ret = 0;
|
||||
|
||||
intel_plane = to_intel_plane(plane);
|
||||
|
||||
I915_WRITE(DVSKEYVAL(intel_plane->pipe), key->min_value);
|
||||
I915_WRITE(DVSKEYMAX(intel_plane->pipe), key->max_value);
|
||||
I915_WRITE(DVSKEYMSK(intel_plane->pipe), key->channel_mask);
|
||||
|
||||
dvscntr = I915_READ(DVSCNTR(intel_plane->pipe));
|
||||
dvscntr &= ~(DVS_SOURCE_KEY | DVS_DEST_KEY);
|
||||
if (key->flags & I915_SET_COLORKEY_DESTINATION)
|
||||
dvscntr |= DVS_DEST_KEY;
|
||||
else if (key->flags & I915_SET_COLORKEY_SOURCE)
|
||||
dvscntr |= DVS_SOURCE_KEY;
|
||||
I915_WRITE(DVSCNTR(intel_plane->pipe), dvscntr);
|
||||
|
||||
POSTING_READ(DVSKEYMSK(intel_plane->pipe));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
snb_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key)
|
||||
{
|
||||
struct drm_device *dev = plane->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_plane *intel_plane;
|
||||
u32 dvscntr;
|
||||
|
||||
intel_plane = to_intel_plane(plane);
|
||||
|
||||
key->min_value = I915_READ(DVSKEYVAL(intel_plane->pipe));
|
||||
key->max_value = I915_READ(DVSKEYMAX(intel_plane->pipe));
|
||||
key->channel_mask = I915_READ(DVSKEYMSK(intel_plane->pipe));
|
||||
key->flags = 0;
|
||||
|
||||
dvscntr = I915_READ(DVSCNTR(intel_plane->pipe));
|
||||
|
||||
if (dvscntr & DVS_DEST_KEY)
|
||||
key->flags = I915_SET_COLORKEY_DESTINATION;
|
||||
else if (dvscntr & DVS_SOURCE_KEY)
|
||||
key->flags = I915_SET_COLORKEY_SOURCE;
|
||||
else
|
||||
key->flags = I915_SET_COLORKEY_NONE;
|
||||
}
|
||||
|
||||
static int
|
||||
intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
|
||||
struct drm_framebuffer *fb, int crtc_x, int crtc_y,
|
||||
unsigned int crtc_w, unsigned int crtc_h,
|
||||
uint32_t src_x, uint32_t src_y,
|
||||
uint32_t src_w, uint32_t src_h)
|
||||
{
|
||||
struct drm_device *dev = plane->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
struct intel_plane *intel_plane = to_intel_plane(plane);
|
||||
struct intel_framebuffer *intel_fb;
|
||||
struct drm_i915_gem_object *obj, *old_obj;
|
||||
int pipe = intel_plane->pipe;
|
||||
int ret = 0;
|
||||
int x = src_x >> 16, y = src_y >> 16;
|
||||
int primary_w = crtc->mode.hdisplay, primary_h = crtc->mode.vdisplay;
|
||||
bool disable_primary = false;
|
||||
|
||||
intel_fb = to_intel_framebuffer(fb);
|
||||
obj = intel_fb->obj;
|
||||
|
||||
old_obj = intel_plane->obj;
|
||||
|
||||
/* Pipe must be running... */
|
||||
if (!(I915_READ(PIPECONF(pipe)) & PIPECONF_ENABLE))
|
||||
return -EINVAL;
|
||||
|
||||
if (crtc_x >= primary_w || crtc_y >= primary_h)
|
||||
return -EINVAL;
|
||||
|
||||
/* Don't modify another pipe's plane */
|
||||
if (intel_plane->pipe != intel_crtc->pipe)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Clamp the width & height into the visible area. Note we don't
|
||||
* try to scale the source if part of the visible region is offscreen.
|
||||
* The caller must handle that by adjusting source offset and size.
|
||||
*/
|
||||
if ((crtc_x < 0) && ((crtc_x + crtc_w) > 0)) {
|
||||
crtc_w += crtc_x;
|
||||
crtc_x = 0;
|
||||
}
|
||||
if ((crtc_x + crtc_w) <= 0) /* Nothing to display */
|
||||
goto out;
|
||||
if ((crtc_x + crtc_w) > primary_w)
|
||||
crtc_w = primary_w - crtc_x;
|
||||
|
||||
if ((crtc_y < 0) && ((crtc_y + crtc_h) > 0)) {
|
||||
crtc_h += crtc_y;
|
||||
crtc_y = 0;
|
||||
}
|
||||
if ((crtc_y + crtc_h) <= 0) /* Nothing to display */
|
||||
goto out;
|
||||
if (crtc_y + crtc_h > primary_h)
|
||||
crtc_h = primary_h - crtc_y;
|
||||
|
||||
if (!crtc_w || !crtc_h) /* Again, nothing to display */
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* We can take a larger source and scale it down, but
|
||||
* only so much... 16x is the max on SNB.
|
||||
*/
|
||||
if (((src_w * src_h) / (crtc_w * crtc_h)) > intel_plane->max_downscale)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* If the sprite is completely covering the primary plane,
|
||||
* we can disable the primary and save power.
|
||||
*/
|
||||
if ((crtc_x == 0) && (crtc_y == 0) &&
|
||||
(crtc_w == primary_w) && (crtc_h == primary_h))
|
||||
disable_primary = true;
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
|
||||
ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
intel_plane->obj = obj;
|
||||
|
||||
/*
|
||||
* Be sure to re-enable the primary before the sprite is no longer
|
||||
* covering it fully.
|
||||
*/
|
||||
if (!disable_primary && intel_plane->primary_disabled) {
|
||||
intel_enable_primary(crtc);
|
||||
intel_plane->primary_disabled = false;
|
||||
}
|
||||
|
||||
intel_plane->update_plane(plane, fb, obj, crtc_x, crtc_y,
|
||||
crtc_w, crtc_h, x, y, src_w, src_h);
|
||||
|
||||
if (disable_primary) {
|
||||
intel_disable_primary(crtc);
|
||||
intel_plane->primary_disabled = true;
|
||||
}
|
||||
|
||||
/* Unpin old obj after new one is active to avoid ugliness */
|
||||
if (old_obj) {
|
||||
/*
|
||||
* It's fairly common to simply update the position of
|
||||
* an existing object. In that case, we don't need to
|
||||
* wait for vblank to avoid ugliness, we only need to
|
||||
* do the pin & ref bookkeeping.
|
||||
*/
|
||||
if (old_obj != obj) {
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe);
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
}
|
||||
// i915_gem_object_unpin(old_obj);
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
intel_disable_plane(struct drm_plane *plane)
|
||||
{
|
||||
struct drm_device *dev = plane->dev;
|
||||
struct intel_plane *intel_plane = to_intel_plane(plane);
|
||||
int ret = 0;
|
||||
|
||||
if (intel_plane->primary_disabled) {
|
||||
intel_enable_primary(plane->crtc);
|
||||
intel_plane->primary_disabled = false;
|
||||
}
|
||||
|
||||
intel_plane->disable_plane(plane);
|
||||
|
||||
if (!intel_plane->obj)
|
||||
goto out;
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
// i915_gem_object_unpin(intel_plane->obj);
|
||||
intel_plane->obj = NULL;
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
out:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void intel_destroy_plane(struct drm_plane *plane)
|
||||
{
|
||||
struct intel_plane *intel_plane = to_intel_plane(plane);
|
||||
intel_disable_plane(plane);
|
||||
drm_plane_cleanup(plane);
|
||||
kfree(intel_plane);
|
||||
}
|
||||
|
||||
int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
struct drm_intel_sprite_colorkey *set = data;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct drm_mode_object *obj;
|
||||
struct drm_plane *plane;
|
||||
struct intel_plane *intel_plane;
|
||||
int ret = 0;
|
||||
|
||||
if (!dev_priv)
|
||||
return -EINVAL;
|
||||
|
||||
/* Make sure we don't try to enable both src & dest simultaneously */
|
||||
if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
|
||||
obj = drm_mode_object_find(dev, set->plane_id, DRM_MODE_OBJECT_PLANE);
|
||||
if (!obj) {
|
||||
ret = -EINVAL;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
plane = obj_to_plane(obj);
|
||||
intel_plane = to_intel_plane(plane);
|
||||
ret = intel_plane->update_colorkey(plane, set);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
struct drm_intel_sprite_colorkey *get = data;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct drm_mode_object *obj;
|
||||
struct drm_plane *plane;
|
||||
struct intel_plane *intel_plane;
|
||||
int ret = 0;
|
||||
|
||||
if (!dev_priv)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
|
||||
obj = drm_mode_object_find(dev, get->plane_id, DRM_MODE_OBJECT_PLANE);
|
||||
if (!obj) {
|
||||
ret = -EINVAL;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
plane = obj_to_plane(obj);
|
||||
intel_plane = to_intel_plane(plane);
|
||||
intel_plane->get_colorkey(plane, get);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct drm_plane_funcs intel_plane_funcs = {
|
||||
.update_plane = intel_update_plane,
|
||||
.disable_plane = intel_disable_plane,
|
||||
.destroy = intel_destroy_plane,
|
||||
};
|
||||
|
||||
static uint32_t snb_plane_formats[] = {
|
||||
DRM_FORMAT_XBGR8888,
|
||||
DRM_FORMAT_XRGB8888,
|
||||
DRM_FORMAT_YUYV,
|
||||
DRM_FORMAT_YVYU,
|
||||
DRM_FORMAT_UYVY,
|
||||
DRM_FORMAT_VYUY,
|
||||
};
|
||||
|
||||
int
|
||||
intel_plane_init(struct drm_device *dev, enum pipe pipe)
|
||||
{
|
||||
struct intel_plane *intel_plane;
|
||||
unsigned long possible_crtcs;
|
||||
int ret;
|
||||
|
||||
if (!(IS_GEN6(dev) || IS_GEN7(dev)))
|
||||
return -ENODEV;
|
||||
|
||||
intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL);
|
||||
if (!intel_plane)
|
||||
return -ENOMEM;
|
||||
|
||||
if (IS_GEN6(dev)) {
|
||||
intel_plane->max_downscale = 16;
|
||||
intel_plane->update_plane = snb_update_plane;
|
||||
intel_plane->disable_plane = snb_disable_plane;
|
||||
intel_plane->update_colorkey = snb_update_colorkey;
|
||||
intel_plane->get_colorkey = snb_get_colorkey;
|
||||
} else if (IS_GEN7(dev)) {
|
||||
intel_plane->max_downscale = 2;
|
||||
intel_plane->update_plane = ivb_update_plane;
|
||||
intel_plane->disable_plane = ivb_disable_plane;
|
||||
intel_plane->update_colorkey = ivb_update_colorkey;
|
||||
intel_plane->get_colorkey = ivb_get_colorkey;
|
||||
}
|
||||
|
||||
intel_plane->pipe = pipe;
|
||||
possible_crtcs = (1 << pipe);
|
||||
ret = drm_plane_init(dev, &intel_plane->base, possible_crtcs,
|
||||
&intel_plane_funcs, snb_plane_formats,
|
||||
ARRAY_SIZE(snb_plane_formats), false);
|
||||
if (ret)
|
||||
kfree(intel_plane);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -191,48 +191,31 @@ int init_display_kms(struct drm_device *dev)
|
||||
};
|
||||
safe_sti(ifl);
|
||||
|
||||
{
|
||||
#define XY_COLOR_BLT ((2<<29)|(0x50<<22)|(0x4))
|
||||
#define BLT_WRITE_ALPHA (1<<21)
|
||||
#define BLT_WRITE_RGB (1<<20)
|
||||
|
||||
#if 1
|
||||
{
|
||||
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_i915_gem_object *obj;
|
||||
struct intel_ring_buffer *ring;
|
||||
|
||||
u32_t br13, cmd, *b;
|
||||
|
||||
int n=0;
|
||||
|
||||
cmd = XY_COLOR_BLT | BLT_WRITE_ALPHA | BLT_WRITE_RGB;
|
||||
br13 = os_display->pitch;
|
||||
br13 |= 0xF0 << 16;
|
||||
br13 |= 3 << 24;
|
||||
|
||||
obj = i915_gem_alloc_object(dev, 4096);
|
||||
i915_gem_object_pin(obj, 4096, true);
|
||||
|
||||
cmd_buffer = MapIoMem(obj->pages[0], 4096, PG_SW|PG_NOCACHE);
|
||||
cmd_offset = obj->gtt_offset;
|
||||
};
|
||||
#endif
|
||||
|
||||
b = (u32_t*)cmd_buffer;
|
||||
b[n++] = cmd;
|
||||
b[n++] = br13;
|
||||
b[n++] = 0; // top, left
|
||||
b[n++] = (128 << 16) | 128; // bottom, right
|
||||
b[n++] = 0; // dst
|
||||
b[n++] = 0x0000FF00;
|
||||
b[n++] = MI_BATCH_BUFFER_END;
|
||||
if( n & 1)
|
||||
b[n++] = MI_NOOP;
|
||||
|
||||
// cmd_buffer = (u32_t)&b[n];
|
||||
// i915_gem_object_set_to_gtt_domain(obj, false);
|
||||
|
||||
|
||||
ring = &dev_priv->ring[BCS];
|
||||
ring->dispatch_execbuffer(ring,cmd_offset, n*4);
|
||||
int err;
|
||||
|
||||
err = init_bitmaps();
|
||||
if( !err )
|
||||
{
|
||||
printf("Initialize bitmap manager\n");
|
||||
};
|
||||
|
||||
LEAVE();
|
||||
@ -303,7 +286,11 @@ do_set:
|
||||
|
||||
fb->width = reqmode->width;
|
||||
fb->height = reqmode->height;
|
||||
fb->pitch = ALIGN(reqmode->width * 4, 64);
|
||||
fb->pitches[0] = ALIGN(reqmode->width * 4, 64);
|
||||
fb->pitches[1] = ALIGN(reqmode->width * 4, 64);
|
||||
fb->pitches[2] = ALIGN(reqmode->width * 4, 64);
|
||||
fb->pitches[3] = ALIGN(reqmode->width * 4, 64);
|
||||
|
||||
fb->bits_per_pixel = 32;
|
||||
fb->depth == 24;
|
||||
|
||||
@ -320,13 +307,13 @@ do_set:
|
||||
{
|
||||
os_display->width = fb->width;
|
||||
os_display->height = fb->height;
|
||||
os_display->pitch = fb->pitch;
|
||||
os_display->pitch = fb->pitches[0];
|
||||
os_display->vrefresh = drm_mode_vrefresh(mode);
|
||||
|
||||
sysSetScreen(fb->width, fb->height, fb->pitch);
|
||||
sysSetScreen(fb->width, fb->height, fb->pitches[0]);
|
||||
|
||||
dbgprintf("new mode %d x %d pitch %d\n",
|
||||
fb->width, fb->height, fb->pitch);
|
||||
fb->width, fb->height, fb->pitches[0]);
|
||||
}
|
||||
else
|
||||
DRM_ERROR("failed to set mode %d_%d on crtc %p\n",
|
||||
@ -406,6 +393,8 @@ int set_user_mode(videomode_t *mode)
|
||||
|
||||
void __attribute__((regparm(1))) destroy_cursor(cursor_t *cursor)
|
||||
{
|
||||
/* FIXME synchronization */
|
||||
|
||||
list_del(&cursor->list);
|
||||
// radeon_bo_unpin(cursor->robj);
|
||||
// KernelFree(cursor->data);
|
||||
@ -592,68 +581,36 @@ extern struct drm_device *main_device;
|
||||
|
||||
#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
|
||||
|
||||
int video_blit(uint64_t src_offset, int x, int y,
|
||||
int w, int h, int pitch)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
||||
drm_i915_private_t *dev_priv = main_device->dev_private;
|
||||
struct intel_ring_buffer *ring;
|
||||
|
||||
u32_t br13, cmd, *b;
|
||||
u32_t offset;
|
||||
|
||||
int n=0;
|
||||
|
||||
// if( cmd_buffer & 0xF80 )
|
||||
// cmd_buffer&= 0xFFFFF000;
|
||||
|
||||
// b = (u32_t*)ALIGN(cmd_buffer,16);
|
||||
|
||||
// offset = cmd_offset + ((u32_t)b & 0xFFF);
|
||||
|
||||
b = cmd_buffer;
|
||||
|
||||
cmd = XY_SRC_COPY_BLT_CMD | BLT_WRITE_RGB;
|
||||
br13 = os_display->pitch;
|
||||
br13 |= 0xCC << 16;
|
||||
br13 |= 3 << 24;
|
||||
|
||||
b[n++] = cmd;
|
||||
b[n++] = br13;
|
||||
b[n++] = (y << 16) | x;
|
||||
b[n++] = ( (y+h) << 16) | (x+w); // bottom, right
|
||||
b[n++] = 0; // dst_offset
|
||||
b[n++] = 0; //src_top|src_left
|
||||
|
||||
b[n++] = pitch;
|
||||
b[n++] = (u32_t)src_offset;
|
||||
|
||||
b[n++] = MI_BATCH_BUFFER_END;
|
||||
if( n & 1)
|
||||
b[n++] = MI_NOOP;
|
||||
|
||||
// i915_gem_object_set_to_gtt_domain(obj, false);
|
||||
|
||||
ring = &dev_priv->ring[BCS];
|
||||
ring->dispatch_execbuffer(ring, cmd_offset, n*4);
|
||||
|
||||
intel_ring_begin(ring, 4);
|
||||
// if (ret)
|
||||
// return ret;
|
||||
|
||||
// cmd = MI_FLUSH_DW;
|
||||
// if (invalidate & I915_GEM_GPU_DOMAINS)
|
||||
// cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD;
|
||||
intel_ring_emit(ring, MI_FLUSH_DW);
|
||||
intel_ring_emit(ring, 0);
|
||||
intel_ring_emit(ring, 0);
|
||||
intel_ring_emit(ring, MI_NOOP);
|
||||
intel_ring_advance(ring);
|
||||
int left;
|
||||
int top;
|
||||
int right;
|
||||
int bottom;
|
||||
}rect_t;
|
||||
|
||||
|
||||
fail:
|
||||
return -1;
|
||||
};
|
||||
#include "clip.inc"
|
||||
|
||||
void FASTCALL GetWindowRect(rect_t *rc)__asm__("GetWindowRect");
|
||||
|
||||
#define CURRENT_TASK (0x80003000)
|
||||
|
||||
static u32_t get_display_map()
|
||||
{
|
||||
u32_t addr;
|
||||
|
||||
addr = (u32_t)os_display;
|
||||
addr+= sizeof(display_t); /* shoot me */
|
||||
return *(u32_t*)addr;
|
||||
}
|
||||
|
||||
#define XY_SRC_COPY_CHROMA_CMD ((2<<29)|(0x73<<22)|8)
|
||||
#define ROP_COPY_SRC 0xCC
|
||||
#define FORMAT8888 3
|
||||
|
||||
typedef int v4si __attribute__ ((vector_size (16)));
|
||||
|
||||
|
||||
int blit_video(u32 hbitmap, int dst_x, int dst_y,
|
||||
@ -663,42 +620,188 @@ int blit_video(u32 hbitmap, int dst_x, int dst_y,
|
||||
struct intel_ring_buffer *ring;
|
||||
|
||||
bitmap_t *bitmap;
|
||||
u32_t br13, cmd, *b;
|
||||
u32_t offset;
|
||||
rect_t winrc;
|
||||
clip_t dst_clip;
|
||||
clip_t src_clip;
|
||||
u32_t width;
|
||||
u32_t height;
|
||||
|
||||
u32_t br13, cmd, slot_mask, *b;
|
||||
u32_t offset;
|
||||
u8 slot;
|
||||
int n=0;
|
||||
|
||||
if(unlikely(hbitmap==0))
|
||||
return -1;
|
||||
|
||||
bitmap = hman_get_data(&bm_man, hbitmap);
|
||||
bitmap = (bitmap_t*)hman_get_data(&bm_man, hbitmap);
|
||||
|
||||
if(unlikely(bitmap==NULL))
|
||||
return -1;
|
||||
|
||||
// if( cmd_buffer & 0xF80 )
|
||||
// cmd_buffer&= 0xFFFFF000;
|
||||
|
||||
// b = (u32_t*)ALIGN(cmd_buffer,16);
|
||||
GetWindowRect(&winrc);
|
||||
|
||||
// offset = cmd_offset + ((u32_t)b & 0xFFF);
|
||||
dst_clip.xmin = 0;
|
||||
dst_clip.ymin = 0;
|
||||
dst_clip.xmax = winrc.right-winrc.left-1;
|
||||
dst_clip.ymax = winrc.bottom -winrc.top -1;
|
||||
|
||||
b = cmd_buffer;
|
||||
src_clip.xmin = 0;
|
||||
src_clip.ymin = 0;
|
||||
src_clip.xmax = bitmap->width - 1;
|
||||
src_clip.ymax = bitmap->height - 1;
|
||||
|
||||
width = w;
|
||||
height = h;
|
||||
|
||||
if( blit_clip(&dst_clip, &dst_x, &dst_y,
|
||||
&src_clip, &src_x, &src_y,
|
||||
&width, &height) )
|
||||
return 0;
|
||||
|
||||
dst_x+= winrc.left;
|
||||
dst_y+= winrc.top;
|
||||
|
||||
slot = *((u8*)CURRENT_TASK);
|
||||
|
||||
slot_mask = (u32_t)slot<<24;
|
||||
|
||||
{
|
||||
#if 0
|
||||
static v4si write_mask = {0xFF000000, 0xFF000000,
|
||||
0xFF000000, 0xFF000000};
|
||||
|
||||
u8* src_offset;
|
||||
u8* dst_offset;
|
||||
|
||||
src_offset = (u8*)(src_y*bitmap->pitch + src_x*4);
|
||||
src_offset += (u32)bitmap->uaddr;
|
||||
|
||||
dst_offset = (u8*)(dst_y*os_display->width + dst_x);
|
||||
dst_offset+= get_display_map();
|
||||
|
||||
u32_t tmp_h = height;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"movdqa %[write_mask], %%xmm7 \n"
|
||||
"movd %[slot_mask], %%xmm6 \n"
|
||||
"punpckldq %%xmm6, %%xmm6 \n"
|
||||
"punpcklqdq %%xmm6, %%xmm6 \n"
|
||||
:: [write_mask] "m" (write_mask),
|
||||
[slot_mask] "g" (slot_mask)
|
||||
:"xmm7", "xmm6");
|
||||
|
||||
while( tmp_h--)
|
||||
{
|
||||
u32_t tmp_w = width;
|
||||
|
||||
u8* tmp_src = src_offset;
|
||||
u8* tmp_dst = dst_offset;
|
||||
|
||||
src_offset+= bitmap->pitch;
|
||||
dst_offset+= os_display->width;
|
||||
|
||||
while( tmp_w >= 8 )
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"movq (%0), %%xmm0 \n"
|
||||
"punpcklbw %%xmm0, %%xmm0 \n"
|
||||
"movdqa %%xmm0, %%xmm1 \n"
|
||||
"punpcklwd %%xmm0, %%xmm0 \n"
|
||||
"punpckhwd %%xmm1, %%xmm1 \n"
|
||||
"pcmpeqb %%xmm6, %%xmm0 \n"
|
||||
"pcmpeqb %%xmm6, %%xmm1 \n"
|
||||
"maskmovdqu %%xmm7, %%xmm0 \n"
|
||||
"addl $16, %%edi \n"
|
||||
"maskmovdqu %%xmm7, %%xmm1 \n"
|
||||
:: "r" (tmp_dst), "D" (tmp_src)
|
||||
:"xmm0", "xmm1");
|
||||
__asm__ __volatile__ ("":::"edi");
|
||||
tmp_w -= 8;
|
||||
tmp_src += 32;
|
||||
tmp_dst += 8;
|
||||
};
|
||||
|
||||
if( tmp_w >= 4 )
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"movd (%0), %%xmm0 \n"
|
||||
"punpcklbw %%xmm0, %%xmm0 \n"
|
||||
"punpcklwd %%xmm0, %%xmm0 \n"
|
||||
"pcmpeqb %%xmm6, %%xmm0 \n"
|
||||
"maskmovdqu %%xmm7, %%xmm0 \n"
|
||||
:: "r" (tmp_dst), "D" (tmp_src)
|
||||
:"xmm0");
|
||||
tmp_w -= 4;
|
||||
tmp_src += 16;
|
||||
tmp_dst += 4;
|
||||
};
|
||||
|
||||
while( tmp_w--)
|
||||
{
|
||||
*(tmp_src+3) = (*tmp_dst==slot)?0xFF:0x00;
|
||||
tmp_src+=4;
|
||||
tmp_dst++;
|
||||
};
|
||||
};
|
||||
#else
|
||||
u8* src_offset;
|
||||
u8* dst_offset;
|
||||
|
||||
src_offset = (u8*)(src_y*bitmap->pitch + src_x*4);
|
||||
src_offset += (u32)bitmap->uaddr;
|
||||
|
||||
dst_offset = (u8*)(dst_y*os_display->width + dst_x);
|
||||
dst_offset+= get_display_map();
|
||||
|
||||
u32_t tmp_h = height;
|
||||
|
||||
while( tmp_h--)
|
||||
{
|
||||
u32_t tmp_w = width;
|
||||
|
||||
u8* tmp_src = src_offset;
|
||||
u8* tmp_dst = dst_offset;
|
||||
|
||||
src_offset+= bitmap->pitch;
|
||||
dst_offset+= os_display->width;
|
||||
|
||||
while( tmp_w--)
|
||||
{
|
||||
*(tmp_src+3) = (*tmp_dst==slot)?0xFF:0x00;
|
||||
tmp_src+=4;
|
||||
tmp_dst++;
|
||||
};
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
if((cmd_buffer & 0xFC0)==0xFC0)
|
||||
cmd_buffer&= 0xFFFFF000;
|
||||
|
||||
b = (u32_t*)ALIGN(cmd_buffer,16);
|
||||
|
||||
offset = cmd_offset + ((u32_t)b & 0xFFF);
|
||||
|
||||
cmd = XY_SRC_COPY_CHROMA_CMD | BLT_WRITE_RGB | BLT_WRITE_ALPHA;
|
||||
cmd |= 3 << 17;
|
||||
|
||||
cmd = XY_SRC_COPY_BLT_CMD | BLT_WRITE_RGB;
|
||||
br13 = os_display->pitch;
|
||||
br13 |= 0xCC << 16;
|
||||
br13 |= 3 << 24;
|
||||
br13|= ROP_COPY_SRC << 16;
|
||||
br13|= FORMAT8888 << 24;
|
||||
|
||||
b[n++] = cmd;
|
||||
b[n++] = br13;
|
||||
b[n++] = (dst_y << 16) | dst_x;
|
||||
b[n++] = ( (dst_y+h) << 16) | (dst_x+w); // bottom, right
|
||||
b[n++] = 0; // dst_offset
|
||||
b[n++] = (src_y << 16) | src_x;
|
||||
b[n++] = (dst_y << 16) | dst_x; // left, top
|
||||
b[n++] = ((dst_y+height-1)<< 16)|(dst_x+width-1); // bottom, right
|
||||
b[n++] = 0; // destination
|
||||
b[n++] = (src_y << 16) | src_x; // source left & top
|
||||
b[n++] = bitmap->pitch; // source pitch
|
||||
b[n++] = bitmap->gaddr; // source
|
||||
|
||||
b[n++] = bitmap->pitch;
|
||||
b[n++] = bitmap->gaddr;
|
||||
b[n++] = 0; // Transparency Color Low
|
||||
b[n++] = 0x00FFFFFF; // Transparency Color High
|
||||
|
||||
b[n++] = MI_BATCH_BUFFER_END;
|
||||
if( n & 1)
|
||||
@ -706,7 +809,11 @@ int blit_video(u32 hbitmap, int dst_x, int dst_y,
|
||||
|
||||
// i915_gem_object_set_to_gtt_domain(obj, false);
|
||||
|
||||
ring = &dev_priv->ring[BCS];
|
||||
if (HAS_BLT(main_device))
|
||||
ring = &dev_priv->ring[BCS];
|
||||
else
|
||||
ring = &dev_priv->ring[RCS];
|
||||
|
||||
ring->dispatch_execbuffer(ring, cmd_offset, n*4);
|
||||
|
||||
intel_ring_begin(ring, 4);
|
||||
|
@ -12,14 +12,13 @@
|
||||
#include <linux/pci.h>
|
||||
#include <syscall.h>
|
||||
|
||||
typedef struct bitmap bitmap_t;
|
||||
#include "bitmap.h"
|
||||
|
||||
void parse_cmdline(char *cmdline, char *log);
|
||||
int _stdcall display_handler(ioctl_t *io);
|
||||
int init_agp(void);
|
||||
|
||||
int create_video(int width, int height, u32_t *outp);
|
||||
int create_bitmap(bitmap_t **pbitmap, int width, int height);
|
||||
int video_blit(uint64_t src_offset, int x, int y,
|
||||
int w, int h, int pitch);
|
||||
|
||||
@ -52,7 +51,7 @@ u32_t drvEntry(int action, char *cmdline)
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
dbgprintf("i915_early_preview second edition\n cmdline: %s\n", cmdline);
|
||||
dbgprintf("i915 blitter preview\n cmdline: %s\n", cmdline);
|
||||
|
||||
enum_pci_devices();
|
||||
|
||||
@ -78,9 +77,9 @@ u32_t drvEntry(int action, char *cmdline)
|
||||
#define SRV_ENUM_MODES 1
|
||||
#define SRV_SET_MODE 2
|
||||
|
||||
#define SRV_CREATE_VIDEO 9
|
||||
#define SRV_BLIT_VIDEO 10
|
||||
#define SRV_CREATE_BITMAP 11
|
||||
#define SRV_CREATE_BITMAP 10
|
||||
|
||||
#define SRV_BLIT_VIDEO 20
|
||||
|
||||
#define check_input(size) \
|
||||
if( unlikely((inp==NULL)||(io->inp_size != (size))) ) \
|
||||
@ -124,25 +123,18 @@ int _stdcall display_handler(ioctl_t *io)
|
||||
retval = set_user_mode((videomode_t*)inp);
|
||||
break;
|
||||
|
||||
case SRV_CREATE_VIDEO:
|
||||
check_input(2);
|
||||
check_output(4);
|
||||
retval = create_video(inp[0], inp[1], outp);
|
||||
case SRV_CREATE_BITMAP:
|
||||
check_input(5);
|
||||
retval = create_bitmap((struct ubitmap*)inp);
|
||||
break;
|
||||
|
||||
|
||||
case SRV_BLIT_VIDEO:
|
||||
video_blit( ((uint64_t*)inp)[0], inp[2], inp[3],
|
||||
inp[4], inp[5], inp[6]);
|
||||
blit_video( inp[0], inp[1], inp[2],
|
||||
inp[3], inp[4], inp[5], inp[6]);
|
||||
|
||||
retval = 0;
|
||||
break;
|
||||
|
||||
case SRV_CREATE_BITMAP:
|
||||
check_input(8);
|
||||
check_output(4);
|
||||
retval = create_bitmap((bitmap_t**)outp, inp[0], inp[1]);
|
||||
break;
|
||||
|
||||
};
|
||||
|
||||
return retval;
|
||||
|
Loading…
Reference in New Issue
Block a user