forked from KolibriOS/kolibrios
i915: enable tiled framebuffer
git-svn-id: svn://kolibrios.org@4280 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
bd92a354fb
commit
304eb30a10
@ -273,7 +273,6 @@ drm_gem_handle_delete(struct drm_file *filp, u32 handle)
|
|||||||
idr_remove(&filp->object_idr, handle);
|
idr_remove(&filp->object_idr, handle);
|
||||||
spin_unlock(&filp->table_lock);
|
spin_unlock(&filp->table_lock);
|
||||||
|
|
||||||
// drm_gem_remove_prime_handles(obj, filp);
|
|
||||||
|
|
||||||
if (dev->driver->gem_close_object)
|
if (dev->driver->gem_close_object)
|
||||||
dev->driver->gem_close_object(obj, filp);
|
dev->driver->gem_close_object(obj, filp);
|
||||||
@ -317,12 +316,6 @@ drm_gem_handle_create_tail(struct drm_file *file_priv,
|
|||||||
}
|
}
|
||||||
*handlep = ret;
|
*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) {
|
if (dev->driver->gem_open_object) {
|
||||||
ret = dev->driver->gem_open_object(obj, file_priv);
|
ret = dev->driver->gem_open_object(obj, file_priv);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -76,6 +76,7 @@ NAME_SRC= main.c \
|
|||||||
intel_sprite.c \
|
intel_sprite.c \
|
||||||
intel_uncore.c \
|
intel_uncore.c \
|
||||||
kms_display.c \
|
kms_display.c \
|
||||||
|
kos_gem_fb.c \
|
||||||
utils.c \
|
utils.c \
|
||||||
../hdmi.c \
|
../hdmi.c \
|
||||||
Gtt/intel-agp.c \
|
Gtt/intel-agp.c \
|
||||||
|
@ -1156,7 +1156,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
|
|||||||
if (ret)
|
if (ret)
|
||||||
DRM_INFO("failed to find VBIOS tables\n");
|
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
|
/* Initialise stolen first so that we may reserve preallocated
|
||||||
* objects for the BIOS to KMS transition.
|
* objects for the BIOS to KMS transition.
|
||||||
@ -1524,6 +1524,8 @@ int i915_driver_unload(struct drm_device *dev)
|
|||||||
cancel_work_sync(&dev_priv->gpu_error.work);
|
cancel_work_sync(&dev_priv->gpu_error.work);
|
||||||
i915_destroy_error_state(dev);
|
i915_destroy_error_state(dev);
|
||||||
|
|
||||||
|
cancel_delayed_work_sync(&dev_priv->pc8.enable_work);
|
||||||
|
|
||||||
if (dev->pdev->msi_enabled)
|
if (dev->pdev->msi_enabled)
|
||||||
pci_disable_msi(dev->pdev);
|
pci_disable_msi(dev->pdev);
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ MODULE_PARM_DESC(panel_ignore_lid,
|
|||||||
"Override lid status (0=autodetect, 1=autodetect disabled [default], "
|
"Override lid status (0=autodetect, 1=autodetect disabled [default], "
|
||||||
"-1=force lid closed, -2=force lid open)");
|
"-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_param_named(powersave, i915_powersave, int, 0600);
|
||||||
MODULE_PARM_DESC(powersave,
|
MODULE_PARM_DESC(powersave,
|
||||||
"Enable powersavings, fbc, downclocking, etc. (default: true)");
|
"Enable powersavings, fbc, downclocking, etc. (default: true)");
|
||||||
@ -72,7 +72,7 @@ module_param_named(semaphores, i915_semaphores, int, 0600);
|
|||||||
MODULE_PARM_DESC(semaphores,
|
MODULE_PARM_DESC(semaphores,
|
||||||
"Use semaphores for inter-ring sync (default: -1 (use per-chip defaults))");
|
"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_param_named(i915_enable_rc6, i915_enable_rc6, int, 0400);
|
||||||
MODULE_PARM_DESC(i915_enable_rc6,
|
MODULE_PARM_DESC(i915_enable_rc6,
|
||||||
"Enable power-saving render C-state 6. "
|
"Enable power-saving render C-state 6. "
|
||||||
@ -81,7 +81,7 @@ MODULE_PARM_DESC(i915_enable_rc6,
|
|||||||
"For example, 3 would enable rc6 and deep rc6, and 7 would enable everything. "
|
"For example, 3 would enable rc6 and deep rc6, and 7 would enable everything. "
|
||||||
"default: -1 (use per-chip default)");
|
"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_param_named(i915_enable_fbc, i915_enable_fbc, int, 0600);
|
||||||
MODULE_PARM_DESC(i915_enable_fbc,
|
MODULE_PARM_DESC(i915_enable_fbc,
|
||||||
"Enable frame buffer compression for power savings "
|
"Enable frame buffer compression for power savings "
|
||||||
@ -150,7 +150,7 @@ module_param_named(fastboot, i915_fastboot, bool, 0600);
|
|||||||
MODULE_PARM_DESC(fastboot, "Try to skip unnecessary mode sets at boot time "
|
MODULE_PARM_DESC(fastboot, "Try to skip unnecessary mode sets at boot time "
|
||||||
"(default: false)");
|
"(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_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)");
|
MODULE_PARM_DESC(enable_pc8, "Enable support for low power package C states (PC8+) (default: true)");
|
||||||
|
|
||||||
|
@ -509,10 +509,12 @@ struct i915_address_space {
|
|||||||
|
|
||||||
/* FIXME: Need a more generic return type */
|
/* FIXME: Need a more generic return type */
|
||||||
gen6_gtt_pte_t (*pte_encode)(dma_addr_t addr,
|
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,
|
void (*clear_range)(struct i915_address_space *vm,
|
||||||
unsigned int first_entry,
|
unsigned int first_entry,
|
||||||
unsigned int num_entries);
|
unsigned int num_entries,
|
||||||
|
bool use_scratch);
|
||||||
void (*insert_entries)(struct i915_address_space *vm,
|
void (*insert_entries)(struct i915_address_space *vm,
|
||||||
struct sg_table *st,
|
struct sg_table *st,
|
||||||
unsigned int first_entry,
|
unsigned int first_entry,
|
||||||
@ -2071,6 +2073,8 @@ void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt,
|
|||||||
void i915_ppgtt_unbind_object(struct i915_hw_ppgtt *ppgtt,
|
void i915_ppgtt_unbind_object(struct i915_hw_ppgtt *ppgtt,
|
||||||
struct drm_i915_gem_object *obj);
|
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);
|
void i915_gem_restore_gtt_mappings(struct drm_device *dev);
|
||||||
int __must_check i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj);
|
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,
|
void i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj,
|
||||||
@ -2340,6 +2344,12 @@ timespec_to_jiffies_timeout(const struct timespec *value)
|
|||||||
return min_t(unsigned long, MAX_JIFFY_OFFSET, j + 1);
|
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
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -2349,19 +2359,27 @@ typedef struct
|
|||||||
int freq;
|
int freq;
|
||||||
}videomode_t;
|
}videomode_t;
|
||||||
|
|
||||||
|
struct cmdtable
|
||||||
static inline int mutex_trylock(struct mutex *lock)
|
|
||||||
{
|
{
|
||||||
if (likely(atomic_cmpxchg(&lock->count, 1, 0) == 1))
|
char *key;
|
||||||
return 1;
|
int size;
|
||||||
return 0;
|
int *val;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
#define CMDENTRY(key, val) {(key), (sizeof(key)-1), &val}
|
||||||
|
|
||||||
|
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)
|
#define ioread32(addr) readl(addr)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <drm/drmP.h>
|
#include <drm/drmP.h>
|
||||||
|
#include <drm/drm_vma_manager.h>
|
||||||
#include <drm/i915_drm.h>
|
#include <drm/i915_drm.h>
|
||||||
#include "i915_drv.h"
|
#include "i915_drv.h"
|
||||||
#include "i915_trace.h"
|
#include "i915_trace.h"
|
||||||
@ -2619,6 +2620,9 @@ static void i965_write_fence_reg(struct drm_device *dev, int reg,
|
|||||||
POSTING_READ(fence_reg + 4);
|
POSTING_READ(fence_reg + 4);
|
||||||
|
|
||||||
I915_WRITE(fence_reg + 0, val);
|
I915_WRITE(fence_reg + 0, val);
|
||||||
|
|
||||||
|
dbgprintf("%s val %x%x\n",__FUNCTION__, (int)(val >> 32), (int)val);
|
||||||
|
|
||||||
POSTING_READ(fence_reg);
|
POSTING_READ(fence_reg);
|
||||||
} else {
|
} else {
|
||||||
I915_WRITE(fence_reg + 4, 0);
|
I915_WRITE(fence_reg + 4, 0);
|
||||||
@ -3668,9 +3672,6 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj,
|
|||||||
if (WARN_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT))
|
if (WARN_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT))
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
// if( obj == get_fb_obj())
|
|
||||||
// return 0;
|
|
||||||
|
|
||||||
WARN_ON(map_and_fenceable && !i915_is_ggtt(vm));
|
WARN_ON(map_and_fenceable && !i915_is_ggtt(vm));
|
||||||
|
|
||||||
vma = i915_gem_obj_to_vma(obj, vm);
|
vma = i915_gem_obj_to_vma(obj, vm);
|
||||||
|
@ -299,11 +299,31 @@ static int context_idr_cleanup(int id, void *p, void *data)
|
|||||||
|
|
||||||
BUG_ON(id == DEFAULT_CONTEXT_ID);
|
BUG_ON(id == DEFAULT_CONTEXT_ID);
|
||||||
|
|
||||||
|
i915_gem_context_unreference(ctx);
|
||||||
|
|
||||||
return 0;
|
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;
|
||||||
|
|
||||||
|
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)
|
void i915_gem_context_close(struct drm_device *dev, struct drm_file *file)
|
||||||
{
|
{
|
||||||
struct drm_i915_file_private *file_priv = file->driver_priv;
|
struct drm_i915_file_private *file_priv = file->driver_priv;
|
||||||
|
@ -65,9 +65,10 @@
|
|||||||
#define HSW_WT_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x6)
|
#define HSW_WT_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x6)
|
||||||
|
|
||||||
static gen6_gtt_pte_t snb_pte_encode(dma_addr_t addr,
|
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);
|
pte |= GEN6_PTE_ADDR_ENCODE(addr);
|
||||||
|
|
||||||
switch (level) {
|
switch (level) {
|
||||||
@ -86,9 +87,10 @@ static gen6_gtt_pte_t snb_pte_encode(dma_addr_t addr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gen6_gtt_pte_t ivb_pte_encode(dma_addr_t addr,
|
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);
|
pte |= GEN6_PTE_ADDR_ENCODE(addr);
|
||||||
|
|
||||||
switch (level) {
|
switch (level) {
|
||||||
@ -112,9 +114,10 @@ static gen6_gtt_pte_t ivb_pte_encode(dma_addr_t addr,
|
|||||||
#define BYT_PTE_SNOOPED_BY_CPU_CACHES (1 << 2)
|
#define BYT_PTE_SNOOPED_BY_CPU_CACHES (1 << 2)
|
||||||
|
|
||||||
static gen6_gtt_pte_t byt_pte_encode(dma_addr_t addr,
|
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);
|
pte |= GEN6_PTE_ADDR_ENCODE(addr);
|
||||||
|
|
||||||
/* Mark the page as writeable. Other platforms don't have a
|
/* Mark the page as writeable. Other platforms don't have a
|
||||||
@ -129,9 +132,10 @@ static gen6_gtt_pte_t byt_pte_encode(dma_addr_t addr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gen6_gtt_pte_t hsw_pte_encode(dma_addr_t addr,
|
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);
|
pte |= HSW_PTE_ADDR_ENCODE(addr);
|
||||||
|
|
||||||
if (level != I915_CACHE_NONE)
|
if (level != I915_CACHE_NONE)
|
||||||
@ -141,9 +145,10 @@ static gen6_gtt_pte_t hsw_pte_encode(dma_addr_t addr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr,
|
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);
|
pte |= HSW_PTE_ADDR_ENCODE(addr);
|
||||||
|
|
||||||
switch (level) {
|
switch (level) {
|
||||||
@ -243,7 +248,8 @@ static int gen6_ppgtt_enable(struct drm_device *dev)
|
|||||||
/* PPGTT support for Sandybdrige/Gen6 and later */
|
/* PPGTT support for Sandybdrige/Gen6 and later */
|
||||||
static void gen6_ppgtt_clear_range(struct i915_address_space *vm,
|
static void gen6_ppgtt_clear_range(struct i915_address_space *vm,
|
||||||
unsigned first_entry,
|
unsigned first_entry,
|
||||||
unsigned num_entries)
|
unsigned num_entries,
|
||||||
|
bool use_scratch)
|
||||||
{
|
{
|
||||||
struct i915_hw_ppgtt *ppgtt =
|
struct i915_hw_ppgtt *ppgtt =
|
||||||
container_of(vm, struct i915_hw_ppgtt, base);
|
container_of(vm, struct i915_hw_ppgtt, base);
|
||||||
@ -252,7 +258,7 @@ static void gen6_ppgtt_clear_range(struct i915_address_space *vm,
|
|||||||
unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES;
|
unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES;
|
||||||
unsigned last_pte, i;
|
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);
|
pt_vaddr = AllocKernelSpace(4096);
|
||||||
|
|
||||||
@ -301,7 +307,7 @@ static void gen6_ppgtt_insert_entries(struct i915_address_space *vm,
|
|||||||
dma_addr_t page_addr;
|
dma_addr_t page_addr;
|
||||||
|
|
||||||
page_addr = sg_page_iter_dma_address(&sg_iter);
|
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) {
|
if (++act_pte == I915_PPGTT_PT_ENTRIES) {
|
||||||
act_pt++;
|
act_pt++;
|
||||||
MapPage(pt_vaddr,(addr_t)(ppgtt->pt_pages[act_pt]), 3);
|
MapPage(pt_vaddr,(addr_t)(ppgtt->pt_pages[act_pt]), 3);
|
||||||
@ -380,7 +386,7 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ppgtt->base.clear_range(&ppgtt->base, 0,
|
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);
|
ppgtt->pd_offset = first_pd_entry_in_global_pt * sizeof(gen6_gtt_pte_t);
|
||||||
|
|
||||||
@ -457,7 +463,8 @@ void i915_ppgtt_unbind_object(struct i915_hw_ppgtt *ppgtt,
|
|||||||
{
|
{
|
||||||
ppgtt->base.clear_range(&ppgtt->base,
|
ppgtt->base.clear_range(&ppgtt->base,
|
||||||
i915_gem_obj_ggtt_offset(obj) >> PAGE_SHIFT,
|
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;
|
extern int intel_iommu_gfx_mapped;
|
||||||
@ -498,15 +505,65 @@ static void undo_idling(struct drm_i915_private *dev_priv, bool interruptible)
|
|||||||
dev_priv->mm.interruptible = interruptible;
|
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)
|
void i915_gem_restore_gtt_mappings(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
struct drm_i915_gem_object *obj;
|
struct drm_i915_gem_object *obj;
|
||||||
|
|
||||||
|
i915_check_and_clear_faults(dev);
|
||||||
|
|
||||||
/* First fill our portion of the GTT with scratch pages */
|
/* First fill our portion of the GTT with scratch pages */
|
||||||
dev_priv->gtt.base.clear_range(&dev_priv->gtt.base,
|
dev_priv->gtt.base.clear_range(&dev_priv->gtt.base,
|
||||||
dev_priv->gtt.base.start / PAGE_SIZE,
|
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) {
|
list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
|
||||||
i915_gem_clflush_object(obj, obj->pin_display);
|
i915_gem_clflush_object(obj, obj->pin_display);
|
||||||
@ -549,7 +606,7 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
|
|||||||
|
|
||||||
for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) {
|
for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) {
|
||||||
addr = sg_page_iter_dma_address(&sg_iter);
|
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++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -561,7 +618,7 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
|
|||||||
*/
|
*/
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
WARN_ON(readl(>t_entries[i-1]) !=
|
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
|
/* 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
|
* want to flush the TLBs only after we're certain all the PTE updates
|
||||||
@ -573,7 +630,8 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
|
|||||||
|
|
||||||
static void gen6_ggtt_clear_range(struct i915_address_space *vm,
|
static void gen6_ggtt_clear_range(struct i915_address_space *vm,
|
||||||
unsigned int first_entry,
|
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;
|
struct drm_i915_private *dev_priv = vm->dev->dev_private;
|
||||||
gen6_gtt_pte_t scratch_pte, __iomem *gtt_base =
|
gen6_gtt_pte_t scratch_pte, __iomem *gtt_base =
|
||||||
@ -586,7 +644,8 @@ static void gen6_ggtt_clear_range(struct i915_address_space *vm,
|
|||||||
first_entry, num_entries, max_entries))
|
first_entry, num_entries, max_entries))
|
||||||
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++)
|
for (i = 0; i < num_entries; i++)
|
||||||
iowrite32(scratch_pte, >t_base[i]);
|
iowrite32(scratch_pte, >t_base[i]);
|
||||||
readl(gtt_base);
|
readl(gtt_base);
|
||||||
@ -607,7 +666,8 @@ static void i915_ggtt_insert_entries(struct i915_address_space *vm,
|
|||||||
|
|
||||||
static void i915_ggtt_clear_range(struct i915_address_space *vm,
|
static void i915_ggtt_clear_range(struct i915_address_space *vm,
|
||||||
unsigned int first_entry,
|
unsigned int first_entry,
|
||||||
unsigned int num_entries)
|
unsigned int num_entries,
|
||||||
|
bool unused)
|
||||||
{
|
{
|
||||||
intel_gtt_clear_range(first_entry, num_entries);
|
intel_gtt_clear_range(first_entry, num_entries);
|
||||||
}
|
}
|
||||||
@ -635,7 +695,8 @@ void i915_gem_gtt_unbind_object(struct drm_i915_gem_object *obj)
|
|||||||
|
|
||||||
dev_priv->gtt.base.clear_range(&dev_priv->gtt.base,
|
dev_priv->gtt.base.clear_range(&dev_priv->gtt.base,
|
||||||
entry,
|
entry,
|
||||||
obj->base.size >> PAGE_SHIFT);
|
obj->base.size >> PAGE_SHIFT,
|
||||||
|
true);
|
||||||
|
|
||||||
obj->has_global_gtt_mapping = 0;
|
obj->has_global_gtt_mapping = 0;
|
||||||
}
|
}
|
||||||
@ -722,11 +783,11 @@ void i915_gem_setup_global_gtt(struct drm_device *dev,
|
|||||||
const unsigned long count = (hole_end - hole_start) / PAGE_SIZE;
|
const unsigned long count = (hole_end - hole_start) / PAGE_SIZE;
|
||||||
DRM_DEBUG_KMS("clearing unused GTT space: [%lx, %lx]\n",
|
DRM_DEBUG_KMS("clearing unused GTT space: [%lx, %lx]\n",
|
||||||
hole_start, hole_end);
|
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 */
|
/* 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
|
static bool
|
||||||
@ -752,7 +813,6 @@ void i915_gem_init_global_gtt(struct drm_device *dev)
|
|||||||
gtt_size = dev_priv->gtt.base.total;
|
gtt_size = dev_priv->gtt.base.total;
|
||||||
mappable_size = dev_priv->gtt.mappable_end;
|
mappable_size = dev_priv->gtt.mappable_end;
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (intel_enable_ppgtt(dev) && HAS_ALIASING_PPGTT(dev)) {
|
if (intel_enable_ppgtt(dev) && HAS_ALIASING_PPGTT(dev)) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -762,7 +822,7 @@ void i915_gem_init_global_gtt(struct drm_device *dev)
|
|||||||
gtt_size -= GEN6_PPGTT_PD_ENTRIES * PAGE_SIZE;
|
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);
|
ret = i915_gem_init_aliasing_ppgtt(dev);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
@ -772,9 +832,7 @@ void i915_gem_init_global_gtt(struct drm_device *dev)
|
|||||||
drm_mm_takedown(&dev_priv->gtt.base.mm);
|
drm_mm_takedown(&dev_priv->gtt.base.mm);
|
||||||
gtt_size += GEN6_PPGTT_PD_ENTRIES * PAGE_SIZE;
|
gtt_size += GEN6_PPGTT_PD_ENTRIES * PAGE_SIZE;
|
||||||
}
|
}
|
||||||
#endif
|
i915_gem_setup_global_gtt(dev, 0, mappable_size, gtt_size);
|
||||||
|
|
||||||
i915_gem_setup_global_gtt(dev, LFB_SIZE, mappable_size, gtt_size-LFB_SIZE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int setup_scratch_page(struct drm_device *dev)
|
static int setup_scratch_page(struct drm_device *dev)
|
||||||
|
@ -604,6 +604,10 @@
|
|||||||
#define ARB_MODE_SWIZZLE_IVB (1<<5)
|
#define ARB_MODE_SWIZZLE_IVB (1<<5)
|
||||||
#define RENDER_HWS_PGA_GEN7 (0x04080)
|
#define RENDER_HWS_PGA_GEN7 (0x04080)
|
||||||
#define RING_FAULT_REG(ring) (0x4094 + 0x100*(ring)->id)
|
#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 DONE_REG 0x40b0
|
||||||
#define BSD_HWS_PGA_GEN7 (0x04180)
|
#define BSD_HWS_PGA_GEN7 (0x04180)
|
||||||
#define BLT_HWS_PGA_GEN7 (0x04280)
|
#define BLT_HWS_PGA_GEN7 (0x04280)
|
||||||
@ -4279,7 +4283,9 @@
|
|||||||
#define FDI_RX_CHICKEN(pipe) _PIPE(pipe, _FDI_RXA_CHICKEN, _FDI_RXB_CHICKEN)
|
#define FDI_RX_CHICKEN(pipe) _PIPE(pipe, _FDI_RXA_CHICKEN, _FDI_RXB_CHICKEN)
|
||||||
|
|
||||||
#define SOUTH_DSPCLK_GATE_D 0xc2020
|
#define SOUTH_DSPCLK_GATE_D 0xc2020
|
||||||
|
#define PCH_DPLUNIT_CLOCK_GATE_DISABLE (1<<30)
|
||||||
#define PCH_DPLSUNIT_CLOCK_GATE_DISABLE (1<<29)
|
#define PCH_DPLSUNIT_CLOCK_GATE_DISABLE (1<<29)
|
||||||
|
#define PCH_CPUNIT_CLOCK_GATE_DISABLE (1<<14)
|
||||||
#define PCH_LP_PARTITION_LEVEL_DISABLE (1<<12)
|
#define PCH_LP_PARTITION_LEVEL_DISABLE (1<<12)
|
||||||
|
|
||||||
/* CPU: FDI_TX */
|
/* CPU: FDI_TX */
|
||||||
|
@ -82,8 +82,7 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void intel_crt_get_config(struct intel_encoder *encoder,
|
static unsigned int intel_crt_get_flags(struct intel_encoder *encoder)
|
||||||
struct intel_crtc_config *pipe_config)
|
|
||||||
{
|
{
|
||||||
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
|
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
|
||||||
struct intel_crt *crt = intel_encoder_to_crt(encoder);
|
struct intel_crt *crt = intel_encoder_to_crt(encoder);
|
||||||
@ -101,7 +100,25 @@ static void intel_crt_get_config(struct intel_encoder *encoder,
|
|||||||
else
|
else
|
||||||
flags |= DRM_MODE_FLAG_NVSYNC;
|
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
|
/* Note: The caller is required to filter out dpms modes not supported by the
|
||||||
@ -776,6 +793,9 @@ void intel_crt_init(struct drm_device *dev)
|
|||||||
crt->base.mode_set = intel_crt_mode_set;
|
crt->base.mode_set = intel_crt_mode_set;
|
||||||
crt->base.disable = intel_disable_crt;
|
crt->base.disable = intel_disable_crt;
|
||||||
crt->base.enable = intel_enable_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;
|
crt->base.get_config = intel_crt_get_config;
|
||||||
if (I915_HAS_HOTPLUG(dev))
|
if (I915_HAS_HOTPLUG(dev))
|
||||||
crt->base.hpd_pin = HPD_CRT;
|
crt->base.hpd_pin = HPD_CRT;
|
||||||
|
@ -1249,7 +1249,7 @@ static void intel_ddi_hot_plug(struct intel_encoder *intel_encoder)
|
|||||||
intel_dp_check_link_status(intel_dp);
|
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 intel_crtc_config *pipe_config)
|
||||||
{
|
{
|
||||||
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
|
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
|
||||||
@ -1268,6 +1268,23 @@ static void intel_ddi_get_config(struct intel_encoder *encoder,
|
|||||||
flags |= DRM_MODE_FLAG_NVSYNC;
|
flags |= DRM_MODE_FLAG_NVSYNC;
|
||||||
|
|
||||||
pipe_config->adjusted_mode.flags |= flags;
|
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)
|
static void intel_ddi_destroy(struct drm_encoder *encoder)
|
||||||
|
@ -1828,6 +1828,8 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
|
|||||||
u32 alignment;
|
u32 alignment;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
ENTER();
|
||||||
|
|
||||||
switch (obj->tiling_mode) {
|
switch (obj->tiling_mode) {
|
||||||
case I915_TILING_NONE:
|
case I915_TILING_NONE:
|
||||||
if (IS_BROADWATER(dev) || IS_CRESTLINE(dev))
|
if (IS_BROADWATER(dev) || IS_CRESTLINE(dev))
|
||||||
@ -1876,6 +1878,9 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
|
|||||||
i915_gem_object_pin_fence(obj);
|
i915_gem_object_pin_fence(obj);
|
||||||
|
|
||||||
dev_priv->mm.interruptible = true;
|
dev_priv->mm.interruptible = true;
|
||||||
|
|
||||||
|
LEAVE();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_unpin:
|
err_unpin:
|
||||||
@ -2240,15 +2245,28 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
|
|||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&dev->struct_mutex);
|
mutex_lock(&dev->struct_mutex);
|
||||||
// ret = intel_pin_and_fence_fb_obj(dev,
|
ret = intel_pin_and_fence_fb_obj(dev,
|
||||||
// to_intel_framebuffer(fb)->obj,
|
to_intel_framebuffer(fb)->obj,
|
||||||
// NULL);
|
NULL);
|
||||||
// if (ret != 0) {
|
if (ret != 0) {
|
||||||
// mutex_unlock(&dev->struct_mutex);
|
mutex_unlock(&dev->struct_mutex);
|
||||||
// DRM_ERROR("pin & fence failed\n");
|
DRM_ERROR("pin & fence failed\n");
|
||||||
// return ret;
|
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);
|
ret = dev_priv->display.update_plane(crtc, fb, x, y);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@ -2317,9 +2335,10 @@ static void intel_fdi_normal_train(struct drm_crtc *crtc)
|
|||||||
FDI_FE_ERRC_ENABLE);
|
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)
|
static void ivb_modeset_global_resources(struct drm_device *dev)
|
||||||
@ -2971,6 +2990,48 @@ static void ironlake_pch_transcoder_set_timings(struct intel_crtc *crtc,
|
|||||||
I915_READ(VSYNCSHIFT(cpu_transcoder)));
|
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:
|
* Enable PCH resources required for PCH ports:
|
||||||
* - PCH PLLs
|
* - PCH PLLs
|
||||||
@ -2989,6 +3050,9 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
|
|||||||
|
|
||||||
assert_pch_transcoder_disabled(dev_priv, pipe);
|
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
|
/* Write the TU size bits before fdi link training, so that error
|
||||||
* detection works. */
|
* detection works. */
|
||||||
I915_WRITE(FDI_RX_TUSIZE1(pipe),
|
I915_WRITE(FDI_RX_TUSIZE1(pipe),
|
||||||
@ -3852,12 +3916,12 @@ static void intel_crtc_disable(struct drm_crtc *crtc)
|
|||||||
assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane);
|
assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane);
|
||||||
assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe);
|
assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe);
|
||||||
|
|
||||||
// if (crtc->fb) {
|
if (crtc->fb) {
|
||||||
// mutex_lock(&dev->struct_mutex);
|
mutex_lock(&dev->struct_mutex);
|
||||||
// intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj);
|
intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj);
|
||||||
// mutex_unlock(&dev->struct_mutex);
|
mutex_unlock(&dev->struct_mutex);
|
||||||
// crtc->fb = NULL;
|
crtc->fb = NULL;
|
||||||
// }
|
}
|
||||||
|
|
||||||
/* Update computed state. */
|
/* Update computed state. */
|
||||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||||
@ -4977,6 +5041,22 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
|
|||||||
if (!(tmp & PIPECONF_ENABLE))
|
if (!(tmp & PIPECONF_ENABLE))
|
||||||
return false;
|
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);
|
intel_get_pipe_timings(crtc, pipe_config);
|
||||||
|
|
||||||
i9xx_get_pfit_config(crtc, pipe_config);
|
i9xx_get_pfit_config(crtc, pipe_config);
|
||||||
@ -5570,48 +5650,6 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc,
|
|||||||
return true;
|
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)
|
int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -5805,9 +5843,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
|
|||||||
&intel_crtc->config.fdi_m_n);
|
&intel_crtc->config.fdi_m_n);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_IVYBRIDGE(dev))
|
|
||||||
ivybridge_update_fdi_bc_bifurcation(intel_crtc);
|
|
||||||
|
|
||||||
ironlake_set_pipeconf(crtc);
|
ironlake_set_pipeconf(crtc);
|
||||||
|
|
||||||
/* Set up the display plane register */
|
/* Set up the display plane register */
|
||||||
@ -5875,6 +5910,23 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
|
|||||||
if (!(tmp & PIPECONF_ENABLE))
|
if (!(tmp & PIPECONF_ENABLE))
|
||||||
return false;
|
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) {
|
if (I915_READ(PCH_TRANSCONF(crtc->pipe)) & TRANS_ENABLE) {
|
||||||
struct intel_shared_dpll *pll;
|
struct intel_shared_dpll *pll;
|
||||||
|
|
||||||
@ -7050,22 +7102,22 @@ mode_fits_in_fbdev(struct drm_device *dev,
|
|||||||
struct drm_i915_gem_object *obj;
|
struct drm_i915_gem_object *obj;
|
||||||
struct drm_framebuffer *fb;
|
struct drm_framebuffer *fb;
|
||||||
|
|
||||||
// if (dev_priv->fbdev == NULL)
|
if (dev_priv->fbdev == NULL)
|
||||||
// return NULL;
|
|
||||||
|
|
||||||
// obj = dev_priv->fbdev->ifb.obj;
|
|
||||||
// if (obj == NULL)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// if (obj->base.size < mode->vdisplay * fb->pitch)
|
obj = dev_priv->fbdev->ifb.obj;
|
||||||
|
if (obj == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
fb = &dev_priv->fbdev->ifb.base;
|
||||||
if (fb->pitches[0] < intel_framebuffer_pitch_for_width(mode->hdisplay,
|
if (fb->pitches[0] < intel_framebuffer_pitch_for_width(mode->hdisplay,
|
||||||
fb->bits_per_pixel))
|
fb->bits_per_pixel))
|
||||||
// return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (obj->base.size < mode->vdisplay * fb->pitches[0])
|
if (obj->base.size < mode->vdisplay * fb->pitches[0])
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// return fb;
|
return fb;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool intel_get_load_detect_pipe(struct drm_connector *connector,
|
bool intel_get_load_detect_pipe(struct drm_connector *connector,
|
||||||
@ -8597,6 +8649,9 @@ intel_pipe_config_compare(struct drm_device *dev,
|
|||||||
PIPE_CONF_CHECK_X(dpll_hw_state.fp0);
|
PIPE_CONF_CHECK_X(dpll_hw_state.fp0);
|
||||||
PIPE_CONF_CHECK_X(dpll_hw_state.fp1);
|
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_X
|
||||||
#undef PIPE_CONF_CHECK_I
|
#undef PIPE_CONF_CHECK_I
|
||||||
#undef PIPE_CONF_CHECK_FLAGS
|
#undef PIPE_CONF_CHECK_FLAGS
|
||||||
@ -9952,10 +10007,6 @@ static void intel_init_quirks(struct drm_device *dev)
|
|||||||
q->subsystem_device == PCI_ANY_ID))
|
q->subsystem_device == PCI_ANY_ID))
|
||||||
q->hook(dev);
|
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 */
|
/* Disable the VGA plane that we never use */
|
||||||
@ -10471,11 +10522,9 @@ void intel_modeset_cleanup(struct drm_device *dev)
|
|||||||
|
|
||||||
/* flush any delayed tasks or pending work */
|
/* flush any delayed tasks or pending work */
|
||||||
flush_scheduled_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 */
|
/* destroy backlight, if any, before the connectors */
|
||||||
// flush_scheduled_work();
|
intel_panel_destroy_backlight(dev);
|
||||||
|
|
||||||
drm_mode_config_cleanup(dev);
|
drm_mode_config_cleanup(dev);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1390,6 +1390,26 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
|
|||||||
else
|
else
|
||||||
pipe_config->port_clock = 270000;
|
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)
|
static bool is_edp_psr(struct intel_dp *intel_dp)
|
||||||
|
@ -770,6 +770,8 @@ extern void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder);
|
|||||||
extern bool
|
extern bool
|
||||||
intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector);
|
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_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 void intel_display_handle_reset(struct drm_device *dev);
|
||||||
extern bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
|
extern bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
|
||||||
|
@ -43,12 +43,7 @@
|
|||||||
#include <drm/i915_drm.h>
|
#include <drm/i915_drm.h>
|
||||||
#include "i915_drv.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)
|
struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
|
||||||
{
|
{
|
||||||
@ -105,6 +100,8 @@ static int intelfb_create(struct drm_fb_helper *helper,
|
|||||||
struct device *device = &dev->pdev->dev;
|
struct device *device = &dev->pdev->dev;
|
||||||
int size, ret;
|
int size, ret;
|
||||||
|
|
||||||
|
ENTER();
|
||||||
|
|
||||||
/* we don't do packed 24bpp */
|
/* we don't do packed 24bpp */
|
||||||
if (sizes->surface_bpp == 24)
|
if (sizes->surface_bpp == 24)
|
||||||
sizes->surface_bpp = 32;
|
sizes->surface_bpp = 32;
|
||||||
@ -113,49 +110,29 @@ static int intelfb_create(struct drm_fb_helper *helper,
|
|||||||
mode_cmd.height = sizes->surface_height;
|
mode_cmd.height = sizes->surface_height;
|
||||||
|
|
||||||
mode_cmd.pitches[0] = ALIGN(mode_cmd.width * ((sizes->surface_bpp + 7) /
|
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,
|
mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
|
||||||
sizes->surface_depth);
|
sizes->surface_depth);
|
||||||
|
|
||||||
size = mode_cmd.pitches[0] * mode_cmd.height;
|
size = mode_cmd.pitches[0] * mode_cmd.height;
|
||||||
size = ALIGN(size, PAGE_SIZE);
|
size = ALIGN(size, PAGE_SIZE);
|
||||||
obj = i915_gem_alloc_object(dev, size);
|
obj = fb_obj;
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
DRM_ERROR("failed to allocate framebuffer\n");
|
DRM_ERROR("failed to allocate framebuffer\n");
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
obj->stride = mode_cmd.pitches[0];
|
||||||
|
|
||||||
mutex_lock(&dev->struct_mutex);
|
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 */
|
/* 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) {
|
if (ret) {
|
||||||
DRM_ERROR("failed to pin fb: %d\n", ret);
|
DRM_ERROR("failed to pin fb: %d\n", ret);
|
||||||
goto out_unref;
|
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);
|
info = framebuffer_alloc(0, device);
|
||||||
if (!info) {
|
if (!info) {
|
||||||
@ -194,6 +171,8 @@ static int intelfb_create(struct drm_fb_helper *helper,
|
|||||||
info->screen_base = (void*) 0xFE000000;
|
info->screen_base = (void*) 0xFE000000;
|
||||||
info->screen_size = size;
|
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_fix(info, fb->pitches[0], fb->depth);
|
||||||
drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height);
|
drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height);
|
||||||
@ -206,9 +185,6 @@ static int intelfb_create(struct drm_fb_helper *helper,
|
|||||||
|
|
||||||
|
|
||||||
mutex_unlock(&dev->struct_mutex);
|
mutex_unlock(&dev->struct_mutex);
|
||||||
|
|
||||||
fb_obj = obj;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_unpin:
|
out_unpin:
|
||||||
|
@ -698,6 +698,22 @@ static const struct dmi_system_id intel_no_lvds[] = {
|
|||||||
DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Q900"),
|
DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Q900"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.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,
|
.callback = intel_no_lvds_dmi_callback,
|
||||||
.ident = "Intel D510MO",
|
.ident = "Intel D510MO",
|
||||||
|
@ -4768,7 +4768,9 @@ static void cpt_init_clock_gating(struct drm_device *dev)
|
|||||||
* gating for the panel power sequencer or it will fail to
|
* gating for the panel power sequencer or it will fail to
|
||||||
* start up when no ports are active.
|
* 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) |
|
I915_WRITE(SOUTH_CHICKEN2, I915_READ(SOUTH_CHICKEN2) |
|
||||||
DPLS_EDP_PPS_FIX_DIS);
|
DPLS_EDP_PPS_FIX_DIS);
|
||||||
/* The below fixes the weird display corruption, a few pixels shifted
|
/* The below fixes the weird display corruption, a few pixels shifted
|
||||||
|
@ -106,6 +106,7 @@ bool set_mode(struct drm_device *dev, struct drm_connector *connector,
|
|||||||
struct drm_framebuffer *fb = NULL;
|
struct drm_framebuffer *fb = NULL;
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
struct drm_encoder *encoder;
|
struct drm_encoder *encoder;
|
||||||
|
struct drm_i915_gem_object *fb_obj;
|
||||||
struct drm_mode_set set;
|
struct drm_mode_set set;
|
||||||
char *con_name;
|
char *con_name;
|
||||||
char *enc_name;
|
char *enc_name;
|
||||||
@ -162,14 +163,16 @@ do_set:
|
|||||||
if (crtc->invert_dimensions)
|
if (crtc->invert_dimensions)
|
||||||
swap(hdisplay, vdisplay);
|
swap(hdisplay, vdisplay);
|
||||||
|
|
||||||
|
fb_obj = get_fb_obj();
|
||||||
fb = fb_helper->fb;
|
fb = fb_helper->fb;
|
||||||
|
|
||||||
fb->width = reqmode->width;
|
fb->width = reqmode->width;
|
||||||
fb->height = reqmode->height;
|
fb->height = reqmode->height;
|
||||||
fb->pitches[0] = ALIGN(reqmode->width * 4, 64);
|
|
||||||
fb->pitches[1] = ALIGN(reqmode->width * 4, 64);
|
fb->pitches[0] = fb->pitches[1] = fb->pitches[2] =
|
||||||
fb->pitches[2] = ALIGN(reqmode->width * 4, 64);
|
fb->pitches[3] = ALIGN(reqmode->width * 4, 512);
|
||||||
fb->pitches[3] = ALIGN(reqmode->width * 4, 64);
|
|
||||||
|
fb_obj->stride = fb->pitches[0];
|
||||||
|
|
||||||
fb->bits_per_pixel = 32;
|
fb->bits_per_pixel = 32;
|
||||||
fb->depth = 24;
|
fb->depth = 24;
|
||||||
@ -178,6 +181,8 @@ do_set:
|
|||||||
crtc->enabled = true;
|
crtc->enabled = true;
|
||||||
os_display->crtc = crtc;
|
os_display->crtc = crtc;
|
||||||
|
|
||||||
|
i915_gem_object_put_fence(fb_obj);
|
||||||
|
|
||||||
set.crtc = crtc;
|
set.crtc = crtc;
|
||||||
set.x = 0;
|
set.x = 0;
|
||||||
set.y = 0;
|
set.y = 0;
|
||||||
@ -261,7 +266,7 @@ static struct drm_connector* get_def_connector(struct drm_device *dev)
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
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 *connector;
|
||||||
struct drm_connector_helper_funcs *connector_funcs;
|
struct drm_connector_helper_funcs *connector_funcs;
|
||||||
@ -273,6 +278,10 @@ int init_display_kms(struct drm_device *dev)
|
|||||||
u32_t ifl;
|
u32_t ifl;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
ENTER();
|
||||||
|
|
||||||
|
mutex_lock(&dev->mode_config.mutex);
|
||||||
|
|
||||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head)
|
list_for_each_entry(connector, &dev->mode_config.connector_list, head)
|
||||||
{
|
{
|
||||||
if( connector->status != connector_status_connected)
|
if( connector->status != connector_status_connected)
|
||||||
@ -289,20 +298,22 @@ int init_display_kms(struct drm_device *dev)
|
|||||||
connector->encoder = encoder;
|
connector->encoder = encoder;
|
||||||
crtc = encoder->crtc;
|
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, connector->base.id,
|
||||||
connector->status, connector->encoder,
|
connector->status, connector->encoder,
|
||||||
crtc, crtc->base.id );
|
crtc, crtc->base.id );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
if(connector == NULL)
|
if(connector == NULL)
|
||||||
{
|
{
|
||||||
DRM_ERROR("No active connectors!\n");
|
DRM_DEBUG_KMS("No active connectors!\n");
|
||||||
|
mutex_unlock(&dev->mode_config.mutex);
|
||||||
return -1;
|
return -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
dbgprintf("CRTC %p\n", crtc);
|
||||||
|
|
||||||
if(crtc == NULL)
|
if(crtc == NULL)
|
||||||
{
|
{
|
||||||
struct drm_crtc *tmp_crtc;
|
struct drm_crtc *tmp_crtc;
|
||||||
@ -310,24 +321,28 @@ int init_display_kms(struct drm_device *dev)
|
|||||||
|
|
||||||
list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head)
|
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)
|
if (encoder->possible_crtcs & crtc_mask)
|
||||||
{
|
{
|
||||||
crtc = tmp_crtc;
|
crtc = tmp_crtc;
|
||||||
encoder->crtc = crtc;
|
encoder->crtc = crtc;
|
||||||
|
dbgprintf("CRTC %p\n", crtc);
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
crtc_mask <<= 1;
|
crtc_mask <<= 1;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
dbgprintf("CRTC %p\n", crtc);
|
||||||
|
|
||||||
if(crtc == NULL)
|
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;
|
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 = GetDisplay();
|
||||||
os_display->ddev = dev;
|
os_display->ddev = dev;
|
||||||
@ -361,10 +376,53 @@ int init_display_kms(struct drm_device *dev)
|
|||||||
};
|
};
|
||||||
safe_sti(ifl);
|
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__
|
#ifdef __HWA__
|
||||||
err = init_bitmaps();
|
err = init_bitmaps();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
LEAVE();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
199
drivers/video/drm/i915/kos_gem_fb.c
Normal file
199
drivers/video/drm/i915/kos_gem_fb.c
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -28,10 +28,10 @@ struct pci_device {
|
|||||||
|
|
||||||
struct drm_device *main_device;
|
struct drm_device *main_device;
|
||||||
struct drm_file *drm_file_handlers[256];
|
struct drm_file *drm_file_handlers[256];
|
||||||
|
videomode_t usermode;
|
||||||
|
|
||||||
void cpu_detect();
|
void cpu_detect();
|
||||||
|
|
||||||
void parse_cmdline(char *cmdline, char *log);
|
|
||||||
int _stdcall display_handler(ioctl_t *io);
|
int _stdcall display_handler(ioctl_t *io);
|
||||||
int init_agp(void);
|
int init_agp(void);
|
||||||
|
|
||||||
@ -51,6 +51,15 @@ int i915_getparam(struct drm_device *dev, void *data,
|
|||||||
int i915_mask_update(struct drm_device *dev, void *data,
|
int i915_mask_update(struct drm_device *dev, void *data,
|
||||||
struct drm_file *file);
|
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];
|
static char log[256];
|
||||||
|
|
||||||
@ -158,8 +167,22 @@ u32_t __attribute__((externally_visible)) drvEntry(int action, char *cmdline)
|
|||||||
if( GetService("DISPLAY") != 0 )
|
if( GetService("DISPLAY") != 0 )
|
||||||
return 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 )
|
if( cmdline && *cmdline )
|
||||||
parse_cmdline(cmdline, log);
|
parse_cmdline(cmdline, cmdtable, log, &usermode);
|
||||||
|
|
||||||
if(!dbg_open(log))
|
if(!dbg_open(log))
|
||||||
{
|
{
|
||||||
@ -171,7 +194,6 @@ u32_t __attribute__((externally_visible)) drvEntry(int action, char *cmdline)
|
|||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
dbgprintf(" i915 v3.12-6\n cmdline: %s\n", cmdline);
|
|
||||||
|
|
||||||
cpu_detect();
|
cpu_detect();
|
||||||
// dbgprintf("\ncache line size %d\n", x86_clflush_size);
|
// dbgprintf("\ncache line size %d\n", x86_clflush_size);
|
||||||
@ -184,7 +206,8 @@ u32_t __attribute__((externally_visible)) drvEntry(int action, char *cmdline)
|
|||||||
dbgprintf("Epic Fail :(\n");
|
dbgprintf("Epic Fail :(\n");
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
init_display_kms(main_device);
|
|
||||||
|
init_display_kms(main_device, &usermode);
|
||||||
|
|
||||||
err = RegService("DISPLAY", display_handler);
|
err = RegService("DISPLAY", display_handler);
|
||||||
|
|
||||||
@ -458,38 +481,6 @@ int pci_scan_filter(u32_t id, u32_t busnr, u32_t devfn)
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
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,
|
static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
|
||||||
@ -571,3 +562,137 @@ void get_pci_info(struct pci_device *dev)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
@ -783,18 +783,9 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
|
|||||||
return (void __iomem *)(unsigned long)
|
return (void __iomem *)(unsigned long)
|
||||||
pci_resource_start(pdev, PCI_ROM_RESOURCE);
|
pci_resource_start(pdev, PCI_ROM_RESOURCE);
|
||||||
} else {
|
} else {
|
||||||
/* assign the ROM an address if it doesn't have one */
|
start = (loff_t)0xC0000;
|
||||||
// if (res->parent == NULL &&
|
*size = 0x20000; /* cover C000:0 through E000:0 */
|
||||||
// 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;
|
|
||||||
|
|
||||||
/* Enable ROM space decodes */
|
|
||||||
// if (pci_enable_rom(pdev))
|
|
||||||
// return NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user