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);
|
||||
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 @@ drm_gem_handle_create_tail(struct drm_file *file_priv,
|
||||
}
|
||||
*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) {
|
||||
|
@ -76,6 +76,7 @@ NAME_SRC= main.c \
|
||||
intel_sprite.c \
|
||||
intel_uncore.c \
|
||||
kms_display.c \
|
||||
kos_gem_fb.c \
|
||||
utils.c \
|
||||
../hdmi.c \
|
||||
Gtt/intel-agp.c \
|
||||
|
@ -1156,7 +1156,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
|
||||
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 @@ int i915_driver_unload(struct drm_device *dev)
|
||||
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);
|
||||
|
||||
|
@ -62,7 +62,7 @@ MODULE_PARM_DESC(panel_ignore_lid,
|
||||
"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_param_named(semaphores, i915_semaphores, int, 0600);
|
||||
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 @@ MODULE_PARM_DESC(i915_enable_rc6,
|
||||
"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_param_named(fastboot, i915_fastboot, bool, 0600);
|
||||
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)");
|
||||
|
||||
|
@ -509,10 +509,12 @@ struct i915_address_space {
|
||||
|
||||
/* 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_bind_object(struct i915_hw_ppgtt *ppgtt,
|
||||
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 @@ timespec_to_jiffies_timeout(const struct timespec *value)
|
||||
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 @@ typedef struct
|
||||
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}
|
||||
|
||||
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
|
||||
|
@ -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 @@ static void i965_write_fence_reg(struct drm_device *dev, int reg,
|
||||
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 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj,
|
||||
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);
|
||||
|
@ -299,11 +299,31 @@ static int context_idr_cleanup(int id, void *p, void *data)
|
||||
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
struct drm_i915_file_private *file_priv = file->driver_priv;
|
||||
|
@ -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 snb_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);
|
||||
|
||||
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)
|
||||
|
||||
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 byt_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);
|
||||
|
||||
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,
|
||||
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 @@ static int gen6_ppgtt_enable(struct drm_device *dev)
|
||||
/* 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 @@ static void gen6_ppgtt_clear_range(struct i915_address_space *vm,
|
||||
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 @@ static void gen6_ppgtt_insert_entries(struct i915_address_space *vm,
|
||||
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 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
|
||||
}
|
||||
|
||||
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 @@ void i915_ppgtt_unbind_object(struct i915_hw_ppgtt *ppgtt,
|
||||
{
|
||||
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 @@ static void undo_idling(struct drm_i915_private *dev_priv, bool 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)
|
||||
{
|
||||
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 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
|
||||
|
||||
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 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
|
||||
*/
|
||||
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_insert_entries(struct i915_address_space *vm,
|
||||
|
||||
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 @@ static void gen6_ggtt_clear_range(struct i915_address_space *vm,
|
||||
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_insert_entries(struct i915_address_space *vm,
|
||||
|
||||
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 @@ void i915_gem_gtt_unbind_object(struct drm_i915_gem_object *obj)
|
||||
|
||||
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 @@ void i915_gem_setup_global_gtt(struct drm_device *dev,
|
||||
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 @@ void i915_gem_init_global_gtt(struct drm_device *dev)
|
||||
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 @@ void i915_gem_init_global_gtt(struct drm_device *dev)
|
||||
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 @@ void i915_gem_init_global_gtt(struct drm_device *dev)
|
||||
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)
|
||||
|
@ -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 */
|
||||
|
@ -82,8 +82,7 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder,
|
||||
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,7 +100,25 @@ static void intel_crt_get_config(struct intel_encoder *encoder,
|
||||
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
|
||||
@ -776,6 +793,9 @@ void intel_crt_init(struct drm_device *dev)
|
||||
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;
|
||||
|
@ -1249,7 +1249,7 @@ static void intel_ddi_hot_plug(struct intel_encoder *intel_encoder)
|
||||
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,6 +1268,23 @@ static void intel_ddi_get_config(struct intel_encoder *encoder,
|
||||
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)
|
||||
|
@ -1828,6 +1828,8 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
|
||||
u32 alignment;
|
||||
int ret;
|
||||
|
||||
ENTER();
|
||||
|
||||
switch (obj->tiling_mode) {
|
||||
case I915_TILING_NONE:
|
||||
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);
|
||||
|
||||
dev_priv->mm.interruptible = true;
|
||||
|
||||
LEAVE();
|
||||
|
||||
return 0;
|
||||
|
||||
err_unpin:
|
||||
@ -2240,15 +2245,28 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
|
||||
}
|
||||
|
||||
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 @@ static void intel_fdi_normal_train(struct drm_crtc *crtc)
|
||||
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 @@ static void ironlake_pch_transcoder_set_timings(struct intel_crtc *crtc,
|
||||
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 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
|
||||
|
||||
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 @@ static void intel_crtc_disable(struct drm_crtc *crtc)
|
||||
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 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
|
||||
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 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc,
|
||||
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 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
|
||||
&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 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
|
||||
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 @@ mode_fits_in_fbdev(struct drm_device *dev,
|
||||
struct drm_i915_gem_object *obj;
|
||||
struct drm_framebuffer *fb;
|
||||
|
||||
// if (dev_priv->fbdev == NULL)
|
||||
// return NULL;
|
||||
|
||||
// obj = dev_priv->fbdev->ifb.obj;
|
||||
// if (obj == NULL)
|
||||
if (dev_priv->fbdev == 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,
|
||||
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 @@ intel_pipe_config_compare(struct drm_device *dev,
|
||||
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 @@ static void intel_init_quirks(struct drm_device *dev)
|
||||
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 @@ void intel_modeset_cleanup(struct drm_device *dev)
|
||||
|
||||
/* 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
|
||||
|
@ -1390,6 +1390,26 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
|
||||
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)
|
||||
|
@ -770,6 +770,8 @@ extern void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder);
|
||||
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,
|
||||
|
@ -43,12 +43,7 @@
|
||||
#include <drm/i915_drm.h>
|
||||
#include "i915_drv.h"
|
||||
|
||||
static struct drm_i915_gem_object *fb_obj;
|
||||
|
||||
struct drm_i915_gem_object *get_fb_obj()
|
||||
{
|
||||
return fb_obj;
|
||||
};
|
||||
struct drm_i915_gem_object *fb_obj;
|
||||
|
||||
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;
|
||||
int size, ret;
|
||||
|
||||
ENTER();
|
||||
|
||||
/* we don't do packed 24bpp */
|
||||
if (sizes->surface_bpp == 24)
|
||||
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.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;
|
||||
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) {
|
||||
@ -194,6 +171,8 @@ static int intelfb_create(struct drm_fb_helper *helper,
|
||||
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 @@ static int intelfb_create(struct drm_fb_helper *helper,
|
||||
|
||||
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
||||
fb_obj = obj;
|
||||
|
||||
return 0;
|
||||
|
||||
out_unpin:
|
||||
|
@ -698,6 +698,22 @@ static const struct dmi_system_id intel_no_lvds[] = {
|
||||
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,
|
||||
.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
|
||||
* 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
|
||||
|
@ -106,6 +106,7 @@ bool set_mode(struct drm_device *dev, struct drm_connector *connector,
|
||||
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,14 +163,16 @@ do_set:
|
||||
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 @@ do_set:
|
||||
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 @@ 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_helper_funcs *connector_funcs;
|
||||
@ -273,6 +278,10 @@ int init_display_kms(struct drm_device *dev)
|
||||
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 @@ int init_display_kms(struct drm_device *dev)
|
||||
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,24 +321,28 @@ int init_display_kms(struct drm_device *dev)
|
||||
|
||||
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;
|
||||
};
|
||||
};
|
||||
|
||||
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:%d]\n", crtc->base.id);
|
||||
DRM_DEBUG_KMS("[Select CRTC: %p ID:%d]\n",crtc, crtc->base.id);
|
||||
|
||||
os_display = GetDisplay();
|
||||
os_display->ddev = dev;
|
||||
@ -361,10 +376,53 @@ int init_display_kms(struct drm_device *dev)
|
||||
};
|
||||
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;
|
||||
};
|
||||
|
||||
|
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_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,6 +51,15 @@ int i915_getparam(struct drm_device *dev, void *data,
|
||||
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];
|
||||
|
||||
@ -158,8 +167,22 @@ u32_t __attribute__((externally_visible)) drvEntry(int action, char *cmdline)
|
||||
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 @@ u32_t __attribute__((externally_visible)) drvEntry(int action, char *cmdline)
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
dbgprintf(" i915 v3.12-6\n cmdline: %s\n", cmdline);
|
||||
|
||||
cpu_detect();
|
||||
// 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");
|
||||
return 0;
|
||||
};
|
||||
init_display_kms(main_device);
|
||||
|
||||
init_display_kms(main_device, &usermode);
|
||||
|
||||
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,
|
||||
@ -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)
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user