Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 2342 → Rev 2341

/drivers/video/drm/i915/intel_sprite.c
File deleted
/drivers/video/drm/i915/bitmap.c
6,16 → 6,6
#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;
30,14 → 20,12
};
 
 
int create_bitmap(struct ubitmap *pbitmap)
int create_bitmap(struct ubitmap *pbitmap, int width, int height)
{
struct drm_i915_gem_object *obj;
 
bitmap_t *bitmap;
u32 handle;
u32 width;
u32 height;
u32 size;
u32 pitch;
void *uaddr;
47,24 → 35,15
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;
 
73,7 → 52,6
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)
110,15 → 88,9
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:
127,7 → 99,7
// drm_gem_object_unreference(&obj->base);
err2:
free_handle(&bm_man, handle);
__DestroyObject(bitmap);
DestroyObject(bitmap);
err1:
return -1;
 
134,6 → 106,67
};
 
 
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;
/drivers/video/drm/i915/bitmap.h
55,6 → 55,5
void *data;
};
 
int create_bitmap(struct ubitmap *pbitmap);
int init_bitmaps();
int create_bitmap(struct ubitmap *pbitmap, int width, int height);
 
/drivers/video/drm/i915/i915_drv.c
53,7 → 53,7
 
unsigned int i915_powersave __read_mostly = 0;
 
unsigned int i915_enable_rc6 __read_mostly = -1;
unsigned int i915_enable_rc6 __read_mostly = 0;
 
unsigned int i915_enable_fbc __read_mostly = 0;
 
66,7 → 66,7
#define PCI_VENDOR_ID_INTEL 0x8086
 
#define INTEL_VGA_DEVICE(id, info) { \
.class = PCI_BASE_CLASS_DISPLAY << 16, \
.class = PCI_CLASS_DISPLAY_VGA << 8, \
.class_mask = 0xff0000, \
.vendor = 0x8086, \
.device = id, \
277,7 → 277,7
}
}
 
void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
{
int count;
 
293,22 → 293,6
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
317,37 → 301,28
*/
void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
{
unsigned long irqflags;
// WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
 
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);
/* 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);
}
 
void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
static 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)
{
unsigned long irqflags;
// WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
 
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);
if (atomic_dec_and_test(&dev_priv->forcewake_count))
__gen6_gt_force_wake_put(dev_priv);
}
 
void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
466,39 → 441,3
}
 
 
#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
/drivers/video/drm/i915/i915_drv.h
105,7 → 105,6
struct opregion_acpi;
struct opregion_swsci;
struct opregion_asle;
struct drm_i915_private;
 
struct intel_opregion {
struct opregion_header *header;
125,9 → 124,6
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;
141,6 → 137,7
u8 slave_addr;
u8 dvo_wiring;
u8 i2c_pin;
u8 i2c_speed;
u8 ddc_pin;
};
 
170,7 → 167,7
u32 instdone1;
u32 seqno;
u64 bbaddr;
u64 fence[I915_MAX_NUM_FENCES];
u64 fence[16];
struct timeval time;
struct drm_i915_error_object {
int page_count;
184,7 → 181,7
u32 gtt_offset;
u32 read_domains;
u32 write_domain;
s32 fence_reg:I915_MAX_NUM_FENCE_BITS;
s32 fence_reg:5;
s32 pinned:2;
u32 tiling:2;
u32 dirty:1;
205,15 → 202,11
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);
222,8 → 215,6
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 */
286,13 → 277,7
int relative_constants_mode;
 
void __iomem *regs;
/** 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;
u32 gt_fifo_count;
 
struct intel_gmbus {
struct i2c_adapter adapter;
343,8 → 328,6
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;
 
358,11 → 341,11
 
/* 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 */
 
372,7 → 355,6
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;
390,7 → 372,7
// struct notifier_block lid_notifier;
 
int crt_ddc_pin;
struct drm_i915_fence_reg fence_regs[I915_MAX_NUM_FENCES]; /* assume 965 */
struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */
int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */
int num_fence_regs; /* 8 on pre-965, 16 otherwise */
 
521,7 → 503,7
u8 saveAR[21];
u8 saveDACMASK;
u8 saveCR[37];
uint64_t saveFENCE[I915_MAX_NUM_FENCES];
uint64_t saveFENCE[16];
u32 saveCURACNTR;
u32 saveCURAPOS;
u32 saveCURABASE;
688,9 → 670,10
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[3];
struct drm_crtc *pipe_to_crtc_mapping[3];
struct drm_crtc *plane_to_crtc_mapping[2];
struct drm_crtc *pipe_to_crtc_mapping[2];
// wait_queue_head_t pending_flip_queue;
bool flip_pending_is_done;
 
722,7 → 705,6
 
u64 last_count1;
unsigned long last_time1;
unsigned long chipset_power;
u64 last_count2;
struct timespec last_time2;
unsigned long gfx_power;
745,6 → 727,8
 
// struct drm_property *broadcast_rgb_property;
// struct drm_property *force_audio_property;
 
atomic_t forcewake_count;
} drm_i915_private_t;
 
enum i915_cache_level {
791,8 → 775,10
* 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:I915_MAX_NUM_FENCE_BITS;
signed int fence_reg : 5;
 
/**
* Advice: are the backing pages purgeable?
929,7 → 915,7
 
struct drm_i915_file_private {
struct {
spinlock_t lock;
// struct spinlock lock;
struct list_head request_list;
} mm;
};
1173,9 → 1159,6
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);
1272,10 → 1255,12
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 */
1311,17 → 1296,11
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 __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
extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev);
1370,7 → 1349,18
((reg) != FORCEWAKE))
 
#define __i915_read(x, y) \
u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg);
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; \
}
 
__i915_read(8, b)
__i915_read(16, w)
1379,8 → 1369,13
#undef __i915_read
 
#define __i915_write(x, y) \
void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val);
 
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); \
}
__i915_write(8, b)
__i915_write(16, w)
__i915_write(32, l)
/drivers/video/drm/i915/i915_gem.c
246,8 → 246,6
u32 handle;
 
size = roundup(size, PAGE_SIZE);
if (size == 0)
return -EINVAL;
 
/* Allocate the new object */
obj = i915_gem_alloc_object(dev, size);
1567,6 → 1565,13
 
 
 
 
 
 
 
 
 
 
struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
size_t size)
{
1588,7 → 1593,7
obj->base.write_domain = I915_GEM_DOMAIN_CPU;
obj->base.read_domains = I915_GEM_DOMAIN_CPU;
 
if (IS_GEN6(dev) || IS_GEN7(dev)) {
if (IS_GEN6(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
1782,7 → 1787,7
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 < I915_MAX_NUM_FENCES; i++)
for (i = 0; i < 16; i++)
INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list);
// INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
// i915_gem_retire_work_handler);
/drivers/video/drm/i915/intel_display.c
31,7 → 31,6
#include <linux/kernel.h>
#include <linux/slab.h>
//#include <linux/vgaarb.h>
#include <drm/drm_edid.h>
#include "drmP.h"
#include "intel_drv.h"
#include "i915_drm.h"
834,19 → 833,6
u32 val;
bool cur_state;
 
if (HAS_PCH_CPT(dev_priv->dev)) {
u32 pch_dpll;
 
pch_dpll = I915_READ(PCH_DPLL_SEL);
 
/* Make sure the selected PLL is enabled to the transcoder */
WARN(!((pch_dpll >> (4 * pipe)) & 8),
"transcoder %d PLL not enabled\n", pipe);
 
/* Convert the transcoder pipe number to a pll pipe number */
pipe = (pch_dpll >> (4 * pipe)) & 1;
}
 
reg = PCH_DPLL(pipe);
val = I915_READ(reg);
cur_state = !!(val & DPLL_VCO_ENABLE);
946,7 → 932,7
pipe_name(pipe));
}
 
void assert_pipe(struct drm_i915_private *dev_priv,
static void assert_pipe(struct drm_i915_private *dev_priv,
enum pipe pipe, bool state)
{
int reg;
960,6 → 946,8
"pipe %c assertion failure (expected %s, current %s)\n",
pipe_name(pipe), state_string(state), state_string(cur_state));
}
#define assert_pipe_enabled(d, p) assert_pipe(d, p, true)
#define assert_pipe_disabled(d, p) assert_pipe(d, p, false)
 
static void assert_plane_enabled(struct drm_i915_private *dev_priv,
enum plane plane)
1214,9 → 1202,6
int reg;
u32 val;
 
if (pipe > 1)
return;
 
/* PCH only available on ILK+ */
BUG_ON(dev_priv->info->gen < 5);
 
1235,12 → 1220,8
enum pipe pipe)
{
int reg;
u32 val, pll_mask = TRANSC_DPLL_ENABLE | TRANSC_DPLLB_SEL,
pll_sel = TRANSC_DPLL_ENABLE;
u32 val;
 
if (pipe > 1)
return;
 
/* PCH only available on ILK+ */
BUG_ON(dev_priv->info->gen < 5);
 
1247,15 → 1228,6
/* Make sure transcoder isn't still depending on us */
assert_transcoder_disabled(dev_priv, pipe);
 
if (pipe == 0)
pll_sel |= TRANSC_DPLLA_SEL;
else if (pipe == 1)
pll_sel |= TRANSC_DPLLB_SEL;
 
 
if ((I915_READ(PCH_DPLL_SEL) & pll_mask) == pll_sel)
return;
 
reg = PCH_DPLL(pipe);
val = I915_READ(reg);
val &= ~DPLL_VCO_ENABLE;
1315,7 → 1287,7
I915_WRITE(reg, val);
/* wait for PCH transcoder off, transcoder state */
if (wait_for((I915_READ(reg) & TRANS_STATE_ENABLE) == 0, 50))
DRM_ERROR("failed to disable transcoder %d\n", pipe);
DRM_ERROR("failed to disable transcoder\n");
}
 
/**
1550,8 → 1522,8
u32 fbc_ctl, fbc_ctl2;
 
cfb_pitch = dev_priv->cfb_size / FBC_LL_SIZE;
if (fb->pitches[0] < cfb_pitch)
cfb_pitch = fb->pitches[0];
if (fb->pitch < cfb_pitch)
cfb_pitch = fb->pitch;
 
/* FBC_CTL wants 64B units */
cfb_pitch = (cfb_pitch / 64) - 1;
1815,7 → 1787,6
struct drm_framebuffer *fb;
struct intel_framebuffer *intel_fb;
struct drm_i915_gem_object *obj;
int enable_fbc;
 
DRM_DEBUG_KMS("\n");
 
1856,15 → 1827,8
intel_fb = to_intel_framebuffer(fb);
obj = intel_fb->obj;
 
enable_fbc = i915_enable_fbc;
if (enable_fbc < 0) {
DRM_DEBUG_KMS("fbc set to per-chip default\n");
enable_fbc = 1;
if (INTEL_INFO(dev)->gen <= 5)
enable_fbc = 0;
}
if (!enable_fbc) {
DRM_DEBUG_KMS("fbc disabled per module param\n");
if (!i915_enable_fbc) {
DRM_DEBUG_KMS("fbc disabled per module param (default off)\n");
dev_priv->no_fbc_reason = FBC_MODULE_PARAM;
goto out_disable;
}
2069,11 → 2033,11
I915_WRITE(reg, dspcntr);
 
Start = obj->gtt_offset;
Offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
Offset = y * fb->pitch + x * (fb->bits_per_pixel / 8);
 
DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n",
Start, Offset, x, y, fb->pitches[0]);
I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
Start, Offset, x, y, fb->pitch);
I915_WRITE(DSPSTRIDE(plane), fb->pitch);
if (INTEL_INFO(dev)->gen >= 4) {
I915_WRITE(DSPSURF(plane), Start);
I915_WRITE(DSPTILEOFF(plane), (y << 16) | x);
2101,7 → 2065,6
switch (plane) {
case 0:
case 1:
case 2:
break;
default:
DRM_ERROR("Can't update plane %d in SAREA\n", plane);
2150,11 → 2113,11
I915_WRITE(reg, dspcntr);
 
Start = obj->gtt_offset;
Offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
Offset = y * fb->pitch + x * (fb->bits_per_pixel / 8);
 
DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n",
Start, Offset, x, y, fb->pitches[0]);
I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
Start, Offset, x, y, fb->pitch);
I915_WRITE(DSPSTRIDE(plane), fb->pitch);
I915_WRITE(DSPSURF(plane), Start);
I915_WRITE(DSPTILEOFF(plane), (y << 16) | x);
I915_WRITE(DSPADDR(plane), Offset);
2195,7 → 2158,7
struct drm_device *dev = crtc->dev;
struct drm_i915_master_private *master_priv;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int ret;
int ret = 0;
 
ENTER();
 
2209,10 → 2172,6
case 0:
case 1:
break;
case 2:
if (IS_IVYBRIDGE(dev))
break;
/* fall through otherwise */
default:
DRM_ERROR("no plane for crtc\n");
return -EINVAL;
2611,7 → 2570,6
temp |= FDI_LINK_TRAIN_PATTERN_1_IVB;
temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B;
temp |= FDI_COMPOSITE_SYNC;
I915_WRITE(reg, temp | FDI_TX_ENABLE);
 
reg = FDI_RX_CTL(pipe);
2619,7 → 2577,6
temp &= ~FDI_LINK_TRAIN_AUTO;
temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
temp |= FDI_COMPOSITE_SYNC;
I915_WRITE(reg, temp | FDI_RX_ENABLE);
 
POSTING_READ(reg);
2879,7 → 2836,7
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int pipe = intel_crtc->pipe;
u32 reg, temp, transc_sel;
u32 reg, temp;
 
/* For PCH output, training FDI link */
dev_priv->display.fdi_link_train(crtc);
2887,21 → 2844,12
intel_enable_pch_pll(dev_priv, pipe);
 
if (HAS_PCH_CPT(dev)) {
transc_sel = intel_crtc->use_pll_a ? TRANSC_DPLLA_SEL :
TRANSC_DPLLB_SEL;
 
/* Be sure PCH DPLL SEL is set */
temp = I915_READ(PCH_DPLL_SEL);
if (pipe == 0) {
temp &= ~(TRANSA_DPLLB_SEL);
if (pipe == 0 && (temp & TRANSA_DPLL_ENABLE) == 0)
temp |= (TRANSA_DPLL_ENABLE | TRANSA_DPLLA_SEL);
} else if (pipe == 1) {
temp &= ~(TRANSB_DPLLB_SEL);
else if (pipe == 1 && (temp & TRANSB_DPLL_ENABLE) == 0)
temp |= (TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL);
} else if (pipe == 2) {
temp &= ~(TRANSC_DPLLB_SEL);
temp |= (TRANSC_DPLL_ENABLE | transc_sel);
}
I915_WRITE(PCH_DPLL_SEL, temp);
}
 
2919,8 → 2867,7
 
/* For PCH DP, enable TRANS_DP_CTL */
if (HAS_PCH_CPT(dev) &&
(intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) ||
intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) {
intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) {
u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK) >> 5;
reg = TRANS_DP_CTL(pipe);
temp = I915_READ(reg);
2958,24 → 2905,6
intel_enable_transcoder(dev_priv, pipe);
}
 
void intel_cpt_verify_modeset(struct drm_device *dev, int pipe)
{
struct drm_i915_private *dev_priv = dev->dev_private;
int dslreg = PIPEDSL(pipe), tc2reg = TRANS_CHICKEN2(pipe);
u32 temp;
 
temp = I915_READ(dslreg);
udelay(500);
if (wait_for(I915_READ(dslreg) != temp, 5)) {
/* Without this, mode sets may fail silently on FDI */
I915_WRITE(tc2reg, TRANS_AUTOTRAIN_GEN_STALL_DIS);
udelay(250);
I915_WRITE(tc2reg, 0);
if (wait_for(I915_READ(dslreg) != temp, 5))
DRM_ERROR("mode set failed: pipe %d stuck\n", pipe);
}
}
 
static void ironlake_crtc_enable(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
3088,13 → 3017,13
temp = I915_READ(PCH_DPLL_SEL);
switch (pipe) {
case 0:
temp &= ~(TRANSA_DPLL_ENABLE | TRANSA_DPLLB_SEL);
temp &= ~(TRANSA_DPLL_ENABLE | TRANSA_DPLLA_SEL);
break;
case 1:
temp &= ~(TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL);
break;
case 2:
/* C shares PLL A or B */
/* FIXME: manage transcoder PLLs? */
temp &= ~(TRANSC_DPLL_ENABLE | TRANSC_DPLLB_SEL);
break;
default:
3104,7 → 3033,6
}
 
/* disable PCH DPLL */
if (!intel_crtc->no_pll)
intel_disable_pch_pll(dev_priv, pipe);
 
/* Switch from PCDclk to Rawclk */
3353,15 → 3281,8
void intel_encoder_commit(struct drm_encoder *encoder)
{
struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
struct drm_device *dev = encoder->dev;
struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
struct intel_crtc *intel_crtc = to_intel_crtc(intel_encoder->base.crtc);
 
/* lvds has its own version of commit see intel_lvds_commit */
encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
 
if (HAS_PCH_CPT(dev))
intel_cpt_verify_modeset(dev, intel_crtc->pipe);
}
 
void intel_encoder_destroy(struct drm_encoder *encoder)
4503,7 → 4424,7
*/
}
 
void sandybridge_update_wm(struct drm_device *dev)
static void sandybridge_update_wm(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */
4537,20 → 4458,6
enabled |= 2;
}
 
