/drivers/video/drm/drm_gem.c |
---|
273,7 → 273,6 |
idr_remove(&filp->object_idr, handle); |
spin_unlock(&filp->table_lock); |
// drm_gem_remove_prime_handles(obj, filp); |
if (dev->driver->gem_close_object) |
dev->driver->gem_close_object(obj, filp); |
317,12 → 316,6 |
} |
*handlep = ret; |
// ret = drm_vma_node_allow(&obj->vma_node, file_priv->filp); |
// if (ret) { |
// drm_gem_handle_delete(file_priv, *handlep); |
// return ret; |
// } |
if (dev->driver->gem_open_object) { |
ret = dev->driver->gem_open_object(obj, file_priv); |
if (ret) { |
/drivers/video/drm/i915/Makefile |
---|
76,6 → 76,7 |
intel_sprite.c \ |
intel_uncore.c \ |
kms_display.c \ |
kos_gem_fb.c \ |
utils.c \ |
../hdmi.c \ |
Gtt/intel-agp.c \ |
/drivers/video/drm/i915/i915_dma.c |
---|
1156,8 → 1156,8 |
if (ret) |
DRM_INFO("failed to find VBIOS tables\n"); |
fb_obj = kos_gem_fb_object_create(dev,0,12*1024*1024); |
/* Initialise stolen first so that we may reserve preallocated |
* objects for the BIOS to KMS transition. |
*/ |
1524,6 → 1524,8 |
cancel_work_sync(&dev_priv->gpu_error.work); |
i915_destroy_error_state(dev); |
cancel_delayed_work_sync(&dev_priv->pc8.enable_work); |
if (dev->pdev->msi_enabled) |
pci_disable_msi(dev->pdev); |
/drivers/video/drm/i915/i915_drv.c |
---|
62,7 → 62,7 |
"Override lid status (0=autodetect, 1=autodetect disabled [default], " |
"-1=force lid closed, -2=force lid open)"); |
unsigned int i915_powersave __read_mostly = 1; |
unsigned int i915_powersave __read_mostly = 0; |
module_param_named(powersave, i915_powersave, int, 0600); |
MODULE_PARM_DESC(powersave, |
"Enable powersavings, fbc, downclocking, etc. (default: true)"); |
72,7 → 72,7 |
MODULE_PARM_DESC(semaphores, |
"Use semaphores for inter-ring sync (default: -1 (use per-chip defaults))"); |
int i915_enable_rc6 __read_mostly = -1; |
int i915_enable_rc6 __read_mostly = 0; |
module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0400); |
MODULE_PARM_DESC(i915_enable_rc6, |
"Enable power-saving render C-state 6. " |
81,7 → 81,7 |
"For example, 3 would enable rc6 and deep rc6, and 7 would enable everything. " |
"default: -1 (use per-chip default)"); |
int i915_enable_fbc __read_mostly = -1; |
int i915_enable_fbc __read_mostly = 0; |
module_param_named(i915_enable_fbc, i915_enable_fbc, int, 0600); |
MODULE_PARM_DESC(i915_enable_fbc, |
"Enable frame buffer compression for power savings " |
150,7 → 150,7 |
MODULE_PARM_DESC(fastboot, "Try to skip unnecessary mode sets at boot time " |
"(default: false)"); |
int i915_enable_pc8 __read_mostly = 1; |
int i915_enable_pc8 __read_mostly = 0; |
module_param_named(enable_pc8, i915_enable_pc8, int, 0600); |
MODULE_PARM_DESC(enable_pc8, "Enable support for low power package C states (PC8+) (default: true)"); |
/drivers/video/drm/i915/i915_drv.h |
---|
509,10 → 509,12 |
/* FIXME: Need a more generic return type */ |
gen6_gtt_pte_t (*pte_encode)(dma_addr_t addr, |
enum i915_cache_level level); |
enum i915_cache_level level, |
bool valid); /* Create a valid PTE */ |
void (*clear_range)(struct i915_address_space *vm, |
unsigned int first_entry, |
unsigned int num_entries); |
unsigned int num_entries, |
bool use_scratch); |
void (*insert_entries)(struct i915_address_space *vm, |
struct sg_table *st, |
unsigned int first_entry, |
2071,6 → 2073,8 |
void i915_ppgtt_unbind_object(struct i915_hw_ppgtt *ppgtt, |
struct drm_i915_gem_object *obj); |
void i915_check_and_clear_faults(struct drm_device *dev); |
void i915_gem_suspend_gtt_mappings(struct drm_device *dev); |
void i915_gem_restore_gtt_mappings(struct drm_device *dev); |
int __must_check i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj); |
void i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj, |
2340,6 → 2344,12 |
return min_t(unsigned long, MAX_JIFFY_OFFSET, j + 1); |
} |
static inline int mutex_trylock(struct mutex *lock) |
{ |
if (likely(atomic_cmpxchg(&lock->count, 1, 0) == 1)) |
return 1; |
return 0; |
} |
typedef struct |
{ |
2349,19 → 2359,27 |
int freq; |
}videomode_t; |
static inline int mutex_trylock(struct mutex *lock) |
struct cmdtable |
{ |
if (likely(atomic_cmpxchg(&lock->count, 1, 0) == 1)) |
return 1; |
return 0; |
} |
char *key; |
int size; |
int *val; |
}; |
#define CMDENTRY(key, val) {(key), (sizeof(key)-1), &val} |
#define ioread32(addr) readl(addr) |
void parse_cmdline(char *cmdline, struct cmdtable *table, char *log, videomode_t *mode); |
struct drm_i915_gem_object |
*kos_gem_fb_object_create(struct drm_device *dev, u32 gtt_offset, u32 size); |
extern struct drm_i915_gem_object *fb_obj; |
static struct drm_i915_gem_object *get_fb_obj() |
{ |
return fb_obj; |
}; |
#define ioread32(addr) readl(addr) |
#endif |
/drivers/video/drm/i915/i915_gem.c |
---|
26,6 → 26,7 |
*/ |
#include <drm/drmP.h> |
#include <drm/drm_vma_manager.h> |
#include <drm/i915_drm.h> |
#include "i915_drv.h" |
#include "i915_trace.h" |
2619,6 → 2620,9 |
POSTING_READ(fence_reg + 4); |
I915_WRITE(fence_reg + 0, val); |
dbgprintf("%s val %x%x\n",__FUNCTION__, (int)(val >> 32), (int)val); |
POSTING_READ(fence_reg); |
} else { |
I915_WRITE(fence_reg + 4, 0); |
3668,9 → 3672,6 |
if (WARN_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT)) |
return -EBUSY; |
// if( obj == get_fb_obj()) |
// return 0; |
WARN_ON(map_and_fenceable && !i915_is_ggtt(vm)); |
vma = i915_gem_obj_to_vma(obj, vm); |
/drivers/video/drm/i915/i915_gem_context.c |
---|
299,9 → 299,29 |
BUG_ON(id == DEFAULT_CONTEXT_ID); |
i915_gem_context_unreference(ctx); |
return 0; |
} |
struct i915_ctx_hang_stats * |
i915_gem_context_get_hang_stats(struct drm_device *dev, |
struct drm_file *file, |
u32 id) |
{ |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct drm_i915_file_private *file_priv = file->driver_priv; |
struct i915_hw_context *ctx; |
return 0; |
if (id == DEFAULT_CONTEXT_ID) |
return &file_priv->hang_stats; |
ctx = NULL; |
if (!dev_priv->hw_contexts_disabled) |
ctx = i915_gem_context_get(file->driver_priv, id); |
if (ctx == NULL) |
return ERR_PTR(-ENOENT); |
return &ctx->hang_stats; |
} |
void i915_gem_context_close(struct drm_device *dev, struct drm_file *file) |
/drivers/video/drm/i915/i915_gem_gtt.c |
---|
65,9 → 65,10 |
#define HSW_WT_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x6) |
static gen6_gtt_pte_t snb_pte_encode(dma_addr_t addr, |
enum i915_cache_level level) |
enum i915_cache_level level, |
bool valid) |
{ |
gen6_gtt_pte_t pte = GEN6_PTE_VALID; |
gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0; |
pte |= GEN6_PTE_ADDR_ENCODE(addr); |
switch (level) { |
86,9 → 87,10 |
} |
static gen6_gtt_pte_t ivb_pte_encode(dma_addr_t addr, |
enum i915_cache_level level) |
enum i915_cache_level level, |
bool valid) |
{ |
gen6_gtt_pte_t pte = GEN6_PTE_VALID; |
gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0; |
pte |= GEN6_PTE_ADDR_ENCODE(addr); |
switch (level) { |
112,9 → 114,10 |
#define BYT_PTE_SNOOPED_BY_CPU_CACHES (1 << 2) |
static gen6_gtt_pte_t byt_pte_encode(dma_addr_t addr, |
enum i915_cache_level level) |
enum i915_cache_level level, |
bool valid) |
{ |
gen6_gtt_pte_t pte = GEN6_PTE_VALID; |
gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0; |
pte |= GEN6_PTE_ADDR_ENCODE(addr); |
/* Mark the page as writeable. Other platforms don't have a |
129,9 → 132,10 |
} |
static gen6_gtt_pte_t hsw_pte_encode(dma_addr_t addr, |
enum i915_cache_level level) |
enum i915_cache_level level, |
bool valid) |
{ |
gen6_gtt_pte_t pte = GEN6_PTE_VALID; |
gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0; |
pte |= HSW_PTE_ADDR_ENCODE(addr); |
if (level != I915_CACHE_NONE) |
141,9 → 145,10 |
} |
static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr, |
enum i915_cache_level level) |
enum i915_cache_level level, |
bool valid) |
{ |
gen6_gtt_pte_t pte = GEN6_PTE_VALID; |
gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0; |
pte |= HSW_PTE_ADDR_ENCODE(addr); |
switch (level) { |
243,7 → 248,8 |
/* PPGTT support for Sandybdrige/Gen6 and later */ |
static void gen6_ppgtt_clear_range(struct i915_address_space *vm, |
unsigned first_entry, |
unsigned num_entries) |
unsigned num_entries, |
bool use_scratch) |
{ |
struct i915_hw_ppgtt *ppgtt = |
container_of(vm, struct i915_hw_ppgtt, base); |
252,7 → 258,7 |
unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES; |
unsigned last_pte, i; |
scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC); |
scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, true); |
pt_vaddr = AllocKernelSpace(4096); |
301,7 → 307,7 |
dma_addr_t page_addr; |
page_addr = sg_page_iter_dma_address(&sg_iter); |
pt_vaddr[act_pte] = vm->pte_encode(page_addr, cache_level); |
pt_vaddr[act_pte] = vm->pte_encode(page_addr, cache_level, true); |
if (++act_pte == I915_PPGTT_PT_ENTRIES) { |
act_pt++; |
MapPage(pt_vaddr,(addr_t)(ppgtt->pt_pages[act_pt]), 3); |
380,7 → 386,7 |
} |
ppgtt->base.clear_range(&ppgtt->base, 0, |
ppgtt->num_pd_entries*I915_PPGTT_PT_ENTRIES); |
ppgtt->num_pd_entries * I915_PPGTT_PT_ENTRIES, true); |
ppgtt->pd_offset = first_pd_entry_in_global_pt * sizeof(gen6_gtt_pte_t); |
457,7 → 463,8 |
{ |
ppgtt->base.clear_range(&ppgtt->base, |
i915_gem_obj_ggtt_offset(obj) >> PAGE_SHIFT, |
obj->base.size >> PAGE_SHIFT); |
obj->base.size >> PAGE_SHIFT, |
true); |
} |
extern int intel_iommu_gfx_mapped; |
498,15 → 505,65 |
dev_priv->mm.interruptible = interruptible; |
} |
void i915_check_and_clear_faults(struct drm_device *dev) |
{ |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct intel_ring_buffer *ring; |
int i; |
if (INTEL_INFO(dev)->gen < 6) |
return; |
for_each_ring(ring, dev_priv, i) { |
u32 fault_reg; |
fault_reg = I915_READ(RING_FAULT_REG(ring)); |
if (fault_reg & RING_FAULT_VALID) { |
DRM_DEBUG_DRIVER("Unexpected fault\n" |
"\tAddr: 0x%08lx\\n" |
"\tAddress space: %s\n" |
"\tSource ID: %d\n" |
"\tType: %d\n", |
fault_reg & PAGE_MASK, |
fault_reg & RING_FAULT_GTTSEL_MASK ? "GGTT" : "PPGTT", |
RING_FAULT_SRCID(fault_reg), |
RING_FAULT_FAULT_TYPE(fault_reg)); |
I915_WRITE(RING_FAULT_REG(ring), |
fault_reg & ~RING_FAULT_VALID); |
} |
} |
POSTING_READ(RING_FAULT_REG(&dev_priv->ring[RCS])); |
} |
void i915_gem_suspend_gtt_mappings(struct drm_device *dev) |
{ |
struct drm_i915_private *dev_priv = dev->dev_private; |
/* Don't bother messing with faults pre GEN6 as we have little |
* documentation supporting that it's a good idea. |
*/ |
if (INTEL_INFO(dev)->gen < 6) |
return; |
i915_check_and_clear_faults(dev); |
dev_priv->gtt.base.clear_range(&dev_priv->gtt.base, |
dev_priv->gtt.base.start / PAGE_SIZE, |
dev_priv->gtt.base.total / PAGE_SIZE, |
false); |
} |
void i915_gem_restore_gtt_mappings(struct drm_device *dev) |
{ |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct drm_i915_gem_object *obj; |
i915_check_and_clear_faults(dev); |
/* First fill our portion of the GTT with scratch pages */ |
dev_priv->gtt.base.clear_range(&dev_priv->gtt.base, |
dev_priv->gtt.base.start / PAGE_SIZE, |
dev_priv->gtt.base.total / PAGE_SIZE); |
dev_priv->gtt.base.total / PAGE_SIZE, |
true); |
list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { |
i915_gem_clflush_object(obj, obj->pin_display); |
549,7 → 606,7 |
for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) { |
addr = sg_page_iter_dma_address(&sg_iter); |
iowrite32(vm->pte_encode(addr, level), >t_entries[i]); |
iowrite32(vm->pte_encode(addr, level, true), >t_entries[i]); |
i++; |
} |
561,7 → 618,7 |
*/ |
if (i != 0) |
WARN_ON(readl(>t_entries[i-1]) != |
vm->pte_encode(addr, level)); |
vm->pte_encode(addr, level, true)); |
/* This next bit makes the above posting read even more important. We |
* want to flush the TLBs only after we're certain all the PTE updates |
573,7 → 630,8 |
static void gen6_ggtt_clear_range(struct i915_address_space *vm, |
unsigned int first_entry, |
unsigned int num_entries) |
unsigned int num_entries, |
bool use_scratch) |
{ |
struct drm_i915_private *dev_priv = vm->dev->dev_private; |
gen6_gtt_pte_t scratch_pte, __iomem *gtt_base = |
586,7 → 644,8 |
first_entry, num_entries, max_entries)) |
num_entries = max_entries; |
scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC); |
scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, use_scratch); |
for (i = 0; i < num_entries; i++) |
iowrite32(scratch_pte, >t_base[i]); |
readl(gtt_base); |
607,7 → 666,8 |
static void i915_ggtt_clear_range(struct i915_address_space *vm, |
unsigned int first_entry, |
unsigned int num_entries) |
unsigned int num_entries, |
bool unused) |
{ |
intel_gtt_clear_range(first_entry, num_entries); |
} |
635,7 → 695,8 |
dev_priv->gtt.base.clear_range(&dev_priv->gtt.base, |
entry, |
obj->base.size >> PAGE_SHIFT); |
obj->base.size >> PAGE_SHIFT, |
true); |
obj->has_global_gtt_mapping = 0; |
} |
722,11 → 783,11 |
const unsigned long count = (hole_end - hole_start) / PAGE_SIZE; |
DRM_DEBUG_KMS("clearing unused GTT space: [%lx, %lx]\n", |
hole_start, hole_end); |
ggtt_vm->clear_range(ggtt_vm, hole_start / PAGE_SIZE, count); |
ggtt_vm->clear_range(ggtt_vm, hole_start / PAGE_SIZE, count, true); |
} |
/* And finally clear the reserved guard page */ |
ggtt_vm->clear_range(ggtt_vm, end / PAGE_SIZE - 1, 1); |
ggtt_vm->clear_range(ggtt_vm, end / PAGE_SIZE - 1, 1, true); |
} |
static bool |
752,7 → 813,6 |
gtt_size = dev_priv->gtt.base.total; |
mappable_size = dev_priv->gtt.mappable_end; |
#if 0 |
if (intel_enable_ppgtt(dev) && HAS_ALIASING_PPGTT(dev)) { |
int ret; |
762,7 → 822,7 |
gtt_size -= GEN6_PPGTT_PD_ENTRIES * PAGE_SIZE; |
} |
i915_gem_setup_global_gtt(dev, LFB_SIZE, mappable_size, gtt_size-LFB_SIZE); |
i915_gem_setup_global_gtt(dev, 0, mappable_size, gtt_size); |
ret = i915_gem_init_aliasing_ppgtt(dev); |
if (!ret) |
772,9 → 832,7 |
drm_mm_takedown(&dev_priv->gtt.base.mm); |
gtt_size += GEN6_PPGTT_PD_ENTRIES * PAGE_SIZE; |
} |
#endif |
i915_gem_setup_global_gtt(dev, LFB_SIZE, mappable_size, gtt_size-LFB_SIZE); |
i915_gem_setup_global_gtt(dev, 0, mappable_size, gtt_size); |
} |
static int setup_scratch_page(struct drm_device *dev) |
/drivers/video/drm/i915/i915_reg.h |
---|
604,6 → 604,10 |
#define ARB_MODE_SWIZZLE_IVB (1<<5) |
#define RENDER_HWS_PGA_GEN7 (0x04080) |
#define RING_FAULT_REG(ring) (0x4094 + 0x100*(ring)->id) |
#define RING_FAULT_GTTSEL_MASK (1<<11) |
#define RING_FAULT_SRCID(x) ((x >> 3) & 0xff) |
#define RING_FAULT_FAULT_TYPE(x) ((x >> 1) & 0x3) |
#define RING_FAULT_VALID (1<<0) |
#define DONE_REG 0x40b0 |
#define BSD_HWS_PGA_GEN7 (0x04180) |
#define BLT_HWS_PGA_GEN7 (0x04280) |
4279,7 → 4283,9 |
#define FDI_RX_CHICKEN(pipe) _PIPE(pipe, _FDI_RXA_CHICKEN, _FDI_RXB_CHICKEN) |
#define SOUTH_DSPCLK_GATE_D 0xc2020 |
#define PCH_DPLUNIT_CLOCK_GATE_DISABLE (1<<30) |
#define PCH_DPLSUNIT_CLOCK_GATE_DISABLE (1<<29) |
#define PCH_CPUNIT_CLOCK_GATE_DISABLE (1<<14) |
#define PCH_LP_PARTITION_LEVEL_DISABLE (1<<12) |
/* CPU: FDI_TX */ |
/drivers/video/drm/i915/intel_crt.c |
---|
82,8 → 82,7 |
return true; |
} |
static void intel_crt_get_config(struct intel_encoder *encoder, |
struct intel_crtc_config *pipe_config) |
static unsigned int intel_crt_get_flags(struct intel_encoder *encoder) |
{ |
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; |
struct intel_crt *crt = intel_encoder_to_crt(encoder); |
101,9 → 100,27 |
else |
flags |= DRM_MODE_FLAG_NVSYNC; |
pipe_config->adjusted_mode.flags |= flags; |
return flags; |
} |
static void intel_crt_get_config(struct intel_encoder *encoder, |
struct intel_crtc_config *pipe_config) |
{ |
pipe_config->adjusted_mode.flags |= intel_crt_get_flags(encoder); |
} |
static void hsw_crt_get_config(struct intel_encoder *encoder, |
struct intel_crtc_config *pipe_config) |
{ |
intel_ddi_get_config(encoder, pipe_config); |
pipe_config->adjusted_mode.flags &= ~(DRM_MODE_FLAG_PHSYNC | |
DRM_MODE_FLAG_NHSYNC | |
DRM_MODE_FLAG_PVSYNC | |
DRM_MODE_FLAG_NVSYNC); |
pipe_config->adjusted_mode.flags |= intel_crt_get_flags(encoder); |
} |
/* Note: The caller is required to filter out dpms modes not supported by the |
* platform. */ |
static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode) |
776,6 → 793,9 |
crt->base.mode_set = intel_crt_mode_set; |
crt->base.disable = intel_disable_crt; |
crt->base.enable = intel_enable_crt; |
if (IS_HASWELL(dev)) |
crt->base.get_config = hsw_crt_get_config; |
else |
crt->base.get_config = intel_crt_get_config; |
if (I915_HAS_HOTPLUG(dev)) |
crt->base.hpd_pin = HPD_CRT; |
/drivers/video/drm/i915/intel_ddi.c |
---|
1249,7 → 1249,7 |
intel_dp_check_link_status(intel_dp); |
} |
static void intel_ddi_get_config(struct intel_encoder *encoder, |
void intel_ddi_get_config(struct intel_encoder *encoder, |
struct intel_crtc_config *pipe_config) |
{ |
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; |
1268,7 → 1268,24 |
flags |= DRM_MODE_FLAG_NVSYNC; |
pipe_config->adjusted_mode.flags |= flags; |
switch (temp & TRANS_DDI_BPC_MASK) { |
case TRANS_DDI_BPC_6: |
pipe_config->pipe_bpp = 18; |
break; |
case TRANS_DDI_BPC_8: |
pipe_config->pipe_bpp = 24; |
break; |
case TRANS_DDI_BPC_10: |
pipe_config->pipe_bpp = 30; |
break; |
case TRANS_DDI_BPC_12: |
pipe_config->pipe_bpp = 36; |
break; |
default: |
break; |
} |
} |
static void intel_ddi_destroy(struct drm_encoder *encoder) |
{ |
/drivers/video/drm/i915/intel_display.c |
---|
1828,6 → 1828,8 |
u32 alignment; |
int ret; |
ENTER(); |
switch (obj->tiling_mode) { |
case I915_TILING_NONE: |
if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) |
1876,6 → 1878,9 |
i915_gem_object_pin_fence(obj); |
dev_priv->mm.interruptible = true; |
LEAVE(); |
return 0; |
err_unpin: |
2240,15 → 2245,28 |
} |
mutex_lock(&dev->struct_mutex); |
// ret = intel_pin_and_fence_fb_obj(dev, |
// to_intel_framebuffer(fb)->obj, |
// NULL); |
// if (ret != 0) { |
// mutex_unlock(&dev->struct_mutex); |
// DRM_ERROR("pin & fence failed\n"); |
// return ret; |
// } |
ret = intel_pin_and_fence_fb_obj(dev, |
to_intel_framebuffer(fb)->obj, |
NULL); |
if (ret != 0) { |
mutex_unlock(&dev->struct_mutex); |
DRM_ERROR("pin & fence failed\n"); |
return ret; |
} |
/* Update pipe size and adjust fitter if needed */ |
if (i915_fastboot) { |
I915_WRITE(PIPESRC(intel_crtc->pipe), |
((crtc->mode.hdisplay - 1) << 16) | |
(crtc->mode.vdisplay - 1)); |
if (!intel_crtc->config.pch_pfit.enabled && |
(intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) || |
intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) { |
I915_WRITE(PF_CTL(intel_crtc->pipe), 0); |
I915_WRITE(PF_WIN_POS(intel_crtc->pipe), 0); |
I915_WRITE(PF_WIN_SZ(intel_crtc->pipe), 0); |
} |
} |
ret = dev_priv->display.update_plane(crtc, fb, x, y); |
if (ret) { |
2317,9 → 2335,10 |
FDI_FE_ERRC_ENABLE); |
} |
static bool pipe_has_enabled_pch(struct intel_crtc *intel_crtc) |
static bool pipe_has_enabled_pch(struct intel_crtc *crtc) |
{ |
return intel_crtc->base.enabled && intel_crtc->config.has_pch_encoder; |
return crtc->base.enabled && crtc->active && |
crtc->config.has_pch_encoder; |
} |
static void ivb_modeset_global_resources(struct drm_device *dev) |
2971,6 → 2990,48 |
I915_READ(VSYNCSHIFT(cpu_transcoder))); |
} |
static void cpt_enable_fdi_bc_bifurcation(struct drm_device *dev) |
{ |
struct drm_i915_private *dev_priv = dev->dev_private; |
uint32_t temp; |
temp = I915_READ(SOUTH_CHICKEN1); |
if (temp & FDI_BC_BIFURCATION_SELECT) |
return; |
WARN_ON(I915_READ(FDI_RX_CTL(PIPE_B)) & FDI_RX_ENABLE); |
WARN_ON(I915_READ(FDI_RX_CTL(PIPE_C)) & FDI_RX_ENABLE); |
temp |= FDI_BC_BIFURCATION_SELECT; |
DRM_DEBUG_KMS("enabling fdi C rx\n"); |
I915_WRITE(SOUTH_CHICKEN1, temp); |
POSTING_READ(SOUTH_CHICKEN1); |
} |
static void ivybridge_update_fdi_bc_bifurcation(struct intel_crtc *intel_crtc) |
{ |
struct drm_device *dev = intel_crtc->base.dev; |
struct drm_i915_private *dev_priv = dev->dev_private; |
switch (intel_crtc->pipe) { |
case PIPE_A: |
break; |
case PIPE_B: |
if (intel_crtc->config.fdi_lanes > 2) |
WARN_ON(I915_READ(SOUTH_CHICKEN1) & FDI_BC_BIFURCATION_SELECT); |
else |
cpt_enable_fdi_bc_bifurcation(dev); |
break; |
case PIPE_C: |
cpt_enable_fdi_bc_bifurcation(dev); |
break; |
default: |
BUG(); |
} |
} |
/* |
* Enable PCH resources required for PCH ports: |
* - PCH PLLs |
2989,6 → 3050,9 |
assert_pch_transcoder_disabled(dev_priv, pipe); |
if (IS_IVYBRIDGE(dev)) |
ivybridge_update_fdi_bc_bifurcation(intel_crtc); |
/* Write the TU size bits before fdi link training, so that error |
* detection works. */ |
I915_WRITE(FDI_RX_TUSIZE1(pipe), |
3852,12 → 3916,12 |
assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane); |
assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe); |
// if (crtc->fb) { |
// mutex_lock(&dev->struct_mutex); |
// intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj); |
// mutex_unlock(&dev->struct_mutex); |
// crtc->fb = NULL; |
// } |
if (crtc->fb) { |
mutex_lock(&dev->struct_mutex); |
intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj); |
mutex_unlock(&dev->struct_mutex); |
crtc->fb = NULL; |
} |
/* Update computed state. */ |
list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
4977,6 → 5041,22 |
if (!(tmp & PIPECONF_ENABLE)) |
return false; |
if (IS_G4X(dev) || IS_VALLEYVIEW(dev)) { |
switch (tmp & PIPECONF_BPC_MASK) { |
case PIPECONF_6BPC: |
pipe_config->pipe_bpp = 18; |
break; |
case PIPECONF_8BPC: |
pipe_config->pipe_bpp = 24; |
break; |
case PIPECONF_10BPC: |
pipe_config->pipe_bpp = 30; |
break; |
default: |
break; |
} |
} |
intel_get_pipe_timings(crtc, pipe_config); |
i9xx_get_pfit_config(crtc, pipe_config); |
5570,48 → 5650,6 |
return true; |
} |
static void cpt_enable_fdi_bc_bifurcation(struct drm_device *dev) |
{ |
struct drm_i915_private *dev_priv = dev->dev_private; |
uint32_t temp; |
temp = I915_READ(SOUTH_CHICKEN1); |
if (temp & FDI_BC_BIFURCATION_SELECT) |
return; |
WARN_ON(I915_READ(FDI_RX_CTL(PIPE_B)) & FDI_RX_ENABLE); |
WARN_ON(I915_READ(FDI_RX_CTL(PIPE_C)) & FDI_RX_ENABLE); |
temp |= FDI_BC_BIFURCATION_SELECT; |
DRM_DEBUG_KMS("enabling fdi C rx\n"); |
I915_WRITE(SOUTH_CHICKEN1, temp); |
POSTING_READ(SOUTH_CHICKEN1); |
} |
static void ivybridge_update_fdi_bc_bifurcation(struct intel_crtc *intel_crtc) |
{ |
struct drm_device *dev = intel_crtc->base.dev; |
struct drm_i915_private *dev_priv = dev->dev_private; |
switch (intel_crtc->pipe) { |
case PIPE_A: |
break; |
case PIPE_B: |
if (intel_crtc->config.fdi_lanes > 2) |
WARN_ON(I915_READ(SOUTH_CHICKEN1) & FDI_BC_BIFURCATION_SELECT); |
else |
cpt_enable_fdi_bc_bifurcation(dev); |
break; |
case PIPE_C: |
cpt_enable_fdi_bc_bifurcation(dev); |
break; |
default: |
BUG(); |
} |
} |
int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp) |
{ |
/* |
5805,9 → 5843,6 |
&intel_crtc->config.fdi_m_n); |
} |
if (IS_IVYBRIDGE(dev)) |
ivybridge_update_fdi_bc_bifurcation(intel_crtc); |
ironlake_set_pipeconf(crtc); |
/* Set up the display plane register */ |
5875,6 → 5910,23 |
if (!(tmp & PIPECONF_ENABLE)) |
return false; |
switch (tmp & PIPECONF_BPC_MASK) { |
case PIPECONF_6BPC: |
pipe_config->pipe_bpp = 18; |
break; |
case PIPECONF_8BPC: |
pipe_config->pipe_bpp = 24; |
break; |
case PIPECONF_10BPC: |
pipe_config->pipe_bpp = 30; |
break; |
case PIPECONF_12BPC: |
pipe_config->pipe_bpp = 36; |
break; |
default: |
break; |
} |
if (I915_READ(PCH_TRANSCONF(crtc->pipe)) & TRANS_ENABLE) { |
struct intel_shared_dpll *pll; |
7050,22 → 7102,22 |
struct drm_i915_gem_object *obj; |
struct drm_framebuffer *fb; |
// if (dev_priv->fbdev == NULL) |
// return NULL; |
if (dev_priv->fbdev == NULL) |
return NULL; |
// obj = dev_priv->fbdev->ifb.obj; |
// if (obj == NULL) |
obj = dev_priv->fbdev->ifb.obj; |
if (obj == NULL) |
return NULL; |
// if (obj->base.size < mode->vdisplay * fb->pitch) |
fb = &dev_priv->fbdev->ifb.base; |
if (fb->pitches[0] < intel_framebuffer_pitch_for_width(mode->hdisplay, |
fb->bits_per_pixel)) |
// return NULL; |
return NULL; |
if (obj->base.size < mode->vdisplay * fb->pitches[0]) |
return NULL; |
// return fb; |
return fb; |
} |
bool intel_get_load_detect_pipe(struct drm_connector *connector, |
8597,6 → 8649,9 |
PIPE_CONF_CHECK_X(dpll_hw_state.fp0); |
PIPE_CONF_CHECK_X(dpll_hw_state.fp1); |
if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) |
PIPE_CONF_CHECK_I(pipe_bpp); |
#undef PIPE_CONF_CHECK_X |
#undef PIPE_CONF_CHECK_I |
#undef PIPE_CONF_CHECK_FLAGS |
9952,10 → 10007,6 |
q->subsystem_device == PCI_ANY_ID)) |
q->hook(dev); |
} |
// for (i = 0; i < ARRAY_SIZE(intel_dmi_quirks); i++) { |
// if (dmi_check_system(*intel_dmi_quirks[i].dmi_id_list) != 0) |
// intel_dmi_quirks[i].hook(dev); |
// } |
} |
/* Disable the VGA plane that we never use */ |
10471,11 → 10522,9 |
/* flush any delayed tasks or pending work */ |
flush_scheduled_work(); |
// cancel_work_sync(&dev_priv->hotplug_work); |
// cancel_work_sync(&dev_priv->rps.work); |
/* flush any delayed tasks or pending work */ |
// flush_scheduled_work(); |
/* destroy backlight, if any, before the connectors */ |
intel_panel_destroy_backlight(dev); |
drm_mode_config_cleanup(dev); |
#endif |
/drivers/video/drm/i915/intel_dp.c |
---|
1390,7 → 1390,27 |
else |
pipe_config->port_clock = 270000; |
} |
if (is_edp(intel_dp) && dev_priv->vbt.edp_bpp && |
pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) { |
/* |
* This is a big fat ugly hack. |
* |
* Some machines in UEFI boot mode provide us a VBT that has 18 |
* bpp and 1.62 GHz link bandwidth for eDP, which for reasons |
* unknown we fail to light up. Yet the same BIOS boots up with |
* 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as |
* max, not what it tells us to use. |
* |
* Note: This will still be broken if the eDP panel is not lit |
* up by the BIOS, and thus we can't get the mode at module |
* load. |
*/ |
DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n", |
pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp); |
dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp; |
} |
} |
static bool is_edp_psr(struct intel_dp *intel_dp) |
{ |
/drivers/video/drm/i915/intel_drv.h |
---|
770,6 → 770,8 |
extern bool |
intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector); |
extern void intel_ddi_fdi_disable(struct drm_crtc *crtc); |
extern void intel_ddi_get_config(struct intel_encoder *encoder, |
struct intel_crtc_config *pipe_config); |
extern void intel_display_handle_reset(struct drm_device *dev); |
extern bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, |
/drivers/video/drm/i915/intel_fb.c |
---|
43,13 → 43,8 |
#include <drm/i915_drm.h> |
#include "i915_drv.h" |
static struct drm_i915_gem_object *fb_obj; |
struct drm_i915_gem_object *fb_obj; |
struct drm_i915_gem_object *get_fb_obj() |
{ |
return fb_obj; |
}; |
struct fb_info *framebuffer_alloc(size_t size, struct device *dev) |
{ |
#define BYTES_PER_LONG (BITS_PER_LONG/8) |
105,6 → 100,8 |
struct device *device = &dev->pdev->dev; |
int size, ret; |
ENTER(); |
/* we don't do packed 24bpp */ |
if (sizes->surface_bpp == 24) |
sizes->surface_bpp = 32; |
113,13 → 110,13 |
mode_cmd.height = sizes->surface_height; |
mode_cmd.pitches[0] = ALIGN(mode_cmd.width * ((sizes->surface_bpp + 7) / |
8), 64); |
8), 512); |
mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, |
sizes->surface_depth); |
size = mode_cmd.pitches[0] * mode_cmd.height; |
size = ALIGN(size, PAGE_SIZE); |
obj = i915_gem_alloc_object(dev, size); |
obj = fb_obj; |
if (!obj) { |
DRM_ERROR("failed to allocate framebuffer\n"); |
ret = -ENOMEM; |
126,37 → 123,17 |
goto out; |
} |
obj->stride = mode_cmd.pitches[0]; |
mutex_lock(&dev->struct_mutex); |
#if 0 |
// skip this part and use existing framebiffer |
/* Flush everything out, we'll be doing GTT only from now on */ |
ret = intel_pin_and_fence_fb_obj(dev, obj, false); |
ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); |
if (ret) { |
DRM_ERROR("failed to pin fb: %d\n", ret); |
goto out_unref; |
} |
#endif |
/***********************************************************************/ |
{ |
#define LFB_SIZE 0xC00000 |
static struct drm_mm_node lfb_vm_node; |
lfb_vm_node.size = LFB_SIZE; |
lfb_vm_node.start = 0; |
lfb_vm_node.mm = NULL; |
obj->pin_count = 2; |
obj->cache_level = I915_CACHE_NONE; |
obj->base.write_domain = 0; |
obj->base.read_domains = I915_GEM_DOMAIN_GTT; |
} |
/***********************************************************************/ |
info = framebuffer_alloc(0, device); |
if (!info) { |
ret = -ENOMEM; |
194,6 → 171,8 |
info->screen_base = (void*) 0xFE000000; |
info->screen_size = size; |
/* This driver doesn't need a VT switch to restore the mode on resume */ |
info->skip_vt_switch = true; |
drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); |
drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height); |
206,9 → 185,6 |
mutex_unlock(&dev->struct_mutex); |
fb_obj = obj; |
return 0; |
out_unpin: |
/drivers/video/drm/i915/intel_lvds.c |
---|
700,6 → 700,22 |
}, |
{ |
.callback = intel_no_lvds_dmi_callback, |
.ident = "Intel D410PT", |
.matches = { |
DMI_MATCH(DMI_BOARD_VENDOR, "Intel"), |
DMI_MATCH(DMI_BOARD_NAME, "D410PT"), |
}, |
}, |
{ |
.callback = intel_no_lvds_dmi_callback, |
.ident = "Intel D425KT", |
.matches = { |
DMI_MATCH(DMI_BOARD_VENDOR, "Intel"), |
DMI_EXACT_MATCH(DMI_BOARD_NAME, "D425KT"), |
}, |
}, |
{ |
.callback = intel_no_lvds_dmi_callback, |
.ident = "Intel D510MO", |
.matches = { |
DMI_MATCH(DMI_BOARD_VENDOR, "Intel"), |
/drivers/video/drm/i915/intel_pm.c |
---|
4768,7 → 4768,9 |
* gating for the panel power sequencer or it will fail to |
* start up when no ports are active. |
*/ |
I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE); |
I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE | |
PCH_DPLUNIT_CLOCK_GATE_DISABLE | |
PCH_CPUNIT_CLOCK_GATE_DISABLE); |
I915_WRITE(SOUTH_CHICKEN2, I915_READ(SOUTH_CHICKEN2) | |
DPLS_EDP_PPS_FIX_DIS); |
/* The below fixes the weird display corruption, a few pixels shifted |
/drivers/video/drm/i915/kms_display.c |
---|
106,6 → 106,7 |
struct drm_framebuffer *fb = NULL; |
struct drm_crtc *crtc; |
struct drm_encoder *encoder; |
struct drm_i915_gem_object *fb_obj; |
struct drm_mode_set set; |
char *con_name; |
char *enc_name; |
162,15 → 163,17 |
if (crtc->invert_dimensions) |
swap(hdisplay, vdisplay); |
fb_obj = get_fb_obj(); |
fb = fb_helper->fb; |
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->pitches[0] = fb->pitches[1] = fb->pitches[2] = |
fb->pitches[3] = ALIGN(reqmode->width * 4, 512); |
fb_obj->stride = fb->pitches[0]; |
fb->bits_per_pixel = 32; |
fb->depth = 24; |
178,6 → 181,8 |
crtc->enabled = true; |
os_display->crtc = crtc; |
i915_gem_object_put_fence(fb_obj); |
set.crtc = crtc; |
set.x = 0; |
set.y = 0; |
261,7 → 266,7 |
}; |
int init_display_kms(struct drm_device *dev) |
int init_display_kms(struct drm_device *dev, videomode_t *usermode) |
{ |
struct drm_connector *connector; |
struct drm_connector_helper_funcs *connector_funcs; |
273,6 → 278,10 |
u32_t ifl; |
int err; |
ENTER(); |
mutex_lock(&dev->mode_config.mutex); |
list_for_each_entry(connector, &dev->mode_config.connector_list, head) |
{ |
if( connector->status != connector_status_connected) |
289,20 → 298,22 |
connector->encoder = encoder; |
crtc = encoder->crtc; |
DRM_DEBUG_KMS("CONNECTOR %x ID:%d status:%d ENCODER %x CRTC %x ID:%d\n", |
DRM_DEBUG_KMS("CONNECTOR %p ID:%d status:%d ENCODER %x CRTC %p ID:%d\n", |
connector, connector->base.id, |
connector->status, connector->encoder, |
crtc, crtc->base.id ); |
break; |
}; |
if(connector == NULL) |
{ |
DRM_ERROR("No active connectors!\n"); |
DRM_DEBUG_KMS("No active connectors!\n"); |
mutex_unlock(&dev->mode_config.mutex); |
return -1; |
}; |
dbgprintf("CRTC %p\n", crtc); |
if(crtc == NULL) |
{ |
struct drm_crtc *tmp_crtc; |
310,10 → 321,12 |
list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) |
{ |
dbgprintf("tmp_crtc %p\n", tmp_crtc); |
if (encoder->possible_crtcs & crtc_mask) |
{ |
crtc = tmp_crtc; |
encoder->crtc = crtc; |
dbgprintf("CRTC %p\n", crtc); |
break; |
}; |
crtc_mask <<= 1; |
320,15 → 333,17 |
}; |
}; |
dbgprintf("CRTC %p\n", crtc); |
if(crtc == NULL) |
{ |
DRM_ERROR("No CRTC for encoder %d\n", encoder->base.id); |
DRM_DEBUG_KMS("No CRTC for encoder %d\n", encoder->base.id); |
mutex_unlock(&dev->mode_config.mutex); |
return -1; |
}; |
DRM_DEBUG_KMS("[Select CRTC: %p ID:%d]\n",crtc, crtc->base.id); |
DRM_DEBUG_KMS("[Select CRTC:%d]\n", crtc->base.id); |
os_display = GetDisplay(); |
os_display->ddev = dev; |
os_display->connector = connector; |
361,10 → 376,53 |
}; |
safe_sti(ifl); |
if( (usermode->width == 0) || |
(usermode->height == 0)) |
{ |
struct drm_display_mode *mode; |
// connector->funcs->fill_modes(connector, dev->mode_config.max_width, |
// dev->mode_config.max_height); |
list_for_each_entry(mode, &connector->modes, head) |
{ |
printf("check mode w:%d h:%d %dHz\n", |
drm_mode_width(mode), drm_mode_height(mode), |
drm_mode_vrefresh(mode)); |
if( os_display->width == drm_mode_width(mode) && |
os_display->height == drm_mode_height(mode) && |
drm_mode_vrefresh(mode) == 60) |
{ |
usermode->width = os_display->width; |
usermode->height = os_display->height; |
usermode->freq = 60; |
break; |
} |
} |
if( usermode->width == 0 || |
usermode->height == 0) |
{ |
mode = list_entry(connector->modes.next, typeof(*mode), head); |
usermode->width = drm_mode_width(mode); |
usermode->height = drm_mode_height(mode); |
usermode->freq = drm_mode_vrefresh(mode); |
}; |
}; |
mutex_unlock(&dev->mode_config.mutex); |
set_mode(dev, os_display->connector, usermode, false); |
#ifdef __HWA__ |
err = init_bitmaps(); |
#endif |
LEAVE(); |
return 0; |
}; |
/drivers/video/drm/i915/kos_gem_fb.c |
---|
0,0 → 1,199 |
/* |
* Copyright © 2008-2012 Intel Corporation |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the next |
* paragraph) shall be included in all copies or substantial portions of the |
* Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
* IN THE SOFTWARE. |
* |
* Authors: |
* Eric Anholt <eric@anholt.net> |
* Chris Wilson <chris@chris-wilson.co.uk> |
* |
*/ |
#include <drm/drmP.h> |
#include <drm/i915_drm.h> |
#include "i915_drv.h" |
static struct sg_table * |
i915_pages_create_for_fb(struct drm_device *dev, |
u32 offset, u32 size) |
{ |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct sg_table *st; |
struct scatterlist *sg; |
addr_t fb_pages; |
DRM_DEBUG_DRIVER("offset=0x%x, size=%d\n", offset, size); |
// BUG_ON(offset > dev_priv->gtt.stolen_size - size); |
/* We hide that we have no struct page backing our stolen object |
* by wrapping the contiguous physical allocation with a fake |
* dma mapping in a single scatterlist. |
*/ |
st = kmalloc(sizeof(*st), GFP_KERNEL); |
if (st == NULL) |
return NULL; |
if (sg_alloc_table(st, 1, GFP_KERNEL)) { |
kfree(st); |
return NULL; |
} |
fb_pages = AllocPages(size/PAGE_SIZE); |
if(fb_pages == 0) |
{ |
kfree(st); |
return NULL; |
}; |
sg = st->sgl; |
sg->offset = offset; |
sg->length = size; |
sg_dma_address(sg) = (dma_addr_t)fb_pages; |
sg_dma_len(sg) = size; |
return st; |
} |
static int kos_fb_object_get_pages(struct drm_i915_gem_object *obj) |
{ |
BUG(); |
return -EINVAL; |
} |
static void kos_fb_object_put_pages(struct drm_i915_gem_object *obj) |
{ |
/* Should only be called during free */ |
sg_free_table(obj->pages); |
kfree(obj->pages); |
} |
static const struct drm_i915_gem_object_ops kos_fb_object_ops = { |
.get_pages = kos_fb_object_get_pages, |
.put_pages = kos_fb_object_put_pages, |
}; |
static struct drm_i915_gem_object * |
_kos_fb_object_create(struct drm_device *dev, |
struct drm_mm_node *fb_node) |
{ |
struct drm_i915_gem_object *obj; |
obj = i915_gem_object_alloc(dev); |
if (obj == NULL) |
return NULL; |
drm_gem_private_object_init(dev, &obj->base, fb_node->size); |
i915_gem_object_init(obj, &kos_fb_object_ops); |
obj->pages = i915_pages_create_for_fb(dev, |
fb_node->start, fb_node->size); |
if (obj->pages == NULL) |
goto cleanup; |
obj->has_dma_mapping = true; |
i915_gem_object_pin_pages(obj); |
obj->stolen = fb_node; |
obj->base.read_domains = I915_GEM_DOMAIN_GTT; |
obj->cache_level = I915_CACHE_NONE; |
obj->tiling_mode = I915_TILING_X; |
return obj; |
cleanup: |
i915_gem_object_free(obj); |
return NULL; |
} |
struct drm_i915_gem_object * |
kos_gem_fb_object_create(struct drm_device *dev, |
u32 gtt_offset, |
u32 size) |
{ |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct i915_address_space *ggtt = &dev_priv->gtt.base; |
struct drm_i915_gem_object *obj; |
struct drm_mm_node *fb_node; |
struct i915_vma *vma; |
int ret; |
DRM_DEBUG_KMS("creating preallocated framebuffer object: gtt_offset=%x, size=%x\n", |
gtt_offset, size); |
/* KISS and expect everything to be page-aligned */ |
BUG_ON(size & 4095); |
if (WARN_ON(size == 0)) |
return NULL; |
fb_node = kzalloc(sizeof(*fb_node), GFP_KERNEL); |
if (!fb_node) |
return NULL; |
fb_node->start = gtt_offset; |
fb_node->size = size; |
obj = _kos_fb_object_create(dev, fb_node); |
if (obj == NULL) { |
DRM_DEBUG_KMS("failed to preallocate framebuffer object\n"); |
kfree(fb_node); |
return NULL; |
} |
vma = i915_gem_vma_create(obj, ggtt); |
if (IS_ERR(vma)) { |
ret = PTR_ERR(vma); |
goto err_out; |
} |
/* To simplify the initialisation sequence between KMS and GTT, |
* we allow construction of the stolen object prior to |
* setting up the GTT space. The actual reservation will occur |
* later. |
*/ |
vma->node.start = gtt_offset; |
vma->node.size = size; |
if (drm_mm_initialized(&ggtt->mm)) { |
ret = drm_mm_reserve_node(&ggtt->mm, &vma->node); |
if (ret) { |
DRM_DEBUG_KMS("failed to allocate framebuffer GTT space\n"); |
goto err_vma; |
} |
} |
obj->has_global_gtt_mapping = 1; |
list_add_tail(&obj->global_list, &dev_priv->mm.bound_list); |
list_add_tail(&vma->mm_list, &ggtt->inactive_list); |
return obj; |
err_vma: |
i915_gem_vma_destroy(vma); |
err_out: |
kfree(fb_node); |
drm_gem_object_unreference(&obj->base); |
return NULL; |
} |
/drivers/video/drm/i915/main.c |
---|
28,10 → 28,10 |
struct drm_device *main_device; |
struct drm_file *drm_file_handlers[256]; |
videomode_t usermode; |
void cpu_detect(); |
void parse_cmdline(char *cmdline, char *log); |
int _stdcall display_handler(ioctl_t *io); |
int init_agp(void); |
51,7 → 51,16 |
int i915_mask_update(struct drm_device *dev, void *data, |
struct drm_file *file); |
struct cmdtable cmdtable[]= { |
CMDENTRY("-pm=", i915_powersave), |
CMDENTRY("-rc6=", i915_enable_rc6), |
CMDENTRY("-fbc=", i915_enable_fbc), |
CMDENTRY("-ppgt=", i915_enable_ppgtt), |
CMDENTRY("-pc8=", i915_enable_pc8), |
{NULL, 0} |
}; |
static char log[256]; |
struct workqueue_struct *system_wq; |
158,8 → 167,22 |
if( GetService("DISPLAY") != 0 ) |
return 0; |
printf("i915 v3.12\n\nusage: i915 [options]\n" |
"-pm=<0,1> Enable powersavings, fbc, downclocking, etc. (default: 0 - false)\n"); |
printf("-rc6=<-1,0-7> Enable power-saving render C-state 6.\n" |
" Different stages can be selected via bitmask values\n" |
" (0 = disable; 1 = enable rc6; 2 = enable deep rc6; 4 = enable deepest rc6).\n" |
" For example, 3 would enable rc6 and deep rc6, and 7 would enable everything.\n" |
" default: -1 (use per-chip default)\n"); |
printf("-fbc=<-1,0,1> Enable frame buffer compression for power savings\n" |
" (default: 0 - false)\n"); |
printf("-ppgt=<0,1> Enable PPGTT (default: 0 - false)\n"); |
printf("-pc8=<0,1> Enable support for low power package C states (PC8+) (default: 0 - false)\n"); |
printf("-l<path> path to log file\n"); |
printf("-m<WxHxHz> set videomode\n"); |
if( cmdline && *cmdline ) |
parse_cmdline(cmdline, log); |
parse_cmdline(cmdline, cmdtable, log, &usermode); |
if(!dbg_open(log)) |
{ |
171,7 → 194,6 |
return 0; |
}; |
} |
dbgprintf(" i915 v3.12-6\n cmdline: %s\n", cmdline); |
cpu_detect(); |
// dbgprintf("\ncache line size %d\n", x86_clflush_size); |
184,8 → 206,9 |
dbgprintf("Epic Fail :(\n"); |
return 0; |
}; |
init_display_kms(main_device); |
init_display_kms(main_device, &usermode); |
err = RegService("DISPLAY", display_handler); |
if( err != 0) |
458,40 → 481,8 |
}; |
static char* parse_path(char *p, char *log) |
{ |
char c; |
while( (c = *p++) == ' '); |
p--; |
while( (c = *log++ = *p++) && (c != ' ')); |
*log = 0; |
return p; |
}; |
void parse_cmdline(char *cmdline, char *log) |
{ |
char *p = cmdline; |
char c = *p++; |
while( c ) |
{ |
if( c == '-') |
{ |
switch(*p++) |
{ |
case 'l': |
p = parse_path(p, log); |
break; |
}; |
}; |
c = *p++; |
}; |
}; |
static inline void __cpuid(unsigned int *eax, unsigned int *ebx, |
unsigned int *ecx, unsigned int *edx) |
{ |
571,3 → 562,137 |
char *strstr(const char *cs, const char *ct); |
static int my_atoi(char **cmd) |
{ |
char* p = *cmd; |
int val = 0; |
int sign = 1; |
if(*p == '-') |
{ |
sign = -1; |
p++; |
}; |
for (;; *p++) { |
switch (*p) { |
case '0' ... '9': |
val = 10*val+(*p-'0'); |
break; |
default: |
*cmd = p; |
return val*sign; |
} |
} |
} |
char* parse_mode(char *p, videomode_t *mode) |
{ |
char c; |
while( (c = *p++) == ' '); |
if( c ) |
{ |
p--; |
mode->width = my_atoi(&p); |
if(*p == 'x') p++; |
mode->height = my_atoi(&p); |
if(*p == 'x') p++; |
mode->bpp = 32; |
mode->freq = my_atoi(&p); |
if( mode->freq == 0 ) |
mode->freq = 60; |
} |
return p; |
}; |
static char* parse_path(char *p, char *log) |
{ |
char c; |
while( (c = *p++) == ' '); |
p--; |
while( (c = *log++ = *p++) && (c != ' ')); |
*log = 0; |
return p; |
}; |
void parse_cmdline(char *cmdline, struct cmdtable *table, char *log, videomode_t *mode) |
{ |
char *p = cmdline; |
char *p1; |
int val; |
char c = *p++; |
if( table ) |
{ |
while(table->key) |
{ |
if(p1 = strstr(cmdline, table->key)) |
{ |
p1+= table->size; |
*table->val = my_atoi(&p1); |
// printf("%s %d\n", table->key, *table->val); |
} |
table++; |
} |
} |
while( c ) |
{ |
if( c == '-') |
{ |
switch(*p++) |
{ |
case 'l': |
p = parse_path(p, log); |
break; |
case 'm': |
p = parse_mode(p, mode); |
break; |
}; |
}; |
c = *p++; |
}; |
}; |
char *strstr(const char *cs, const char *ct) |
{ |
int d0, d1; |
register char *__res; |
__asm__ __volatile__( |
"movl %6,%%edi\n\t" |
"repne\n\t" |
"scasb\n\t" |
"notl %%ecx\n\t" |
"decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */ |
"movl %%ecx,%%edx\n" |
"1:\tmovl %6,%%edi\n\t" |
"movl %%esi,%%eax\n\t" |
"movl %%edx,%%ecx\n\t" |
"repe\n\t" |
"cmpsb\n\t" |
"je 2f\n\t" /* also works for empty string, see above */ |
"xchgl %%eax,%%esi\n\t" |
"incl %%esi\n\t" |
"cmpb $0,-1(%%eax)\n\t" |
"jne 1b\n\t" |
"xorl %%eax,%%eax\n\t" |
"2:" |
: "=a" (__res), "=&c" (d0), "=&S" (d1) |
: "0" (0), "1" (0xffffffff), "2" (cs), "g" (ct) |
: "dx", "di"); |
return __res; |
} |
/drivers/video/drm/i915/pci.c |
---|
783,18 → 783,9 |
return (void __iomem *)(unsigned long) |
pci_resource_start(pdev, PCI_ROM_RESOURCE); |
} else { |
/* assign the ROM an address if it doesn't have one */ |
// if (res->parent == NULL && |
// pci_assign_resource(pdev,PCI_ROM_RESOURCE)) |
return NULL; |
// start = pci_resource_start(pdev, PCI_ROM_RESOURCE); |
// *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); |
// if (*size == 0) |
// return NULL; |
start = (loff_t)0xC0000; |
*size = 0x20000; /* cover C000:0 through E000:0 */ |
/* Enable ROM space decodes */ |
// if (pci_enable_rom(pdev)) |
// return NULL; |
} |
} |