mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 18:10:52 +07:00
Merge branch 'server-fixes' into drm-next
Merge the fixes for the server driver dirty update paths * server-fixes: drm/cirrus: deal with bo reserve fail in dirty update path drm/ast: deal with bo reserve fail in dirty update path drm/mgag200: deal with bo reserve fail in dirty update path
This commit is contained in:
commit
d2dbaaf626
@ -241,6 +241,8 @@ struct ast_fbdev {
|
||||
void *sysram;
|
||||
int size;
|
||||
struct ttm_bo_kmap_obj mapping;
|
||||
int x1, y1, x2, y2; /* dirty rect */
|
||||
spinlock_t dirty_lock;
|
||||
};
|
||||
|
||||
#define to_ast_crtc(x) container_of(x, struct ast_crtc, base)
|
||||
|
@ -53,16 +53,52 @@ static void ast_dirty_update(struct ast_fbdev *afbdev,
|
||||
int bpp = (afbdev->afb.base.bits_per_pixel + 7)/8;
|
||||
int ret;
|
||||
bool unmap = false;
|
||||
bool store_for_later = false;
|
||||
int x2, y2;
|
||||
unsigned long flags;
|
||||
|
||||
obj = afbdev->afb.obj;
|
||||
bo = gem_to_ast_bo(obj);
|
||||
|
||||
/*
|
||||
* try and reserve the BO, if we fail with busy
|
||||
* then the BO is being moved and we should
|
||||
* store up the damage until later.
|
||||
*/
|
||||
ret = ast_bo_reserve(bo, true);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to reserve fb bo\n");
|
||||
if (ret != -EBUSY)
|
||||
return;
|
||||
|
||||
store_for_later = true;
|
||||
}
|
||||
|
||||
x2 = x + width - 1;
|
||||
y2 = y + height - 1;
|
||||
spin_lock_irqsave(&afbdev->dirty_lock, flags);
|
||||
|
||||
if (afbdev->y1 < y)
|
||||
y = afbdev->y1;
|
||||
if (afbdev->y2 > y2)
|
||||
y2 = afbdev->y2;
|
||||
if (afbdev->x1 < x)
|
||||
x = afbdev->x1;
|
||||
if (afbdev->x2 > x2)
|
||||
x2 = afbdev->x2;
|
||||
|
||||
if (store_for_later) {
|
||||
afbdev->x1 = x;
|
||||
afbdev->x2 = x2;
|
||||
afbdev->y1 = y;
|
||||
afbdev->y2 = y2;
|
||||
spin_unlock_irqrestore(&afbdev->dirty_lock, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
afbdev->x1 = afbdev->y1 = INT_MAX;
|
||||
afbdev->x2 = afbdev->y2 = 0;
|
||||
spin_unlock_irqrestore(&afbdev->dirty_lock, flags);
|
||||
|
||||
if (!bo->kmap.virtual) {
|
||||
ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
|
||||
if (ret) {
|
||||
@ -72,10 +108,10 @@ static void ast_dirty_update(struct ast_fbdev *afbdev,
|
||||
}
|
||||
unmap = true;
|
||||
}
|
||||
for (i = y; i < y + height; i++) {
|
||||
for (i = y; i <= y2; i++) {
|
||||
/* assume equal stride for now */
|
||||
src_offset = dst_offset = i * afbdev->afb.base.pitches[0] + (x * bpp);
|
||||
memcpy_toio(bo->kmap.virtual + src_offset, afbdev->sysram + src_offset, width * bpp);
|
||||
memcpy_toio(bo->kmap.virtual + src_offset, afbdev->sysram + src_offset, (x2 - x + 1) * bpp);
|
||||
|
||||
}
|
||||
if (unmap)
|
||||
@ -292,6 +328,7 @@ int ast_fbdev_init(struct drm_device *dev)
|
||||
|
||||
ast->fbdev = afbdev;
|
||||
afbdev->helper.funcs = &ast_fb_helper_funcs;
|
||||
spin_lock_init(&afbdev->dirty_lock);
|
||||
ret = drm_fb_helper_init(dev, &afbdev->helper,
|
||||
1, 1);
|
||||
if (ret) {
|
||||
|
@ -316,7 +316,7 @@ int ast_bo_reserve(struct ast_bo *bo, bool no_wait)
|
||||
|
||||
ret = ttm_bo_reserve(&bo->bo, true, no_wait, false, 0);
|
||||
if (ret) {
|
||||
if (ret != -ERESTARTSYS)
|
||||
if (ret != -ERESTARTSYS && ret != -EBUSY)
|
||||
DRM_ERROR("reserve failed %p\n", bo);
|
||||
return ret;
|
||||
}
|
||||
|
@ -154,6 +154,8 @@ struct cirrus_fbdev {
|
||||
struct list_head fbdev_list;
|
||||
void *sysram;
|
||||
int size;
|
||||
int x1, y1, x2, y2; /* dirty rect */
|
||||
spinlock_t dirty_lock;
|
||||
};
|
||||
|
||||
struct cirrus_bo {
|
||||
|
@ -27,16 +27,51 @@ static void cirrus_dirty_update(struct cirrus_fbdev *afbdev,
|
||||
int bpp = (afbdev->gfb.base.bits_per_pixel + 7)/8;
|
||||
int ret;
|
||||
bool unmap = false;
|
||||
bool store_for_later = false;
|
||||
int x2, y2;
|
||||
unsigned long flags;
|
||||
|
||||
obj = afbdev->gfb.obj;
|
||||
bo = gem_to_cirrus_bo(obj);
|
||||
|
||||
/*
|
||||
* try and reserve the BO, if we fail with busy
|
||||
* then the BO is being moved and we should
|
||||
* store up the damage until later.
|
||||
*/
|
||||
ret = cirrus_bo_reserve(bo, true);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to reserve fb bo\n");
|
||||
if (ret != -EBUSY)
|
||||
return;
|
||||
store_for_later = true;
|
||||
}
|
||||
|
||||
x2 = x + width - 1;
|
||||
y2 = y + height - 1;
|
||||
spin_lock_irqsave(&afbdev->dirty_lock, flags);
|
||||
|
||||
if (afbdev->y1 < y)
|
||||
y = afbdev->y1;
|
||||
if (afbdev->y2 > y2)
|
||||
y2 = afbdev->y2;
|
||||
if (afbdev->x1 < x)
|
||||
x = afbdev->x1;
|
||||
if (afbdev->x2 > x2)
|
||||
x2 = afbdev->x2;
|
||||
|
||||
if (store_for_later) {
|
||||
afbdev->x1 = x;
|
||||
afbdev->x2 = x2;
|
||||
afbdev->y1 = y;
|
||||
afbdev->y2 = y2;
|
||||
spin_unlock_irqrestore(&afbdev->dirty_lock, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
afbdev->x1 = afbdev->y1 = INT_MAX;
|
||||
afbdev->x2 = afbdev->y2 = 0;
|
||||
spin_unlock_irqrestore(&afbdev->dirty_lock, flags);
|
||||
|
||||
if (!bo->kmap.virtual) {
|
||||
ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
|
||||
if (ret) {
|
||||
@ -268,6 +303,7 @@ int cirrus_fbdev_init(struct cirrus_device *cdev)
|
||||
|
||||
cdev->mode_info.gfbdev = gfbdev;
|
||||
gfbdev->helper.funcs = &cirrus_fb_helper_funcs;
|
||||
spin_lock_init(&gfbdev->dirty_lock);
|
||||
|
||||
ret = drm_fb_helper_init(cdev->dev, &gfbdev->helper,
|
||||
cdev->num_crtc, CIRRUSFB_CONN_LIMIT);
|
||||
|
@ -321,7 +321,7 @@ int cirrus_bo_reserve(struct cirrus_bo *bo, bool no_wait)
|
||||
|
||||
ret = ttm_bo_reserve(&bo->bo, true, no_wait, false, 0);
|
||||
if (ret) {
|
||||
if (ret != -ERESTARTSYS)
|
||||
if (ret != -ERESTARTSYS && ret != -EBUSY)
|
||||
DRM_ERROR("reserve failed %p\n", bo);
|
||||
return ret;
|
||||
}
|
||||
|
@ -115,6 +115,8 @@ struct mga_fbdev {
|
||||
void *sysram;
|
||||
int size;
|
||||
struct ttm_bo_kmap_obj mapping;
|
||||
int x1, y1, x2, y2; /* dirty rect */
|
||||
spinlock_t dirty_lock;
|
||||
};
|
||||
|
||||
struct mga_crtc {
|
||||
|
@ -29,16 +29,52 @@ static void mga_dirty_update(struct mga_fbdev *mfbdev,
|
||||
int bpp = (mfbdev->mfb.base.bits_per_pixel + 7)/8;
|
||||
int ret;
|
||||
bool unmap = false;
|
||||
bool store_for_later = false;
|
||||
int x2, y2;
|
||||
unsigned long flags;
|
||||
|
||||
obj = mfbdev->mfb.obj;
|
||||
bo = gem_to_mga_bo(obj);
|
||||
|
||||
/*
|
||||
* try and reserve the BO, if we fail with busy
|
||||
* then the BO is being moved and we should
|
||||
* store up the damage until later.
|
||||
*/
|
||||
ret = mgag200_bo_reserve(bo, true);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to reserve fb bo\n");
|
||||
if (ret != -EBUSY)
|
||||
return;
|
||||
|
||||
store_for_later = true;
|
||||
}
|
||||
|
||||
x2 = x + width - 1;
|
||||
y2 = y + height - 1;
|
||||
spin_lock_irqsave(&mfbdev->dirty_lock, flags);
|
||||
|
||||
if (mfbdev->y1 < y)
|
||||
y = mfbdev->y1;
|
||||
if (mfbdev->y2 > y2)
|
||||
y2 = mfbdev->y2;
|
||||
if (mfbdev->x1 < x)
|
||||
x = mfbdev->x1;
|
||||
if (mfbdev->x2 > x2)
|
||||
x2 = mfbdev->x2;
|
||||
|
||||
if (store_for_later) {
|
||||
mfbdev->x1 = x;
|
||||
mfbdev->x2 = x2;
|
||||
mfbdev->y1 = y;
|
||||
mfbdev->y2 = y2;
|
||||
spin_unlock_irqrestore(&mfbdev->dirty_lock, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
mfbdev->x1 = mfbdev->y1 = INT_MAX;
|
||||
mfbdev->x2 = mfbdev->y2 = 0;
|
||||
spin_unlock_irqrestore(&mfbdev->dirty_lock, flags);
|
||||
|
||||
if (!bo->kmap.virtual) {
|
||||
ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
|
||||
if (ret) {
|
||||
@ -48,10 +84,10 @@ static void mga_dirty_update(struct mga_fbdev *mfbdev,
|
||||
}
|
||||
unmap = true;
|
||||
}
|
||||
for (i = y; i < y + height; i++) {
|
||||
for (i = y; i <= y2; i++) {
|
||||
/* assume equal stride for now */
|
||||
src_offset = dst_offset = i * mfbdev->mfb.base.pitches[0] + (x * bpp);
|
||||
memcpy_toio(bo->kmap.virtual + src_offset, mfbdev->sysram + src_offset, width * bpp);
|
||||
memcpy_toio(bo->kmap.virtual + src_offset, mfbdev->sysram + src_offset, (x2 - x + 1) * bpp);
|
||||
|
||||
}
|
||||
if (unmap)
|
||||
@ -252,6 +288,7 @@ int mgag200_fbdev_init(struct mga_device *mdev)
|
||||
|
||||
mdev->mfbdev = mfbdev;
|
||||
mfbdev->helper.funcs = &mga_fb_helper_funcs;
|
||||
spin_lock_init(&mfbdev->dirty_lock);
|
||||
|
||||
ret = drm_fb_helper_init(mdev->dev, &mfbdev->helper,
|
||||
mdev->num_crtc, MGAG200FB_CONN_LIMIT);
|
||||
|
@ -315,8 +315,8 @@ int mgag200_bo_reserve(struct mgag200_bo *bo, bool no_wait)
|
||||
|
||||
ret = ttm_bo_reserve(&bo->bo, true, no_wait, false, 0);
|
||||
if (ret) {
|
||||
if (ret != -ERESTARTSYS)
|
||||
DRM_ERROR("reserve failed %p\n", bo);
|
||||
if (ret != -ERESTARTSYS && ret != -EBUSY)
|
||||
DRM_ERROR("reserve failed %p %d\n", bo, ret);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user