/* IVB has 3 pipes */
if (IS_IVYBRIDGE(dev) &&
g4x_compute_wm0(dev, 2,
&sandybridge_display_wm_info, latency,
&sandybridge_cursor_wm_info, latency,
&plane_wm, &cursor_wm)) {
I915_WRITE(WM0_PIPEC_IVB,
(plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
DRM_DEBUG_KMS("FIFO watermarks For pipe C -"
" plane %d, cursor: %d\n",
plane_wm, cursor_wm);
enabled |= 3;
}
 
/*
* Calculate and update the self-refresh watermark only when one
* display plane is used.
4565,11 → 4472,16
I915_WRITE(WM2_LP_ILK, 0);
I915_WRITE(WM1_LP_ILK, 0);
 
if (!single_plane_enabled(enabled) ||
dev_priv->sprite_scaling_enabled)
if (!single_plane_enabled(enabled))
{
LEAVE();
return;
};
 
enabled = ffs(enabled) - 1;
 
dbgprintf("compute wm1\n");
 
/* WM1 */
if (!ironlake_compute_srwm(dev, 1, enabled,
SNB_READ_WM1_LATENCY() * 500,
4585,6 → 4497,8
(plane_wm << WM1_LP_SR_SHIFT) |
cursor_wm);
 
dbgprintf("compute wm2\n");
 
/* WM2 */
if (!ironlake_compute_srwm(dev, 2, enabled,
SNB_READ_WM2_LATENCY() * 500,
4600,6 → 4514,8
(plane_wm << WM1_LP_SR_SHIFT) |
cursor_wm);
 
dbgprintf("compute wm3\n");
 
/* WM3 */
if (!ironlake_compute_srwm(dev, 3, enabled,
SNB_READ_WM3_LATENCY() * 500,
4614,151 → 4530,11
(fbc_wm << WM1_LP_FBC_SHIFT) |
(plane_wm << WM1_LP_SR_SHIFT) |
cursor_wm);
}
 
static bool
sandybridge_compute_sprite_wm(struct drm_device *dev, int plane,
uint32_t sprite_width, int pixel_size,
const struct intel_watermark_params *display,
int display_latency_ns, int *sprite_wm)
{
struct drm_crtc *crtc;
int clock;
int entries, tlb_miss;
LEAVE();
 
crtc = intel_get_crtc_for_plane(dev, plane);
if (crtc->fb == NULL || !crtc->enabled) {
*sprite_wm = display->guard_size;
return false;
}
 
clock = crtc->mode.clock;
 
/* Use the small buffer method to calculate the sprite watermark */
entries = ((clock * pixel_size / 1000) * display_latency_ns) / 1000;
tlb_miss = display->fifo_size*display->cacheline_size -
sprite_width * 8;
if (tlb_miss > 0)
entries += tlb_miss;
entries = DIV_ROUND_UP(entries, display->cacheline_size);
*sprite_wm = entries + display->guard_size;
if (*sprite_wm > (int)display->max_wm)
*sprite_wm = display->max_wm;
 
return true;
}
 
static bool
sandybridge_compute_sprite_srwm(struct drm_device *dev, int plane,
uint32_t sprite_width, int pixel_size,
const struct intel_watermark_params *display,
int latency_ns, int *sprite_wm)
{
struct drm_crtc *crtc;
unsigned long line_time_us;
int clock;
int line_count, line_size;
int small, large;
int entries;
 
if (!latency_ns) {
*sprite_wm = 0;
return false;
}
 
crtc = intel_get_crtc_for_plane(dev, plane);
clock = crtc->mode.clock;
 
line_time_us = (sprite_width * 1000) / clock;
line_count = (latency_ns / line_time_us + 1000) / 1000;
line_size = sprite_width * pixel_size;
 
/* Use the minimum of the small and large buffer method for primary */
small = ((clock * pixel_size / 1000) * latency_ns) / 1000;
large = line_count * line_size;
 
entries = DIV_ROUND_UP(min(small, large), display->cacheline_size);
*sprite_wm = entries + display->guard_size;
 
return *sprite_wm > 0x3ff ? false : true;
}
 
static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe,
uint32_t sprite_width, int pixel_size)
{
struct drm_i915_private *dev_priv = dev->dev_private;
int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */
int sprite_wm, reg;
int ret;
 
switch (pipe) {
case 0:
reg = WM0_PIPEA_ILK;
break;
case 1:
reg = WM0_PIPEB_ILK;
break;
case 2:
reg = WM0_PIPEC_IVB;
break;
default:
return; /* bad pipe */
}
 
ret = sandybridge_compute_sprite_wm(dev, pipe, sprite_width, pixel_size,
&sandybridge_display_wm_info,
latency, &sprite_wm);
if (!ret) {
DRM_DEBUG_KMS("failed to compute sprite wm for pipe %d\n",
pipe);
return;
}
 
I915_WRITE(reg, I915_READ(reg) | (sprite_wm << WM0_PIPE_SPRITE_SHIFT));
DRM_DEBUG_KMS("sprite watermarks For pipe %d - %d\n", pipe, sprite_wm);
 
 
ret = sandybridge_compute_sprite_srwm(dev, pipe, sprite_width,
pixel_size,
&sandybridge_display_srwm_info,
SNB_READ_WM1_LATENCY() * 500,
&sprite_wm);
if (!ret) {
DRM_DEBUG_KMS("failed to compute sprite lp1 wm on pipe %d\n",
pipe);
return;
}
I915_WRITE(WM1S_LP_ILK, sprite_wm);
 
/* Only IVB has two more LP watermarks for sprite */
if (!IS_IVYBRIDGE(dev))
return;
 
ret = sandybridge_compute_sprite_srwm(dev, pipe, sprite_width,
pixel_size,
&sandybridge_display_srwm_info,
SNB_READ_WM2_LATENCY() * 500,
&sprite_wm);
if (!ret) {
DRM_DEBUG_KMS("failed to compute sprite lp2 wm on pipe %d\n",
pipe);
return;
}
I915_WRITE(WM2S_LP_IVB, sprite_wm);
 
ret = sandybridge_compute_sprite_srwm(dev, pipe, sprite_width,
pixel_size,
&sandybridge_display_srwm_info,
SNB_READ_WM3_LATENCY() * 500,
&sprite_wm);
if (!ret) {
DRM_DEBUG_KMS("failed to compute sprite lp3 wm on pipe %d\n",
pipe);
return;
}
I915_WRITE(WM3S_LP_IVB, sprite_wm);
}
 
/**
* intel_update_watermarks - update FIFO watermark values based on current modes
*
4800,21 → 4576,9
LEAVE();
}
 
void intel_update_sprite_watermarks(struct drm_device *dev, int pipe,
uint32_t sprite_width, int pixel_size)
{
struct drm_i915_private *dev_priv = dev->dev_private;
 
if (dev_priv->display.update_sprite_wm)
dev_priv->display.update_sprite_wm(dev, pipe, sprite_width,
pixel_size);
}
 
static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv)
{
if (i915_panel_use_ssc >= 0)
return i915_panel_use_ssc != 0;
return dev_priv->lvds_use_ssc
return dev_priv->lvds_use_ssc && i915_panel_use_ssc
&& !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE);
}
 
4821,7 → 4585,6
/**
* intel_choose_pipe_bpp_dither - figure out what color depth the pipe should send
* @crtc: CRTC structure
* @mode: requested mode
*
* A pipe may be connected to one or more outputs. Based on the depth of the
* attached framebuffer, choose a good color depth to use on the pipe.
4833,7 → 4596,6
* HDMI supports only 8bpc or 12bpc, so clamp to 8bpc with dither for 10bpc
* Displays may support a restricted set as well, check EDID and clamp as
* appropriate.
* DP may want to dither down to 6bpc to fit larger modes
*
* RETURNS:
* Dithering requirement (i.e. false if display bpc and pipe bpc match,
4840,8 → 4602,7
* true if they don't match).
*/
static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
unsigned int *pipe_bpp,
struct drm_display_mode *mode)
unsigned int *pipe_bpp)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
4866,7 → 4627,7
lvds_bpc = 6;
 
if (lvds_bpc < display_bpc) {
DRM_DEBUG_KMS("clamping display bpc (was %d) to LVDS (%d)\n", display_bpc, lvds_bpc);
DRM_DEBUG_DRIVER("clamping display bpc (was %d) to LVDS (%d)\n", display_bpc, lvds_bpc);
display_bpc = lvds_bpc;
}
continue;
4877,7 → 4638,7
unsigned int edp_bpc = dev_priv->edp.bpp / 3;
 
if (edp_bpc < display_bpc) {
DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc);
DRM_DEBUG_DRIVER("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc);
display_bpc = edp_bpc;
}
continue;
4892,7 → 4653,7
/* Don't use an invalid EDID bpc value */
if (connector->display_info.bpc &&
connector->display_info.bpc < display_bpc) {
DRM_DEBUG_KMS("clamping display bpc (was %d) to EDID reported max of %d\n", display_bpc, connector->display_info.bpc);
DRM_DEBUG_DRIVER("clamping display bpc (was %d) to EDID reported max of %d\n", display_bpc, connector->display_info.bpc);
display_bpc = connector->display_info.bpc;
}
}
4903,20 → 4664,15
*/
if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
if (display_bpc > 8 && display_bpc < 12) {
DRM_DEBUG_KMS("forcing bpc to 12 for HDMI\n");
DRM_DEBUG_DRIVER("forcing bpc to 12 for HDMI\n");
display_bpc = 12;
} else {
DRM_DEBUG_KMS("forcing bpc to 8 for HDMI\n");
DRM_DEBUG_DRIVER("forcing bpc to 8 for HDMI\n");
display_bpc = 8;
}
}
}
 
if (mode->private_flags & INTEL_MODE_DP_FORCE_6BPC) {
DRM_DEBUG_KMS("Dithering DP to 6bpc\n");
display_bpc = 6;
}
 
/*
* We could just drive the pipe at the highest bpc all the time and
* enable dithering as needed, but that costs bandwidth. So choose
4933,13 → 4689,13
bpc = 6; /* min is 18bpp */
break;
case 24:
bpc = 8;
bpc = min((unsigned int)8, display_bpc);
break;
case 30:
bpc = 10;
bpc = min((unsigned int)10, display_bpc);
break;
case 48:
bpc = 12;
bpc = min((unsigned int)12, display_bpc);
break;
default:
DRM_DEBUG("unsupported depth, assuming 24 bits\n");
4947,12 → 4703,10
break;
}
 
display_bpc = min(display_bpc, bpc);
 
DRM_DEBUG_KMS("setting pipe bpc to %d (max display bpc %d)\n",
DRM_DEBUG_DRIVER("setting pipe bpc to %d (max display bpc %d)\n",
bpc, display_bpc);
 
*pipe_bpp = display_bpc * 3;
*pipe_bpp = bpc * 3;
 
return display_bpc != bpc;
}
5178,16 → 4932,6
pipeconf &= ~PIPECONF_DOUBLE_WIDE;
}
 
/* default to 8bpc */
pipeconf &= ~(PIPECONF_BPP_MASK | PIPECONF_DITHER_EN);
if (is_dp) {
if (mode->private_flags & INTEL_MODE_DP_FORCE_6BPC) {
pipeconf |= PIPECONF_BPP_6 |
PIPECONF_DITHER_EN |
PIPECONF_DITHER_TYPE_SP;
}
}
 
dpll |= DPLL_VCO_ENABLE;
 
DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
5306,7 → 5050,7
adjusted_mode->crtc_vsync_end -= 1;
adjusted_mode->crtc_vsync_start -= 1;
} else
pipeconf &= ~PIPECONF_INTERLACE_MASK; /* progressive */
pipeconf &= ~PIPECONF_INTERLACE_W_FIELD_INDICATION; /* progressive */
 
I915_WRITE(HTOTAL(pipe),
(adjusted_mode->crtc_hdisplay - 1) |
5355,52 → 5099,36
return ret;
}
 
/*
* Initialize reference clocks when the driver loads
*/
void ironlake_init_pch_refclk(struct drm_device *dev)
static void ironlake_update_pch_refclk(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_mode_config *mode_config = &dev->mode_config;
struct drm_crtc *crtc;
struct intel_encoder *encoder;
struct intel_encoder *has_edp_encoder = NULL;
u32 temp;
bool has_lvds = false;
bool has_cpu_edp = false;
bool has_pch_edp = false;
bool has_panel = false;
bool has_ck505 = false;
bool can_ssc = false;
 
/* We need to take the global config into account */
list_for_each_entry(crtc, &mode_config->crtc_list, head) {
if (!crtc->enabled)
continue;
 
list_for_each_entry(encoder, &mode_config->encoder_list,
base.head) {
if (encoder->base.crtc != crtc)
continue;
 
switch (encoder->type) {
case INTEL_OUTPUT_LVDS:
has_panel = true;
has_lvds = true;
break;
case INTEL_OUTPUT_EDP:
has_panel = true;
if (intel_encoder_is_pch_edp(&encoder->base))
has_pch_edp = true;
else
has_cpu_edp = true;
has_edp_encoder = encoder;
break;
}
}
 
if (HAS_PCH_IBX(dev)) {
has_ck505 = dev_priv->display_clock_mode;
can_ssc = has_ck505;
} else {
has_ck505 = false;
can_ssc = true;
}
 
DRM_DEBUG_KMS("has_panel %d has_lvds %d has_pch_edp %d has_cpu_edp %d has_ck505 %d\n",
has_panel, has_lvds, has_pch_edp, has_cpu_edp,
has_ck505);
 
/* Ironlake: try to setup display ref clock before DPLL
* enabling. This is only under driver's control after
* PCH B stepping, previous chipset stepping should be
5409,102 → 5137,43
temp = I915_READ(PCH_DREF_CONTROL);
/* Always enable nonspread source */
temp &= ~DREF_NONSPREAD_SOURCE_MASK;
 
if (has_ck505)
temp |= DREF_NONSPREAD_CK505_ENABLE;
else
temp |= DREF_NONSPREAD_SOURCE_ENABLE;
 
if (has_panel) {
temp &= ~DREF_SSC_SOURCE_MASK;
temp |= DREF_SSC_SOURCE_ENABLE;
I915_WRITE(PCH_DREF_CONTROL, temp);
 
/* SSC must be turned on before enabling the CPU output */
if (intel_panel_use_ssc(dev_priv) && can_ssc) {
DRM_DEBUG_KMS("Using SSC on panel\n");
POSTING_READ(PCH_DREF_CONTROL);
udelay(200);
 
if (has_edp_encoder) {
if (intel_panel_use_ssc(dev_priv)) {
temp |= DREF_SSC1_ENABLE;
}
I915_WRITE(PCH_DREF_CONTROL, temp);
 
/* Get SSC going before enabling the outputs */
I915_WRITE(PCH_DREF_CONTROL, temp);
POSTING_READ(PCH_DREF_CONTROL);
udelay(200);
 
}
temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
 
/* Enable CPU source on CPU attached eDP */
if (has_cpu_edp) {
if (intel_panel_use_ssc(dev_priv) && can_ssc) {
DRM_DEBUG_KMS("Using SSC on eDP\n");
if (!intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
if (intel_panel_use_ssc(dev_priv))
temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD;
}
else
temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
} else
temp |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
 
I915_WRITE(PCH_DREF_CONTROL, temp);
POSTING_READ(PCH_DREF_CONTROL);
udelay(200);
} else {
DRM_DEBUG_KMS("Disabling SSC entirely\n");
 
temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
 
/* Turn off CPU output */
temp |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
 
/* Enable SSC on PCH eDP if needed */
if (intel_panel_use_ssc(dev_priv)) {
DRM_ERROR("enabling SSC on PCH\n");
temp |= DREF_SUPERSPREAD_SOURCE_ENABLE;
}
}
I915_WRITE(PCH_DREF_CONTROL, temp);
POSTING_READ(PCH_DREF_CONTROL);
udelay(200);
 
/* Turn off the SSC source */
temp &= ~DREF_SSC_SOURCE_MASK;
temp |= DREF_SSC_SOURCE_DISABLE;
 
/* Turn off SSC1 */
temp &= ~ DREF_SSC1_ENABLE;
 
I915_WRITE(PCH_DREF_CONTROL, temp);
POSTING_READ(PCH_DREF_CONTROL);
udelay(200);
}
}
 
static int ironlake_get_refclk(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_encoder *encoder;
struct drm_mode_config *mode_config = &dev->mode_config;
struct intel_encoder *edp_encoder = NULL;
int num_connectors = 0;
bool is_lvds = false;
 
list_for_each_entry(encoder, &mode_config->encoder_list, base.head) {
if (encoder->base.crtc != crtc)
continue;
 
switch (encoder->type) {
case INTEL_OUTPUT_LVDS:
is_lvds = true;
break;
case INTEL_OUTPUT_EDP:
edp_encoder = encoder;
break;
}
num_connectors++;
}
 
if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) {
DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n",
dev_priv->lvds_ssc_freq);
return dev_priv->lvds_ssc_freq * 1000;
}
 
return 120000;
}
 
static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode,
5566,7 → 5235,16
num_connectors++;
}
 
refclk = ironlake_get_refclk(crtc);
if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) {
refclk = dev_priv->lvds_ssc_freq * 1000;
DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n",
refclk / 1000);
} else {
refclk = 96000;
if (!has_edp_encoder ||
intel_encoder_is_pch_edp(&has_edp_encoder->base))
refclk = 120000; /* 120Mhz refclk */
}
 
