mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-25 06:30:54 +07:00
amd, intel, tilcdc, omap, and malidp fixes.
-----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJYy2bCAAoJEAx081l5xIa+wDAQAJTrgKmSOu8Vqv8YZqAHc46r bnsYOs9Xs4YYId8QP2QXkqI8lzlDmNlecn9ARYRBLR/UfAVqnZzirWjolL66D5FI ZVj9R+WuujrN/8eimkZPwcZRfdi6RRgwHRbbXthMoiKXq/ydE5xnUtEv5rp9WHFb QZeUrhhDdNXNORiwOlCjpqu7DvolRQmfroOh7xaDgSQoCmhyCB9D3pRyFONGDbkf LSf5WUP4VFTYrGCKZLXCqZkfcve+k99sQcuFcEnX3Pg+XFjScrCTa5XAiBLiV3bR 62JI2rcyZqKkLV9iqXDQp/P3Rbz9qero0xaDpF51aNWKJlsioW07V9BLsEemdxg2 3wdG51jsGDZ2g9cQL37vfKXQH5r3V1KUaXD1HVdY2y4vWT3BBWc8I7UAddfeCCAF FBMzyAd9SjoI6PgkEZqshFAO1Z/QWux9wjpcZ7CWte8F/5Cul8QOl7ZO8Hg4bN5i VaKTxAT91FwvDgbfVSZ+L+EeVyns9WKRUDt19HRIPruKMwjLPBGmZrL4UChIzacz XJYkFdR1rOUQFsgcPnyWqkBQfjB0hiryJSuGGXMAIWKlsbsCUth/+ekUrwDtBNdP zbzyRBa0WMlNxCxeVcmNfCXMqNYJUlcD7lAMe3aKg/WUIQqVTcT6gyxcf8dkhVu9 hosSva7b03GnK9ei44+y =0d8b -----END PGP SIGNATURE----- Merge tag 'drm-fixes-for-v4.11-rc3' of git://people.freedesktop.org/~airlied/linux Pull drm fixes from Dave Airlie: "Bunch of fixes across the drivers, in a St Patrick's day pull request (please turn terminal colors to green on black or black on green for full effect). On the arm side, tilcdc, omap and malidp got fixes, while amd has some powermanagement fixes, and intel has a set of fixes across the driver. Nothing seems to bad or scary at this point" * tag 'drm-fixes-for-v4.11-rc3' of git://people.freedesktop.org/~airlied/linux: (27 commits) drm/amd/amdgpu: Fix debugfs reg read/write address width drm/amdgpu/si: add dpm quirk for Oland drm/radeon/si: add dpm quirk for Oland drm: amd: remove broken include path drm/amd/powerplay: fix copy error in smu7_clockpoweragting.c drm/tilcdc: Set framebuffer DMA address to HW only if CRTC is enabled drm/tilcdc: Fix hardcoded fail-return value in tilcdc_crtc_create() drm/i915: Fix forcewake active domain tracking drm/i915: Nuke skl_update_plane debug message from the pipe update critical section drm/i915: use correct node for handling cache domain eviction uapi: fix drm/omap_drm.h userspace compilation errors drm/omap: fix dmabuf mmap for dma_alloc'ed buffers drm/amdgpu: fix parser init error path to avoid crash in parser fini drm/amd/amdgpu: Disable GFX_PG on Carrizo until compute issues solved drm: mali-dp: Fix smart layer not going to composition drm: mali-dp: Remove mclk rate management drm/i915: Drain the freed state from the tail of the next commit drm/i915: Nuke debug messages from the pipe update critical section drm/i915: Use pagecache write to prepopulate shmemfs from pwrite-ioctl drm/i915: Store a permanent error in obj->mm.pages ...
This commit is contained in:
commit
102ed8c35a
@ -3,6 +3,4 @@
|
||||
# of AMDSOC/AMDGPU drm driver.
|
||||
# It provides the HW control for ACP related functionalities.
|
||||
|
||||
subdir-ccflags-y += -I$(AMDACPPATH)/ -I$(AMDACPPATH)/include
|
||||
|
||||
AMD_ACP_FILES := $(AMDACPPATH)/acp_hw.o
|
||||
|
@ -240,6 +240,8 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
|
||||
for (; i >= 0; i--)
|
||||
drm_free_large(p->chunks[i].kdata);
|
||||
kfree(p->chunks);
|
||||
p->chunks = NULL;
|
||||
p->nchunks = 0;
|
||||
put_ctx:
|
||||
amdgpu_ctx_put(p->ctx);
|
||||
free_chunk:
|
||||
|
@ -2590,7 +2590,7 @@ static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,
|
||||
use_bank = 0;
|
||||
}
|
||||
|
||||
*pos &= 0x3FFFF;
|
||||
*pos &= (1UL << 22) - 1;
|
||||
|
||||
if (use_bank) {
|
||||
if ((sh_bank != 0xFFFFFFFF && sh_bank >= adev->gfx.config.max_sh_per_se) ||
|
||||
@ -2666,7 +2666,7 @@ static ssize_t amdgpu_debugfs_regs_write(struct file *f, const char __user *buf,
|
||||
use_bank = 0;
|
||||
}
|
||||
|
||||
*pos &= 0x3FFFF;
|
||||
*pos &= (1UL << 22) - 1;
|
||||
|
||||
if (use_bank) {
|
||||
if ((sh_bank != 0xFFFFFFFF && sh_bank >= adev->gfx.config.max_sh_per_se) ||
|
||||
|
@ -3464,6 +3464,12 @@ static void si_apply_state_adjust_rules(struct amdgpu_device *adev,
|
||||
(adev->pdev->device == 0x6667)) {
|
||||
max_sclk = 75000;
|
||||
}
|
||||
} else if (adev->asic_type == CHIP_OLAND) {
|
||||
if ((adev->pdev->device == 0x6604) &&
|
||||
(adev->pdev->subsystem_vendor == 0x1028) &&
|
||||
(adev->pdev->subsystem_device == 0x066F)) {
|
||||
max_sclk = 75000;
|
||||
}
|
||||
}
|
||||
|
||||
if (rps->vce_active) {
|
||||
|
@ -1051,7 +1051,7 @@ static int vi_common_early_init(void *handle)
|
||||
/* rev0 hardware requires workarounds to support PG */
|
||||
adev->pg_flags = 0;
|
||||
if (adev->rev_id != 0x00) {
|
||||
adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG |
|
||||
adev->pg_flags |=
|
||||
AMD_PG_SUPPORT_GFX_SMG |
|
||||
AMD_PG_SUPPORT_GFX_PIPELINE |
|
||||
AMD_PG_SUPPORT_CP |
|
||||
|
@ -178,7 +178,7 @@ int smu7_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
|
||||
if (bgate) {
|
||||
cgs_set_powergating_state(hwmgr->device,
|
||||
AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_PG_STATE_UNGATE);
|
||||
AMD_PG_STATE_GATE);
|
||||
cgs_set_clockgating_state(hwmgr->device,
|
||||
AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_CG_STATE_GATE);
|
||||
|
@ -63,8 +63,7 @@ static void malidp_crtc_enable(struct drm_crtc *crtc)
|
||||
|
||||
clk_prepare_enable(hwdev->pxlclk);
|
||||
|
||||
/* mclk needs to be set to the same or higher rate than pxlclk */
|
||||
clk_set_rate(hwdev->mclk, crtc->state->adjusted_mode.crtc_clock * 1000);
|
||||
/* We rely on firmware to set mclk to a sensible level. */
|
||||
clk_set_rate(hwdev->pxlclk, crtc->state->adjusted_mode.crtc_clock * 1000);
|
||||
|
||||
hwdev->modeset(hwdev, &vm);
|
||||
|
@ -83,7 +83,7 @@ static const struct malidp_layer malidp550_layers[] = {
|
||||
{ DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE, MALIDP_DE_LV_STRIDE0 },
|
||||
{ DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE, MALIDP_DE_LG_STRIDE },
|
||||
{ DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE, MALIDP_DE_LV_STRIDE0 },
|
||||
{ DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE, 0 },
|
||||
{ DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE, MALIDP550_DE_LS_R1_STRIDE },
|
||||
};
|
||||
|
||||
#define MALIDP_DE_DEFAULT_PREFETCH_START 5
|
||||
|
@ -37,6 +37,8 @@
|
||||
#define LAYER_V_VAL(x) (((x) & 0x1fff) << 16)
|
||||
#define MALIDP_LAYER_COMP_SIZE 0x010
|
||||
#define MALIDP_LAYER_OFFSET 0x014
|
||||
#define MALIDP550_LS_ENABLE 0x01c
|
||||
#define MALIDP550_LS_R1_IN_SIZE 0x020
|
||||
|
||||
/*
|
||||
* This 4-entry look-up-table is used to determine the full 8-bit alpha value
|
||||
@ -242,6 +244,11 @@ static void malidp_de_plane_update(struct drm_plane *plane,
|
||||
LAYER_V_VAL(plane->state->crtc_y),
|
||||
mp->layer->base + MALIDP_LAYER_OFFSET);
|
||||
|
||||
if (mp->layer->id == DE_SMART)
|
||||
malidp_hw_write(mp->hwdev,
|
||||
LAYER_H_VAL(src_w) | LAYER_V_VAL(src_h),
|
||||
mp->layer->base + MALIDP550_LS_R1_IN_SIZE);
|
||||
|
||||
/* first clear the rotation bits */
|
||||
val = malidp_hw_read(mp->hwdev, mp->layer->base + MALIDP_LAYER_CONTROL);
|
||||
val &= ~LAYER_ROT_MASK;
|
||||
@ -330,9 +337,16 @@ int malidp_de_planes_init(struct drm_device *drm)
|
||||
plane->hwdev = malidp->dev;
|
||||
plane->layer = &map->layers[i];
|
||||
|
||||
/* Skip the features which the SMART layer doesn't have */
|
||||
if (id == DE_SMART)
|
||||
if (id == DE_SMART) {
|
||||
/*
|
||||
* Enable the first rectangle in the SMART layer to be
|
||||
* able to use it as a drm plane.
|
||||
*/
|
||||
malidp_hw_write(malidp->dev, 1,
|
||||
plane->layer->base + MALIDP550_LS_ENABLE);
|
||||
/* Skip the features which the SMART layer doesn't have. */
|
||||
continue;
|
||||
}
|
||||
|
||||
drm_plane_create_rotation_property(&plane->base, DRM_ROTATE_0, flags);
|
||||
malidp_hw_write(malidp->dev, MALIDP_ALPHA_LUT,
|
||||
|
@ -84,6 +84,7 @@
|
||||
/* Stride register offsets relative to Lx_BASE */
|
||||
#define MALIDP_DE_LG_STRIDE 0x18
|
||||
#define MALIDP_DE_LV_STRIDE0 0x18
|
||||
#define MALIDP550_DE_LS_R1_STRIDE 0x28
|
||||
|
||||
/* macros to set values into registers */
|
||||
#define MALIDP_DE_H_FRONTPORCH(x) (((x) & 0xfff) << 0)
|
||||
|
@ -293,6 +293,7 @@ enum plane_id {
|
||||
PLANE_PRIMARY,
|
||||
PLANE_SPRITE0,
|
||||
PLANE_SPRITE1,
|
||||
PLANE_SPRITE2,
|
||||
PLANE_CURSOR,
|
||||
I915_MAX_PLANES,
|
||||
};
|
||||
|
@ -1434,6 +1434,12 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
|
||||
|
||||
trace_i915_gem_object_pwrite(obj, args->offset, args->size);
|
||||
|
||||
ret = -ENODEV;
|
||||
if (obj->ops->pwrite)
|
||||
ret = obj->ops->pwrite(obj, args);
|
||||
if (ret != -ENODEV)
|
||||
goto err;
|
||||
|
||||
ret = i915_gem_object_wait(obj,
|
||||
I915_WAIT_INTERRUPTIBLE |
|
||||
I915_WAIT_ALL,
|
||||
@ -2119,6 +2125,7 @@ i915_gem_object_truncate(struct drm_i915_gem_object *obj)
|
||||
*/
|
||||
shmem_truncate_range(file_inode(obj->base.filp), 0, (loff_t)-1);
|
||||
obj->mm.madv = __I915_MADV_PURGED;
|
||||
obj->mm.pages = ERR_PTR(-EFAULT);
|
||||
}
|
||||
|
||||
/* Try to discard unwanted pages */
|
||||
@ -2218,7 +2225,9 @@ void __i915_gem_object_put_pages(struct drm_i915_gem_object *obj,
|
||||
|
||||
__i915_gem_object_reset_page_iter(obj);
|
||||
|
||||
if (!IS_ERR(pages))
|
||||
obj->ops->put_pages(obj, pages);
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&obj->mm.lock);
|
||||
}
|
||||
@ -2437,7 +2446,7 @@ int __i915_gem_object_get_pages(struct drm_i915_gem_object *obj)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (unlikely(!obj->mm.pages)) {
|
||||
if (unlikely(IS_ERR_OR_NULL(obj->mm.pages))) {
|
||||
err = ____i915_gem_object_get_pages(obj);
|
||||
if (err)
|
||||
goto unlock;
|
||||
@ -2515,7 +2524,7 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
|
||||
|
||||
pinned = true;
|
||||
if (!atomic_inc_not_zero(&obj->mm.pages_pin_count)) {
|
||||
if (unlikely(!obj->mm.pages)) {
|
||||
if (unlikely(IS_ERR_OR_NULL(obj->mm.pages))) {
|
||||
ret = ____i915_gem_object_get_pages(obj);
|
||||
if (ret)
|
||||
goto err_unlock;
|
||||
@ -2563,6 +2572,75 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
static int
|
||||
i915_gem_object_pwrite_gtt(struct drm_i915_gem_object *obj,
|
||||
const struct drm_i915_gem_pwrite *arg)
|
||||
{
|
||||
struct address_space *mapping = obj->base.filp->f_mapping;
|
||||
char __user *user_data = u64_to_user_ptr(arg->data_ptr);
|
||||
u64 remain, offset;
|
||||
unsigned int pg;
|
||||
|
||||
/* Before we instantiate/pin the backing store for our use, we
|
||||
* can prepopulate the shmemfs filp efficiently using a write into
|
||||
* the pagecache. We avoid the penalty of instantiating all the
|
||||
* pages, important if the user is just writing to a few and never
|
||||
* uses the object on the GPU, and using a direct write into shmemfs
|
||||
* allows it to avoid the cost of retrieving a page (either swapin
|
||||
* or clearing-before-use) before it is overwritten.
|
||||
*/
|
||||
if (READ_ONCE(obj->mm.pages))
|
||||
return -ENODEV;
|
||||
|
||||
/* Before the pages are instantiated the object is treated as being
|
||||
* in the CPU domain. The pages will be clflushed as required before
|
||||
* use, and we can freely write into the pages directly. If userspace
|
||||
* races pwrite with any other operation; corruption will ensue -
|
||||
* that is userspace's prerogative!
|
||||
*/
|
||||
|
||||
remain = arg->size;
|
||||
offset = arg->offset;
|
||||
pg = offset_in_page(offset);
|
||||
|
||||
do {
|
||||
unsigned int len, unwritten;
|
||||
struct page *page;
|
||||
void *data, *vaddr;
|
||||
int err;
|
||||
|
||||
len = PAGE_SIZE - pg;
|
||||
if (len > remain)
|
||||
len = remain;
|
||||
|
||||
err = pagecache_write_begin(obj->base.filp, mapping,
|
||||
offset, len, 0,
|
||||
&page, &data);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
vaddr = kmap(page);
|
||||
unwritten = copy_from_user(vaddr + pg, user_data, len);
|
||||
kunmap(page);
|
||||
|
||||
err = pagecache_write_end(obj->base.filp, mapping,
|
||||
offset, len, len - unwritten,
|
||||
page, data);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (unwritten)
|
||||
return -EFAULT;
|
||||
|
||||
remain -= len;
|
||||
user_data += len;
|
||||
offset += len;
|
||||
pg = 0;
|
||||
} while (remain);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool ban_context(const struct i915_gem_context *ctx)
|
||||
{
|
||||
return (i915_gem_context_is_bannable(ctx) &&
|
||||
@ -3029,6 +3107,16 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
|
||||
args->timeout_ns -= ktime_to_ns(ktime_sub(ktime_get(), start));
|
||||
if (args->timeout_ns < 0)
|
||||
args->timeout_ns = 0;
|
||||
|
||||
/*
|
||||
* Apparently ktime isn't accurate enough and occasionally has a
|
||||
* bit of mismatch in the jiffies<->nsecs<->ktime loop. So patch
|
||||
* things up to make the test happy. We allow up to 1 jiffy.
|
||||
*
|
||||
* This is a regression from the timespec->ktime conversion.
|
||||
*/
|
||||
if (ret == -ETIME && !nsecs_to_jiffies(args->timeout_ns))
|
||||
args->timeout_ns = 0;
|
||||
}
|
||||
|
||||
i915_gem_object_put(obj);
|
||||
@ -3974,8 +4062,11 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
|
||||
static const struct drm_i915_gem_object_ops i915_gem_object_ops = {
|
||||
.flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE |
|
||||
I915_GEM_OBJECT_IS_SHRINKABLE,
|
||||
|
||||
.get_pages = i915_gem_object_get_pages_gtt,
|
||||
.put_pages = i915_gem_object_put_pages_gtt,
|
||||
|
||||
.pwrite = i915_gem_object_pwrite_gtt,
|
||||
};
|
||||
|
||||
struct drm_i915_gem_object *
|
||||
|
@ -293,12 +293,12 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
|
||||
* those as well to make room for our guard pages.
|
||||
*/
|
||||
if (check_color) {
|
||||
if (vma->node.start + vma->node.size == node->start) {
|
||||
if (vma->node.color == node->color)
|
||||
if (node->start + node->size == target->start) {
|
||||
if (node->color == target->color)
|
||||
continue;
|
||||
}
|
||||
if (vma->node.start == node->start + node->size) {
|
||||
if (vma->node.color == node->color)
|
||||
if (node->start == target->start + target->size) {
|
||||
if (node->color == target->color)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -54,6 +54,9 @@ struct drm_i915_gem_object_ops {
|
||||
struct sg_table *(*get_pages)(struct drm_i915_gem_object *);
|
||||
void (*put_pages)(struct drm_i915_gem_object *, struct sg_table *);
|
||||
|
||||
int (*pwrite)(struct drm_i915_gem_object *,
|
||||
const struct drm_i915_gem_pwrite *);
|
||||
|
||||
int (*dmabuf_export)(struct drm_i915_gem_object *);
|
||||
void (*release)(struct drm_i915_gem_object *);
|
||||
};
|
||||
|
@ -512,10 +512,36 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
i915_vma_remove(struct i915_vma *vma)
|
||||
{
|
||||
struct drm_i915_gem_object *obj = vma->obj;
|
||||
|
||||
GEM_BUG_ON(!drm_mm_node_allocated(&vma->node));
|
||||
GEM_BUG_ON(vma->flags & (I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND));
|
||||
|
||||
drm_mm_remove_node(&vma->node);
|
||||
list_move_tail(&vma->vm_link, &vma->vm->unbound_list);
|
||||
|
||||
/* Since the unbound list is global, only move to that list if
|
||||
* no more VMAs exist.
|
||||
*/
|
||||
if (--obj->bind_count == 0)
|
||||
list_move_tail(&obj->global_link,
|
||||
&to_i915(obj->base.dev)->mm.unbound_list);
|
||||
|
||||
/* And finally now the object is completely decoupled from this vma,
|
||||
* we can drop its hold on the backing storage and allow it to be
|
||||
* reaped by the shrinker.
|
||||
*/
|
||||
i915_gem_object_unpin_pages(obj);
|
||||
GEM_BUG_ON(atomic_read(&obj->mm.pages_pin_count) < obj->bind_count);
|
||||
}
|
||||
|
||||
int __i915_vma_do_pin(struct i915_vma *vma,
|
||||
u64 size, u64 alignment, u64 flags)
|
||||
{
|
||||
unsigned int bound = vma->flags;
|
||||
const unsigned int bound = vma->flags;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&vma->vm->i915->drm.struct_mutex);
|
||||
@ -524,18 +550,18 @@ int __i915_vma_do_pin(struct i915_vma *vma,
|
||||
|
||||
if (WARN_ON(bound & I915_VMA_PIN_OVERFLOW)) {
|
||||
ret = -EBUSY;
|
||||
goto err;
|
||||
goto err_unpin;
|
||||
}
|
||||
|
||||
if ((bound & I915_VMA_BIND_MASK) == 0) {
|
||||
ret = i915_vma_insert(vma, size, alignment, flags);
|
||||
if (ret)
|
||||
goto err;
|
||||
goto err_unpin;
|
||||
}
|
||||
|
||||
ret = i915_vma_bind(vma, vma->obj->cache_level, flags);
|
||||
if (ret)
|
||||
goto err;
|
||||
goto err_remove;
|
||||
|
||||
if ((bound ^ vma->flags) & I915_VMA_GLOBAL_BIND)
|
||||
__i915_vma_set_map_and_fenceable(vma);
|
||||
@ -544,7 +570,12 @@ int __i915_vma_do_pin(struct i915_vma *vma,
|
||||
GEM_BUG_ON(i915_vma_misplaced(vma, size, alignment, flags));
|
||||
return 0;
|
||||
|
||||
err:
|
||||
err_remove:
|
||||
if ((bound & I915_VMA_BIND_MASK) == 0) {
|
||||
GEM_BUG_ON(vma->pages);
|
||||
i915_vma_remove(vma);
|
||||
}
|
||||
err_unpin:
|
||||
__i915_vma_unpin(vma);
|
||||
return ret;
|
||||
}
|
||||
@ -657,9 +688,6 @@ int i915_vma_unbind(struct i915_vma *vma)
|
||||
}
|
||||
vma->flags &= ~(I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND);
|
||||
|
||||
drm_mm_remove_node(&vma->node);
|
||||
list_move_tail(&vma->vm_link, &vma->vm->unbound_list);
|
||||
|
||||
if (vma->pages != obj->mm.pages) {
|
||||
GEM_BUG_ON(!vma->pages);
|
||||
sg_free_table(vma->pages);
|
||||
@ -667,18 +695,7 @@ int i915_vma_unbind(struct i915_vma *vma)
|
||||
}
|
||||
vma->pages = NULL;
|
||||
|
||||
/* Since the unbound list is global, only move to that list if
|
||||
* no more VMAs exist. */
|
||||
if (--obj->bind_count == 0)
|
||||
list_move_tail(&obj->global_link,
|
||||
&to_i915(obj->base.dev)->mm.unbound_list);
|
||||
|
||||
/* And finally now the object is completely decoupled from this vma,
|
||||
* we can drop its hold on the backing storage and allow it to be
|
||||
* reaped by the shrinker.
|
||||
*/
|
||||
i915_gem_object_unpin_pages(obj);
|
||||
GEM_BUG_ON(atomic_read(&obj->mm.pages_pin_count) < obj->bind_count);
|
||||
i915_vma_remove(vma);
|
||||
|
||||
destroy:
|
||||
if (unlikely(i915_vma_is_closed(vma)))
|
||||
|
@ -3669,10 +3669,6 @@ static void intel_update_pipe_config(struct intel_crtc *crtc,
|
||||
/* drm_atomic_helper_update_legacy_modeset_state might not be called. */
|
||||
crtc->base.mode = crtc->base.state->mode;
|
||||
|
||||
DRM_DEBUG_KMS("Updating pipe size %ix%i -> %ix%i\n",
|
||||
old_crtc_state->pipe_src_w, old_crtc_state->pipe_src_h,
|
||||
pipe_config->pipe_src_w, pipe_config->pipe_src_h);
|
||||
|
||||
/*
|
||||
* Update pipe size and adjust fitter if needed: the reason for this is
|
||||
* that in compute_mode_changes we check the native mode (not the pfit
|
||||
@ -4796,23 +4792,17 @@ static void skylake_pfit_enable(struct intel_crtc *crtc)
|
||||
struct intel_crtc_scaler_state *scaler_state =
|
||||
&crtc->config->scaler_state;
|
||||
|
||||
DRM_DEBUG_KMS("for crtc_state = %p\n", crtc->config);
|
||||
|
||||
if (crtc->config->pch_pfit.enabled) {
|
||||
int id;
|
||||
|
||||
if (WARN_ON(crtc->config->scaler_state.scaler_id < 0)) {
|
||||
DRM_ERROR("Requesting pfit without getting a scaler first\n");
|
||||
if (WARN_ON(crtc->config->scaler_state.scaler_id < 0))
|
||||
return;
|
||||
}
|
||||
|
||||
id = scaler_state->scaler_id;
|
||||
I915_WRITE(SKL_PS_CTRL(pipe, id), PS_SCALER_EN |
|
||||
PS_FILTER_MEDIUM | scaler_state->scalers[id].mode);
|
||||
I915_WRITE(SKL_PS_WIN_POS(pipe, id), crtc->config->pch_pfit.pos);
|
||||
I915_WRITE(SKL_PS_WIN_SZ(pipe, id), crtc->config->pch_pfit.size);
|
||||
|
||||
DRM_DEBUG_KMS("for crtc_state = %p scaler_id = %d\n", crtc->config, id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -14379,6 +14369,24 @@ static void skl_update_crtcs(struct drm_atomic_state *state,
|
||||
} while (progress);
|
||||
}
|
||||
|
||||
static void intel_atomic_helper_free_state(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct intel_atomic_state *state, *next;
|
||||
struct llist_node *freed;
|
||||
|
||||
freed = llist_del_all(&dev_priv->atomic_helper.free_list);
|
||||
llist_for_each_entry_safe(state, next, freed, freed)
|
||||
drm_atomic_state_put(&state->base);
|
||||
}
|
||||
|
||||
static void intel_atomic_helper_free_state_worker(struct work_struct *work)
|
||||
{
|
||||
struct drm_i915_private *dev_priv =
|
||||
container_of(work, typeof(*dev_priv), atomic_helper.free_work);
|
||||
|
||||
intel_atomic_helper_free_state(dev_priv);
|
||||
}
|
||||
|
||||
static void intel_atomic_commit_tail(struct drm_atomic_state *state)
|
||||
{
|
||||
struct drm_device *dev = state->dev;
|
||||
@ -14545,6 +14553,8 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
|
||||
* can happen also when the device is completely off.
|
||||
*/
|
||||
intel_uncore_arm_unclaimed_mmio_detection(dev_priv);
|
||||
|
||||
intel_atomic_helper_free_state(dev_priv);
|
||||
}
|
||||
|
||||
static void intel_atomic_commit_work(struct work_struct *work)
|
||||
@ -14946,17 +14956,19 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc,
|
||||
to_intel_atomic_state(old_crtc_state->state);
|
||||
bool modeset = needs_modeset(crtc->state);
|
||||
|
||||
if (!modeset &&
|
||||
(intel_cstate->base.color_mgmt_changed ||
|
||||
intel_cstate->update_pipe)) {
|
||||
intel_color_set_csc(crtc->state);
|
||||
intel_color_load_luts(crtc->state);
|
||||
}
|
||||
|
||||
/* Perform vblank evasion around commit operation */
|
||||
intel_pipe_update_start(intel_crtc);
|
||||
|
||||
if (modeset)
|
||||
goto out;
|
||||
|
||||
if (crtc->state->color_mgmt_changed || to_intel_crtc_state(crtc->state)->update_pipe) {
|
||||
intel_color_set_csc(crtc->state);
|
||||
intel_color_load_luts(crtc->state);
|
||||
}
|
||||
|
||||
if (intel_cstate->update_pipe)
|
||||
intel_update_pipe_config(intel_crtc, old_intel_cstate);
|
||||
else if (INTEL_GEN(dev_priv) >= 9)
|
||||
@ -16599,18 +16611,6 @@ static void sanitize_watermarks(struct drm_device *dev)
|
||||
drm_modeset_acquire_fini(&ctx);
|
||||
}
|
||||
|
||||
static void intel_atomic_helper_free_state(struct work_struct *work)
|
||||
{
|
||||
struct drm_i915_private *dev_priv =
|
||||
container_of(work, typeof(*dev_priv), atomic_helper.free_work);
|
||||
struct intel_atomic_state *state, *next;
|
||||
struct llist_node *freed;
|
||||
|
||||
freed = llist_del_all(&dev_priv->atomic_helper.free_list);
|
||||
llist_for_each_entry_safe(state, next, freed, freed)
|
||||
drm_atomic_state_put(&state->base);
|
||||
}
|
||||
|
||||
int intel_modeset_init(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
@ -16631,7 +16631,7 @@ int intel_modeset_init(struct drm_device *dev)
|
||||
dev->mode_config.funcs = &intel_mode_funcs;
|
||||
|
||||
INIT_WORK(&dev_priv->atomic_helper.free_work,
|
||||
intel_atomic_helper_free_state);
|
||||
intel_atomic_helper_free_state_worker);
|
||||
|
||||
intel_init_quirks(dev);
|
||||
|
||||
|
@ -357,14 +357,13 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,
|
||||
bool *enabled, int width, int height)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(fb_helper->dev);
|
||||
unsigned long conn_configured, mask;
|
||||
unsigned long conn_configured, conn_seq, mask;
|
||||
unsigned int count = min(fb_helper->connector_count, BITS_PER_LONG);
|
||||
int i, j;
|
||||
bool *save_enabled;
|
||||
bool fallback = true;
|
||||
int num_connectors_enabled = 0;
|
||||
int num_connectors_detected = 0;
|
||||
int pass = 0;
|
||||
|
||||
save_enabled = kcalloc(count, sizeof(bool), GFP_KERNEL);
|
||||
if (!save_enabled)
|
||||
@ -374,6 +373,7 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,
|
||||
mask = BIT(count) - 1;
|
||||
conn_configured = 0;
|
||||
retry:
|
||||
conn_seq = conn_configured;
|
||||
for (i = 0; i < count; i++) {
|
||||
struct drm_fb_helper_connector *fb_conn;
|
||||
struct drm_connector *connector;
|
||||
@ -387,7 +387,7 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,
|
||||
if (conn_configured & BIT(i))
|
||||
continue;
|
||||
|
||||
if (pass == 0 && !connector->has_tile)
|
||||
if (conn_seq == 0 && !connector->has_tile)
|
||||
continue;
|
||||
|
||||
if (connector->status == connector_status_connected)
|
||||
@ -498,10 +498,8 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,
|
||||
conn_configured |= BIT(i);
|
||||
}
|
||||
|
||||
if ((conn_configured & mask) != mask) {
|
||||
pass++;
|
||||
if ((conn_configured & mask) != mask && conn_configured != conn_seq)
|
||||
goto retry;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the BIOS didn't enable everything it could, fall back to have the
|
||||
|
@ -4891,6 +4891,12 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
|
||||
break;
|
||||
}
|
||||
|
||||
/* When byt can survive without system hang with dynamic
|
||||
* sw freq adjustments, this restriction can be lifted.
|
||||
*/
|
||||
if (IS_VALLEYVIEW(dev_priv))
|
||||
goto skip_hw_write;
|
||||
|
||||
I915_WRITE(GEN6_RP_UP_EI,
|
||||
GT_INTERVAL_FROM_US(dev_priv, ei_up));
|
||||
I915_WRITE(GEN6_RP_UP_THRESHOLD,
|
||||
@ -4911,6 +4917,7 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
|
||||
GEN6_RP_UP_BUSY_AVG |
|
||||
GEN6_RP_DOWN_IDLE_AVG);
|
||||
|
||||
skip_hw_write:
|
||||
dev_priv->rps.power = new_power;
|
||||
dev_priv->rps.up_threshold = threshold_up;
|
||||
dev_priv->rps.down_threshold = threshold_down;
|
||||
@ -7916,10 +7923,10 @@ static bool skl_pcode_try_request(struct drm_i915_private *dev_priv, u32 mbox,
|
||||
* @timeout_base_ms: timeout for polling with preemption enabled
|
||||
*
|
||||
* Keep resending the @request to @mbox until PCODE acknowledges it, PCODE
|
||||
* reports an error or an overall timeout of @timeout_base_ms+10 ms expires.
|
||||
* reports an error or an overall timeout of @timeout_base_ms+50 ms expires.
|
||||
* The request is acknowledged once the PCODE reply dword equals @reply after
|
||||
* applying @reply_mask. Polling is first attempted with preemption enabled
|
||||
* for @timeout_base_ms and if this times out for another 10 ms with
|
||||
* for @timeout_base_ms and if this times out for another 50 ms with
|
||||
* preemption disabled.
|
||||
*
|
||||
* Returns 0 on success, %-ETIMEDOUT in case of a timeout, <0 in case of some
|
||||
@ -7955,14 +7962,15 @@ int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
|
||||
* worst case) _and_ PCODE was busy for some reason even after a
|
||||
* (queued) request and @timeout_base_ms delay. As a workaround retry
|
||||
* the poll with preemption disabled to maximize the number of
|
||||
* requests. Increase the timeout from @timeout_base_ms to 10ms to
|
||||
* requests. Increase the timeout from @timeout_base_ms to 50ms to
|
||||
* account for interrupts that could reduce the number of these
|
||||
* requests.
|
||||
* requests, and for any quirks of the PCODE firmware that delays
|
||||
* the request completion.
|
||||
*/
|
||||
DRM_DEBUG_KMS("PCODE timeout, retrying with preemption disabled\n");
|
||||
WARN_ON_ONCE(timeout_base_ms > 3);
|
||||
preempt_disable();
|
||||
ret = wait_for_atomic(COND, 10);
|
||||
ret = wait_for_atomic(COND, 50);
|
||||
preempt_enable();
|
||||
|
||||
out:
|
||||
|
@ -254,9 +254,6 @@ skl_update_plane(struct drm_plane *drm_plane,
|
||||
int scaler_id = plane_state->scaler_id;
|
||||
const struct intel_scaler *scaler;
|
||||
|
||||
DRM_DEBUG_KMS("plane = %d PS_PLANE_SEL(plane) = 0x%x\n",
|
||||
plane_id, PS_PLANE_SEL(plane_id));
|
||||
|
||||
scaler = &crtc_state->scaler_state.scalers[scaler_id];
|
||||
|
||||
I915_WRITE(SKL_PS_CTRL(pipe, scaler_id),
|
||||
|
@ -119,6 +119,8 @@ fw_domains_get(struct drm_i915_private *dev_priv, enum forcewake_domains fw_doma
|
||||
|
||||
for_each_fw_domain_masked(d, fw_domains, dev_priv)
|
||||
fw_domain_wait_ack(d);
|
||||
|
||||
dev_priv->uncore.fw_domains_active |= fw_domains;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -130,6 +132,8 @@ fw_domains_put(struct drm_i915_private *dev_priv, enum forcewake_domains fw_doma
|
||||
fw_domain_put(d);
|
||||
fw_domain_posting_read(d);
|
||||
}
|
||||
|
||||
dev_priv->uncore.fw_domains_active &= ~fw_domains;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -240,10 +244,8 @@ intel_uncore_fw_release_timer(struct hrtimer *timer)
|
||||
if (WARN_ON(domain->wake_count == 0))
|
||||
domain->wake_count++;
|
||||
|
||||
if (--domain->wake_count == 0) {
|
||||
if (--domain->wake_count == 0)
|
||||
dev_priv->uncore.funcs.force_wake_put(dev_priv, domain->mask);
|
||||
dev_priv->uncore.fw_domains_active &= ~domain->mask;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
|
||||
|
||||
@ -454,10 +456,8 @@ static void __intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
|
||||
fw_domains &= ~domain->mask;
|
||||
}
|
||||
|
||||
if (fw_domains) {
|
||||
if (fw_domains)
|
||||
dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_domains);
|
||||
dev_priv->uncore.fw_domains_active |= fw_domains;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -968,7 +968,6 @@ static noinline void ___force_wake_auto(struct drm_i915_private *dev_priv,
|
||||
fw_domain_arm_timer(domain);
|
||||
|
||||
dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_domains);
|
||||
dev_priv->uncore.fw_domains_active |= fw_domains;
|
||||
}
|
||||
|
||||
static inline void __force_wake_auto(struct drm_i915_private *dev_priv,
|
||||
|
@ -147,9 +147,6 @@ static int omap_gem_dmabuf_mmap(struct dma_buf *buffer,
|
||||
struct drm_gem_object *obj = buffer->priv;
|
||||
int ret = 0;
|
||||
|
||||
if (WARN_ON(!obj->filp))
|
||||
return -EINVAL;
|
||||
|
||||
ret = drm_gem_mmap_obj(obj, omap_gem_mmap_size(obj), vma);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -2984,6 +2984,12 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,
|
||||
(rdev->pdev->device == 0x6667)) {
|
||||
max_sclk = 75000;
|
||||
}
|
||||
} else if (rdev->family == CHIP_OLAND) {
|
||||
if ((rdev->pdev->device == 0x6604) &&
|
||||
(rdev->pdev->subsystem_vendor == 0x1028) &&
|
||||
(rdev->pdev->subsystem_device == 0x066F)) {
|
||||
max_sclk = 75000;
|
||||
}
|
||||
}
|
||||
|
||||
if (rps->vce_active) {
|
||||
|
@ -464,6 +464,7 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
|
||||
unsigned long flags;
|
||||
|
||||
WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
|
||||
mutex_lock(&tilcdc_crtc->enable_lock);
|
||||
@ -484,7 +485,17 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc)
|
||||
tilcdc_write_mask(dev, LCDC_RASTER_CTRL_REG,
|
||||
LCDC_PALETTE_LOAD_MODE(DATA_ONLY),
|
||||
LCDC_PALETTE_LOAD_MODE_MASK);
|
||||
|
||||
/* There is no real chance for a race here as the time stamp
|
||||
* is taken before the raster DMA is started. The spin-lock is
|
||||
* taken to have a memory barrier after taking the time-stamp
|
||||
* and to avoid a context switch between taking the stamp and
|
||||
* enabling the raster.
|
||||
*/
|
||||
spin_lock_irqsave(&tilcdc_crtc->irq_lock, flags);
|
||||
tilcdc_crtc->last_vblank = ktime_get();
|
||||
tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
|
||||
spin_unlock_irqrestore(&tilcdc_crtc->irq_lock, flags);
|
||||
|
||||
drm_crtc_vblank_on(crtc);
|
||||
|
||||
@ -539,7 +550,6 @@ static void tilcdc_crtc_off(struct drm_crtc *crtc, bool shutdown)
|
||||
}
|
||||
|
||||
drm_flip_work_commit(&tilcdc_crtc->unref_work, priv->wq);
|
||||
tilcdc_crtc->last_vblank = 0;
|
||||
|
||||
tilcdc_crtc->enabled = false;
|
||||
mutex_unlock(&tilcdc_crtc->enable_lock);
|
||||
@ -602,7 +612,6 @@ int tilcdc_crtc_update_fb(struct drm_crtc *crtc,
|
||||
{
|
||||
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
unsigned long flags;
|
||||
|
||||
WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
|
||||
|
||||
@ -614,28 +623,30 @@ int tilcdc_crtc_update_fb(struct drm_crtc *crtc,
|
||||
drm_framebuffer_reference(fb);
|
||||
|
||||
crtc->primary->fb = fb;
|
||||
tilcdc_crtc->event = event;
|
||||
|
||||
spin_lock_irqsave(&tilcdc_crtc->irq_lock, flags);
|
||||
mutex_lock(&tilcdc_crtc->enable_lock);
|
||||
|
||||
if (crtc->hwmode.vrefresh && ktime_to_ns(tilcdc_crtc->last_vblank)) {
|
||||
if (tilcdc_crtc->enabled) {
|
||||
unsigned long flags;
|
||||
ktime_t next_vblank;
|
||||
s64 tdiff;
|
||||
|
||||
spin_lock_irqsave(&tilcdc_crtc->irq_lock, flags);
|
||||
|
||||
next_vblank = ktime_add_us(tilcdc_crtc->last_vblank,
|
||||
1000000 / crtc->hwmode.vrefresh);
|
||||
|
||||
tdiff = ktime_to_us(ktime_sub(next_vblank, ktime_get()));
|
||||
|
||||
if (tdiff < TILCDC_VBLANK_SAFETY_THRESHOLD_US)
|
||||
tilcdc_crtc->next_fb = fb;
|
||||
}
|
||||
|
||||
if (tilcdc_crtc->next_fb != fb)
|
||||
else
|
||||
set_scanout(crtc, fb);
|
||||
|
||||
tilcdc_crtc->event = event;
|
||||
|
||||
spin_unlock_irqrestore(&tilcdc_crtc->irq_lock, flags);
|
||||
}
|
||||
|
||||
mutex_unlock(&tilcdc_crtc->enable_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1036,5 +1047,5 @@ int tilcdc_crtc_create(struct drm_device *dev)
|
||||
|
||||
fail:
|
||||
tilcdc_crtc_destroy(crtc);
|
||||
return -ENOMEM;
|
||||
return ret;
|
||||
}
|
||||
|
@ -33,8 +33,8 @@ extern "C" {
|
||||
#define OMAP_PARAM_CHIPSET_ID 1 /* ie. 0x3430, 0x4430, etc */
|
||||
|
||||
struct drm_omap_param {
|
||||
uint64_t param; /* in */
|
||||
uint64_t value; /* in (set_param), out (get_param) */
|
||||
__u64 param; /* in */
|
||||
__u64 value; /* in (set_param), out (get_param) */
|
||||
};
|
||||
|
||||
#define OMAP_BO_SCANOUT 0x00000001 /* scanout capable (phys contiguous) */
|
||||
@ -53,18 +53,18 @@ struct drm_omap_param {
|
||||
#define OMAP_BO_TILED (OMAP_BO_TILED_8 | OMAP_BO_TILED_16 | OMAP_BO_TILED_32)
|
||||
|
||||
union omap_gem_size {
|
||||
uint32_t bytes; /* (for non-tiled formats) */
|
||||
__u32 bytes; /* (for non-tiled formats) */
|
||||
struct {
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
__u16 width;
|
||||
__u16 height;
|
||||
} tiled; /* (for tiled formats) */
|
||||
};
|
||||
|
||||
struct drm_omap_gem_new {
|
||||
union omap_gem_size size; /* in */
|
||||
uint32_t flags; /* in */
|
||||
uint32_t handle; /* out */
|
||||
uint32_t __pad;
|
||||
__u32 flags; /* in */
|
||||
__u32 handle; /* out */
|
||||
__u32 __pad;
|
||||
};
|
||||
|
||||
/* mask of operations: */
|
||||
@ -74,33 +74,33 @@ enum omap_gem_op {
|
||||
};
|
||||
|
||||
struct drm_omap_gem_cpu_prep {
|
||||
uint32_t handle; /* buffer handle (in) */
|
||||
uint32_t op; /* mask of omap_gem_op (in) */
|
||||
__u32 handle; /* buffer handle (in) */
|
||||
__u32 op; /* mask of omap_gem_op (in) */
|
||||
};
|
||||
|
||||
struct drm_omap_gem_cpu_fini {
|
||||
uint32_t handle; /* buffer handle (in) */
|
||||
uint32_t op; /* mask of omap_gem_op (in) */
|
||||
__u32 handle; /* buffer handle (in) */
|
||||
__u32 op; /* mask of omap_gem_op (in) */
|
||||
/* TODO maybe here we pass down info about what regions are touched
|
||||
* by sw so we can be clever about cache ops? For now a placeholder,
|
||||
* set to zero and we just do full buffer flush..
|
||||
*/
|
||||
uint32_t nregions;
|
||||
uint32_t __pad;
|
||||
__u32 nregions;
|
||||
__u32 __pad;
|
||||
};
|
||||
|
||||
struct drm_omap_gem_info {
|
||||
uint32_t handle; /* buffer handle (in) */
|
||||
uint32_t pad;
|
||||
uint64_t offset; /* mmap offset (out) */
|
||||
__u32 handle; /* buffer handle (in) */
|
||||
__u32 pad;
|
||||
__u64 offset; /* mmap offset (out) */
|
||||
/* note: in case of tiled buffers, the user virtual size can be
|
||||
* different from the physical size (ie. how many pages are needed
|
||||
* to back the object) which is returned in DRM_IOCTL_GEM_OPEN..
|
||||
* This size here is the one that should be used if you want to
|
||||
* mmap() the buffer:
|
||||
*/
|
||||
uint32_t size; /* virtual size for mmap'ing (out) */
|
||||
uint32_t __pad;
|
||||
__u32 size; /* virtual size for mmap'ing (out) */
|
||||
__u32 __pad;
|
||||
};
|
||||
|
||||
#define DRM_OMAP_GET_PARAM 0x00
|
||||
|
Loading…
Reference in New Issue
Block a user