/*
* Returns a set of divisors for the desired target clock with the given
5651,7 → 5329,7
/* determine panel color depth */
temp = I915_READ(PIPECONF(pipe));
temp &= ~PIPE_BPC_MASK;
dither = intel_choose_pipe_bpp_dither(crtc, &pipe_bpp, mode);
dither = intel_choose_pipe_bpp_dither(crtc, &pipe_bpp);
switch (pipe_bpp) {
case 18:
temp |= PIPE_6BPC;
5693,6 → 5371,8
ironlake_compute_m_n(intel_crtc->bpp, lane, target_clock, link_bw,
&m_n);
 
ironlake_update_pch_refclk(dev);
 
fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
if (has_reduced_clock)
fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 |
5764,13 → 5444,11
/* Set up the display plane register */
dspcntr = DISPPLANE_GAMMA_ENABLE;
 
DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe);
DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
drm_mode_debug_printmodeline(mode);
 
/* PCH eDP needs FDI, but CPU eDP does not */
if (!intel_crtc->no_pll) {
if (!has_edp_encoder ||
intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
if (!has_edp_encoder || intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
I915_WRITE(PCH_FP0(pipe), fp);
I915_WRITE(PCH_DPLL(pipe), dpll & ~DPLL_VCO_ENABLE);
 
5777,19 → 5455,28
POSTING_READ(PCH_DPLL(pipe));
udelay(150);
}
} else {
if (dpll == (I915_READ(PCH_DPLL(0)) & 0x7fffffff) &&
fp == I915_READ(PCH_FP0(0))) {
intel_crtc->use_pll_a = true;
DRM_DEBUG_KMS("using pipe a dpll\n");
} else if (dpll == (I915_READ(PCH_DPLL(1)) & 0x7fffffff) &&
fp == I915_READ(PCH_FP0(1))) {
intel_crtc->use_pll_a = false;
DRM_DEBUG_KMS("using pipe b dpll\n");
} else {
DRM_DEBUG_KMS("no matching PLL configuration for pipe 2\n");
return -EINVAL;
 
/* enable transcoder DPLL */
if (HAS_PCH_CPT(dev)) {
temp = I915_READ(PCH_DPLL_SEL);
switch (pipe) {
case 0:
temp |= TRANSA_DPLL_ENABLE | TRANSA_DPLLA_SEL;
break;
case 1:
temp |= TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL;
break;
case 2:
/* FIXME: manage transcoder PLLs? */
temp |= TRANSC_DPLL_ENABLE | TRANSC_DPLLB_SEL;
break;
default:
BUG();
}
I915_WRITE(PCH_DPLL_SEL, temp);
 
POSTING_READ(PCH_DPLL_SEL);
udelay(150);
}
 
/* The LVDS pin pair needs to be on before the DPLLs are enabled.
5799,16 → 5486,17
if (is_lvds) {
temp = I915_READ(PCH_LVDS);
temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
if (HAS_PCH_CPT(dev)) {
if (pipe == 1) {
if (HAS_PCH_CPT(dev))
temp |= PORT_TRANS_B_SEL_CPT;
else
temp |= LVDS_PIPEB_SELECT;
} else {
if (HAS_PCH_CPT(dev))
temp &= ~PORT_TRANS_SEL_MASK;
temp |= PORT_TRANS_SEL_CPT(pipe);
} else {
if (pipe == 1)
temp |= LVDS_PIPEB_SELECT;
else
temp &= ~LVDS_PIPEB_SELECT;
}
 
/* set the corresponsding LVDS_BORDER bit */
temp |= dev_priv->lvds_border_bits;
/* Set the B0-B3 data pairs corresponding to whether we're going to
5846,7 → 5534,7
pipeconf &= ~PIPECONF_DITHER_TYPE_MASK;
if ((is_lvds && dev_priv->lvds_dither) || dither) {
pipeconf |= PIPECONF_DITHER_EN;
pipeconf |= PIPECONF_DITHER_TYPE_SP;
pipeconf |= PIPECONF_DITHER_TYPE_ST1;
}
if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
intel_dp_set_m_n(crtc, mode, adjusted_mode);
5858,9 → 5546,8
I915_WRITE(TRANSDPLINK_N1(pipe), 0);
}
 
if (!intel_crtc->no_pll &&
(!has_edp_encoder ||
intel_encoder_is_pch_edp(&has_edp_encoder->base))) {
if (!has_edp_encoder ||
intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
I915_WRITE(PCH_DPLL(pipe), dpll);
 
/* Wait for the clocks to stabilize. */
5876,7 → 5563,6
}
 
intel_crtc->lowfreq_avail = false;
if (!intel_crtc->no_pll) {
if (is_lvds && has_reduced_clock && i915_powersave) {
I915_WRITE(PCH_FP1(pipe), fp2);
intel_crtc->lowfreq_avail = true;
5891,7 → 5577,6
pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK;
}
}
}
 
if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
5992,172 → 5677,6
return ret;
}
 
static bool intel_eld_uptodate(struct drm_connector *connector,
int reg_eldv, uint32_t bits_eldv,
int reg_elda, uint32_t bits_elda,
int reg_edid)
{
struct drm_i915_private *dev_priv = connector->dev->dev_private;
uint8_t *eld = connector->eld;
uint32_t i;
 
i = I915_READ(reg_eldv);
i &= bits_eldv;
 
if (!eld[0])
return !i;
 
if (!i)
return false;
 
i = I915_READ(reg_elda);
i &= ~bits_elda;
I915_WRITE(reg_elda, i);
 
for (i = 0; i < eld[2]; i++)
if (I915_READ(reg_edid) != *((uint32_t *)eld + i))
return false;
 
return true;
}
 
static void g4x_write_eld(struct drm_connector *connector,
struct drm_crtc *crtc)
{
struct drm_i915_private *dev_priv = connector->dev->dev_private;
uint8_t *eld = connector->eld;
uint32_t eldv;
uint32_t len;
uint32_t i;
 
i = I915_READ(G4X_AUD_VID_DID);
 
if (i == INTEL_AUDIO_DEVBLC || i == INTEL_AUDIO_DEVCL)
eldv = G4X_ELDV_DEVCL_DEVBLC;
else
eldv = G4X_ELDV_DEVCTG;
 
if (intel_eld_uptodate(connector,
G4X_AUD_CNTL_ST, eldv,
G4X_AUD_CNTL_ST, G4X_ELD_ADDR,
G4X_HDMIW_HDMIEDID))
return;
 
i = I915_READ(G4X_AUD_CNTL_ST);
i &= ~(eldv | G4X_ELD_ADDR);
len = (i >> 9) & 0x1f; /* ELD buffer size */
I915_WRITE(G4X_AUD_CNTL_ST, i);
 
if (!eld[0])
return;
 
len = min_t(uint8_t, eld[2], len);
DRM_DEBUG_DRIVER("ELD size %d\n", len);
for (i = 0; i < len; i++)
I915_WRITE(G4X_HDMIW_HDMIEDID, *((uint32_t *)eld + i));
 
i = I915_READ(G4X_AUD_CNTL_ST);
i |= eldv;
I915_WRITE(G4X_AUD_CNTL_ST, i);
}
 
static void ironlake_write_eld(struct drm_connector *connector,
struct drm_crtc *crtc)
{
struct drm_i915_private *dev_priv = connector->dev->dev_private;
uint8_t *eld = connector->eld;
uint32_t eldv;
uint32_t i;
int len;
int hdmiw_hdmiedid;
int aud_cntl_st;
int aud_cntrl_st2;
 
if (HAS_PCH_IBX(connector->dev)) {
hdmiw_hdmiedid = IBX_HDMIW_HDMIEDID_A;
aud_cntl_st = IBX_AUD_CNTL_ST_A;
aud_cntrl_st2 = IBX_AUD_CNTL_ST2;
} else {
hdmiw_hdmiedid = CPT_HDMIW_HDMIEDID_A;
aud_cntl_st = CPT_AUD_CNTL_ST_A;
aud_cntrl_st2 = CPT_AUD_CNTRL_ST2;
}
 
i = to_intel_crtc(crtc)->pipe;
hdmiw_hdmiedid += i * 0x100;
aud_cntl_st += i * 0x100;
 
DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(i));
 
i = I915_READ(aud_cntl_st);
i = (i >> 29) & 0x3; /* DIP_Port_Select, 0x1 = PortB */
if (!i) {
DRM_DEBUG_DRIVER("Audio directed to unknown port\n");
/* operate blindly on all ports */
eldv = IBX_ELD_VALIDB;
eldv |= IBX_ELD_VALIDB << 4;
eldv |= IBX_ELD_VALIDB << 8;
} else {
DRM_DEBUG_DRIVER("ELD on port %c\n", 'A' + i);
eldv = IBX_ELD_VALIDB << ((i - 1) * 4);
}
 
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) {
DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n");
eld[5] |= (1 << 2); /* Conn_Type, 0x1 = DisplayPort */
}
 
if (intel_eld_uptodate(connector,
aud_cntrl_st2, eldv,
aud_cntl_st, IBX_ELD_ADDRESS,
hdmiw_hdmiedid))
return;
 
i = I915_READ(aud_cntrl_st2);
i &= ~eldv;
I915_WRITE(aud_cntrl_st2, i);
 
if (!eld[0])
return;
 
i = I915_READ(aud_cntl_st);
i &= ~IBX_ELD_ADDRESS;
I915_WRITE(aud_cntl_st, i);
 
len = min_t(uint8_t, eld[2], 21); /* 84 bytes of hw ELD buffer */
DRM_DEBUG_DRIVER("ELD size %d\n", len);
for (i = 0; i < len; i++)
I915_WRITE(hdmiw_hdmiedid, *((uint32_t *)eld + i));
 
i = I915_READ(aud_cntrl_st2);
i |= eldv;
I915_WRITE(aud_cntrl_st2, i);
}
 
void intel_write_eld(struct drm_encoder *encoder,
struct drm_display_mode *mode)
{
struct drm_crtc *crtc = encoder->crtc;
struct drm_connector *connector;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
 
connector = drm_select_eld(encoder, mode);
if (!connector)
return;
 
DRM_DEBUG_DRIVER("ELD on [CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
connector->base.id,
drm_get_connector_name(connector),
connector->encoder->base.id,
drm_get_encoder_name(connector->encoder));
 
connector->eld[6] = drm_av_sync_delay(connector, mode) / 2;
 
if (dev_priv->display.write_eld)
dev_priv->display.write_eld(connector, crtc);
}
 
/** Loads the palette/gamma unit for the CRTC with the prepared values */
void intel_crtc_load_lut(struct drm_crtc *crtc)
{
6879,8 → 6398,6
intel_crtc->bpp = 24; /* default for pre-Ironlake */
 
if (HAS_PCH_SPLIT(dev)) {
if (pipe == 2 && IS_IVYBRIDGE(dev))
intel_crtc->no_pll = true;
intel_helper_funcs.prepare = ironlake_crtc_prepare;
intel_helper_funcs.commit = ironlake_crtc_commit;
} else {
7042,9 → 6559,6
/* disable all the possible outputs/crtcs before entering KMS mode */
// drm_helper_disable_unused_functions(dev);
 
if (HAS_PCH_SPLIT(dev))
ironlake_init_pch_refclk(dev);
 
LEAVE();
}
 
7059,6 → 6573,15
 
 
 
 
 
 
 
 
 
 
 
 
static const struct drm_framebuffer_funcs intel_fb_funcs = {
// .destroy = intel_user_framebuffer_destroy,
// .create_handle = intel_user_framebuffer_create_handle,
7066,7 → 6589,7
 
int intel_framebuffer_init(struct drm_device *dev,
struct intel_framebuffer *intel_fb,
struct drm_mode_fb_cmd2 *mode_cmd,
struct drm_mode_fb_cmd *mode_cmd,
struct drm_i915_gem_object *obj)
{
int ret;
7074,25 → 6597,21
if (obj->tiling_mode == I915_TILING_Y)
return -EINVAL;
 
if (mode_cmd->pitches[0] & 63)
if (mode_cmd->pitch & 63)
return -EINVAL;
 
switch (mode_cmd->pixel_format) {
case DRM_FORMAT_RGB332:
case DRM_FORMAT_RGB565:
case DRM_FORMAT_XRGB8888:
case DRM_FORMAT_ARGB8888:
case DRM_FORMAT_XRGB2101010:
case DRM_FORMAT_ARGB2101010:
/* RGB formats are common across chipsets */
switch (mode_cmd->bpp) {
case 8:
case 16:
/* Only pre-ILK can handle 5:5:5 */
if (mode_cmd->depth == 15 && !HAS_PCH_SPLIT(dev))
return -EINVAL;
break;
case DRM_FORMAT_YUYV:
case DRM_FORMAT_UYVY:
case DRM_FORMAT_YVYU:
case DRM_FORMAT_VYUY:
 
case 24:
case 32:
break;
default:
DRM_ERROR("unsupported pixel format\n");
return -EINVAL;
}
 
7301,31 → 6820,6
dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK);
}
 
static bool intel_enable_rc6(struct drm_device *dev)
{
/*
* Respect the kernel parameter if it is set
*/
if (i915_enable_rc6 >= 0)
return i915_enable_rc6;
 
/*
* Disable RC6 on Ironlake
*/
if (INTEL_INFO(dev)->gen == 5)
return 0;
 
/*
* Disable rc6 on Sandybridge
*/
if (INTEL_INFO(dev)->gen == 6) {
DRM_DEBUG_DRIVER("Sandybridge: RC6 disabled\n");
return 0;
}
DRM_DEBUG_DRIVER("RC6 enabled\n");
return 1;
}
 
void gen6_enable_rps(struct drm_i915_private *dev_priv)
{
u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
7362,7 → 6856,7
I915_WRITE(GEN6_RC6p_THRESHOLD, 100000);
I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */
 
if (intel_enable_rc6(dev_priv->dev))
if (i915_enable_rc6)
rc6_mask = GEN6_RC_CTL_RC6p_ENABLE |
GEN6_RC_CTL_RC6_ENABLE;
 
7389,7 → 6883,7
I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
I915_WRITE(GEN6_RP_CONTROL,
GEN6_RP_MEDIA_TURBO |
GEN6_RP_MEDIA_HW_MODE |
GEN6_RP_USE_NORMAL_FREQ |
GEN6_RP_MEDIA_IS_GFX |
GEN6_RP_ENABLE |
GEN6_RP_UP_BUSY_AVG |
7588,20 → 7082,6
I915_WRITE(WM2_LP_ILK, 0);
I915_WRITE(WM1_LP_ILK, 0);
 
/* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock
* gating disable must be set. Failure to set it results in
* flickering pixels due to Z write ordering failures after
* some amount of runtime in the Mesa "fire" demo, and Unigine
* Sanctuary and Tropics, and apparently anything else with
* alpha test or pixel discard.
*
* According to the spec, bit 11 (RCCUNIT) must also be set,
* but we didn't debug actual testcases to find it out.
*/
I915_WRITE(GEN6_UCGCTL2,
GEN6_RCPBUNIT_CLOCK_GATE_DISABLE |
GEN6_RCCUNIT_CLOCK_GATE_DISABLE);
 
/*
* According to the spec the following bits should be
* set in order to enable memory self-refresh and fbc:
7644,10 → 7124,6
 
I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE);
 
I915_WRITE(IVB_CHICKEN3,
CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE |
CHICKEN3_DGMG_DONE_FIX_DISABLE);
 
for_each_pipe(pipe) {
I915_WRITE(DSPCNTR(pipe),
I915_READ(DSPCNTR(pipe)) |
7815,7 → 7291,7
/* rc6 disabled by default due to repeated reports of hanging during
* boot and resume.
*/
if (!intel_enable_rc6(dev))
if (!i915_enable_rc6)
return;
 
mutex_lock(&dev->struct_mutex);
7936,34 → 7412,6
 
/* For FIFO watermark updates */
if (HAS_PCH_SPLIT(dev)) {
dev_priv->display.force_wake_get = __gen6_gt_force_wake_get;
dev_priv->display.force_wake_put = __gen6_gt_force_wake_put;
 
/* IVB configs may use multi-threaded forcewake */
if (IS_IVYBRIDGE(dev)) {
u32 ecobus;
 
/* A small trick here - if the bios hasn't configured MT forcewake,
* and if the device is in RC6, then force_wake_mt_get will not wake
* the device and the ECOBUS read will return zero. Which will be
* (correctly) interpreted by the test below as MT forcewake being
* disabled.
*/
mutex_lock(&dev->struct_mutex);
__gen6_gt_force_wake_mt_get(dev_priv);
ecobus = I915_READ_NOTRACE(ECOBUS);
__gen6_gt_force_wake_mt_put(dev_priv);
mutex_unlock(&dev->struct_mutex);
 
if (ecobus & FORCEWAKE_MT_ENABLE) {
DRM_DEBUG_KMS("Using MT version of forcewake\n");
dev_priv->display.force_wake_get =
__gen6_gt_force_wake_mt_get;
dev_priv->display.force_wake_put =
__gen6_gt_force_wake_mt_put;
}
}
 
if (HAS_PCH_IBX(dev))
dev_priv->display.init_pch_clock_gating = ibx_init_clock_gating;
else if (HAS_PCH_CPT(dev))
7979,11 → 7427,9
}
dev_priv->display.fdi_link_train = ironlake_fdi_link_train;
dev_priv->display.init_clock_gating = ironlake_init_clock_gating;
dev_priv->display.write_eld = ironlake_write_eld;
} else if (IS_GEN6(dev)) {
if (SNB_READ_WM0_LATENCY()) {
dev_priv->display.update_wm = sandybridge_update_wm;
dev_priv->display.update_sprite_wm = sandybridge_update_sprite_wm;
} else {
DRM_DEBUG_KMS("Failed to read display plane latency. "
"Disable CxSR\n");
7991,13 → 7437,11
}
dev_priv->display.fdi_link_train = gen6_fdi_link_train;
dev_priv->display.init_clock_gating = gen6_init_clock_gating;
dev_priv->display.write_eld = ironlake_write_eld;
} else if (IS_IVYBRIDGE(dev)) {
/* FIXME: detect B0+ stepping and use auto training */
dev_priv->display.fdi_link_train = ivb_manual_fdi_link_train;
if (SNB_READ_WM0_LATENCY()) {
dev_priv->display.update_wm = sandybridge_update_wm;
dev_priv->display.update_sprite_wm = sandybridge_update_sprite_wm;
} else {
DRM_DEBUG_KMS("Failed to read display plane latency. "
"Disable CxSR\n");
8004,7 → 7448,7
dev_priv->display.update_wm = NULL;
}
dev_priv->display.init_clock_gating = ivybridge_init_clock_gating;
dev_priv->display.write_eld = ironlake_write_eld;
 
} else
dev_priv->display.update_wm = NULL;
} else if (IS_PINEVIEW(dev)) {
8024,7 → 7468,6
dev_priv->display.update_wm = pineview_update_wm;
dev_priv->display.init_clock_gating = gen3_init_clock_gating;
} else if (IS_G4X(dev)) {
dev_priv->display.write_eld = g4x_write_eld;
dev_priv->display.update_wm = g4x_update_wm;
dev_priv->display.init_clock_gating = g4x_init_clock_gating;
} else if (IS_GEN4(dev)) {
8183,7 → 7626,7
void intel_modeset_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
int i, ret;
int i;
 
drm_mode_config_init(dev);
 
8213,9 → 7656,6
 
for (i = 0; i < dev_priv->num_pipe; i++) {
intel_crtc_init(dev, i);
ret = intel_plane_init(dev, i);
if (ret)
DRM_DEBUG_KMS("plane %d init failed: %d\n", i, ret);
}
 
/* Just disable it once at startup */
/drivers/video/drm/i915/intel_ringbuffer.c
36,16 → 36,6
//#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);
135,118 → 125,6
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)
{
327,6 → 205,16
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)
{
407,17 → 295,13
GFX_MODE_ENABLE(GFX_REPLAY_MODE));
}
 
if (INTEL_INFO(dev)->gen >= 5) {
if (INTEL_INFO(dev)->gen >= 6) {
} else if (IS_GEN5(dev)) {
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;
}
 
430,33 → 314,35
}
 
static void
update_mboxes(struct intel_ring_buffer *ring,
u32 seqno,
u32 mmio_offset)
update_semaphore(struct intel_ring_buffer *ring, int i, u32 seqno)
{
intel_ring_emit(ring, MI_SEMAPHORE_MBOX |
MI_SEMAPHORE_GLOBAL_GTT |
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 |
MI_SEMAPHORE_REGISTER |
MI_SEMAPHORE_UPDATE);
intel_ring_emit(ring, seqno);
intel_ring_emit(ring, mmio_offset);
intel_ring_emit(ring,
RING_SYNC_0(dev_priv->ring[id].mmio_base) + 4*i);
}
 
/**
* 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 *seqno)
u32 *result)
{
u32 mbox1_reg;
u32 mbox2_reg;
u32 seqno;
int ret;
 
ret = intel_ring_begin(ring, 10);
463,98 → 349,48
if (ret)
return ret;
 
mbox1_reg = ring->signal_mbox[0];
mbox2_reg = ring->signal_mbox[1];
seqno = i915_gem_get_seqno(ring->dev);
update_semaphore(ring, 0, seqno);
update_semaphore(ring, 1, seqno);
 
*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;
}
 
/**
* 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,
int
intel_ring_sync(struct intel_ring_buffer *ring,
struct intel_ring_buffer *to,
u32 seqno)
{
int ret;
u32 dw1 = MI_SEMAPHORE_MBOX |
MI_SEMAPHORE_COMPARE |
MI_SEMAPHORE_REGISTER;
 
ret = intel_ring_begin(waiter, 4);
ret = intel_ring_begin(ring, 4);
if (ret)
return ret;
 
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);
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);
 
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(4) | PIPE_CONTROL_QW_WRITE | \
PIPE_CONTROL_DEPTH_STALL); \
intel_ring_emit(ring__, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \
PIPE_CONTROL_DEPTH_STALL | 2); \
intel_ring_emit(ring__, (addr__) | PIPE_CONTROL_GLOBAL_GTT); \
intel_ring_emit(ring__, 0); \
intel_ring_emit(ring__, 0); \
582,9 → 418,8
if (ret)
return ret;
 
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, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH);
intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT);
intel_ring_emit(ring, seqno);
intel_ring_emit(ring, 0);
599,9 → 434,8
PIPE_CONTROL_FLUSH(ring, scratch_addr);
scratch_addr += 128;
PIPE_CONTROL_FLUSH(ring, scratch_addr);
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, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH |
PIPE_CONTROL_NOTIFY);
intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT);
intel_ring_emit(ring, seqno);
635,19 → 469,6
}
 
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)
{
return intel_read_status_page(ring, I915_GEM_HWS_INDEX);
692,6 → 513,7
POSTING_READ(IMR);
}
 
#if 0
static bool
render_ring_get_irq(struct intel_ring_buffer *ring)
{
731,6 → 553,7
}
spin_unlock(&ring->irq_lock);
}
#endif
 
void intel_ring_setup_status_page(struct intel_ring_buffer *ring)
{
803,6 → 626,8
return 0;
}
 
#if 0
 
static bool
gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag)
{
812,12 → 637,6
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;
842,9 → 661,6
ironlake_disable_irq(dev_priv, gflag);
}
spin_unlock(&ring->irq_lock);
 
if (IS_GEN7(dev))
gen6_gt_force_wake_put(dev_priv);
}
 
static bool
882,6 → 698,7
}
spin_unlock(&ring->irq_lock);
}
#endif
 
static int
ring_dispatch_execbuffer(struct intel_ring_buffer *ring, u32 offset, u32 length)
1011,7 → 828,7
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)) {
1221,16 → 1038,11
.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 */
1244,9 → 1056,9
.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,
};
 
1312,6 → 1124,8
return 0;
}
 
#if 0
 
static bool
gen6_render_ring_get_irq(struct intel_ring_buffer *ring)
{
1344,6 → 1158,8
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",
1354,17 → 1170,13
.write_tail = gen6_bsd_ring_write_tail,
.flush = gen6_ring_flush,
.add_request = gen6_add_request,
.get_seqno = gen6_ring_get_seqno,
.irq_get = gen6_bsd_ring_get_irq,
.irq_put = gen6_bsd_ring_put_irq,
// .get_seqno = 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
1382,6 → 1194,7
GT_BLT_USER_INTERRUPT,
GEN6_BLITTER_USER_INTERRUPT);
}
#endif
 
 
/* Workaround for some stepping of SNB,
1489,16 → 1302,11
.write_tail = ring_write_tail,
.flush = blt_ring_flush,
.add_request = gen6_add_request,
.get_seqno = gen6_ring_get_seqno,
.irq_get = blt_ring_get_irq,
.irq_put = blt_ring_put_irq,
// .get_seqno = 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)
1509,13 → 1317,11
*ring = render_ring;
if (INTEL_INFO(dev)->gen >= 6) {
ring->add_request = gen6_add_request;
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;
// ring->irq_get = gen6_render_ring_get_irq;
// ring->irq_put = gen6_render_ring_put_irq;
} 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)) {
/drivers/video/drm/i915/intel_sdvo.c
58,7 → 58,6
#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[] = {
102,11 → 101,6
*/
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.
1074,13 → 1068,15
 
/* Set the SDVO control regs. */
if (INTEL_INFO(dev)->gen >= 4) {
/* The real mode polarity is set by the SDVO commands, using
* struct intel_sdvo_dtd. */
sdvox = SDVO_VSYNC_ACTIVE_HIGH | SDVO_HSYNC_ACTIVE_HIGH;
sdvox = 0;
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) {
1093,12 → 1089,8
}
sdvox |= (9 << 19) | SDVO_BORDER_ENABLE;
}
 
if (INTEL_PCH_TYPE(dev) >= PCH_CPT)
sdvox |= TRANSCODER_CPT(intel_crtc->pipe);
else
sdvox |= TRANSCODER(intel_crtc->pipe);
 
if (intel_crtc->pipe == 1)
sdvox |= SDVO_PIPE_B_SELECT;
if (intel_sdvo->has_hdmi_audio)
sdvox |= SDVO_AUDIO_ENABLE;
 
1225,26 → 1217,81
return true;
}
 
static int intel_sdvo_supports_hotplug(struct intel_sdvo *intel_sdvo)
/* 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)
{
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];
}
 
static void intel_sdvo_enable_hotplug(struct intel_encoder *encoder)
void intel_sdvo_set_hotplug(struct drm_connector *connector, int on)
{
struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base);
u8 response[2];
u8 status;
struct intel_sdvo *intel_sdvo = to_intel_sdvo(connector);
 
intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &intel_sdvo->hotplug_active, 2);
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);
}
#endif
 
static bool
intel_sdvo_multifunc_encoder(struct intel_sdvo *intel_sdvo)
{
/* Is there more than one type of output? */
return hweight16(intel_sdvo->caps.output_flags) > 1;
int caps = intel_sdvo->caps.output_flags & 0xf;
return caps & -caps;
}
 
static struct edid *
1265,7 → 1312,7
}
 
enum drm_connector_status
intel_sdvo_tmds_sink_detect(struct drm_connector *connector)
intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
{
struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
enum drm_connector_status status;
1325,18 → 1372,6
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)
{
1372,7 → 1407,7
if ((intel_sdvo_connector->output_flag & response) == 0)
ret = connector_status_disconnected;
else if (IS_TMDS(intel_sdvo_connector))
ret = intel_sdvo_tmds_sink_detect(connector);
ret = intel_sdvo_hdmi_sink_detect(connector);
else {
struct edid *edid;
 
1381,12 → 1416,10
if (edid == NULL)
edid = intel_sdvo_get_analog_edid(connector);
if (edid != NULL) {
if (intel_sdvo_connector_matches_edid(intel_sdvo_connector,
edid))
if (edid->input & DRM_EDID_INPUT_DIGITAL)
ret = connector_status_disconnected;
else
ret = connector_status_connected;
else
ret = connector_status_disconnected;
 
connector->display_info.raw_edid = NULL;
kfree(edid);
} else
1427,8 → 1460,11
edid = intel_sdvo_get_analog_edid(connector);
 
if (edid != NULL) {
if (intel_sdvo_connector_matches_edid(to_intel_sdvo_connector(connector),
edid)) {
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) {
drm_mode_connector_update_edid_property(connector, edid);
drm_add_edid_modes(connector, edid);
}
1908,7 → 1944,7
struct intel_sdvo *sdvo, u32 reg)
{
struct sdvo_device_mapping *mapping;
u8 pin;
u8 pin, speed;
 
if (IS_SDVOB(reg))
mapping = &dev_priv->sdvo_mappings[0];
1916,17 → 1952,19
mapping = &dev_priv->sdvo_mappings[1];
 
pin = GMBUS_PORT_DPB;
if (mapping->initialized)
speed = GMBUS_RATE_1MHZ >> 8;
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, GMBUS_RATE_1MHZ);
intel_gmbus_set_speed(sdvo->i2c, speed);
intel_gmbus_force_bit(sdvo->i2c, true);
} else {
} else
sdvo->i2c = &dev_priv->gmbus[GMBUS_PORT_DPB].adapter;
}
}
 
static bool
intel_sdvo_is_hdmi_connector(struct intel_sdvo *intel_sdvo, int device)
2006,7 → 2044,6
{
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;
 
2024,16 → 2061,6
 
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;
2216,7 → 2243,7
bytes[0], bytes[1]);
return false;
}
intel_sdvo->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
intel_sdvo->base.crtc_mask = (1 << 0) | (1 << 1);
 
return true;
}
2541,14 → 2568,6
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",
/drivers/video/drm/i915/kms_display.c
191,31 → 191,48
};
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
 
int err;
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;
 
err = init_bitmaps();
if( !err )
{
printf("Initialize bitmap manager\n");
// 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);
 
};
 
LEAVE();
286,11 → 303,7
 
fb->width = reqmode->width;
fb->height = reqmode->height;
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->pitch = ALIGN(reqmode->width * 4, 64);
fb->bits_per_pixel = 32;
fb->depth == 24;
 
307,13 → 320,13
{
os_display->width = fb->width;
os_display->height = fb->height;
os_display->pitch = fb->pitches[0];
os_display->pitch = fb->pitch;
os_display->vrefresh = drm_mode_vrefresh(mode);
 
sysSetScreen(fb->width, fb->height, fb->pitches[0]);
sysSetScreen(fb->width, fb->height, fb->pitch);
 
dbgprintf("new mode %d x %d pitch %d\n",
fb->width, fb->height, fb->pitches[0]);
fb->width, fb->height, fb->pitch);
}
else
DRM_ERROR("failed to set mode %d_%d on crtc %p\n",
393,8 → 406,6
 
void __attribute__((regparm(1))) destroy_cursor(cursor_t *cursor)
{
/* FIXME synchronization */
 
list_del(&cursor->list);
// radeon_bo_unpin(cursor->robj);
// KernelFree(cursor->data);
581,227 → 592,113
 
#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
 
 
typedef struct
int video_blit(uint64_t src_offset, int x, int y,
int w, int h, int pitch)
{
int left;
int top;
int right;
int bottom;
}rect_t;
 
 
#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,
int src_x, int src_y, u32 w, u32 h)
{
drm_i915_private_t *dev_priv = main_device->dev_private;
struct intel_ring_buffer *ring;
 
bitmap_t *bitmap;
rect_t winrc;
clip_t dst_clip;
clip_t src_clip;
u32_t width;
u32_t height;
u32_t br13, cmd, *b;
u32_t offset;
 
u32_t br13, cmd, slot_mask, *b;
u32_t offset;
u8 slot;
int n=0;
 
if(unlikely(hbitmap==0))
return -1;
// if( cmd_buffer & 0xF80 )
// cmd_buffer&= 0xFFFFF000;
 
bitmap = (bitmap_t*)hman_get_data(&bm_man, hbitmap);
// b = (u32_t*)ALIGN(cmd_buffer,16);
 
if(unlikely(bitmap==NULL))
return -1;
// offset = cmd_offset + ((u32_t)b & 0xFFF);
 
b = cmd_buffer;
 
GetWindowRect(&winrc);
cmd = XY_SRC_COPY_BLT_CMD | BLT_WRITE_RGB;
br13 = os_display->pitch;
br13 |= 0xCC << 16;
br13 |= 3 << 24;
 
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[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
 
src_clip.xmin = 0;
src_clip.ymin = 0;
src_clip.xmax = bitmap->width - 1;
src_clip.ymax = bitmap->height - 1;
b[n++] = pitch;
b[n++] = (u32_t)src_offset;
 
width = w;
height = h;
b[n++] = MI_BATCH_BUFFER_END;
if( n & 1)
b[n++] = MI_NOOP;
 
if( blit_clip(&dst_clip, &dst_x, &dst_y,
&src_clip, &src_x, &src_y,
&width, &height) )
return 0;
// i915_gem_object_set_to_gtt_domain(obj, false);
 
dst_x+= winrc.left;
dst_y+= winrc.top;
ring = &dev_priv->ring[BCS];
ring->dispatch_execbuffer(ring, cmd_offset, n*4);
 
slot = *((u8*)CURRENT_TASK);
intel_ring_begin(ring, 4);
// if (ret)
// return ret;
 
slot_mask = (u32_t)slot<<24;
// 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);
 
{
#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;
fail:
return -1;
};
 
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--)
int blit_video(u32 hbitmap, int dst_x, int dst_y,
int src_x, int src_y, u32 w, u32 h)
{
*(tmp_src+3) = (*tmp_dst==slot)?0xFF:0x00;
tmp_src+=4;
tmp_dst++;
};
};
#else
u8* src_offset;
u8* dst_offset;
drm_i915_private_t *dev_priv = main_device->dev_private;
struct intel_ring_buffer *ring;
 
src_offset = (u8*)(src_y*bitmap->pitch + src_x*4);
src_offset += (u32)bitmap->uaddr;
bitmap_t *bitmap;
u32_t br13, cmd, *b;
u32_t offset;
 
dst_offset = (u8*)(dst_y*os_display->width + dst_x);
dst_offset+= get_display_map();
int n=0;
 
u32_t tmp_h = height;
if(unlikely(hbitmap==0))
return -1;
 
while( tmp_h--)
{
u32_t tmp_w = width;
bitmap = hman_get_data(&bm_man, hbitmap);
 
u8* tmp_src = src_offset;
u8* tmp_dst = dst_offset;
if(unlikely(bitmap==NULL))
return -1;
 
src_offset+= bitmap->pitch;
dst_offset+= os_display->width;
// if( cmd_buffer & 0xF80 )
// cmd_buffer&= 0xFFFFF000;
 
while( tmp_w--)
{
*(tmp_src+3) = (*tmp_dst==slot)?0xFF:0x00;
tmp_src+=4;
tmp_dst++;
};
};
}
#endif
// b = (u32_t*)ALIGN(cmd_buffer,16);
 
if((cmd_buffer & 0xFC0)==0xFC0)
cmd_buffer&= 0xFFFFF000;
// offset = cmd_offset + ((u32_t)b & 0xFFF);
 
b = (u32_t*)ALIGN(cmd_buffer,16);
b = cmd_buffer;
 
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|= ROP_COPY_SRC << 16;
br13|= FORMAT8888 << 24;
br13 |= 0xCC << 16;
br13 |= 3 << 24;
 
b[n++] = cmd;
b[n++] = br13;
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++] = (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++] = 0; // Transparency Color Low
b[n++] = 0x00FFFFFF; // Transparency Color High
b[n++] = bitmap->pitch;
b[n++] = bitmap->gaddr;
 
b[n++] = MI_BATCH_BUFFER_END;
if( n & 1)
809,11 → 706,7
 
// i915_gem_object_set_to_gtt_domain(obj, false);
 
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);
/drivers/video/drm/i915/main.c
12,7 → 12,7
#include <linux/pci.h>
#include <syscall.h>
 
#include "bitmap.h"
typedef struct bitmap bitmap_t;
 
void parse_cmdline(char *cmdline, char *log);
int _stdcall display_handler(ioctl_t *io);
19,6 → 19,7
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);
 
51,7 → 52,7
return 0;
};
}
dbgprintf("i915 blitter preview\n cmdline: %s\n", cmdline);
dbgprintf("i915_early_preview second edition\n cmdline: %s\n", cmdline);
 
enum_pci_devices();
 
77,10 → 78,10
#define SRV_ENUM_MODES 1
#define SRV_SET_MODE 2
 
#define SRV_CREATE_BITMAP 10
#define SRV_CREATE_VIDEO 9
#define SRV_BLIT_VIDEO 10
#define SRV_CREATE_BITMAP 11
 
#define SRV_BLIT_VIDEO 20
 
#define check_input(size) \
if( unlikely((inp==NULL)||(io->inp_size != (size))) ) \
break;
123,18 → 124,25
retval = set_user_mode((videomode_t*)inp);
break;
 
case SRV_CREATE_BITMAP:
check_input(5);
retval = create_bitmap((struct ubitmap*)inp);
case SRV_CREATE_VIDEO:
check_input(2);
check_output(4);
retval = create_video(inp[0], inp[1], outp);
break;
 
 
case SRV_BLIT_VIDEO:
blit_video( inp[0], inp[1], inp[2],
inp[3], inp[4], inp[5], inp[6]);
video_blit( ((uint64_t*)inp)[0], 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;
/drivers/video/drm/i915/i915_dma.c
560,14 → 560,11
// 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_IVYBRIDGE(dev))
dev_priv->num_pipe = 3;
else if (IS_MOBILE(dev) || !IS_GEN2(dev))
if (IS_MOBILE(dev) || !IS_GEN2(dev))
dev_priv->num_pipe = 2;
else
dev_priv->num_pipe = 1;
/drivers/video/drm/i915/intel_bios.c
309,13 → 309,6
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);
}
}
 
403,13 → 396,15
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\n",
DRM_DEBUG_KMS("SDVO device: dvo=%x, addr=%x, wiring=%d, ddc_pin=%d, i2c_pin=%d, i2c_speed=%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_pin,
p_mapping->i2c_speed);
} else {
DRM_DEBUG_KMS("Maybe one SDVO port is shared by "
"two SDVO device.\n");
615,7 → 610,7
/* Default to using SSC */
dev_priv->lvds_use_ssc = 1;
dev_priv->lvds_ssc_freq = intel_bios_ssc_frequency(dev, 1);
DRM_DEBUG_KMS("Set default to SSC at %dMHz\n", dev_priv->lvds_ssc_freq);
DRM_DEBUG("Set default to SSC at %dMHz\n", dev_priv->lvds_ssc_freq);
 
/* eDP data */
dev_priv->edp.bpp = 18;
644,7 → 639,7
if (dev_priv->opregion.vbt) {
struct vbt_header *vbt = dev_priv->opregion.vbt;
if (memcmp(vbt->signature, "$VBT", 4) == 0) {
DRM_DEBUG_KMS("Using VBT from OpRegion: %20s\n",
DRM_DEBUG_DRIVER("Using VBT from OpRegion: %20s\n",
vbt->signature);
bdb = (struct bdb_header *)((char *)vbt + vbt->bdb_offset);
} else
/drivers/video/drm/i915/intel_fb.c
93,7 → 93,7
struct drm_i915_private *dev_priv = dev->dev_private;
struct fb_info *info;
struct drm_framebuffer *fb;
struct drm_mode_fb_cmd2 mode_cmd;
struct drm_mode_fb_cmd mode_cmd;
struct drm_i915_gem_object *obj;
struct device *device = &dev->pdev->dev;
int size, ret;
105,12 → 105,11
mode_cmd.width = sizes->surface_width;
mode_cmd.height = sizes->surface_height;
 
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);
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;
 
size = mode_cmd.pitches[0] * mode_cmd.height;
size = mode_cmd.pitch * mode_cmd.height;
size = ALIGN(size, PAGE_SIZE);
obj = i915_gem_alloc_object(dev, size);
if (!obj) {
187,7 → 186,7
 
// memset(info->screen_base, 0, size);
 
drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
drm_fb_helper_fill_fix(info, fb->pitch, 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",
207,7 → 206,6
out:
return ret;
}
 
static int intel_fb_find_or_create_single(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes)
{
/drivers/video/drm/i915/i915_drm.h
198,8 → 198,6
#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)
241,8 → 239,6
#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.
295,7 → 291,6
#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;
658,9 → 653,6
__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;
852,36 → 844,4
__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_ */
/drivers/video/drm/i915/i915_gem_tiling.c
110,10 → 110,7
uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
 
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)) {
if (INTEL_INFO(dev)->gen >= 5) {
/* On Ironlake whatever DRAM config, GPU always do
* same swizzling setup.
*/
462,9 → 459,14
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;
 
481,9 → 483,14
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);
/drivers/video/drm/i915/intel_crt.c
152,13 → 152,17
if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
adpa |= ADPA_VSYNC_ACTIVE_HIGH;
 
/* For CPT allow 3 pipe config, for others just use A or B */
if (intel_crtc->pipe == 0) {
if (HAS_PCH_CPT(dev))
adpa |= PORT_TRANS_SEL_CPT(intel_crtc->pipe);
else if (intel_crtc->pipe == 0)
adpa |= PORT_TRANS_A_SEL_CPT;
else
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);
/drivers/video/drm/i915/intel_dp.c
36,7 → 36,7
#include "i915_drv.h"
#include "drm_dp_helper.h"
 
#define DP_RECEIVER_CAP_SIZE 0xf
 
#define DP_LINK_STATUS_SIZE 6
#define DP_LINK_CHECK_TIMEOUT (10 * 1000)
 
53,18 → 53,12
int dpms_mode;
uint8_t link_bw;
uint8_t lane_count;
uint8_t dpcd[DP_RECEIVER_CAP_SIZE];
uint8_t dpcd[8];
struct i2c_adapter adapter;
struct i2c_algo_dp_aux_data algo;
bool is_pch_edp;
uint8_t train_set[4];
int panel_power_up_delay;
int panel_power_down_delay;
int panel_power_cycle_delay;
int backlight_on_delay;
int backlight_off_delay;
struct drm_display_mode *panel_fixed_mode; /* for eDP */
bool want_panel_vdd;
uint8_t link_status[DP_LINK_STATUS_SIZE];
};
 
/**
92,17 → 86,6
return intel_dp->is_pch_edp;
}
 
/**
* is_cpu_edp - is the port on the CPU and attached to an eDP panel?
* @intel_dp: DP struct
*
* Returns true if the given DP struct corresponds to a CPU eDP port.
*/
static bool is_cpu_edp(struct intel_dp *intel_dp)
{
return is_edp(intel_dp) && !is_pch_edp(intel_dp);
}
 
static struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder)
{
return container_of(encoder, struct intel_dp, base.base);
153,7 → 136,10
static int
intel_dp_max_lane_count(struct intel_dp *intel_dp)
{
int max_lane_count = intel_dp->dpcd[DP_MAX_LANE_COUNT] & 0x1f;
int max_lane_count = 4;
 
if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) {
max_lane_count = intel_dp->dpcd[DP_MAX_LANE_COUNT] & 0x1f;
switch (max_lane_count) {
case 1: case 2: case 4:
break;
160,6 → 146,7
default:
max_lane_count = 4;
}
}
return max_lane_count;
}
 
188,36 → 175,18
return 162000;
}
 
/*
* The units on the numbers in the next two are... bizarre. Examples will
* make it clearer; this one parallels an example in the eDP spec.
*
* intel_dp_max_data_rate for one lane of 2.7GHz evaluates as:
*
* 270000 * 1 * 8 / 10 == 216000
*
* The actual data capacity of that configuration is 2.16Gbit/s, so the
* units are decakilobits. ->clock in a drm_display_mode is in kilohertz -
* or equivalently, kilopixels per second - so for 1680x1050R it'd be
* 119000. At 18bpp that's 2142000 kilobits per second.
*
* Thus the strange-looking division by 10 in intel_dp_link_required, to
* get the result in decakilobits instead of kilobits.
*/
 
/* I think this is a fiction */
static int
intel_dp_link_required(struct intel_dp *intel_dp, int pixel_clock, int check_bpp)
intel_dp_link_required(struct drm_device *dev, struct intel_dp *intel_dp, int pixel_clock)
{
struct drm_crtc *crtc = intel_dp->base.base.crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int bpp = 24;
 
if (check_bpp)
bpp = check_bpp;
else if (intel_crtc)
if (intel_crtc)
bpp = intel_crtc->bpp;
 
return (pixel_clock * bpp + 9) / 10;
return (pixel_clock * bpp + 7) / 8;
}
 
static int
231,29 → 200,25
struct drm_display_mode *mode)
{
struct intel_dp *intel_dp = intel_attached_dp(connector);
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp));
int max_lanes = intel_dp_max_lane_count(intel_dp);
int max_rate, mode_rate;
 
if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) {
if (mode->hdisplay > intel_dp->panel_fixed_mode->hdisplay)
if (is_edp(intel_dp) && dev_priv->panel_fixed_mode) {
if (mode->hdisplay > dev_priv->panel_fixed_mode->hdisplay)
return MODE_PANEL;
 
if (mode->vdisplay > intel_dp->panel_fixed_mode->vdisplay)
if (mode->vdisplay > dev_priv->panel_fixed_mode->vdisplay)
return MODE_PANEL;
}
 
mode_rate = intel_dp_link_required(intel_dp, mode->clock, 0);
max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
 
if (mode_rate > max_rate) {
mode_rate = intel_dp_link_required(intel_dp,
mode->clock, 18);
if (mode_rate > max_rate)
/* only refuse the mode on non eDP since we have seen some weird eDP panels
which are outside spec tolerances but somehow work by magic */
if (!is_edp(intel_dp) &&
(intel_dp_link_required(connector->dev, intel_dp, mode->clock)
> intel_dp_max_data_rate(max_link_clock, max_lanes)))
return MODE_CLOCK_HIGH;
else
mode->private_flags |= INTEL_MODE_DP_FORCE_6BPC;
}
 
if (mode->clock < 10000)
return MODE_CLOCK_LOW;
314,38 → 279,6
}
}
 
static bool ironlake_edp_have_panel_power(struct intel_dp *intel_dp)
{
struct drm_device *dev = intel_dp->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
 
return (I915_READ(PCH_PP_STATUS) & PP_ON) != 0;
}
 
static bool ironlake_edp_have_panel_vdd(struct intel_dp *intel_dp)
{
struct drm_device *dev = intel_dp->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
 
return (I915_READ(PCH_PP_CONTROL) & EDP_FORCE_VDD) != 0;
}
 
static void
intel_dp_check_edp(struct intel_dp *intel_dp)
{
struct drm_device *dev = intel_dp->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
 
if (!is_edp(intel_dp))
return;
if (!ironlake_edp_have_panel_power(intel_dp) && !ironlake_edp_have_panel_vdd(intel_dp)) {
WARN(1, "eDP powered off while attempting aux channel communication.\n");
DRM_DEBUG_KMS("Status 0x%08x Control 0x%08x\n",
I915_READ(PCH_PP_STATUS),
I915_READ(PCH_PP_CONTROL));
}
}
 
static int
intel_dp_aux_ch(struct intel_dp *intel_dp,
uint8_t *send, int send_bytes,
362,7 → 295,6
uint32_t aux_clock_divider;
int try, precharge;
 
intel_dp_check_edp(intel_dp);
/* The clock divider is based off the hrawclk,
* and would like to run at 2MHz. So, take the
* hrawclk value and divide by 2 and use that
370,9 → 302,9
* Note that PCH attached eDP panels should use a 125MHz input
* clock divider.
*/
if (is_cpu_edp(intel_dp)) {
if (IS_GEN6(dev) || IS_GEN7(dev))
aux_clock_divider = 200; /* SNB & IVB eDP input clock at 400Mhz */
if (is_edp(intel_dp) && !is_pch_edp(intel_dp)) {
if (IS_GEN6(dev))
aux_clock_divider = 200; /* SNB eDP input clock at 400Mhz */
else
aux_clock_divider = 225; /* eDP input clock at 450Mhz */
} else if (HAS_PCH_SPLIT(dev))
476,7 → 408,6
int msg_bytes;
uint8_t ack;
 
intel_dp_check_edp(intel_dp);
if (send_bytes > 16)
return -1;
msg[0] = AUX_NATIVE_WRITE << 4;
519,7 → 450,6
uint8_t ack;
int ret;
 
intel_dp_check_edp(intel_dp);
msg[0] = AUX_NATIVE_READ << 4;
msg[1] = address >> 8;
msg[2] = address & 0xff;
563,7 → 493,6
int reply_bytes;
int ret;
 
intel_dp_check_edp(intel_dp);
/* Set up the command byte */
if (mode & MODE_I2C_READ)
msg[0] = AUX_I2C_READ << 4;
644,15 → 573,10
return -EREMOTEIO;
}
 
static void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp);
static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync);
 
static int
intel_dp_i2c_init(struct intel_dp *intel_dp,
struct intel_connector *intel_connector, const char *name)
{
int ret;
 
DRM_DEBUG_KMS("i2c_init %s\n", name);
intel_dp->algo.running = false;
intel_dp->algo.address = 0;
666,10 → 590,7
intel_dp->adapter.algo_data = &intel_dp->algo;
intel_dp->adapter.dev.parent = &intel_connector->base.kdev;
 
ironlake_edp_panel_vdd_on(intel_dp);
ret = i2c_dp_aux_add_bus(&intel_dp->adapter);
ironlake_edp_panel_vdd_off(intel_dp, false);
return ret;
return i2c_dp_aux_add_bus(&intel_dp->adapter);
}
 
static bool
677,15 → 598,15
struct drm_display_mode *adjusted_mode)
{
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
int lane_count, clock;
int max_lane_count = intel_dp_max_lane_count(intel_dp);
int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0;
int bpp = mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 0;
static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
 
if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) {
intel_fixed_panel_mode(intel_dp->panel_fixed_mode, adjusted_mode);
if (is_edp(intel_dp) && dev_priv->panel_fixed_mode) {
intel_fixed_panel_mode(dev_priv->panel_fixed_mode, adjusted_mode);
intel_pch_panel_fitting(dev, DRM_MODE_SCALE_FULLSCREEN,
mode, adjusted_mode);
/*
692,7 → 613,7
* the mode->clock is used to calculate the Data&Link M/N
* of the pipe. For the eDP the fixed clock should be used.
*/
mode->clock = intel_dp->panel_fixed_mode->clock;
mode->clock = dev_priv->panel_fixed_mode->clock;
}
 
for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
699,7 → 620,7
for (clock = 0; clock <= max_clock; clock++) {
int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count);
 
if (intel_dp_link_required(intel_dp, mode->clock, bpp)
if (intel_dp_link_required(encoder->dev, intel_dp, mode->clock)
<= link_avail) {
intel_dp->link_bw = bws[clock];
intel_dp->lane_count = lane_count;
713,6 → 634,19
}
}
 
if (is_edp(intel_dp)) {
/* okay we failed just pick the highest */
intel_dp->lane_count = max_lane_count;
intel_dp->link_bw = bws[max_clock];
adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw);
DRM_DEBUG_KMS("Force picking display port link bw %02x lane "
"count %d clock %d\n",
intel_dp->link_bw, intel_dp->lane_count,
adjusted_mode->clock);
 
return true;
}
 
return false;
}
 
772,11 → 706,12
continue;
 
intel_dp = enc_to_intel_dp(encoder);
if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT ||
intel_dp->base.type == INTEL_OUTPUT_EDP)
{
if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) {
lane_count = intel_dp->lane_count;
break;
} else if (is_edp(intel_dp)) {
lane_count = dev_priv->edp.lanes;
break;
}
}
 
805,54 → 740,28
}
}
 
static void ironlake_edp_pll_on(struct drm_encoder *encoder);
static void ironlake_edp_pll_off(struct drm_encoder *encoder);
 
static void
intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct drm_crtc *crtc = intel_dp->base.base.crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 
/* Turn on the eDP PLL if needed */
if (is_edp(intel_dp)) {
if (!is_pch_edp(intel_dp))
ironlake_edp_pll_on(encoder);
else
ironlake_edp_pll_off(encoder);
}
intel_dp->DP = DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
intel_dp->DP |= intel_dp->color_range;
 
/*
* There are four kinds of DP registers:
*
* IBX PCH
* SNB CPU
* IVB CPU
* CPT PCH
*
* IBX PCH and CPU are the same for almost everything,
* except that the CPU DP PLL is configured in this
* register
*
* CPT PCH is quite different, having many bits moved
* to the TRANS_DP_CTL register instead. That
* configuration happens (oddly) in ironlake_pch_enable
*/
if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
intel_dp->DP |= DP_SYNC_HS_HIGH;
if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
intel_dp->DP |= DP_SYNC_VS_HIGH;
 
/* Preserve the BIOS-computed detected bit. This is
* supposed to be read-only.
*/
intel_dp->DP = I915_READ(intel_dp->output_reg) & DP_DETECTED;
intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
if (HAS_PCH_CPT(dev) && !is_edp(intel_dp))
intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
else
intel_dp->DP |= DP_LINK_TRAIN_OFF;
 
/* Handle DP bits in common between all three register formats */
 
intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
 
switch (intel_dp->lane_count) {
case 1:
intel_dp->DP |= DP_PORT_WIDTH_1;
864,16 → 773,14
intel_dp->DP |= DP_PORT_WIDTH_4;
break;
}
if (intel_dp->has_audio) {
DRM_DEBUG_DRIVER("Enabling DP audio on pipe %c\n",
pipe_name(intel_crtc->pipe));
if (intel_dp->has_audio)
intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE;
intel_write_eld(encoder, adjusted_mode);
}
 
memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE);
intel_dp->link_configuration[0] = intel_dp->link_bw;
intel_dp->link_configuration[1] = intel_dp->lane_count;
intel_dp->link_configuration[8] = DP_SET_ANSI_8B10B;
 
/*
* Check for DPCD version > 1.1 and enhanced framing support
*/
880,44 → 787,14
if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 &&
(intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP)) {
intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
intel_dp->DP |= DP_ENHANCED_FRAMING;
}
 
/* Split out the IBX/CPU vs CPT settings */
 
if (is_cpu_edp(intel_dp) && IS_GEN7(dev)) {
if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
intel_dp->DP |= DP_SYNC_HS_HIGH;
if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
intel_dp->DP |= DP_SYNC_VS_HIGH;
intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
 
if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN)
intel_dp->DP |= DP_ENHANCED_FRAMING;
 
intel_dp->DP |= intel_crtc->pipe << 29;
 
/* don't miss out required setting for eDP */
intel_dp->DP |= DP_PLL_ENABLE;
if (adjusted_mode->clock < 200000)
intel_dp->DP |= DP_PLL_FREQ_160MHZ;
else
intel_dp->DP |= DP_PLL_FREQ_270MHZ;
} else if (!HAS_PCH_CPT(dev) || is_cpu_edp(intel_dp)) {
intel_dp->DP |= intel_dp->color_range;
 
if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
intel_dp->DP |= DP_SYNC_HS_HIGH;
if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
intel_dp->DP |= DP_SYNC_VS_HIGH;
intel_dp->DP |= DP_LINK_TRAIN_OFF;
 
if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN)
intel_dp->DP |= DP_ENHANCED_FRAMING;
 
if (intel_crtc->pipe == 1)
/* CPT DP's pipe select is decided in TRANS_DP_CTL */
if (intel_crtc->pipe == 1 && !HAS_PCH_CPT(dev))
intel_dp->DP |= DP_PIPEB_SELECT;
 
if (is_cpu_edp(intel_dp)) {
if (is_edp(intel_dp) && !is_pch_edp(intel_dp)) {
/* don't miss out required setting for eDP */
intel_dp->DP |= DP_PLL_ENABLE;
if (adjusted_mode->clock < 200000)
925,71 → 802,8
else
intel_dp->DP |= DP_PLL_FREQ_270MHZ;
}
} else {
intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
}
}
 
#define IDLE_ON_MASK (PP_ON | 0 | PP_SEQUENCE_MASK | 0 | PP_SEQUENCE_STATE_MASK)
#define IDLE_ON_VALUE (PP_ON | 0 | PP_SEQUENCE_NONE | 0 | PP_SEQUENCE_STATE_ON_IDLE)
 
#define IDLE_OFF_MASK (PP_ON | 0 | PP_SEQUENCE_MASK | 0 | PP_SEQUENCE_STATE_MASK)
#define IDLE_OFF_VALUE (0 | 0 | PP_SEQUENCE_NONE | 0 | PP_SEQUENCE_STATE_OFF_IDLE)
 
#define IDLE_CYCLE_MASK (PP_ON | 0 | PP_SEQUENCE_MASK | PP_CYCLE_DELAY_ACTIVE | PP_SEQUENCE_STATE_MASK)
#define IDLE_CYCLE_VALUE (0 | 0 | PP_SEQUENCE_NONE | 0 | PP_SEQUENCE_STATE_OFF_IDLE)
 
static void ironlake_wait_panel_status(struct intel_dp *intel_dp,
u32 mask,
u32 value)
{
struct drm_device *dev = intel_dp->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
 
DRM_DEBUG_KMS("mask %08x value %08x status %08x control %08x\n",
mask, value,
I915_READ(PCH_PP_STATUS),
I915_READ(PCH_PP_CONTROL));
 
if (_wait_for((I915_READ(PCH_PP_STATUS) & mask) == value, 5000, 10)) {
DRM_ERROR("Panel status timeout: status %08x control %08x\n",
I915_READ(PCH_PP_STATUS),
I915_READ(PCH_PP_CONTROL));
}
}
 
static void ironlake_wait_panel_on(struct intel_dp *intel_dp)
{
DRM_DEBUG_KMS("Wait for panel power on\n");
ironlake_wait_panel_status(intel_dp, IDLE_ON_MASK, IDLE_ON_VALUE);
}
 
static void ironlake_wait_panel_off(struct intel_dp *intel_dp)
{
DRM_DEBUG_KMS("Wait for panel power off time\n");
ironlake_wait_panel_status(intel_dp, IDLE_OFF_MASK, IDLE_OFF_VALUE);
}
 
static void ironlake_wait_panel_power_cycle(struct intel_dp *intel_dp)
{
DRM_DEBUG_KMS("Wait for panel power cycle\n");
ironlake_wait_panel_status(intel_dp, IDLE_CYCLE_MASK, IDLE_CYCLE_VALUE);
}
 
 
/* Read the current pp_control value, unlocking the register if it
* is locked
*/
 
static u32 ironlake_get_pp_control(struct drm_i915_private *dev_priv)
{
u32 control = I915_READ(PCH_PP_CONTROL);
 
control &= ~PANEL_UNLOCK_MASK;
control |= PANEL_UNLOCK_REGS;
return control;
}
 
static void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp)
{
struct drm_device *dev = intel_dp->base.base.dev;
996,155 → 810,98
struct drm_i915_private *dev_priv = dev->dev_private;
u32 pp;
 
if (!is_edp(intel_dp))
return;
DRM_DEBUG_KMS("Turn eDP VDD on\n");
/*
* If the panel wasn't on, make sure there's not a currently
* active PP sequence before enabling AUX VDD.
*/
if (!(I915_READ(PCH_PP_STATUS) & PP_ON))
msleep(dev_priv->panel_t3);
 
WARN(intel_dp->want_panel_vdd,
"eDP VDD already requested on\n");
 
intel_dp->want_panel_vdd = true;
 
if (ironlake_edp_have_panel_vdd(intel_dp)) {
DRM_DEBUG_KMS("eDP VDD already on\n");
return;
}
 
if (!ironlake_edp_have_panel_power(intel_dp))
ironlake_wait_panel_power_cycle(intel_dp);
 
pp = ironlake_get_pp_control(dev_priv);
pp = I915_READ(PCH_PP_CONTROL);
pp |= EDP_FORCE_VDD;
I915_WRITE(PCH_PP_CONTROL, pp);
POSTING_READ(PCH_PP_CONTROL);
DRM_DEBUG_KMS("PCH_PP_STATUS: 0x%08x PCH_PP_CONTROL: 0x%08x\n",
I915_READ(PCH_PP_STATUS), I915_READ(PCH_PP_CONTROL));
 
/*
* If the panel wasn't on, delay before accessing aux channel
*/
if (!ironlake_edp_have_panel_power(intel_dp)) {
DRM_DEBUG_KMS("eDP was not running\n");
msleep(intel_dp->panel_power_up_delay);
}
}
 
static void ironlake_panel_vdd_off_sync(struct intel_dp *intel_dp)
static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp)
{
struct drm_device *dev = intel_dp->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 pp;
 
if (!intel_dp->want_panel_vdd && ironlake_edp_have_panel_vdd(intel_dp)) {
pp = ironlake_get_pp_control(dev_priv);
pp = I915_READ(PCH_PP_CONTROL);
pp &= ~EDP_FORCE_VDD;
I915_WRITE(PCH_PP_CONTROL, pp);
POSTING_READ(PCH_PP_CONTROL);
 
/* Make sure sequencer is idle before allowing subsequent activity */
DRM_DEBUG_KMS("PCH_PP_STATUS: 0x%08x PCH_PP_CONTROL: 0x%08x\n",
I915_READ(PCH_PP_STATUS), I915_READ(PCH_PP_CONTROL));
 
msleep(intel_dp->panel_power_down_delay);
msleep(dev_priv->panel_t12);
}
}
 
 
static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync)
/* Returns true if the panel was already on when called */
static bool ironlake_edp_panel_on (struct intel_dp *intel_dp)
{
if (!is_edp(intel_dp))
return;
 
DRM_DEBUG_KMS("Turn eDP VDD off %d\n", intel_dp->want_panel_vdd);
WARN(!intel_dp->want_panel_vdd, "eDP VDD not forced on");
 
intel_dp->want_panel_vdd = false;
 
if (sync) {
ironlake_panel_vdd_off_sync(intel_dp);
} else {
/*
* Queue the timer to fire a long
* time from now (relative to the power down delay)
* to keep the panel power up across a sequence of operations
*/
// schedule_delayed_work(&intel_dp->panel_vdd_work,
// msecs_to_jiffies(intel_dp->panel_power_cycle_delay * 5));
}
}
 
static void ironlake_edp_panel_on(struct intel_dp *intel_dp)
{
struct drm_device *dev = intel_dp->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 pp;
u32 pp, idle_on_mask = PP_ON | PP_SEQUENCE_STATE_ON_IDLE;
 
if (!is_edp(intel_dp))
return;
if (I915_READ(PCH_PP_STATUS) & PP_ON)
return true;
 
DRM_DEBUG_KMS("Turn eDP power on\n");
pp = I915_READ(PCH_PP_CONTROL);
 
if (ironlake_edp_have_panel_power(intel_dp)) {
DRM_DEBUG_KMS("eDP power already on\n");
return;
}
 
ironlake_wait_panel_power_cycle(intel_dp);
 
pp = ironlake_get_pp_control(dev_priv);
if (IS_GEN5(dev)) {
/* ILK workaround: disable reset around power sequence */
pp &= ~PANEL_POWER_RESET;
I915_WRITE(PCH_PP_CONTROL, pp);
POSTING_READ(PCH_PP_CONTROL);
}
 
pp |= POWER_TARGET_ON;
if (!IS_GEN5(dev))
pp |= PANEL_POWER_RESET;
 
pp |= PANEL_UNLOCK_REGS | POWER_TARGET_ON;
I915_WRITE(PCH_PP_CONTROL, pp);
POSTING_READ(PCH_PP_CONTROL);
 
ironlake_wait_panel_on(intel_dp);
if (wait_for((I915_READ(PCH_PP_STATUS) & idle_on_mask) == idle_on_mask,
5000))
DRM_ERROR("panel on wait timed out: 0x%08x\n",
I915_READ(PCH_PP_STATUS));
 
if (IS_GEN5(dev)) {
pp |= PANEL_POWER_RESET; /* restore panel reset bit */
I915_WRITE(PCH_PP_CONTROL, pp);
POSTING_READ(PCH_PP_CONTROL);
 
return false;
}
}
 
static void ironlake_edp_panel_off(struct intel_dp *intel_dp)
static void ironlake_edp_panel_off (struct drm_device *dev)
{
struct drm_device *dev = intel_dp->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 pp;
u32 pp, idle_off_mask = PP_ON | PP_SEQUENCE_MASK |
PP_CYCLE_DELAY_ACTIVE | PP_SEQUENCE_STATE_MASK;
 
if (!is_edp(intel_dp))
return;
pp = I915_READ(PCH_PP_CONTROL);
 
DRM_DEBUG_KMS("Turn eDP power off\n");
/* ILK workaround: disable reset around power sequence */
pp &= ~PANEL_POWER_RESET;
I915_WRITE(PCH_PP_CONTROL, pp);
POSTING_READ(PCH_PP_CONTROL);
 
WARN(intel_dp->want_panel_vdd, "Cannot turn power off while VDD is on\n");
pp &= ~POWER_TARGET_ON;
I915_WRITE(PCH_PP_CONTROL, pp);
POSTING_READ(PCH_PP_CONTROL);
 
pp = ironlake_get_pp_control(dev_priv);
pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE);
if (wait_for((I915_READ(PCH_PP_STATUS) & idle_off_mask) == 0, 5000))
DRM_ERROR("panel off wait timed out: 0x%08x\n",
I915_READ(PCH_PP_STATUS));
 
pp |= PANEL_POWER_RESET; /* restore panel reset bit */
I915_WRITE(PCH_PP_CONTROL, pp);
POSTING_READ(PCH_PP_CONTROL);
 
ironlake_wait_panel_off(intel_dp);
}
 
static void ironlake_edp_backlight_on(struct intel_dp *intel_dp)
static void ironlake_edp_backlight_on (struct drm_device *dev)
{
struct drm_device *dev = intel_dp->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 pp;
 
if (!is_edp(intel_dp))
return;
 
DRM_DEBUG_KMS("\n");
/*
* If we enable the backlight right away following a panel power
1152,28 → 909,21
* link. So delay a bit to make sure the image is solid before
* allowing it to appear.
*/
msleep(intel_dp->backlight_on_delay);
pp = ironlake_get_pp_control(dev_priv);
msleep(300);
pp = I915_READ(PCH_PP_CONTROL);
pp |= EDP_BLC_ENABLE;
I915_WRITE(PCH_PP_CONTROL, pp);
POSTING_READ(PCH_PP_CONTROL);
}
 
static void ironlake_edp_backlight_off(struct intel_dp *intel_dp)
static void ironlake_edp_backlight_off (struct drm_device *dev)
{
struct drm_device *dev = intel_dp->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 pp;
 
if (!is_edp(intel_dp))
return;
 
DRM_DEBUG_KMS("\n");
pp = ironlake_get_pp_control(dev_priv);
pp = I915_READ(PCH_PP_CONTROL);
pp &= ~EDP_BLC_ENABLE;
I915_WRITE(PCH_PP_CONTROL, pp);
POSTING_READ(PCH_PP_CONTROL);
msleep(intel_dp->backlight_off_delay);
}
 
static void ironlake_edp_pll_on(struct drm_encoder *encoder)
1236,39 → 986,43
static void intel_dp_prepare(struct drm_encoder *encoder)
{
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct drm_device *dev = encoder->dev;
 
ironlake_edp_backlight_off(intel_dp);
ironlake_edp_panel_off(intel_dp);
 
/* Wake up the sink first */
ironlake_edp_panel_vdd_on(intel_dp);
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
intel_dp_link_down(intel_dp);
ironlake_edp_panel_vdd_off(intel_dp, false);
 
/* Make sure the panel is off before trying to
* change the mode
*/
if (is_edp(intel_dp)) {
ironlake_edp_backlight_off(dev);
ironlake_edp_panel_off(dev);
if (!is_pch_edp(intel_dp))
ironlake_edp_pll_on(encoder);
else
ironlake_edp_pll_off(encoder);
}
intel_dp_link_down(intel_dp);
}
 
static void intel_dp_commit(struct drm_encoder *encoder)
{
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct drm_device *dev = encoder->dev;
struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc);
 
if (is_edp(intel_dp))
ironlake_edp_panel_vdd_on(intel_dp);
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
 
intel_dp_start_link_train(intel_dp);
 
if (is_edp(intel_dp)) {
ironlake_edp_panel_on(intel_dp);
ironlake_edp_panel_vdd_off(intel_dp, true);
ironlake_edp_panel_vdd_off(intel_dp);
}
 
intel_dp_complete_link_train(intel_dp);
ironlake_edp_backlight_on(intel_dp);
 
if (is_edp(intel_dp))
ironlake_edp_backlight_on(dev);
 
intel_dp->dpms_mode = DRM_MODE_DPMS_ON;
 
if (HAS_PCH_CPT(dev))
intel_cpt_verify_modeset(dev, intel_crtc->pipe);
}
 
static void
1280,31 → 1034,29
uint32_t dp_reg = I915_READ(intel_dp->output_reg);
 
if (mode != DRM_MODE_DPMS_ON) {
ironlake_edp_backlight_off(intel_dp);
ironlake_edp_panel_off(intel_dp);
 
ironlake_edp_panel_vdd_on(intel_dp);
if (is_edp(intel_dp))
ironlake_edp_backlight_off(dev);
intel_dp_sink_dpms(intel_dp, mode);
intel_dp_link_down(intel_dp);
ironlake_edp_panel_vdd_off(intel_dp, false);
 
if (is_cpu_edp(intel_dp))
if (is_edp(intel_dp))
ironlake_edp_panel_off(dev);
if (is_edp(intel_dp) && !is_pch_edp(intel_dp))
ironlake_edp_pll_off(encoder);
} else {
if (is_cpu_edp(intel_dp))
ironlake_edp_pll_on(encoder);
 
if (is_edp(intel_dp))
ironlake_edp_panel_vdd_on(intel_dp);
intel_dp_sink_dpms(intel_dp, mode);
if (!(dp_reg & DP_PORT_EN)) {
intel_dp_start_link_train(intel_dp);
if (is_edp(intel_dp)) {
ironlake_edp_panel_on(intel_dp);
ironlake_edp_panel_vdd_off(intel_dp, true);
ironlake_edp_panel_vdd_off(intel_dp);
}
intel_dp_complete_link_train(intel_dp);
} else
ironlake_edp_panel_vdd_off(intel_dp, false);
ironlake_edp_backlight_on(intel_dp);
}
if (is_edp(intel_dp))
ironlake_edp_backlight_on(dev);
}
intel_dp->dpms_mode = mode;
}
 
1338,11 → 1090,11
* link status information
*/
static bool
intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE])
intel_dp_get_link_status(struct intel_dp *intel_dp)
{
return intel_dp_aux_native_read_retry(intel_dp,
DP_LANE0_1_STATUS,
link_status,
intel_dp->link_status,
DP_LINK_STATUS_SIZE);
}
 
1354,25 → 1106,27
}
 
static uint8_t
intel_get_adjust_request_voltage(uint8_t adjust_request[2],
intel_get_adjust_request_voltage(uint8_t link_status[DP_LINK_STATUS_SIZE],
int lane)
{
int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
int s = ((lane & 1) ?
DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT :
DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT);
uint8_t l = adjust_request[lane>>1];
uint8_t l = intel_dp_link_status(link_status, i);
 
return ((l >> s) & 3) << DP_TRAIN_VOLTAGE_SWING_SHIFT;
}
 
static uint8_t
intel_get_adjust_request_pre_emphasis(uint8_t adjust_request[2],
intel_get_adjust_request_pre_emphasis(uint8_t link_status[DP_LINK_STATUS_SIZE],
int lane)
{
int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
int s = ((lane & 1) ?
DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT :
DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT);
uint8_t l = adjust_request[lane>>1];
uint8_t l = intel_dp_link_status(link_status, i);
 
return ((l >> s) & 3) << DP_TRAIN_PRE_EMPHASIS_SHIFT;
}
1394,41 → 1148,16
* These are source-specific values; current Intel hardware supports
* a maximum voltage of 800mV and a maximum pre-emphasis of 6dB
*/
#define I830_DP_VOLTAGE_MAX DP_TRAIN_VOLTAGE_SWING_800
 
static uint8_t
intel_dp_voltage_max(struct intel_dp *intel_dp)
intel_dp_pre_emphasis_max(uint8_t voltage_swing)
{
struct drm_device *dev = intel_dp->base.base.dev;
 
if (IS_GEN7(dev) && is_cpu_edp(intel_dp))
return DP_TRAIN_VOLTAGE_SWING_800;
else if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp))
return DP_TRAIN_VOLTAGE_SWING_1200;
else
return DP_TRAIN_VOLTAGE_SWING_800;
}
 
static uint8_t
intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
{
struct drm_device *dev = intel_dp->base.base.dev;
 
if (IS_GEN7(dev) && is_cpu_edp(intel_dp)) {
switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
case DP_TRAIN_VOLTAGE_SWING_400:
return DP_TRAIN_PRE_EMPHASIS_6;
case DP_TRAIN_VOLTAGE_SWING_600:
case DP_TRAIN_VOLTAGE_SWING_800:
return DP_TRAIN_PRE_EMPHASIS_3_5;
default:
return DP_TRAIN_PRE_EMPHASIS_0;
}
} else {
switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
case DP_TRAIN_VOLTAGE_SWING_400:
return DP_TRAIN_PRE_EMPHASIS_6;
case DP_TRAIN_VOLTAGE_SWING_600:
return DP_TRAIN_PRE_EMPHASIS_6;
case DP_TRAIN_VOLTAGE_SWING_800:
return DP_TRAIN_PRE_EMPHASIS_3_5;
case DP_TRAIN_VOLTAGE_SWING_1200:
1436,21 → 1165,17
return DP_TRAIN_PRE_EMPHASIS_0;
}
}
}
 
static void
intel_get_adjust_train(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE])
intel_get_adjust_train(struct intel_dp *intel_dp)
{
uint8_t v = 0;
uint8_t p = 0;
int lane;
uint8_t *adjust_request = link_status + (DP_ADJUST_REQUEST_LANE0_1 - DP_LANE0_1_STATUS);
uint8_t voltage_max;
uint8_t preemph_max;
 
for (lane = 0; lane < intel_dp->lane_count; lane++) {
uint8_t this_v = intel_get_adjust_request_voltage(adjust_request, lane);
uint8_t this_p = intel_get_adjust_request_pre_emphasis(adjust_request, lane);
uint8_t this_v = intel_get_adjust_request_voltage(intel_dp->link_status, lane);
uint8_t this_p = intel_get_adjust_request_pre_emphasis(intel_dp->link_status, lane);
 
if (this_v > v)
v = this_v;
1458,13 → 1183,11
p = this_p;
}
 
voltage_max = intel_dp_voltage_max(intel_dp);
if (v >= voltage_max)
v = voltage_max | DP_TRAIN_MAX_SWING_REACHED;
if (v >= I830_DP_VOLTAGE_MAX)
v = I830_DP_VOLTAGE_MAX | DP_TRAIN_MAX_SWING_REACHED;
 
preemph_max = intel_dp_pre_emphasis_max(intel_dp, v);
if (p >= preemph_max)
p = preemph_max | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
if (p >= intel_dp_pre_emphasis_max(v))
p = intel_dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
 
for (lane = 0; lane < 4; lane++)
intel_dp->train_set[lane] = v | p;
1471,7 → 1194,7
}
 
static uint32_t
intel_dp_signal_levels(uint8_t train_set)
intel_dp_signal_levels(uint8_t train_set, int lane_count)
{
uint32_t signal_levels = 0;
 
1536,43 → 1259,13
}
}
 
/* Gen7's DP voltage swing and pre-emphasis control */
static uint32_t
intel_gen7_edp_signal_levels(uint8_t train_set)
{
int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
DP_TRAIN_PRE_EMPHASIS_MASK);
switch (signal_levels) {
case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0:
return EDP_LINK_TRAIN_400MV_0DB_IVB;
case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_3_5:
return EDP_LINK_TRAIN_400MV_3_5DB_IVB;
case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_6:
return EDP_LINK_TRAIN_400MV_6DB_IVB;
 
case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_0:
return EDP_LINK_TRAIN_600MV_0DB_IVB;
case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_3_5:
return EDP_LINK_TRAIN_600MV_3_5DB_IVB;
 
case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_0:
return EDP_LINK_TRAIN_800MV_0DB_IVB;
case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_3_5:
return EDP_LINK_TRAIN_800MV_3_5DB_IVB;
 
default:
DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:"
"0x%x\n", signal_levels);
return EDP_LINK_TRAIN_500MV_0DB_IVB;
}
}
 
static uint8_t
intel_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE],
int lane)
{
int i = DP_LANE0_1_STATUS + (lane >> 1);
int s = (lane & 1) * 4;
uint8_t l = link_status[lane>>1];
uint8_t l = intel_dp_link_status(link_status, i);
 
return (l >> s) & 0xf;
}
1597,18 → 1290,18
DP_LANE_CHANNEL_EQ_DONE|\
DP_LANE_SYMBOL_LOCKED)
static bool
intel_channel_eq_ok(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE])
intel_channel_eq_ok(struct intel_dp *intel_dp)
{
uint8_t lane_align;
uint8_t lane_status;
int lane;
 
lane_align = intel_dp_link_status(link_status,
lane_align = intel_dp_link_status(intel_dp->link_status,
DP_LANE_ALIGN_STATUS_UPDATED);
if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0)
return false;
for (lane = 0; lane < intel_dp->lane_count; lane++) {
lane_status = intel_get_lane_status(link_status, lane);
lane_status = intel_get_lane_status(intel_dp->link_status, lane);
if ((lane_status & CHANNEL_EQ_BITS) != CHANNEL_EQ_BITS)
return false;
}
1633,9 → 1326,8
 
ret = intel_dp_aux_native_write(intel_dp,
DP_TRAINING_LANE0_SET,
intel_dp->train_set,
intel_dp->lane_count);
if (ret != intel_dp->lane_count)
intel_dp->train_set, 4);
if (ret != 4)
return false;
 
return true;
1651,7 → 1343,7
int i;
uint8_t voltage;
bool clock_recovery = false;
int voltage_tries, loop_tries;
int tries;
u32 reg;
uint32_t DP = intel_dp->DP;
 
1672,35 → 1364,26
DP_LINK_CONFIGURATION_SIZE);
 
DP |= DP_PORT_EN;
 
if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp)))
if (HAS_PCH_CPT(dev) && !is_edp(intel_dp))
DP &= ~DP_LINK_TRAIN_MASK_CPT;
else
DP &= ~DP_LINK_TRAIN_MASK;
memset(intel_dp->train_set, 0, 4);
voltage = 0xff;
voltage_tries = 0;
loop_tries = 0;
tries = 0;
clock_recovery = false;
for (;;) {
/* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */
uint8_t link_status[DP_LINK_STATUS_SIZE];
uint32_t signal_levels;
 
 
if (IS_GEN7(dev) && is_cpu_edp(intel_dp)) {
signal_levels = intel_gen7_edp_signal_levels(intel_dp->train_set[0]);
DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_IVB) | signal_levels;
} else if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) {
if (IS_GEN6(dev) && is_edp(intel_dp)) {
signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);
DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
} else {
signal_levels = intel_dp_signal_levels(intel_dp->train_set[0]);
DRM_DEBUG_KMS("training pattern 1 signal levels %08x\n", signal_levels);
signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count);
DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
}
 
if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp)))
if (HAS_PCH_CPT(dev) && !is_edp(intel_dp))
reg = DP | DP_LINK_TRAIN_PAT_1_CPT;
else
reg = DP | DP_LINK_TRAIN_PAT_1;
1712,13 → 1395,10
/* Set training pattern 1 */
 
udelay(100);
if (!intel_dp_get_link_status(intel_dp, link_status)) {
DRM_ERROR("failed to get link status\n");
if (!intel_dp_get_link_status(intel_dp))
break;
}
 
if (intel_clock_recovery_ok(link_status, intel_dp->lane_count)) {
DRM_DEBUG_KMS("clock recovery OK\n");
if (intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) {
clock_recovery = true;
break;
}
1727,30 → 1407,20
for (i = 0; i < intel_dp->lane_count; i++)
if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
break;
if (i == intel_dp->lane_count) {
++loop_tries;
if (loop_tries == 5) {
DRM_DEBUG_KMS("too many full retries, give up\n");
if (i == intel_dp->lane_count)
break;
}
memset(intel_dp->train_set, 0, 4);
voltage_tries = 0;
continue;
}
 
/* Check to see if we've tried the same voltage 5 times */
if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
++voltage_tries;
if (voltage_tries == 5) {
DRM_DEBUG_KMS("too many voltage retries, give up\n");
++tries;
if (tries == 5)
break;
}
} else
voltage_tries = 0;
tries = 0;
voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
 
/* Compute new intel_dp->train_set as requested by target */
intel_get_adjust_train(intel_dp, link_status);
intel_get_adjust_train(intel_dp);
}
 
intel_dp->DP = DP;
1773,7 → 1443,6
for (;;) {
/* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */
uint32_t signal_levels;
uint8_t link_status[DP_LINK_STATUS_SIZE];
 
if (cr_tries > 5) {
DRM_ERROR("failed to train DP, aborting\n");
1781,18 → 1450,15
break;
}
 
if (IS_GEN7(dev) && is_cpu_edp(intel_dp)) {
signal_levels = intel_gen7_edp_signal_levels(intel_dp->train_set[0]);
DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_IVB) | signal_levels;
} else if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) {
if (IS_GEN6(dev) && is_edp(intel_dp)) {
signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);
DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
} else {
signal_levels = intel_dp_signal_levels(intel_dp->train_set[0]);
signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count);
DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
}
 
if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp)))
if (HAS_PCH_CPT(dev) && !is_edp(intel_dp))
reg = DP | DP_LINK_TRAIN_PAT_2_CPT;
else
reg = DP | DP_LINK_TRAIN_PAT_2;
1804,17 → 1470,17
break;
 
udelay(400);
if (!intel_dp_get_link_status(intel_dp, link_status))
if (!intel_dp_get_link_status(intel_dp))
break;
 
/* Make sure clock is still ok */
if (!intel_clock_recovery_ok(link_status, intel_dp->lane_count)) {
if (!intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) {
intel_dp_start_link_train(intel_dp);
cr_tries++;
continue;
}
 
if (intel_channel_eq_ok(intel_dp, link_status)) {
if (intel_channel_eq_ok(intel_dp)) {
channel_eq = true;
break;
}
1829,11 → 1495,11
}
 
/* Compute new intel_dp->train_set as requested by target */
intel_get_adjust_train(intel_dp, link_status);
intel_get_adjust_train(intel_dp);
++tries;
}
 
if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp)))
if (HAS_PCH_CPT(dev) && !is_edp(intel_dp))
reg = DP | DP_LINK_TRAIN_OFF_CPT;
else
reg = DP | DP_LINK_TRAIN_OFF;
1863,7 → 1529,7
udelay(100);
}
 
if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) {
if (HAS_PCH_CPT(dev) && !is_edp(intel_dp)) {
DP &= ~DP_LINK_TRAIN_MASK_CPT;
I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT);
} else {
1874,12 → 1540,8
 
msleep(17);
 
if (is_edp(intel_dp)) {
if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp)))
DP |= DP_LINK_TRAIN_OFF_CPT;
else
if (is_edp(intel_dp))
DP |= DP_LINK_TRAIN_OFF;
}
 
if (!HAS_PCH_CPT(dev) &&
I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) {
1914,10 → 1576,8
intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe);
}
 
DP &= ~DP_AUDIO_OUTPUT_ENABLE;
I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN);
POSTING_READ(intel_dp->output_reg);
msleep(intel_dp->panel_power_down_delay);
}
 
static bool
1932,27 → 1592,6
return false;
}
 
static bool
intel_dp_get_sink_irq(struct intel_dp *intel_dp, u8 *sink_irq_vector)
{
int ret;
 
ret = intel_dp_aux_native_read_retry(intel_dp,
DP_DEVICE_SERVICE_IRQ_VECTOR,
sink_irq_vector, 1);
if (!ret)
return false;
 
return true;
}
 
static void
intel_dp_handle_test_request(struct intel_dp *intel_dp)
{
/* NAK by default */
intel_dp_aux_native_write_1(intel_dp, DP_TEST_RESPONSE, DP_TEST_ACK);
}
 
/*
* According to DP spec
* 5.1.2:
1965,9 → 1604,6
static void
intel_dp_check_link_status(struct intel_dp *intel_dp)
{
u8 sink_irq_vector;
u8 link_status[DP_LINK_STATUS_SIZE];
 
if (intel_dp->dpms_mode != DRM_MODE_DPMS_ON)
return;
 
1975,7 → 1611,7
return;
 
/* Try to read receiver status if the link appears to be up */
if (!intel_dp_get_link_status(intel_dp, link_status)) {
if (!intel_dp_get_link_status(intel_dp)) {
intel_dp_link_down(intel_dp);
return;
}
1986,21 → 1622,7
return;
}
 
/* Try to read the source of the interrupt */
if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 &&
intel_dp_get_sink_irq(intel_dp, &sink_irq_vector)) {
/* Clear interrupt source */
intel_dp_aux_native_write_1(intel_dp,
DP_DEVICE_SERVICE_IRQ_VECTOR,
sink_irq_vector);
 
if (sink_irq_vector & DP_AUTOMATED_TEST_REQUEST)
intel_dp_handle_test_request(intel_dp);
if (sink_irq_vector & (DP_CP_IRQ | DP_SINK_SPECIFIC_IRQ))
DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n");
}
 
if (!intel_channel_eq_ok(intel_dp, link_status)) {
if (!intel_channel_eq_ok(intel_dp)) {
DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n",
drm_get_encoder_name(&intel_dp->base.base));
intel_dp_start_link_train(intel_dp);
2061,31 → 1683,6
return intel_dp_detect_dpcd(intel_dp);
}
 
static struct edid *
intel_dp_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
{
struct intel_dp *intel_dp = intel_attached_dp(connector);
struct edid *edid;
 
ironlake_edp_panel_vdd_on(intel_dp);
edid = drm_get_edid(connector, adapter);
ironlake_edp_panel_vdd_off(intel_dp, false);
return edid;
}
 
static int
intel_dp_get_edid_modes(struct drm_connector *connector, struct i2c_adapter *adapter)
{
struct intel_dp *intel_dp = intel_attached_dp(connector);
int ret;
 
ironlake_edp_panel_vdd_on(intel_dp);
ret = intel_ddc_get_modes(connector, adapter);
ironlake_edp_panel_vdd_off(intel_dp, false);
return ret;
}
 
 
/**
* Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect DP connection.
*
2139,36 → 1736,28
/* We should parse the EDID data and find out if it has an audio sink
*/
 
ret = intel_dp_get_edid_modes(connector, &intel_dp->adapter);
ret = intel_ddc_get_modes(connector, &intel_dp->adapter);
if (ret) {
if (is_edp(intel_dp) && !intel_dp->panel_fixed_mode) {
if (is_edp(intel_dp) && !dev_priv->panel_fixed_mode) {
struct drm_display_mode *newmode;
list_for_each_entry(newmode, &connector->probed_modes,
head) {
if ((newmode->type & DRM_MODE_TYPE_PREFERRED)) {
intel_dp->panel_fixed_mode =
if (newmode->type & DRM_MODE_TYPE_PREFERRED) {
dev_priv->panel_fixed_mode =
drm_mode_duplicate(dev, newmode);
break;
}
}
}
 
return ret;
}
 
/* if eDP has no EDID, try to use fixed panel mode from VBT */
if (is_edp(intel_dp)) {
/* initialize panel mode from VBT if available for eDP */
if (intel_dp->panel_fixed_mode == NULL && dev_priv->lfp_lvds_vbt_mode != NULL) {
intel_dp->panel_fixed_mode =
drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode);
if (intel_dp->panel_fixed_mode) {
intel_dp->panel_fixed_mode->type |=
DRM_MODE_TYPE_PREFERRED;
}
}
if (intel_dp->panel_fixed_mode) {
if (dev_priv->panel_fixed_mode != NULL) {
struct drm_display_mode *mode;
mode = drm_mode_duplicate(dev, intel_dp->panel_fixed_mode);
mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode);
drm_mode_probed_add(connector, mode);
return 1;
}
2255,10 → 1844,6
 
// i2c_del_adapter(&intel_dp->adapter);
drm_encoder_cleanup(encoder);
if (is_edp(intel_dp)) {
// cancel_delayed_work_sync(&intel_dp->panel_vdd_work);
ironlake_panel_vdd_off_sync(intel_dp);
}
kfree(intel_dp);
}
 
2311,8 → 1896,7
continue;
 
intel_dp = enc_to_intel_dp(encoder);
if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT ||
intel_dp->base.type == INTEL_OUTPUT_EDP)
if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT)
return intel_dp->output_reg;
}
 
2396,13 → 1980,10
else if (output_reg == DP_D || output_reg == PCH_DP_D)
intel_encoder->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
 
if (is_edp(intel_dp)) {
if (is_edp(intel_dp))
intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT);
// INIT_DELAYED_WORK(&intel_dp->panel_vdd_work,
// ironlake_panel_vdd_work);
}
 
intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
connector->interlace_allowed = true;
connector->doublescan_allowed = 0;
 
2438,59 → 2019,25
break;
}
 
intel_dp_i2c_init(intel_dp, intel_connector, name);
 
/* Cache some DPCD data in the eDP case */
if (is_edp(intel_dp)) {
bool ret;
struct edp_power_seq cur, vbt;
u32 pp_on, pp_off, pp_div;
u32 pp_on, pp_div;
 
pp_on = I915_READ(PCH_PP_ON_DELAYS);
pp_off = I915_READ(PCH_PP_OFF_DELAYS);
pp_div = I915_READ(PCH_PP_DIVISOR);
 
/* Pull timing values out of registers */
cur.t1_t3 = (pp_on & PANEL_POWER_UP_DELAY_MASK) >>
PANEL_POWER_UP_DELAY_SHIFT;
/* Get T3 & T12 values (note: VESA not bspec terminology) */
dev_priv->panel_t3 = (pp_on & 0x1fff0000) >> 16;
dev_priv->panel_t3 /= 10; /* t3 in 100us units */
dev_priv->panel_t12 = pp_div & 0xf;
dev_priv->panel_t12 *= 100; /* t12 in 100ms units */
 
cur.t8 = (pp_on & PANEL_LIGHT_ON_DELAY_MASK) >>
PANEL_LIGHT_ON_DELAY_SHIFT;
 
cur.t9 = (pp_off & PANEL_LIGHT_OFF_DELAY_MASK) >>
PANEL_LIGHT_OFF_DELAY_SHIFT;
 
cur.t10 = (pp_off & PANEL_POWER_DOWN_DELAY_MASK) >>
PANEL_POWER_DOWN_DELAY_SHIFT;
 
cur.t11_t12 = ((pp_div & PANEL_POWER_CYCLE_DELAY_MASK) >>
PANEL_POWER_CYCLE_DELAY_SHIFT) * 1000;
 
DRM_DEBUG_KMS("cur t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n",
cur.t1_t3, cur.t8, cur.t9, cur.t10, cur.t11_t12);
 
vbt = dev_priv->edp.pps;
 
DRM_DEBUG_KMS("vbt t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n",
vbt.t1_t3, vbt.t8, vbt.t9, vbt.t10, vbt.t11_t12);
 
#define get_delay(field) ((max(cur.field, vbt.field) + 9) / 10)
 
intel_dp->panel_power_up_delay = get_delay(t1_t3);
intel_dp->backlight_on_delay = get_delay(t8);
intel_dp->backlight_off_delay = get_delay(t9);
intel_dp->panel_power_down_delay = get_delay(t10);
intel_dp->panel_power_cycle_delay = get_delay(t11_t12);
 
DRM_DEBUG_KMS("panel power up delay %d, power down delay %d, power cycle delay %d\n",
intel_dp->panel_power_up_delay, intel_dp->panel_power_down_delay,
intel_dp->panel_power_cycle_delay);
 
DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n",
intel_dp->backlight_on_delay, intel_dp->backlight_off_delay);
 
ironlake_edp_panel_vdd_on(intel_dp);
ret = intel_dp_get_dpcd(intel_dp);
ironlake_edp_panel_vdd_off(intel_dp, false);
 
ironlake_edp_panel_vdd_off(intel_dp);
if (ret) {
if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11)
dev_priv->no_aux_handshake =
2505,11 → 2052,18
}
}
 
intel_dp_i2c_init(intel_dp, intel_connector, name);
 
intel_encoder->hot_plug = intel_dp_hot_plug;
 
if (is_edp(intel_dp)) {
/* initialize panel mode from VBT if available for eDP */
if (dev_priv->lfp_lvds_vbt_mode) {
dev_priv->panel_fixed_mode =
drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode);
if (dev_priv->panel_fixed_mode) {
dev_priv->panel_fixed_mode->type |=
DRM_MODE_TYPE_PREFERRED;
}
}
dev_priv->int_edp_connector = connector;
intel_panel_setup_backlight(dev);
}
/drivers/video/drm/i915/intel_drv.h
26,7 → 26,6
#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"
112,7 → 111,6
/* 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,
174,37 → 172,12
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
 
212,7 → 185,7
#define DIP_VERSION_AVI 0x2
#define DIP_LEN_AVI 13
 
#define DIP_TYPE_SPD 0x83
#define DIP_TYPE_SPD 0x3
#define DIP_VERSION_SPD 0x1
#define DIP_LEN_SPD 25
#define DIP_SPD_UNKNOWN 0
314,7 → 287,6
extern bool intel_dpd_is_edp(struct drm_device *dev);
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,
366,6 → 338,9
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);
385,7 → 360,7
 
extern int intel_framebuffer_init(struct drm_device *dev,
struct intel_framebuffer *ifb,
struct drm_mode_fb_cmd2 *mode_cmd,
struct drm_mode_fb_cmd *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);
405,25 → 380,5
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__ */
/drivers/video/drm/i915/intel_hdmi.c
69,7 → 69,8
frame->checksum = 0;
frame->ecc = 0;
 
for (i = 0; i < frame->len + DIP_HEADER_SIZE; i++)
/* Header isn't part of the checksum */
for (i = 5; i < frame->len; i++)
sum += data[i];
 
frame->checksum = 0x100 - sum;
103,7 → 104,7
flags |= VIDEO_DIP_ENABLE_AVI | VIDEO_DIP_FREQ_VSYNC;
break;
case DIP_TYPE_SPD:
flags |= VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_FREQ_VSYNC;
flags |= VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_FREQ_2VSYNC;
break;
default:
DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type);
164,9 → 165,9
 
flags = intel_infoframe_index(frame);
 
val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
val &= ~VIDEO_DIP_SELECT_MASK;
 
I915_WRITE(reg, VIDEO_DIP_ENABLE | val | flags);
I915_WRITE(reg, val | flags);
 
for (i = 0; i < len; i += 4) {
I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data);
244,17 → 245,16
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_SEL_CPT(intel_crtc->pipe);
else if (intel_crtc->pipe == 1)
sdvox |= PORT_TRANS_B_SEL_CPT;
else
sdvox |= SDVO_PIPE_B_SELECT;
}
 
I915_WRITE(intel_hdmi->sdvox_reg, sdvox);
POSTING_READ(intel_hdmi->sdvox_reg);
269,11 → 269,7
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);
 
/* HW workaround, need to toggle enable bit off and on for 12bpc, but
285,9 → 281,9
}
 
if (mode != DRM_MODE_DPMS_ON) {
temp &= ~enable_bits;
temp &= ~SDVO_ENABLE;
} else {
temp |= enable_bits;
temp |= SDVO_ENABLE;
}
 
I915_WRITE(intel_hdmi->sdvox_reg, temp);
490,7 → 486,6
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)
516,7 → 511,7
connector->polled = DRM_CONNECTOR_POLL_HPD;
connector->interlace_allowed = 0;
connector->doublescan_allowed = 0;
intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
 
/* Set up the DDC bus. */
if (sdvox_reg == SDVOB) {
543,14 → 538,10
 
intel_hdmi->sdvox_reg = sdvox_reg;
 
if (!HAS_PCH_SPLIT(dev)) {
if (!HAS_PCH_SPLIT(dev))
intel_hdmi->write_infoframe = i9xx_write_infoframe;
I915_WRITE(VIDEO_DIP_CTL, 0);
} else {
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);
 
/drivers/video/drm/i915/intel_i2c.c
550,7 → 550,13
{
struct intel_gmbus *bus = to_intel_gmbus(adapter);
 
bus->reg0 = (bus->reg0 & ~(0x3 << 8)) | speed;
/* speed:
* 0x0 = 100 KHz
* 0x1 = 50 KHz
* 0x2 = 400 KHz
* 0x3 = 1000 Khz
*/
bus->reg0 = (bus->reg0 & ~(0x3 << 8)) | (speed << 8);
}
 
void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit)
/drivers/video/drm/i915/intel_lvds.c
711,14 → 711,6
},
{
.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 = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."),
725,14 → 717,6
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 */
};
906,11 → 890,9
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;
/drivers/video/drm/i915/intel_modes.c
26,7 → 26,6
#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"
75,7 → 74,6
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);
}
/drivers/video/drm/i915/intel_panel.c
193,10 → 193,13
if (HAS_PCH_SPLIT(dev)) {
max >>= 16;
} else {
if (INTEL_INFO(dev)->gen < 4)
if (IS_PINEVIEW(dev)) {
max >>= 17;
else
} else {
max >>= 16;
if (INTEL_INFO(dev)->gen < 4)
max &= ~1;
}
 
if (is_backlight_combination_mode(dev))
max *= 0xff;
215,12 → 218,13
val = I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
} else {
val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
if (INTEL_INFO(dev)->gen < 4)
if (IS_PINEVIEW(dev))
val >>= 1;
 
if (is_backlight_combination_mode(dev)) {
u8 lbpc;
 
val &= ~1;
pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc);
val *= lbpc;
}
237,7 → 241,7
I915_WRITE(BLC_PWM_CPU_CTL, val | level);
}
 
static void intel_panel_actually_set_backlight(struct drm_device *dev, u32 level)
void intel_panel_set_backlight(struct drm_device *dev, u32 level)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 tmp;
257,29 → 261,26
}
 
tmp = I915_READ(BLC_PWM_CTL);
if (INTEL_INFO(dev)->gen < 4)
if (IS_PINEVIEW(dev)) {
tmp &= ~(BACKLIGHT_DUTY_CYCLE_MASK - 1);
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_actually_set_backlight(dev, 0);
}
 
intel_panel_set_backlight(dev, 0);
}
 
void intel_panel_enable_backlight(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
287,8 → 288,8
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)
335,8 → 336,7
static int intel_panel_get_brightness(struct backlight_device *bd)
{
struct drm_device *dev = bl_get_data(bd);
struct drm_i915_private *dev_priv = dev->dev_private;
return dev_priv->backlight_level;
return intel_panel_get_backlight(dev);
}
 
static const struct backlight_ops intel_panel_bl_ops = {
/drivers/video/drm/i915/intel_ringbuffer.h
75,12 → 75,7
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.
185,6 → 180,9
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);
/drivers/video/drm/i915/intel_bios.h
120,9 → 120,7
u8 ssc_freq:1;
u8 enable_lfp_on_override:1;
u8 disable_ssc_ddt:1;
u8 rsvd7:1;
u8 display_clock_mode:1;
u8 rsvd8:1; /* finish byte */
u8 rsvd8:3; /* finish byte */
 
/* bits 3 */
u8 disable_smooth_vision:1;
135,10 → 133,7
/* bits 5 */
u8 int_crt_support:1;
u8 int_tv_support:1;
u8 int_efp_support:1;
u8 dp_ssc_enb:1; /* PCH attached eDP supports SSC */
u8 dp_ssc_freq:1; /* SSC freq for PCH attached eDP */
u8 rsvd11:3; /* finish byte */
u8 rsvd11:6; /* finish byte */
} __attribute__((packed));
 
/* pre-915 */
202,7 → 197,8
struct child_device_config {
u16 handle;
u16 device_type;
u8 device_id[10]; /* ascii string */
u8 i2c_speed;
u8 rsvd[9];
u16 addin_offset;
u8 dvo_port; /* See Device_PORT_* above */
u8 i2c_pin;
450,11 → 446,11
#define EDP_VSWING_1_2V 3
 
struct edp_power_seq {
u16 t1_t3;
u16 t8;
u16 t3;
u16 t7;
u16 t9;
u16 t10;
u16 t11_t12;
u16 t12;
} __attribute__ ((packed));
 
struct edp_link_params {
467,12 → 463,8
struct bdb_edp {
struct edp_power_seq power_seqs[16];
u32 color_depth;
u32 sdrrs_msa_timing_delay;
struct edp_link_params link_params[16];
u32 sdrrs_msa_timing_delay;
 
/* ith bit indicates enabled/disabled for (i+1)th panel */
u16 edp_s3d_feature;
u16 edp_t3_optimization;
} __attribute__ ((packed));
 
void intel_setup_bios(struct drm_device *dev);
/drivers/video/drm/i915/i915_reg.h
194,13 → 194,6
#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
*/
242,22 → 235,16
#define ASYNC_FLIP (1<<22)
#define DISPLAY_PLANE_A (0<<20)
#define DISPLAY_PLANE_B (1<<20)
#define GFX_OP_PIPE_CONTROL(len) ((0x3<<29)|(0x3<<27)|(0x2<<24)|(len-2))
#define PIPE_CONTROL_CS_STALL (1<<20)
#define GFX_OP_PIPE_CONTROL ((0x3<<29)|(0x3<<27)|(0x2<<24)|2)
#define PIPE_CONTROL_QW_WRITE (1<<14)
#define PIPE_CONTROL_DEPTH_STALL (1<<13)
#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_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_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 */
 
 
/*
309,12 → 296,6
#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)
442,7 → 423,6
#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
1554,21 → 1534,12
*/
#define PP_READY (1 << 30)
#define PP_SEQUENCE_NONE (0 << 28)
#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_SEQUENCE_ON (1 << 28)
#define PP_SEQUENCE_OFF (2 << 28)
#define PP_SEQUENCE_MASK 0x30000000
#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
2322,7 → 2293,6
#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)
2446,7 → 2416,6
#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
2461,8 → 2430,6
#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 */
2587,18 → 2554,10
#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)
2679,140 → 2638,6
#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)
3020,10 → 2845,6
#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)
3082,13 → 2903,12
#define SDEIER 0xc400c
 
/* digital port hotplug */
#define PCH_PORT_HOTPLUG 0xc4030 /* SHOTPLUG_CTL */
#define PCH_PORT_HOTPLUG 0xc4030
#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)
3097,7 → 2917,6
#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)
3106,7 → 2925,6
#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)
3127,7 → 2945,7
 
#define _PCH_DPLL_A 0xc6014
#define _PCH_DPLL_B 0xc6018
#define PCH_DPLL(pipe) (pipe == 0 ? _PCH_DPLL_A : _PCH_DPLL_B)
#define PCH_DPLL(pipe) _PIPE(pipe, _PCH_DPLL_A, _PCH_DPLL_B)
 
#define _PCH_FPA0 0xc6040
#define FP_CB_TUNE (0x3<<22)
3134,8 → 2952,8
#define _PCH_FPA1 0xc6044
#define _PCH_FPB0 0xc6048
#define _PCH_FPB1 0xc604c
#define PCH_FP0(pipe) (pipe == 0 ? _PCH_FPA0 : _PCH_FPB0)
#define PCH_FP1(pipe) (pipe == 0 ? _PCH_FPA1 : _PCH_FPB1)
#define PCH_FP0(pipe) _PIPE(pipe, _PCH_FPA0, _PCH_FPB0)
#define PCH_FP1(pipe) _PIPE(pipe, _PCH_FPA1, _PCH_FPB1)
 
#define PCH_DPLL_TEST 0xc606c
 
3349,7 → 3167,6
#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)
3445,10 → 3262,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)
3491,7 → 3308,6
#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)
3498,28 → 3314,9
#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
3589,38 → 3386,12
#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)
3642,11 → 3413,7
#define GEN6_CAGF_MASK (0x7f << GEN6_CAGF_SHIFT)
#define GEN6_RP_CONTROL 0xA024
#define GEN6_RP_MEDIA_TURBO (1<<11)
#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_USE_NORMAL_FREQ (1<<9)
#define GEN6_RP_MEDIA_IS_GFX (1<<8)
#define GEN6_RP_ENABLE (1<<7)
#define GEN6_RP_UP_IDLE_MIN (0x1<<3)
3703,43 → 3470,4
#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_ */