mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-26 16:41:25 +00:00
drm-fixes for 5.3-rc3, take 2
intel fixes (didn't have any ever since the main merge window pull): - gvt fixes (2 cc: stable) - fix gpu reset vs mm-shrinker vs wakeup fun (needed a few patches) - two gem locking fixes (one cc: stable) - pile of misc fixes all over with minor impact, 6 cc: stable, others from this window exynos: - misc minor fixes misc: - some build/Kconfig fixes - regression fix for vm scalability perf test which seems to mostly exercise dmesg/console logging ... - the vgem cache flush fix for arm64 broke the world on x86, so that's reverted again -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEb4nG6jLu8Y5XI+PfTA9ye/CYqnEFAl1Eh6UACgkQTA9ye/CY qnEr0xAAoCm/z3Y02494iuWfHTnSM3ILEILRoKur3ewaYg7u5qLppdFSCPN92EIC M3ODjNLaYSIJWB+mT6II9tdPzARL2Uug5ItJBE0OtnJmexYIdkBDc7GlctfW3ENB KFcW2i3MrA1lrNC69snzO0uWtchfkuXvFH0W8q6l+n5y8Yevcqs12XYZbYQYpV4Z KHScTggWQ2owjKBTDDZ1zYtp+pkto/CUlL2ln6b32T27YtdJIc4vtqB0+sR5iThx KCduQR897WOjueOIsy/qyhg45cC5Eci28HXTMoh/HVjG1igmAAPhapWH48Yrfkdu bSbwbBAaA6OGv+7yWCESpl7Au2KCtQ26nDESOIP4KDl+Kl5uAgoiDTIyCVLI7b6p gYH88LhL7UJKvvej7BtHrQy6BMZElznRWVtEESfCuyk8wn/cAxJNOxbdNIWIUjha NDUTdyZOuY8C8xGDdLLFWX7mn/1lkVFxxTRlx2lgKJROAfjA+CsohgXeMTsStqdX W4Mx/3Q8oBELcsUMGL/+N3vZGPIckk6trs0SteV6J3XaOduWClAQA9KV4JHb7JOq tVC88MkxXK0bZAT9W6sSM5KOmZo6t7XiaP2QZAd5vWljaMPov489e40RK0ZFmKPW xfhWBxNdaTeu7d0X+25oOUBmroUnnGSukOLJheGISwTBDAlkp7U= =2TGW -----END PGP SIGNATURE----- Merge tag 'drm-fixes-2019-08-02-1' of git://anongit.freedesktop.org/drm/drm Pull more drm fixes from Daniel Vetter: "Dave sends his pull, everyone realizes they've been asleep at the wheel and hits send on their own pulls :-/ Normally I'd just ignore these all because w/e for me and Dave. But this time around the latecomers also included drm-intel-fixes, which failed to send out a -fixes pull thus far for this release (screwed up vacation coverage, despite that 2/3 maintainers were around ... they all look appropriately guilty), and that really is overdue to get landed. And since I had to do a pull request anyway I pulled the other two late ones too. intel fixes (didn't have any ever since the main merge window pull): - gvt fixes (2 cc: stable) - fix gpu reset vs mm-shrinker vs wakeup fun (needed a few patches) - two gem locking fixes (one cc: stable) - pile of misc fixes all over with minor impact, 6 cc: stable, others from this window exynos: - misc minor fixes misc: - some build/Kconfig fixes - regression fix for vm scalability perf test which seems to mostly exercise dmesg/console logging ... - the vgem cache flush fix for arm64 broke the world on x86, so that's reverted again * tag 'drm-fixes-2019-08-02-1' of git://anongit.freedesktop.org/drm/drm: (42 commits) Revert "drm/vgem: fix cache synchronization on arm/arm64" drm/exynos: fix missing decrement of retry counter drm/exynos: add CONFIG_MMU dependency drm/exynos: remove redundant assignment to pointer 'node' drm/exynos: using dev_get_drvdata directly drm/bochs: Use shadow buffer for bochs framebuffer console drm/fb-helper: Instanciate shadow FB if configured in device's mode_config drm/fb-helper: Map DRM client buffer only when required drm/client: Support unmapping of DRM client buffers drm/i915: Only recover active engines drm/i915: Add a wakeref getter for iff the wakeref is already active drm/i915: Lift intel_engines_resume() to callers drm/vgem: fix cache synchronization on arm/arm64 drm/i810: Use CONFIG_PREEMPTION drm/bridge: tc358764: Fix build error drm/bridge: lvds-encoder: Fix build error while CONFIG_DRM_KMS_HELPER=m drm/i915/gvt: Adding ppgtt to GVT GEM context after shadow pdps settled. drm/i915/gvt: grab runtime pm first for forcewake use drm/i915/gvt: fix incorrect cache entry for guest page mapping drm/i915/gvt: Checking workload's gma earlier ...
This commit is contained in:
commit
0e31225f99
48 changed files with 527 additions and 257 deletions
|
@ -394,7 +394,7 @@ config DRM_R128
|
||||||
config DRM_I810
|
config DRM_I810
|
||||||
tristate "Intel I810"
|
tristate "Intel I810"
|
||||||
# !PREEMPT because of missing ioctl locking
|
# !PREEMPT because of missing ioctl locking
|
||||||
depends on DRM && AGP && AGP_INTEL && (!PREEMPT || BROKEN)
|
depends on DRM && AGP && AGP_INTEL && (!PREEMPTION || BROKEN)
|
||||||
help
|
help
|
||||||
Choose this option if you have an Intel I810 graphics card. If M is
|
Choose this option if you have an Intel I810 graphics card. If M is
|
||||||
selected, the module will be called i810. AGP support is required
|
selected, the module will be called i810. AGP support is required
|
||||||
|
|
|
@ -191,6 +191,7 @@ int bochs_kms_init(struct bochs_device *bochs)
|
||||||
bochs->dev->mode_config.fb_base = bochs->fb_base;
|
bochs->dev->mode_config.fb_base = bochs->fb_base;
|
||||||
bochs->dev->mode_config.preferred_depth = 24;
|
bochs->dev->mode_config.preferred_depth = 24;
|
||||||
bochs->dev->mode_config.prefer_shadow = 0;
|
bochs->dev->mode_config.prefer_shadow = 0;
|
||||||
|
bochs->dev->mode_config.prefer_shadow_fbdev = 1;
|
||||||
bochs->dev->mode_config.quirk_addfb_prefer_host_byte_order = true;
|
bochs->dev->mode_config.quirk_addfb_prefer_host_byte_order = true;
|
||||||
|
|
||||||
bochs->dev->mode_config.funcs = &bochs_mode_funcs;
|
bochs->dev->mode_config.funcs = &bochs_mode_funcs;
|
||||||
|
|
|
@ -48,6 +48,7 @@ config DRM_DUMB_VGA_DAC
|
||||||
config DRM_LVDS_ENCODER
|
config DRM_LVDS_ENCODER
|
||||||
tristate "Transparent parallel to LVDS encoder support"
|
tristate "Transparent parallel to LVDS encoder support"
|
||||||
depends on OF
|
depends on OF
|
||||||
|
select DRM_KMS_HELPER
|
||||||
select DRM_PANEL_BRIDGE
|
select DRM_PANEL_BRIDGE
|
||||||
help
|
help
|
||||||
Support for transparent parallel to LVDS encoders that don't require
|
Support for transparent parallel to LVDS encoders that don't require
|
||||||
|
@ -116,9 +117,10 @@ config DRM_THINE_THC63LVD1024
|
||||||
|
|
||||||
config DRM_TOSHIBA_TC358764
|
config DRM_TOSHIBA_TC358764
|
||||||
tristate "TC358764 DSI/LVDS bridge"
|
tristate "TC358764 DSI/LVDS bridge"
|
||||||
depends on DRM && DRM_PANEL
|
|
||||||
depends on OF
|
depends on OF
|
||||||
select DRM_MIPI_DSI
|
select DRM_MIPI_DSI
|
||||||
|
select DRM_KMS_HELPER
|
||||||
|
select DRM_PANEL
|
||||||
help
|
help
|
||||||
Toshiba TC358764 DSI/LVDS bridge driver.
|
Toshiba TC358764 DSI/LVDS bridge driver.
|
||||||
|
|
||||||
|
|
|
@ -254,7 +254,6 @@ drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height, u
|
||||||
struct drm_device *dev = client->dev;
|
struct drm_device *dev = client->dev;
|
||||||
struct drm_client_buffer *buffer;
|
struct drm_client_buffer *buffer;
|
||||||
struct drm_gem_object *obj;
|
struct drm_gem_object *obj;
|
||||||
void *vaddr;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
|
buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
|
||||||
|
@ -281,6 +280,36 @@ drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height, u
|
||||||
|
|
||||||
buffer->gem = obj;
|
buffer->gem = obj;
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
|
||||||
|
err_delete:
|
||||||
|
drm_client_buffer_delete(buffer);
|
||||||
|
|
||||||
|
return ERR_PTR(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drm_client_buffer_vmap - Map DRM client buffer into address space
|
||||||
|
* @buffer: DRM client buffer
|
||||||
|
*
|
||||||
|
* This function maps a client buffer into kernel address space. If the
|
||||||
|
* buffer is already mapped, it returns the mapping's address.
|
||||||
|
*
|
||||||
|
* Client buffer mappings are not ref'counted. Each call to
|
||||||
|
* drm_client_buffer_vmap() should be followed by a call to
|
||||||
|
* drm_client_buffer_vunmap(); or the client buffer should be mapped
|
||||||
|
* throughout its lifetime.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* The mapped memory's address
|
||||||
|
*/
|
||||||
|
void *drm_client_buffer_vmap(struct drm_client_buffer *buffer)
|
||||||
|
{
|
||||||
|
void *vaddr;
|
||||||
|
|
||||||
|
if (buffer->vaddr)
|
||||||
|
return buffer->vaddr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: The dependency on GEM here isn't required, we could
|
* FIXME: The dependency on GEM here isn't required, we could
|
||||||
* convert the driver handle to a dma-buf instead and use the
|
* convert the driver handle to a dma-buf instead and use the
|
||||||
|
@ -289,21 +318,30 @@ drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height, u
|
||||||
* fd_install step out of the driver backend hooks, to make that
|
* fd_install step out of the driver backend hooks, to make that
|
||||||
* final step optional for internal users.
|
* final step optional for internal users.
|
||||||
*/
|
*/
|
||||||
vaddr = drm_gem_vmap(obj);
|
vaddr = drm_gem_vmap(buffer->gem);
|
||||||
if (IS_ERR(vaddr)) {
|
if (IS_ERR(vaddr))
|
||||||
ret = PTR_ERR(vaddr);
|
return vaddr;
|
||||||
goto err_delete;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer->vaddr = vaddr;
|
buffer->vaddr = vaddr;
|
||||||
|
|
||||||
return buffer;
|
return vaddr;
|
||||||
|
|
||||||
err_delete:
|
|
||||||
drm_client_buffer_delete(buffer);
|
|
||||||
|
|
||||||
return ERR_PTR(ret);
|
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(drm_client_buffer_vmap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drm_client_buffer_vunmap - Unmap DRM client buffer
|
||||||
|
* @buffer: DRM client buffer
|
||||||
|
*
|
||||||
|
* This function removes a client buffer's memory mapping. Calling this
|
||||||
|
* function is only required by clients that manage their buffer mappings
|
||||||
|
* by themselves.
|
||||||
|
*/
|
||||||
|
void drm_client_buffer_vunmap(struct drm_client_buffer *buffer)
|
||||||
|
{
|
||||||
|
drm_gem_vunmap(buffer->gem, buffer->vaddr);
|
||||||
|
buffer->vaddr = NULL;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(drm_client_buffer_vunmap);
|
||||||
|
|
||||||
static void drm_client_buffer_rmfb(struct drm_client_buffer *buffer)
|
static void drm_client_buffer_rmfb(struct drm_client_buffer *buffer)
|
||||||
{
|
{
|
||||||
|
|
|
@ -403,6 +403,7 @@ static void drm_fb_helper_dirty_work(struct work_struct *work)
|
||||||
struct drm_clip_rect *clip = &helper->dirty_clip;
|
struct drm_clip_rect *clip = &helper->dirty_clip;
|
||||||
struct drm_clip_rect clip_copy;
|
struct drm_clip_rect clip_copy;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
void *vaddr;
|
||||||
|
|
||||||
spin_lock_irqsave(&helper->dirty_lock, flags);
|
spin_lock_irqsave(&helper->dirty_lock, flags);
|
||||||
clip_copy = *clip;
|
clip_copy = *clip;
|
||||||
|
@ -412,10 +413,20 @@ static void drm_fb_helper_dirty_work(struct work_struct *work)
|
||||||
|
|
||||||
/* call dirty callback only when it has been really touched */
|
/* call dirty callback only when it has been really touched */
|
||||||
if (clip_copy.x1 < clip_copy.x2 && clip_copy.y1 < clip_copy.y2) {
|
if (clip_copy.x1 < clip_copy.x2 && clip_copy.y1 < clip_copy.y2) {
|
||||||
|
|
||||||
/* Generic fbdev uses a shadow buffer */
|
/* Generic fbdev uses a shadow buffer */
|
||||||
if (helper->buffer)
|
if (helper->buffer) {
|
||||||
|
vaddr = drm_client_buffer_vmap(helper->buffer);
|
||||||
|
if (IS_ERR(vaddr))
|
||||||
|
return;
|
||||||
drm_fb_helper_dirty_blit_real(helper, &clip_copy);
|
drm_fb_helper_dirty_blit_real(helper, &clip_copy);
|
||||||
helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, &clip_copy, 1);
|
}
|
||||||
|
if (helper->fb->funcs->dirty)
|
||||||
|
helper->fb->funcs->dirty(helper->fb, NULL, 0, 0,
|
||||||
|
&clip_copy, 1);
|
||||||
|
|
||||||
|
if (helper->buffer)
|
||||||
|
drm_client_buffer_vunmap(helper->buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -604,6 +615,16 @@ void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_fb_helper_unlink_fbi);
|
EXPORT_SYMBOL(drm_fb_helper_unlink_fbi);
|
||||||
|
|
||||||
|
static bool drm_fbdev_use_shadow_fb(struct drm_fb_helper *fb_helper)
|
||||||
|
{
|
||||||
|
struct drm_device *dev = fb_helper->dev;
|
||||||
|
struct drm_framebuffer *fb = fb_helper->fb;
|
||||||
|
|
||||||
|
return dev->mode_config.prefer_shadow_fbdev ||
|
||||||
|
dev->mode_config.prefer_shadow ||
|
||||||
|
fb->funcs->dirty;
|
||||||
|
}
|
||||||
|
|
||||||
static void drm_fb_helper_dirty(struct fb_info *info, u32 x, u32 y,
|
static void drm_fb_helper_dirty(struct fb_info *info, u32 x, u32 y,
|
||||||
u32 width, u32 height)
|
u32 width, u32 height)
|
||||||
{
|
{
|
||||||
|
@ -611,7 +632,7 @@ static void drm_fb_helper_dirty(struct fb_info *info, u32 x, u32 y,
|
||||||
struct drm_clip_rect *clip = &helper->dirty_clip;
|
struct drm_clip_rect *clip = &helper->dirty_clip;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if (!helper->fb->funcs->dirty)
|
if (!drm_fbdev_use_shadow_fb(helper))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
spin_lock_irqsave(&helper->dirty_lock, flags);
|
spin_lock_irqsave(&helper->dirty_lock, flags);
|
||||||
|
@ -2178,6 +2199,7 @@ int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
|
||||||
struct drm_framebuffer *fb;
|
struct drm_framebuffer *fb;
|
||||||
struct fb_info *fbi;
|
struct fb_info *fbi;
|
||||||
u32 format;
|
u32 format;
|
||||||
|
void *vaddr;
|
||||||
|
|
||||||
DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d)\n",
|
DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d)\n",
|
||||||
sizes->surface_width, sizes->surface_height,
|
sizes->surface_width, sizes->surface_height,
|
||||||
|
@ -2200,16 +2222,10 @@ int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
|
||||||
fbi->fbops = &drm_fbdev_fb_ops;
|
fbi->fbops = &drm_fbdev_fb_ops;
|
||||||
fbi->screen_size = fb->height * fb->pitches[0];
|
fbi->screen_size = fb->height * fb->pitches[0];
|
||||||
fbi->fix.smem_len = fbi->screen_size;
|
fbi->fix.smem_len = fbi->screen_size;
|
||||||
fbi->screen_buffer = buffer->vaddr;
|
|
||||||
/* Shamelessly leak the physical address to user-space */
|
|
||||||
#if IS_ENABLED(CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM)
|
|
||||||
if (drm_leak_fbdev_smem && fbi->fix.smem_start == 0)
|
|
||||||
fbi->fix.smem_start =
|
|
||||||
page_to_phys(virt_to_page(fbi->screen_buffer));
|
|
||||||
#endif
|
|
||||||
drm_fb_helper_fill_info(fbi, fb_helper, sizes);
|
drm_fb_helper_fill_info(fbi, fb_helper, sizes);
|
||||||
|
|
||||||
if (fb->funcs->dirty) {
|
if (drm_fbdev_use_shadow_fb(fb_helper)) {
|
||||||
struct fb_ops *fbops;
|
struct fb_ops *fbops;
|
||||||
void *shadow;
|
void *shadow;
|
||||||
|
|
||||||
|
@ -2231,6 +2247,19 @@ int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
|
||||||
fbi->fbdefio = &drm_fbdev_defio;
|
fbi->fbdefio = &drm_fbdev_defio;
|
||||||
|
|
||||||
fb_deferred_io_init(fbi);
|
fb_deferred_io_init(fbi);
|
||||||
|
} else {
|
||||||
|
/* buffer is mapped for HW framebuffer */
|
||||||
|
vaddr = drm_client_buffer_vmap(fb_helper->buffer);
|
||||||
|
if (IS_ERR(vaddr))
|
||||||
|
return PTR_ERR(vaddr);
|
||||||
|
|
||||||
|
fbi->screen_buffer = vaddr;
|
||||||
|
/* Shamelessly leak the physical address to user-space */
|
||||||
|
#if IS_ENABLED(CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM)
|
||||||
|
if (drm_leak_fbdev_smem && fbi->fix.smem_start == 0)
|
||||||
|
fbi->fix.smem_start =
|
||||||
|
page_to_phys(virt_to_page(fbi->screen_buffer));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
config DRM_EXYNOS
|
config DRM_EXYNOS
|
||||||
tristate "DRM Support for Samsung SoC EXYNOS Series"
|
tristate "DRM Support for Samsung SoC EXYNOS Series"
|
||||||
depends on OF && DRM && (ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS || ARCH_MULTIPLATFORM || COMPILE_TEST)
|
depends on OF && DRM && (ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS || ARCH_MULTIPLATFORM || COMPILE_TEST)
|
||||||
|
depends on MMU
|
||||||
select DRM_KMS_HELPER
|
select DRM_KMS_HELPER
|
||||||
select VIDEOMODE_HELPERS
|
select VIDEOMODE_HELPERS
|
||||||
select SND_SOC_HDMI_CODEC if SND_SOC
|
select SND_SOC_HDMI_CODEC if SND_SOC
|
||||||
|
|
|
@ -44,7 +44,7 @@ static unsigned int fimc_mask = 0xc;
|
||||||
module_param_named(fimc_devs, fimc_mask, uint, 0644);
|
module_param_named(fimc_devs, fimc_mask, uint, 0644);
|
||||||
MODULE_PARM_DESC(fimc_devs, "Alias mask for assigning FIMC devices to Exynos DRM");
|
MODULE_PARM_DESC(fimc_devs, "Alias mask for assigning FIMC devices to Exynos DRM");
|
||||||
|
|
||||||
#define get_fimc_context(dev) platform_get_drvdata(to_platform_device(dev))
|
#define get_fimc_context(dev) dev_get_drvdata(dev)
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
FIMC_CLK_LCLK,
|
FIMC_CLK_LCLK,
|
||||||
|
|
|
@ -267,7 +267,7 @@ static inline void g2d_hw_reset(struct g2d_data *g2d)
|
||||||
static int g2d_init_cmdlist(struct g2d_data *g2d)
|
static int g2d_init_cmdlist(struct g2d_data *g2d)
|
||||||
{
|
{
|
||||||
struct device *dev = g2d->dev;
|
struct device *dev = g2d->dev;
|
||||||
struct g2d_cmdlist_node *node = g2d->cmdlist_node;
|
struct g2d_cmdlist_node *node;
|
||||||
int nr;
|
int nr;
|
||||||
int ret;
|
int ret;
|
||||||
struct g2d_buf_info *buf_info;
|
struct g2d_buf_info *buf_info;
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
#define GSC_COEF_DEPTH 3
|
#define GSC_COEF_DEPTH 3
|
||||||
#define GSC_AUTOSUSPEND_DELAY 2000
|
#define GSC_AUTOSUSPEND_DELAY 2000
|
||||||
|
|
||||||
#define get_gsc_context(dev) platform_get_drvdata(to_platform_device(dev))
|
#define get_gsc_context(dev) dev_get_drvdata(dev)
|
||||||
#define gsc_read(offset) readl(ctx->regs + (offset))
|
#define gsc_read(offset) readl(ctx->regs + (offset))
|
||||||
#define gsc_write(cfg, offset) writel(cfg, ctx->regs + (offset))
|
#define gsc_write(cfg, offset) writel(cfg, ctx->regs + (offset))
|
||||||
|
|
||||||
|
|
|
@ -94,12 +94,12 @@ static inline int scaler_reset(struct scaler_context *scaler)
|
||||||
scaler_write(SCALER_CFG_SOFT_RESET, SCALER_CFG);
|
scaler_write(SCALER_CFG_SOFT_RESET, SCALER_CFG);
|
||||||
do {
|
do {
|
||||||
cpu_relax();
|
cpu_relax();
|
||||||
} while (retry > 1 &&
|
} while (--retry > 1 &&
|
||||||
scaler_read(SCALER_CFG) & SCALER_CFG_SOFT_RESET);
|
scaler_read(SCALER_CFG) & SCALER_CFG_SOFT_RESET);
|
||||||
do {
|
do {
|
||||||
cpu_relax();
|
cpu_relax();
|
||||||
scaler_write(1, SCALER_INT_EN);
|
scaler_write(1, SCALER_INT_EN);
|
||||||
} while (retry > 0 && scaler_read(SCALER_INT_EN) != 1);
|
} while (--retry > 0 && scaler_read(SCALER_INT_EN) != 1);
|
||||||
|
|
||||||
return retry ? 0 : -EIO;
|
return retry ? 0 : -EIO;
|
||||||
}
|
}
|
||||||
|
|
|
@ -765,7 +765,7 @@ parse_psr(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bdb->version >= 226) {
|
if (bdb->version >= 226) {
|
||||||
u32 wakeup_time = psr_table->psr2_tp2_tp3_wakeup_time;
|
u32 wakeup_time = psr->psr2_tp2_tp3_wakeup_time;
|
||||||
|
|
||||||
wakeup_time = (wakeup_time >> (2 * panel_type)) & 0x3;
|
wakeup_time = (wakeup_time >> (2 * panel_type)) & 0x3;
|
||||||
switch (wakeup_time) {
|
switch (wakeup_time) {
|
||||||
|
|
|
@ -178,6 +178,8 @@ static int icl_get_bw_info(struct drm_i915_private *dev_priv)
|
||||||
clpchgroup = (sa->deburst * deinterleave / num_channels) << i;
|
clpchgroup = (sa->deburst * deinterleave / num_channels) << i;
|
||||||
bi->num_planes = (ipqdepth - clpchgroup) / clpchgroup + 1;
|
bi->num_planes = (ipqdepth - clpchgroup) / clpchgroup + 1;
|
||||||
|
|
||||||
|
bi->num_qgv_points = qi.num_points;
|
||||||
|
|
||||||
for (j = 0; j < qi.num_points; j++) {
|
for (j = 0; j < qi.num_points; j++) {
|
||||||
const struct intel_qgv_point *sp = &qi.points[j];
|
const struct intel_qgv_point *sp = &qi.points[j];
|
||||||
int ct, bw;
|
int ct, bw;
|
||||||
|
@ -195,7 +197,7 @@ static int icl_get_bw_info(struct drm_i915_private *dev_priv)
|
||||||
bi->deratedbw[j] = min(maxdebw,
|
bi->deratedbw[j] = min(maxdebw,
|
||||||
bw * 9 / 10); /* 90% */
|
bw * 9 / 10); /* 90% */
|
||||||
|
|
||||||
DRM_DEBUG_KMS("BW%d / QGV %d: num_planes=%d deratedbw=%d\n",
|
DRM_DEBUG_KMS("BW%d / QGV %d: num_planes=%d deratedbw=%u\n",
|
||||||
i, j, bi->num_planes, bi->deratedbw[j]);
|
i, j, bi->num_planes, bi->deratedbw[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,14 +213,17 @@ static unsigned int icl_max_bw(struct drm_i915_private *dev_priv,
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Did we initialize the bw limits successfully? */
|
|
||||||
if (dev_priv->max_bw[0].num_planes == 0)
|
|
||||||
return UINT_MAX;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(dev_priv->max_bw); i++) {
|
for (i = 0; i < ARRAY_SIZE(dev_priv->max_bw); i++) {
|
||||||
const struct intel_bw_info *bi =
|
const struct intel_bw_info *bi =
|
||||||
&dev_priv->max_bw[i];
|
&dev_priv->max_bw[i];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pcode will not expose all QGV points when
|
||||||
|
* SAGV is forced to off/min/med/max.
|
||||||
|
*/
|
||||||
|
if (qgv_point >= bi->num_qgv_points)
|
||||||
|
return UINT_MAX;
|
||||||
|
|
||||||
if (num_planes >= bi->num_planes)
|
if (num_planes >= bi->num_planes)
|
||||||
return bi->deratedbw[qgv_point];
|
return bi->deratedbw[qgv_point];
|
||||||
}
|
}
|
||||||
|
|
|
@ -2239,6 +2239,17 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
|
||||||
if (crtc_state->has_audio && INTEL_GEN(dev_priv) >= 9)
|
if (crtc_state->has_audio && INTEL_GEN(dev_priv) >= 9)
|
||||||
min_cdclk = max(2 * 96000, min_cdclk);
|
min_cdclk = max(2 * 96000, min_cdclk);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "For DP audio configuration, cdclk frequency shall be set to
|
||||||
|
* meet the following requirements:
|
||||||
|
* DP Link Frequency(MHz) | Cdclk frequency(MHz)
|
||||||
|
* 270 | 320 or higher
|
||||||
|
* 162 | 200 or higher"
|
||||||
|
*/
|
||||||
|
if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
|
||||||
|
intel_crtc_has_dp_encoder(crtc_state) && crtc_state->has_audio)
|
||||||
|
min_cdclk = max(crtc_state->port_clock, min_cdclk);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On Valleyview some DSI panels lose (v|h)sync when the clock is lower
|
* On Valleyview some DSI panels lose (v|h)sync when the clock is lower
|
||||||
* than 320000KHz.
|
* than 320000KHz.
|
||||||
|
|
|
@ -1839,7 +1839,7 @@ static void intel_enable_pipe(const struct intel_crtc_state *new_crtc_state)
|
||||||
/* FIXME: assert CPU port conditions for SNB+ */
|
/* FIXME: assert CPU port conditions for SNB+ */
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_intel_pipe_enable(dev_priv, pipe);
|
trace_intel_pipe_enable(crtc);
|
||||||
|
|
||||||
reg = PIPECONF(cpu_transcoder);
|
reg = PIPECONF(cpu_transcoder);
|
||||||
val = I915_READ(reg);
|
val = I915_READ(reg);
|
||||||
|
@ -1880,7 +1880,7 @@ static void intel_disable_pipe(const struct intel_crtc_state *old_crtc_state)
|
||||||
*/
|
*/
|
||||||
assert_planes_disabled(crtc);
|
assert_planes_disabled(crtc);
|
||||||
|
|
||||||
trace_intel_pipe_disable(dev_priv, pipe);
|
trace_intel_pipe_disable(crtc);
|
||||||
|
|
||||||
reg = PIPECONF(cpu_transcoder);
|
reg = PIPECONF(cpu_transcoder);
|
||||||
val = I915_READ(reg);
|
val = I915_READ(reg);
|
||||||
|
|
|
@ -438,16 +438,23 @@ icl_combo_phy_aux_power_well_disable(struct drm_i915_private *dev_priv,
|
||||||
#define ICL_AUX_PW_TO_CH(pw_idx) \
|
#define ICL_AUX_PW_TO_CH(pw_idx) \
|
||||||
((pw_idx) - ICL_PW_CTL_IDX_AUX_A + AUX_CH_A)
|
((pw_idx) - ICL_PW_CTL_IDX_AUX_A + AUX_CH_A)
|
||||||
|
|
||||||
|
#define ICL_TBT_AUX_PW_TO_CH(pw_idx) \
|
||||||
|
((pw_idx) - ICL_PW_CTL_IDX_AUX_TBT1 + AUX_CH_C)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
icl_tc_phy_aux_power_well_enable(struct drm_i915_private *dev_priv,
|
icl_tc_phy_aux_power_well_enable(struct drm_i915_private *dev_priv,
|
||||||
struct i915_power_well *power_well)
|
struct i915_power_well *power_well)
|
||||||
{
|
{
|
||||||
enum aux_ch aux_ch = ICL_AUX_PW_TO_CH(power_well->desc->hsw.idx);
|
int pw_idx = power_well->desc->hsw.idx;
|
||||||
|
bool is_tbt = power_well->desc->hsw.is_tc_tbt;
|
||||||
|
enum aux_ch aux_ch;
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
|
aux_ch = is_tbt ? ICL_TBT_AUX_PW_TO_CH(pw_idx) :
|
||||||
|
ICL_AUX_PW_TO_CH(pw_idx);
|
||||||
val = I915_READ(DP_AUX_CH_CTL(aux_ch));
|
val = I915_READ(DP_AUX_CH_CTL(aux_ch));
|
||||||
val &= ~DP_AUX_CH_CTL_TBT_IO;
|
val &= ~DP_AUX_CH_CTL_TBT_IO;
|
||||||
if (power_well->desc->hsw.is_tc_tbt)
|
if (is_tbt)
|
||||||
val |= DP_AUX_CH_CTL_TBT_IO;
|
val |= DP_AUX_CH_CTL_TBT_IO;
|
||||||
I915_WRITE(DP_AUX_CH_CTL(aux_ch), val);
|
I915_WRITE(DP_AUX_CH_CTL(aux_ch), val);
|
||||||
|
|
||||||
|
|
|
@ -478,13 +478,13 @@ struct psr_table {
|
||||||
/* TP wake up time in multiple of 100 */
|
/* TP wake up time in multiple of 100 */
|
||||||
u16 tp1_wakeup_time;
|
u16 tp1_wakeup_time;
|
||||||
u16 tp2_tp3_wakeup_time;
|
u16 tp2_tp3_wakeup_time;
|
||||||
|
|
||||||
/* PSR2 TP2/TP3 wakeup time for 16 panels */
|
|
||||||
u32 psr2_tp2_tp3_wakeup_time;
|
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
struct bdb_psr {
|
struct bdb_psr {
|
||||||
struct psr_table psr_table[16];
|
struct psr_table psr_table[16];
|
||||||
|
|
||||||
|
/* PSR2 TP2/TP3 wakeup time for 16 panels */
|
||||||
|
u32 psr2_tp2_tp3_wakeup_time;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -253,14 +253,15 @@ void i915_gem_resume(struct drm_i915_private *i915)
|
||||||
i915_gem_restore_gtt_mappings(i915);
|
i915_gem_restore_gtt_mappings(i915);
|
||||||
i915_gem_restore_fences(i915);
|
i915_gem_restore_fences(i915);
|
||||||
|
|
||||||
|
if (i915_gem_init_hw(i915))
|
||||||
|
goto err_wedged;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* As we didn't flush the kernel context before suspend, we cannot
|
* As we didn't flush the kernel context before suspend, we cannot
|
||||||
* guarantee that the context image is complete. So let's just reset
|
* guarantee that the context image is complete. So let's just reset
|
||||||
* it and start again.
|
* it and start again.
|
||||||
*/
|
*/
|
||||||
intel_gt_resume(i915);
|
if (intel_gt_resume(i915))
|
||||||
|
|
||||||
if (i915_gem_init_hw(i915))
|
|
||||||
goto err_wedged;
|
goto err_wedged;
|
||||||
|
|
||||||
intel_uc_resume(i915);
|
intel_uc_resume(i915);
|
||||||
|
|
|
@ -664,7 +664,15 @@ i915_gem_userptr_put_pages(struct drm_i915_gem_object *obj,
|
||||||
|
|
||||||
for_each_sgt_page(page, sgt_iter, pages) {
|
for_each_sgt_page(page, sgt_iter, pages) {
|
||||||
if (obj->mm.dirty)
|
if (obj->mm.dirty)
|
||||||
set_page_dirty(page);
|
/*
|
||||||
|
* As this may not be anonymous memory (e.g. shmem)
|
||||||
|
* but exist on a real mapping, we have to lock
|
||||||
|
* the page in order to dirty it -- holding
|
||||||
|
* the page reference is not sufficient to
|
||||||
|
* prevent the inode from being truncated.
|
||||||
|
* Play safe and take the lock.
|
||||||
|
*/
|
||||||
|
set_page_dirty_lock(page);
|
||||||
|
|
||||||
mark_page_accessed(page);
|
mark_page_accessed(page);
|
||||||
put_page(page);
|
put_page(page);
|
||||||
|
|
|
@ -126,6 +126,7 @@ static void intel_context_retire(struct i915_active *active)
|
||||||
if (ce->state)
|
if (ce->state)
|
||||||
__context_unpin_state(ce->state);
|
__context_unpin_state(ce->state);
|
||||||
|
|
||||||
|
intel_ring_unpin(ce->ring);
|
||||||
intel_context_put(ce);
|
intel_context_put(ce);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,27 +161,35 @@ int intel_context_active_acquire(struct intel_context *ce, unsigned long flags)
|
||||||
|
|
||||||
intel_context_get(ce);
|
intel_context_get(ce);
|
||||||
|
|
||||||
|
err = intel_ring_pin(ce->ring);
|
||||||
|
if (err)
|
||||||
|
goto err_put;
|
||||||
|
|
||||||
if (!ce->state)
|
if (!ce->state)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err = __context_pin_state(ce->state, flags);
|
err = __context_pin_state(ce->state, flags);
|
||||||
if (err) {
|
if (err)
|
||||||
i915_active_cancel(&ce->active);
|
goto err_ring;
|
||||||
intel_context_put(ce);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Preallocate tracking nodes */
|
/* Preallocate tracking nodes */
|
||||||
if (!i915_gem_context_is_kernel(ce->gem_context)) {
|
if (!i915_gem_context_is_kernel(ce->gem_context)) {
|
||||||
err = i915_active_acquire_preallocate_barrier(&ce->active,
|
err = i915_active_acquire_preallocate_barrier(&ce->active,
|
||||||
ce->engine);
|
ce->engine);
|
||||||
if (err) {
|
if (err)
|
||||||
i915_active_release(&ce->active);
|
goto err_state;
|
||||||
return err;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_state:
|
||||||
|
__context_unpin_state(ce->state);
|
||||||
|
err_ring:
|
||||||
|
intel_ring_unpin(ce->ring);
|
||||||
|
err_put:
|
||||||
|
intel_context_put(ce);
|
||||||
|
i915_active_cancel(&ce->active);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
void intel_context_active_release(struct intel_context *ce)
|
void intel_context_active_release(struct intel_context *ce)
|
||||||
|
|
|
@ -969,9 +969,14 @@ const char *i915_cache_level_str(struct drm_i915_private *i915, int type)
|
||||||
u32 intel_calculate_mcr_s_ss_select(struct drm_i915_private *dev_priv)
|
u32 intel_calculate_mcr_s_ss_select(struct drm_i915_private *dev_priv)
|
||||||
{
|
{
|
||||||
const struct sseu_dev_info *sseu = &RUNTIME_INFO(dev_priv)->sseu;
|
const struct sseu_dev_info *sseu = &RUNTIME_INFO(dev_priv)->sseu;
|
||||||
|
unsigned int slice = fls(sseu->slice_mask) - 1;
|
||||||
|
unsigned int subslice;
|
||||||
u32 mcr_s_ss_select;
|
u32 mcr_s_ss_select;
|
||||||
u32 slice = fls(sseu->slice_mask);
|
|
||||||
u32 subslice = fls(sseu->subslice_mask[slice]);
|
GEM_BUG_ON(slice >= ARRAY_SIZE(sseu->subslice_mask));
|
||||||
|
subslice = fls(sseu->subslice_mask[slice]);
|
||||||
|
GEM_BUG_ON(!subslice);
|
||||||
|
subslice--;
|
||||||
|
|
||||||
if (IS_GEN(dev_priv, 10))
|
if (IS_GEN(dev_priv, 10))
|
||||||
mcr_s_ss_select = GEN8_MCR_SLICE(slice) |
|
mcr_s_ss_select = GEN8_MCR_SLICE(slice) |
|
||||||
|
@ -1471,6 +1476,7 @@ void intel_engine_dump(struct intel_engine_cs *engine,
|
||||||
struct i915_gpu_error * const error = &engine->i915->gpu_error;
|
struct i915_gpu_error * const error = &engine->i915->gpu_error;
|
||||||
struct i915_request *rq;
|
struct i915_request *rq;
|
||||||
intel_wakeref_t wakeref;
|
intel_wakeref_t wakeref;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
if (header) {
|
if (header) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
@ -1490,10 +1496,9 @@ void intel_engine_dump(struct intel_engine_cs *engine,
|
||||||
i915_reset_engine_count(error, engine),
|
i915_reset_engine_count(error, engine),
|
||||||
i915_reset_count(error));
|
i915_reset_count(error));
|
||||||
|
|
||||||
rcu_read_lock();
|
|
||||||
|
|
||||||
drm_printf(m, "\tRequests:\n");
|
drm_printf(m, "\tRequests:\n");
|
||||||
|
|
||||||
|
spin_lock_irqsave(&engine->active.lock, flags);
|
||||||
rq = intel_engine_find_active_request(engine);
|
rq = intel_engine_find_active_request(engine);
|
||||||
if (rq) {
|
if (rq) {
|
||||||
print_request(m, rq, "\t\tactive ");
|
print_request(m, rq, "\t\tactive ");
|
||||||
|
@ -1513,8 +1518,7 @@ void intel_engine_dump(struct intel_engine_cs *engine,
|
||||||
|
|
||||||
print_request_ring(m, rq);
|
print_request_ring(m, rq);
|
||||||
}
|
}
|
||||||
|
spin_unlock_irqrestore(&engine->active.lock, flags);
|
||||||
rcu_read_unlock();
|
|
||||||
|
|
||||||
wakeref = intel_runtime_pm_get_if_in_use(&engine->i915->runtime_pm);
|
wakeref = intel_runtime_pm_get_if_in_use(&engine->i915->runtime_pm);
|
||||||
if (wakeref) {
|
if (wakeref) {
|
||||||
|
@ -1672,7 +1676,6 @@ struct i915_request *
|
||||||
intel_engine_find_active_request(struct intel_engine_cs *engine)
|
intel_engine_find_active_request(struct intel_engine_cs *engine)
|
||||||
{
|
{
|
||||||
struct i915_request *request, *active = NULL;
|
struct i915_request *request, *active = NULL;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We are called by the error capture, reset and to dump engine
|
* We are called by the error capture, reset and to dump engine
|
||||||
|
@ -1685,7 +1688,7 @@ intel_engine_find_active_request(struct intel_engine_cs *engine)
|
||||||
* At all other times, we must assume the GPU is still running, but
|
* At all other times, we must assume the GPU is still running, but
|
||||||
* we only care about the snapshot of this moment.
|
* we only care about the snapshot of this moment.
|
||||||
*/
|
*/
|
||||||
spin_lock_irqsave(&engine->active.lock, flags);
|
lockdep_assert_held(&engine->active.lock);
|
||||||
list_for_each_entry(request, &engine->active.requests, sched.link) {
|
list_for_each_entry(request, &engine->active.requests, sched.link) {
|
||||||
if (i915_request_completed(request))
|
if (i915_request_completed(request))
|
||||||
continue;
|
continue;
|
||||||
|
@ -1700,7 +1703,6 @@ intel_engine_find_active_request(struct intel_engine_cs *engine)
|
||||||
active = request;
|
active = request;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&engine->active.lock, flags);
|
|
||||||
|
|
||||||
return active;
|
return active;
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,27 +142,3 @@ void intel_engine_init__pm(struct intel_engine_cs *engine)
|
||||||
{
|
{
|
||||||
intel_wakeref_init(&engine->wakeref);
|
intel_wakeref_init(&engine->wakeref);
|
||||||
}
|
}
|
||||||
|
|
||||||
int intel_engines_resume(struct drm_i915_private *i915)
|
|
||||||
{
|
|
||||||
struct intel_engine_cs *engine;
|
|
||||||
enum intel_engine_id id;
|
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
intel_gt_pm_get(i915);
|
|
||||||
for_each_engine(engine, i915, id) {
|
|
||||||
intel_engine_pm_get(engine);
|
|
||||||
engine->serial++; /* kernel context lost */
|
|
||||||
err = engine->resume(engine);
|
|
||||||
intel_engine_pm_put(engine);
|
|
||||||
if (err) {
|
|
||||||
dev_err(i915->drm.dev,
|
|
||||||
"Failed to restart %s (%d)\n",
|
|
||||||
engine->name, err);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
intel_gt_pm_put(i915);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,16 +7,22 @@
|
||||||
#ifndef INTEL_ENGINE_PM_H
|
#ifndef INTEL_ENGINE_PM_H
|
||||||
#define INTEL_ENGINE_PM_H
|
#define INTEL_ENGINE_PM_H
|
||||||
|
|
||||||
|
#include "intel_engine_types.h"
|
||||||
|
#include "intel_wakeref.h"
|
||||||
|
|
||||||
struct drm_i915_private;
|
struct drm_i915_private;
|
||||||
struct intel_engine_cs;
|
|
||||||
|
|
||||||
void intel_engine_pm_get(struct intel_engine_cs *engine);
|
void intel_engine_pm_get(struct intel_engine_cs *engine);
|
||||||
void intel_engine_pm_put(struct intel_engine_cs *engine);
|
void intel_engine_pm_put(struct intel_engine_cs *engine);
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
intel_engine_pm_get_if_awake(struct intel_engine_cs *engine)
|
||||||
|
{
|
||||||
|
return intel_wakeref_get_if_active(&engine->wakeref);
|
||||||
|
}
|
||||||
|
|
||||||
void intel_engine_park(struct intel_engine_cs *engine);
|
void intel_engine_park(struct intel_engine_cs *engine);
|
||||||
|
|
||||||
void intel_engine_init__pm(struct intel_engine_cs *engine);
|
void intel_engine_init__pm(struct intel_engine_cs *engine);
|
||||||
|
|
||||||
int intel_engines_resume(struct drm_i915_private *i915);
|
|
||||||
|
|
||||||
#endif /* INTEL_ENGINE_PM_H */
|
#endif /* INTEL_ENGINE_PM_H */
|
||||||
|
|
|
@ -70,6 +70,18 @@ struct intel_ring {
|
||||||
struct list_head request_list;
|
struct list_head request_list;
|
||||||
struct list_head active_link;
|
struct list_head active_link;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As we have two types of rings, one global to the engine used
|
||||||
|
* by ringbuffer submission and those that are exclusive to a
|
||||||
|
* context used by execlists, we have to play safe and allow
|
||||||
|
* atomic updates to the pin_count. However, the actual pinning
|
||||||
|
* of the context is either done during initialisation for
|
||||||
|
* ringbuffer submission or serialised as part of the context
|
||||||
|
* pinning for execlists, and so we do not need a mutex ourselves
|
||||||
|
* to serialise intel_ring_pin/intel_ring_unpin.
|
||||||
|
*/
|
||||||
|
atomic_t pin_count;
|
||||||
|
|
||||||
u32 head;
|
u32 head;
|
||||||
u32 tail;
|
u32 tail;
|
||||||
u32 emit;
|
u32 emit;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "i915_drv.h"
|
#include "i915_drv.h"
|
||||||
|
#include "intel_engine_pm.h"
|
||||||
#include "intel_gt_pm.h"
|
#include "intel_gt_pm.h"
|
||||||
#include "intel_pm.h"
|
#include "intel_pm.h"
|
||||||
#include "intel_wakeref.h"
|
#include "intel_wakeref.h"
|
||||||
|
@ -118,10 +119,11 @@ void intel_gt_sanitize(struct drm_i915_private *i915, bool force)
|
||||||
intel_engine_reset(engine, false);
|
intel_engine_reset(engine, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void intel_gt_resume(struct drm_i915_private *i915)
|
int intel_gt_resume(struct drm_i915_private *i915)
|
||||||
{
|
{
|
||||||
struct intel_engine_cs *engine;
|
struct intel_engine_cs *engine;
|
||||||
enum intel_engine_id id;
|
enum intel_engine_id id;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* After resume, we may need to poke into the pinned kernel
|
* After resume, we may need to poke into the pinned kernel
|
||||||
|
@ -129,9 +131,12 @@ void intel_gt_resume(struct drm_i915_private *i915)
|
||||||
* Only the kernel contexts should remain pinned over suspend,
|
* Only the kernel contexts should remain pinned over suspend,
|
||||||
* allowing us to fixup the user contexts on their first pin.
|
* allowing us to fixup the user contexts on their first pin.
|
||||||
*/
|
*/
|
||||||
|
intel_gt_pm_get(i915);
|
||||||
for_each_engine(engine, i915, id) {
|
for_each_engine(engine, i915, id) {
|
||||||
struct intel_context *ce;
|
struct intel_context *ce;
|
||||||
|
|
||||||
|
intel_engine_pm_get(engine);
|
||||||
|
|
||||||
ce = engine->kernel_context;
|
ce = engine->kernel_context;
|
||||||
if (ce)
|
if (ce)
|
||||||
ce->ops->reset(ce);
|
ce->ops->reset(ce);
|
||||||
|
@ -139,5 +144,19 @@ void intel_gt_resume(struct drm_i915_private *i915)
|
||||||
ce = engine->preempt_context;
|
ce = engine->preempt_context;
|
||||||
if (ce)
|
if (ce)
|
||||||
ce->ops->reset(ce);
|
ce->ops->reset(ce);
|
||||||
|
|
||||||
|
engine->serial++; /* kernel context lost */
|
||||||
|
err = engine->resume(engine);
|
||||||
|
|
||||||
|
intel_engine_pm_put(engine);
|
||||||
|
if (err) {
|
||||||
|
dev_err(i915->drm.dev,
|
||||||
|
"Failed to restart %s (%d)\n",
|
||||||
|
engine->name, err);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
intel_gt_pm_put(i915);
|
||||||
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,6 @@ void intel_gt_pm_put(struct drm_i915_private *i915);
|
||||||
void intel_gt_pm_init(struct drm_i915_private *i915);
|
void intel_gt_pm_init(struct drm_i915_private *i915);
|
||||||
|
|
||||||
void intel_gt_sanitize(struct drm_i915_private *i915, bool force);
|
void intel_gt_sanitize(struct drm_i915_private *i915, bool force);
|
||||||
void intel_gt_resume(struct drm_i915_private *i915);
|
int intel_gt_resume(struct drm_i915_private *i915);
|
||||||
|
|
||||||
#endif /* INTEL_GT_PM_H */
|
#endif /* INTEL_GT_PM_H */
|
||||||
|
|
|
@ -1414,6 +1414,7 @@ static void execlists_context_destroy(struct kref *kref)
|
||||||
{
|
{
|
||||||
struct intel_context *ce = container_of(kref, typeof(*ce), ref);
|
struct intel_context *ce = container_of(kref, typeof(*ce), ref);
|
||||||
|
|
||||||
|
GEM_BUG_ON(!i915_active_is_idle(&ce->active));
|
||||||
GEM_BUG_ON(intel_context_is_pinned(ce));
|
GEM_BUG_ON(intel_context_is_pinned(ce));
|
||||||
|
|
||||||
if (ce->state)
|
if (ce->state)
|
||||||
|
@ -1426,7 +1427,6 @@ static void execlists_context_unpin(struct intel_context *ce)
|
||||||
{
|
{
|
||||||
i915_gem_context_unpin_hw_id(ce->gem_context);
|
i915_gem_context_unpin_hw_id(ce->gem_context);
|
||||||
i915_gem_object_unpin_map(ce->state->obj);
|
i915_gem_object_unpin_map(ce->state->obj);
|
||||||
intel_ring_unpin(ce->ring);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1478,13 +1478,9 @@ __execlists_context_pin(struct intel_context *ce,
|
||||||
goto unpin_active;
|
goto unpin_active;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = intel_ring_pin(ce->ring);
|
|
||||||
if (ret)
|
|
||||||
goto unpin_map;
|
|
||||||
|
|
||||||
ret = i915_gem_context_pin_hw_id(ce->gem_context);
|
ret = i915_gem_context_pin_hw_id(ce->gem_context);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto unpin_ring;
|
goto unpin_map;
|
||||||
|
|
||||||
ce->lrc_desc = lrc_descriptor(ce, engine);
|
ce->lrc_desc = lrc_descriptor(ce, engine);
|
||||||
ce->lrc_reg_state = vaddr + LRC_STATE_PN * PAGE_SIZE;
|
ce->lrc_reg_state = vaddr + LRC_STATE_PN * PAGE_SIZE;
|
||||||
|
@ -1492,8 +1488,6 @@ __execlists_context_pin(struct intel_context *ce,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unpin_ring:
|
|
||||||
intel_ring_unpin(ce->ring);
|
|
||||||
unpin_map:
|
unpin_map:
|
||||||
i915_gem_object_unpin_map(ce->state->obj);
|
i915_gem_object_unpin_map(ce->state->obj);
|
||||||
unpin_active:
|
unpin_active:
|
||||||
|
|
|
@ -687,7 +687,6 @@ static void reset_prepare_engine(struct intel_engine_cs *engine)
|
||||||
* written to the powercontext is undefined and so we may lose
|
* written to the powercontext is undefined and so we may lose
|
||||||
* GPU state upon resume, i.e. fail to restart after a reset.
|
* GPU state upon resume, i.e. fail to restart after a reset.
|
||||||
*/
|
*/
|
||||||
intel_engine_pm_get(engine);
|
|
||||||
intel_uncore_forcewake_get(engine->uncore, FORCEWAKE_ALL);
|
intel_uncore_forcewake_get(engine->uncore, FORCEWAKE_ALL);
|
||||||
engine->reset.prepare(engine);
|
engine->reset.prepare(engine);
|
||||||
}
|
}
|
||||||
|
@ -718,16 +717,21 @@ static void revoke_mmaps(struct drm_i915_private *i915)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reset_prepare(struct drm_i915_private *i915)
|
static intel_engine_mask_t reset_prepare(struct drm_i915_private *i915)
|
||||||
{
|
{
|
||||||
struct intel_engine_cs *engine;
|
struct intel_engine_cs *engine;
|
||||||
|
intel_engine_mask_t awake = 0;
|
||||||
enum intel_engine_id id;
|
enum intel_engine_id id;
|
||||||
|
|
||||||
intel_gt_pm_get(i915);
|
for_each_engine(engine, i915, id) {
|
||||||
for_each_engine(engine, i915, id)
|
if (intel_engine_pm_get_if_awake(engine))
|
||||||
|
awake |= engine->mask;
|
||||||
reset_prepare_engine(engine);
|
reset_prepare_engine(engine);
|
||||||
|
}
|
||||||
|
|
||||||
intel_uc_reset_prepare(i915);
|
intel_uc_reset_prepare(i915);
|
||||||
|
|
||||||
|
return awake;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gt_revoke(struct drm_i915_private *i915)
|
static void gt_revoke(struct drm_i915_private *i915)
|
||||||
|
@ -761,20 +765,22 @@ static int gt_reset(struct drm_i915_private *i915,
|
||||||
static void reset_finish_engine(struct intel_engine_cs *engine)
|
static void reset_finish_engine(struct intel_engine_cs *engine)
|
||||||
{
|
{
|
||||||
engine->reset.finish(engine);
|
engine->reset.finish(engine);
|
||||||
intel_engine_pm_put(engine);
|
|
||||||
intel_uncore_forcewake_put(engine->uncore, FORCEWAKE_ALL);
|
intel_uncore_forcewake_put(engine->uncore, FORCEWAKE_ALL);
|
||||||
|
|
||||||
|
intel_engine_signal_breadcrumbs(engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reset_finish(struct drm_i915_private *i915)
|
static void reset_finish(struct drm_i915_private *i915,
|
||||||
|
intel_engine_mask_t awake)
|
||||||
{
|
{
|
||||||
struct intel_engine_cs *engine;
|
struct intel_engine_cs *engine;
|
||||||
enum intel_engine_id id;
|
enum intel_engine_id id;
|
||||||
|
|
||||||
for_each_engine(engine, i915, id) {
|
for_each_engine(engine, i915, id) {
|
||||||
reset_finish_engine(engine);
|
reset_finish_engine(engine);
|
||||||
intel_engine_signal_breadcrumbs(engine);
|
if (awake & engine->mask)
|
||||||
|
intel_engine_pm_put(engine);
|
||||||
}
|
}
|
||||||
intel_gt_pm_put(i915);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nop_submit_request(struct i915_request *request)
|
static void nop_submit_request(struct i915_request *request)
|
||||||
|
@ -798,6 +804,7 @@ static void __i915_gem_set_wedged(struct drm_i915_private *i915)
|
||||||
{
|
{
|
||||||
struct i915_gpu_error *error = &i915->gpu_error;
|
struct i915_gpu_error *error = &i915->gpu_error;
|
||||||
struct intel_engine_cs *engine;
|
struct intel_engine_cs *engine;
|
||||||
|
intel_engine_mask_t awake;
|
||||||
enum intel_engine_id id;
|
enum intel_engine_id id;
|
||||||
|
|
||||||
if (test_bit(I915_WEDGED, &error->flags))
|
if (test_bit(I915_WEDGED, &error->flags))
|
||||||
|
@ -817,7 +824,7 @@ static void __i915_gem_set_wedged(struct drm_i915_private *i915)
|
||||||
* rolling the global seqno forward (since this would complete requests
|
* rolling the global seqno forward (since this would complete requests
|
||||||
* for which we haven't set the fence error to EIO yet).
|
* for which we haven't set the fence error to EIO yet).
|
||||||
*/
|
*/
|
||||||
reset_prepare(i915);
|
awake = reset_prepare(i915);
|
||||||
|
|
||||||
/* Even if the GPU reset fails, it should still stop the engines */
|
/* Even if the GPU reset fails, it should still stop the engines */
|
||||||
if (!INTEL_INFO(i915)->gpu_reset_clobbers_display)
|
if (!INTEL_INFO(i915)->gpu_reset_clobbers_display)
|
||||||
|
@ -841,7 +848,7 @@ static void __i915_gem_set_wedged(struct drm_i915_private *i915)
|
||||||
for_each_engine(engine, i915, id)
|
for_each_engine(engine, i915, id)
|
||||||
engine->cancel_requests(engine);
|
engine->cancel_requests(engine);
|
||||||
|
|
||||||
reset_finish(i915);
|
reset_finish(i915, awake);
|
||||||
|
|
||||||
GEM_TRACE("end\n");
|
GEM_TRACE("end\n");
|
||||||
}
|
}
|
||||||
|
@ -951,6 +958,21 @@ static int do_reset(struct drm_i915_private *i915,
|
||||||
return gt_reset(i915, stalled_mask);
|
return gt_reset(i915, stalled_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int resume(struct drm_i915_private *i915)
|
||||||
|
{
|
||||||
|
struct intel_engine_cs *engine;
|
||||||
|
enum intel_engine_id id;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
for_each_engine(engine, i915, id) {
|
||||||
|
ret = engine->resume(engine);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* i915_reset - reset chip after a hang
|
* i915_reset - reset chip after a hang
|
||||||
* @i915: #drm_i915_private to reset
|
* @i915: #drm_i915_private to reset
|
||||||
|
@ -973,6 +995,7 @@ void i915_reset(struct drm_i915_private *i915,
|
||||||
const char *reason)
|
const char *reason)
|
||||||
{
|
{
|
||||||
struct i915_gpu_error *error = &i915->gpu_error;
|
struct i915_gpu_error *error = &i915->gpu_error;
|
||||||
|
intel_engine_mask_t awake;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
GEM_TRACE("flags=%lx\n", error->flags);
|
GEM_TRACE("flags=%lx\n", error->flags);
|
||||||
|
@ -989,7 +1012,7 @@ void i915_reset(struct drm_i915_private *i915,
|
||||||
dev_notice(i915->drm.dev, "Resetting chip for %s\n", reason);
|
dev_notice(i915->drm.dev, "Resetting chip for %s\n", reason);
|
||||||
error->reset_count++;
|
error->reset_count++;
|
||||||
|
|
||||||
reset_prepare(i915);
|
awake = reset_prepare(i915);
|
||||||
|
|
||||||
if (!intel_has_gpu_reset(i915)) {
|
if (!intel_has_gpu_reset(i915)) {
|
||||||
if (i915_modparams.reset)
|
if (i915_modparams.reset)
|
||||||
|
@ -1024,13 +1047,17 @@ void i915_reset(struct drm_i915_private *i915,
|
||||||
if (ret) {
|
if (ret) {
|
||||||
DRM_ERROR("Failed to initialise HW following reset (%d)\n",
|
DRM_ERROR("Failed to initialise HW following reset (%d)\n",
|
||||||
ret);
|
ret);
|
||||||
goto error;
|
goto taint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = resume(i915);
|
||||||
|
if (ret)
|
||||||
|
goto taint;
|
||||||
|
|
||||||
i915_queue_hangcheck(i915);
|
i915_queue_hangcheck(i915);
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
reset_finish(i915);
|
reset_finish(i915, awake);
|
||||||
unlock:
|
unlock:
|
||||||
mutex_unlock(&error->wedge_mutex);
|
mutex_unlock(&error->wedge_mutex);
|
||||||
return;
|
return;
|
||||||
|
@ -1081,7 +1108,7 @@ int i915_reset_engine(struct intel_engine_cs *engine, const char *msg)
|
||||||
GEM_TRACE("%s flags=%lx\n", engine->name, error->flags);
|
GEM_TRACE("%s flags=%lx\n", engine->name, error->flags);
|
||||||
GEM_BUG_ON(!test_bit(I915_RESET_ENGINE + engine->id, &error->flags));
|
GEM_BUG_ON(!test_bit(I915_RESET_ENGINE + engine->id, &error->flags));
|
||||||
|
|
||||||
if (!intel_wakeref_active(&engine->wakeref))
|
if (!intel_engine_pm_get_if_awake(engine))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
reset_prepare_engine(engine);
|
reset_prepare_engine(engine);
|
||||||
|
@ -1116,12 +1143,11 @@ int i915_reset_engine(struct intel_engine_cs *engine, const char *msg)
|
||||||
* process to program RING_MODE, HWSP and re-enable submission.
|
* process to program RING_MODE, HWSP and re-enable submission.
|
||||||
*/
|
*/
|
||||||
ret = engine->resume(engine);
|
ret = engine->resume(engine);
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
intel_engine_cancel_stop_cs(engine);
|
intel_engine_cancel_stop_cs(engine);
|
||||||
reset_finish_engine(engine);
|
reset_finish_engine(engine);
|
||||||
|
intel_engine_pm_put(engine);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1149,16 +1149,16 @@ i915_emit_bb_start(struct i915_request *rq,
|
||||||
int intel_ring_pin(struct intel_ring *ring)
|
int intel_ring_pin(struct intel_ring *ring)
|
||||||
{
|
{
|
||||||
struct i915_vma *vma = ring->vma;
|
struct i915_vma *vma = ring->vma;
|
||||||
enum i915_map_type map = i915_coherent_map_type(vma->vm->i915);
|
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
void *addr;
|
void *addr;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
GEM_BUG_ON(ring->vaddr);
|
if (atomic_fetch_inc(&ring->pin_count))
|
||||||
|
return 0;
|
||||||
|
|
||||||
ret = i915_timeline_pin(ring->timeline);
|
ret = i915_timeline_pin(ring->timeline);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto err_unpin;
|
||||||
|
|
||||||
flags = PIN_GLOBAL;
|
flags = PIN_GLOBAL;
|
||||||
|
|
||||||
|
@ -1172,26 +1172,31 @@ int intel_ring_pin(struct intel_ring *ring)
|
||||||
|
|
||||||
ret = i915_vma_pin(vma, 0, 0, flags);
|
ret = i915_vma_pin(vma, 0, 0, flags);
|
||||||
if (unlikely(ret))
|
if (unlikely(ret))
|
||||||
goto unpin_timeline;
|
goto err_timeline;
|
||||||
|
|
||||||
if (i915_vma_is_map_and_fenceable(vma))
|
if (i915_vma_is_map_and_fenceable(vma))
|
||||||
addr = (void __force *)i915_vma_pin_iomap(vma);
|
addr = (void __force *)i915_vma_pin_iomap(vma);
|
||||||
else
|
else
|
||||||
addr = i915_gem_object_pin_map(vma->obj, map);
|
addr = i915_gem_object_pin_map(vma->obj,
|
||||||
|
i915_coherent_map_type(vma->vm->i915));
|
||||||
if (IS_ERR(addr)) {
|
if (IS_ERR(addr)) {
|
||||||
ret = PTR_ERR(addr);
|
ret = PTR_ERR(addr);
|
||||||
goto unpin_ring;
|
goto err_ring;
|
||||||
}
|
}
|
||||||
|
|
||||||
vma->obj->pin_global++;
|
vma->obj->pin_global++;
|
||||||
|
|
||||||
|
GEM_BUG_ON(ring->vaddr);
|
||||||
ring->vaddr = addr;
|
ring->vaddr = addr;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unpin_ring:
|
err_ring:
|
||||||
i915_vma_unpin(vma);
|
i915_vma_unpin(vma);
|
||||||
unpin_timeline:
|
err_timeline:
|
||||||
i915_timeline_unpin(ring->timeline);
|
i915_timeline_unpin(ring->timeline);
|
||||||
|
err_unpin:
|
||||||
|
atomic_dec(&ring->pin_count);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1207,16 +1212,19 @@ void intel_ring_reset(struct intel_ring *ring, u32 tail)
|
||||||
|
|
||||||
void intel_ring_unpin(struct intel_ring *ring)
|
void intel_ring_unpin(struct intel_ring *ring)
|
||||||
{
|
{
|
||||||
GEM_BUG_ON(!ring->vma);
|
if (!atomic_dec_and_test(&ring->pin_count))
|
||||||
GEM_BUG_ON(!ring->vaddr);
|
return;
|
||||||
|
|
||||||
/* Discard any unused bytes beyond that submitted to hw. */
|
/* Discard any unused bytes beyond that submitted to hw. */
|
||||||
intel_ring_reset(ring, ring->tail);
|
intel_ring_reset(ring, ring->tail);
|
||||||
|
|
||||||
|
GEM_BUG_ON(!ring->vma);
|
||||||
if (i915_vma_is_map_and_fenceable(ring->vma))
|
if (i915_vma_is_map_and_fenceable(ring->vma))
|
||||||
i915_vma_unpin_iomap(ring->vma);
|
i915_vma_unpin_iomap(ring->vma);
|
||||||
else
|
else
|
||||||
i915_gem_object_unpin_map(ring->vma->obj);
|
i915_gem_object_unpin_map(ring->vma->obj);
|
||||||
|
|
||||||
|
GEM_BUG_ON(!ring->vaddr);
|
||||||
ring->vaddr = NULL;
|
ring->vaddr = NULL;
|
||||||
|
|
||||||
ring->vma->obj->pin_global--;
|
ring->vma->obj->pin_global--;
|
||||||
|
@ -2081,10 +2089,11 @@ static void ring_destroy(struct intel_engine_cs *engine)
|
||||||
WARN_ON(INTEL_GEN(dev_priv) > 2 &&
|
WARN_ON(INTEL_GEN(dev_priv) > 2 &&
|
||||||
(ENGINE_READ(engine, RING_MI_MODE) & MODE_IDLE) == 0);
|
(ENGINE_READ(engine, RING_MI_MODE) & MODE_IDLE) == 0);
|
||||||
|
|
||||||
|
intel_engine_cleanup_common(engine);
|
||||||
|
|
||||||
intel_ring_unpin(engine->buffer);
|
intel_ring_unpin(engine->buffer);
|
||||||
intel_ring_put(engine->buffer);
|
intel_ring_put(engine->buffer);
|
||||||
|
|
||||||
intel_engine_cleanup_common(engine);
|
|
||||||
kfree(engine);
|
kfree(engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1098,10 +1098,25 @@ static void glk_whitelist_build(struct intel_engine_cs *engine)
|
||||||
|
|
||||||
static void cfl_whitelist_build(struct intel_engine_cs *engine)
|
static void cfl_whitelist_build(struct intel_engine_cs *engine)
|
||||||
{
|
{
|
||||||
|
struct i915_wa_list *w = &engine->whitelist;
|
||||||
|
|
||||||
if (engine->class != RENDER_CLASS)
|
if (engine->class != RENDER_CLASS)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gen9_whitelist_build(&engine->whitelist);
|
gen9_whitelist_build(w);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WaAllowPMDepthAndInvocationCountAccessFromUMD:cfl,whl,cml,aml
|
||||||
|
*
|
||||||
|
* This covers 4 register which are next to one another :
|
||||||
|
* - PS_INVOCATION_COUNT
|
||||||
|
* - PS_INVOCATION_COUNT_UDW
|
||||||
|
* - PS_DEPTH_COUNT
|
||||||
|
* - PS_DEPTH_COUNT_UDW
|
||||||
|
*/
|
||||||
|
whitelist_reg_ext(w, PS_INVOCATION_COUNT,
|
||||||
|
RING_FORCE_TO_NONPRIV_RD |
|
||||||
|
RING_FORCE_TO_NONPRIV_RANGE_4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cnl_whitelist_build(struct intel_engine_cs *engine)
|
static void cnl_whitelist_build(struct intel_engine_cs *engine)
|
||||||
|
@ -1129,6 +1144,19 @@ static void icl_whitelist_build(struct intel_engine_cs *engine)
|
||||||
|
|
||||||
/* WaEnableStateCacheRedirectToCS:icl */
|
/* WaEnableStateCacheRedirectToCS:icl */
|
||||||
whitelist_reg(w, GEN9_SLICE_COMMON_ECO_CHICKEN1);
|
whitelist_reg(w, GEN9_SLICE_COMMON_ECO_CHICKEN1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WaAllowPMDepthAndInvocationCountAccessFromUMD:icl
|
||||||
|
*
|
||||||
|
* This covers 4 register which are next to one another :
|
||||||
|
* - PS_INVOCATION_COUNT
|
||||||
|
* - PS_INVOCATION_COUNT_UDW
|
||||||
|
* - PS_DEPTH_COUNT
|
||||||
|
* - PS_DEPTH_COUNT_UDW
|
||||||
|
*/
|
||||||
|
whitelist_reg_ext(w, PS_INVOCATION_COUNT,
|
||||||
|
RING_FORCE_TO_NONPRIV_RD |
|
||||||
|
RING_FORCE_TO_NONPRIV_RANGE_4);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIDEO_DECODE_CLASS:
|
case VIDEO_DECODE_CLASS:
|
||||||
|
@ -1258,8 +1286,12 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
|
||||||
if (IS_ICL_REVID(i915, ICL_REVID_A0, ICL_REVID_B0))
|
if (IS_ICL_REVID(i915, ICL_REVID_A0, ICL_REVID_B0))
|
||||||
wa_write_or(wal,
|
wa_write_or(wal,
|
||||||
GEN7_SARCHKMD,
|
GEN7_SARCHKMD,
|
||||||
GEN7_DISABLE_DEMAND_PREFETCH |
|
GEN7_DISABLE_DEMAND_PREFETCH);
|
||||||
GEN7_DISABLE_SAMPLER_PREFETCH);
|
|
||||||
|
/* Wa_1606682166:icl */
|
||||||
|
wa_write_or(wal,
|
||||||
|
GEN7_SARCHKMD,
|
||||||
|
GEN7_DISABLE_SAMPLER_PREFETCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_GEN_RANGE(i915, 9, 11)) {
|
if (IS_GEN_RANGE(i915, 9, 11)) {
|
||||||
|
|
|
@ -66,6 +66,7 @@ static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
|
||||||
ring->base.effective_size = sz;
|
ring->base.effective_size = sz;
|
||||||
ring->base.vaddr = (void *)(ring + 1);
|
ring->base.vaddr = (void *)(ring + 1);
|
||||||
ring->base.timeline = &ring->timeline;
|
ring->base.timeline = &ring->timeline;
|
||||||
|
atomic_set(&ring->base.pin_count, 1);
|
||||||
|
|
||||||
INIT_LIST_HEAD(&ring->base.request_list);
|
INIT_LIST_HEAD(&ring->base.request_list);
|
||||||
intel_ring_update_space(&ring->base);
|
intel_ring_update_space(&ring->base);
|
||||||
|
|
|
@ -71,13 +71,16 @@ static int igt_atomic_reset(void *arg)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
for (p = igt_atomic_phases; p->name; p++) {
|
for (p = igt_atomic_phases; p->name; p++) {
|
||||||
|
intel_engine_mask_t awake;
|
||||||
|
|
||||||
GEM_TRACE("intel_gpu_reset under %s\n", p->name);
|
GEM_TRACE("intel_gpu_reset under %s\n", p->name);
|
||||||
|
|
||||||
|
awake = reset_prepare(i915);
|
||||||
p->critical_section_begin();
|
p->critical_section_begin();
|
||||||
reset_prepare(i915);
|
reset_prepare(i915);
|
||||||
err = intel_gpu_reset(i915, ALL_ENGINES);
|
err = intel_gpu_reset(i915, ALL_ENGINES);
|
||||||
reset_finish(i915);
|
|
||||||
p->critical_section_end();
|
p->critical_section_end();
|
||||||
|
reset_finish(i915, awake);
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
pr_err("intel_gpu_reset failed under %s\n", p->name);
|
pr_err("intel_gpu_reset failed under %s\n", p->name);
|
||||||
|
|
|
@ -925,7 +925,12 @@ check_whitelisted_registers(struct intel_engine_cs *engine,
|
||||||
|
|
||||||
err = 0;
|
err = 0;
|
||||||
for (i = 0; i < engine->whitelist.count; i++) {
|
for (i = 0; i < engine->whitelist.count; i++) {
|
||||||
if (!fn(engine, a[i], b[i], engine->whitelist.list[i].reg))
|
const struct i915_wa *wa = &engine->whitelist.list[i];
|
||||||
|
|
||||||
|
if (i915_mmio_reg_offset(wa->reg) & RING_FORCE_TO_NONPRIV_RD)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!fn(engine, a[i], b[i], wa->reg))
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2674,11 +2674,6 @@ static int scan_workload(struct intel_vgpu_workload *workload)
|
||||||
gma_head == gma_tail)
|
gma_head == gma_tail)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!intel_gvt_ggtt_validate_range(s.vgpu, s.ring_start, s.ring_size)) {
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = ip_gma_set(&s, gma_head);
|
ret = ip_gma_set(&s, gma_head);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -2724,11 +2719,6 @@ static int scan_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
|
||||||
s.workload = workload;
|
s.workload = workload;
|
||||||
s.is_ctx_wa = true;
|
s.is_ctx_wa = true;
|
||||||
|
|
||||||
if (!intel_gvt_ggtt_validate_range(s.vgpu, s.ring_start, s.ring_size)) {
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = ip_gma_set(&s, gma_head);
|
ret = ip_gma_set(&s, gma_head);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
|
@ -245,7 +245,7 @@ int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu,
|
||||||
plane->hw_format = fmt;
|
plane->hw_format = fmt;
|
||||||
|
|
||||||
plane->base = vgpu_vreg_t(vgpu, DSPSURF(pipe)) & I915_GTT_PAGE_MASK;
|
plane->base = vgpu_vreg_t(vgpu, DSPSURF(pipe)) & I915_GTT_PAGE_MASK;
|
||||||
if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0))
|
if (!vgpu_gmadr_is_valid(vgpu, plane->base))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
|
plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
|
||||||
|
@ -368,7 +368,7 @@ int intel_vgpu_decode_cursor_plane(struct intel_vgpu *vgpu,
|
||||||
alpha_plane, alpha_force);
|
alpha_plane, alpha_force);
|
||||||
|
|
||||||
plane->base = vgpu_vreg_t(vgpu, CURBASE(pipe)) & I915_GTT_PAGE_MASK;
|
plane->base = vgpu_vreg_t(vgpu, CURBASE(pipe)) & I915_GTT_PAGE_MASK;
|
||||||
if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0))
|
if (!vgpu_gmadr_is_valid(vgpu, plane->base))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
|
plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
|
||||||
|
@ -472,7 +472,7 @@ int intel_vgpu_decode_sprite_plane(struct intel_vgpu *vgpu,
|
||||||
plane->drm_format = drm_format;
|
plane->drm_format = drm_format;
|
||||||
|
|
||||||
plane->base = vgpu_vreg_t(vgpu, SPRSURF(pipe)) & I915_GTT_PAGE_MASK;
|
plane->base = vgpu_vreg_t(vgpu, SPRSURF(pipe)) & I915_GTT_PAGE_MASK;
|
||||||
if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0))
|
if (!vgpu_gmadr_is_valid(vgpu, plane->base))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
|
plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
|
||||||
|
|
|
@ -2141,11 +2141,20 @@ static int emulate_ggtt_mmio_read(struct intel_vgpu *vgpu,
|
||||||
struct intel_vgpu_mm *ggtt_mm = vgpu->gtt.ggtt_mm;
|
struct intel_vgpu_mm *ggtt_mm = vgpu->gtt.ggtt_mm;
|
||||||
const struct intel_gvt_device_info *info = &vgpu->gvt->device_info;
|
const struct intel_gvt_device_info *info = &vgpu->gvt->device_info;
|
||||||
unsigned long index = off >> info->gtt_entry_size_shift;
|
unsigned long index = off >> info->gtt_entry_size_shift;
|
||||||
|
unsigned long gma;
|
||||||
struct intel_gvt_gtt_entry e;
|
struct intel_gvt_gtt_entry e;
|
||||||
|
|
||||||
if (bytes != 4 && bytes != 8)
|
if (bytes != 4 && bytes != 8)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
gma = index << I915_GTT_PAGE_SHIFT;
|
||||||
|
if (!intel_gvt_ggtt_validate_range(vgpu,
|
||||||
|
gma, 1 << I915_GTT_PAGE_SHIFT)) {
|
||||||
|
gvt_dbg_mm("read invalid ggtt at 0x%lx\n", gma);
|
||||||
|
memset(p_data, 0, bytes);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ggtt_get_guest_entry(ggtt_mm, &e, index);
|
ggtt_get_guest_entry(ggtt_mm, &e, index);
|
||||||
memcpy(p_data, (void *)&e.val64 + (off & (info->gtt_entry_size - 1)),
|
memcpy(p_data, (void *)&e.val64 + (off & (info->gtt_entry_size - 1)),
|
||||||
bytes);
|
bytes);
|
||||||
|
|
|
@ -1904,6 +1904,18 @@ static int kvmgt_dma_map_guest_page(unsigned long handle, unsigned long gfn,
|
||||||
|
|
||||||
entry = __gvt_cache_find_gfn(info->vgpu, gfn);
|
entry = __gvt_cache_find_gfn(info->vgpu, gfn);
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
|
ret = gvt_dma_map_page(vgpu, gfn, dma_addr, size);
|
||||||
|
if (ret)
|
||||||
|
goto err_unlock;
|
||||||
|
|
||||||
|
ret = __gvt_cache_add(info->vgpu, gfn, *dma_addr, size);
|
||||||
|
if (ret)
|
||||||
|
goto err_unmap;
|
||||||
|
} else if (entry->size != size) {
|
||||||
|
/* the same gfn with different size: unmap and re-map */
|
||||||
|
gvt_dma_unmap_page(vgpu, gfn, entry->dma_addr, entry->size);
|
||||||
|
__gvt_cache_remove_entry(vgpu, entry);
|
||||||
|
|
||||||
ret = gvt_dma_map_page(vgpu, gfn, dma_addr, size);
|
ret = gvt_dma_map_page(vgpu, gfn, dma_addr, size);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_unlock;
|
goto err_unlock;
|
||||||
|
|
|
@ -364,16 +364,13 @@ static void release_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
|
||||||
wa_ctx->indirect_ctx.shadow_va = NULL;
|
wa_ctx->indirect_ctx.shadow_va = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_context_ppgtt_from_shadow(struct intel_vgpu_workload *workload,
|
static void set_context_ppgtt_from_shadow(struct intel_vgpu_workload *workload,
|
||||||
struct i915_gem_context *ctx)
|
struct i915_gem_context *ctx)
|
||||||
{
|
{
|
||||||
struct intel_vgpu_mm *mm = workload->shadow_mm;
|
struct intel_vgpu_mm *mm = workload->shadow_mm;
|
||||||
struct i915_ppgtt *ppgtt = i915_vm_to_ppgtt(ctx->vm);
|
struct i915_ppgtt *ppgtt = i915_vm_to_ppgtt(ctx->vm);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
if (mm->type != INTEL_GVT_MM_PPGTT || !mm->ppgtt_mm.shadowed)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (mm->ppgtt_mm.root_entry_type == GTT_TYPE_PPGTT_ROOT_L4_ENTRY) {
|
if (mm->ppgtt_mm.root_entry_type == GTT_TYPE_PPGTT_ROOT_L4_ENTRY) {
|
||||||
px_dma(ppgtt->pd) = mm->ppgtt_mm.shadow_pdps[0];
|
px_dma(ppgtt->pd) = mm->ppgtt_mm.shadow_pdps[0];
|
||||||
} else {
|
} else {
|
||||||
|
@ -384,8 +381,6 @@ static int set_context_ppgtt_from_shadow(struct intel_vgpu_workload *workload,
|
||||||
px_dma(pd) = mm->ppgtt_mm.shadow_pdps[i];
|
px_dma(pd) = mm->ppgtt_mm.shadow_pdps[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -614,6 +609,8 @@ static void release_shadow_batch_buffer(struct intel_vgpu_workload *workload)
|
||||||
static int prepare_workload(struct intel_vgpu_workload *workload)
|
static int prepare_workload(struct intel_vgpu_workload *workload)
|
||||||
{
|
{
|
||||||
struct intel_vgpu *vgpu = workload->vgpu;
|
struct intel_vgpu *vgpu = workload->vgpu;
|
||||||
|
struct intel_vgpu_submission *s = &vgpu->submission;
|
||||||
|
int ring = workload->ring_id;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
ret = intel_vgpu_pin_mm(workload->shadow_mm);
|
ret = intel_vgpu_pin_mm(workload->shadow_mm);
|
||||||
|
@ -622,8 +619,16 @@ static int prepare_workload(struct intel_vgpu_workload *workload)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (workload->shadow_mm->type != INTEL_GVT_MM_PPGTT ||
|
||||||
|
!workload->shadow_mm->ppgtt_mm.shadowed) {
|
||||||
|
gvt_vgpu_err("workload shadow ppgtt isn't ready\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
update_shadow_pdps(workload);
|
update_shadow_pdps(workload);
|
||||||
|
|
||||||
|
set_context_ppgtt_from_shadow(workload, s->shadow[ring]->gem_context);
|
||||||
|
|
||||||
ret = intel_vgpu_sync_oos_pages(workload->vgpu);
|
ret = intel_vgpu_sync_oos_pages(workload->vgpu);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
gvt_vgpu_err("fail to vgpu sync oos pages\n");
|
gvt_vgpu_err("fail to vgpu sync oos pages\n");
|
||||||
|
@ -674,7 +679,6 @@ static int dispatch_workload(struct intel_vgpu_workload *workload)
|
||||||
{
|
{
|
||||||
struct intel_vgpu *vgpu = workload->vgpu;
|
struct intel_vgpu *vgpu = workload->vgpu;
|
||||||
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
|
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
|
||||||
struct intel_vgpu_submission *s = &vgpu->submission;
|
|
||||||
struct i915_request *rq;
|
struct i915_request *rq;
|
||||||
int ring_id = workload->ring_id;
|
int ring_id = workload->ring_id;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -685,13 +689,6 @@ static int dispatch_workload(struct intel_vgpu_workload *workload)
|
||||||
mutex_lock(&vgpu->vgpu_lock);
|
mutex_lock(&vgpu->vgpu_lock);
|
||||||
mutex_lock(&dev_priv->drm.struct_mutex);
|
mutex_lock(&dev_priv->drm.struct_mutex);
|
||||||
|
|
||||||
ret = set_context_ppgtt_from_shadow(workload,
|
|
||||||
s->shadow[ring_id]->gem_context);
|
|
||||||
if (ret < 0) {
|
|
||||||
gvt_vgpu_err("workload shadow ppgtt isn't ready\n");
|
|
||||||
goto err_req;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = intel_gvt_workload_req_alloc(workload);
|
ret = intel_gvt_workload_req_alloc(workload);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_req;
|
goto err_req;
|
||||||
|
@ -990,6 +987,7 @@ static int workload_thread(void *priv)
|
||||||
int ret;
|
int ret;
|
||||||
bool need_force_wake = (INTEL_GEN(gvt->dev_priv) >= 9);
|
bool need_force_wake = (INTEL_GEN(gvt->dev_priv) >= 9);
|
||||||
DEFINE_WAIT_FUNC(wait, woken_wake_function);
|
DEFINE_WAIT_FUNC(wait, woken_wake_function);
|
||||||
|
struct intel_runtime_pm *rpm = &gvt->dev_priv->runtime_pm;
|
||||||
|
|
||||||
kfree(p);
|
kfree(p);
|
||||||
|
|
||||||
|
@ -1013,6 +1011,8 @@ static int workload_thread(void *priv)
|
||||||
workload->ring_id, workload,
|
workload->ring_id, workload,
|
||||||
workload->vgpu->id);
|
workload->vgpu->id);
|
||||||
|
|
||||||
|
intel_runtime_pm_get(rpm);
|
||||||
|
|
||||||
gvt_dbg_sched("ring id %d will dispatch workload %p\n",
|
gvt_dbg_sched("ring id %d will dispatch workload %p\n",
|
||||||
workload->ring_id, workload);
|
workload->ring_id, workload);
|
||||||
|
|
||||||
|
@ -1042,6 +1042,7 @@ complete:
|
||||||
intel_uncore_forcewake_put(&gvt->dev_priv->uncore,
|
intel_uncore_forcewake_put(&gvt->dev_priv->uncore,
|
||||||
FORCEWAKE_ALL);
|
FORCEWAKE_ALL);
|
||||||
|
|
||||||
|
intel_runtime_pm_put_unchecked(rpm);
|
||||||
if (ret && (vgpu_is_vm_unhealthy(ret)))
|
if (ret && (vgpu_is_vm_unhealthy(ret)))
|
||||||
enter_failsafe_mode(vgpu, GVT_FAILSAFE_GUEST_ERR);
|
enter_failsafe_mode(vgpu, GVT_FAILSAFE_GUEST_ERR);
|
||||||
}
|
}
|
||||||
|
@ -1492,6 +1493,12 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id,
|
||||||
intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa +
|
intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa +
|
||||||
RING_CTX_OFF(ctx_ctrl.val), &ctx_ctl, 4);
|
RING_CTX_OFF(ctx_ctrl.val), &ctx_ctl, 4);
|
||||||
|
|
||||||
|
if (!intel_gvt_ggtt_validate_range(vgpu, start,
|
||||||
|
_RING_CTL_BUF_SIZE(ctl))) {
|
||||||
|
gvt_vgpu_err("context contain invalid rb at: 0x%x\n", start);
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
workload = alloc_workload(vgpu);
|
workload = alloc_workload(vgpu);
|
||||||
if (IS_ERR(workload))
|
if (IS_ERR(workload))
|
||||||
return workload;
|
return workload;
|
||||||
|
@ -1516,9 +1523,31 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id,
|
||||||
workload->wa_ctx.indirect_ctx.size =
|
workload->wa_ctx.indirect_ctx.size =
|
||||||
(indirect_ctx & INDIRECT_CTX_SIZE_MASK) *
|
(indirect_ctx & INDIRECT_CTX_SIZE_MASK) *
|
||||||
CACHELINE_BYTES;
|
CACHELINE_BYTES;
|
||||||
|
|
||||||
|
if (workload->wa_ctx.indirect_ctx.size != 0) {
|
||||||
|
if (!intel_gvt_ggtt_validate_range(vgpu,
|
||||||
|
workload->wa_ctx.indirect_ctx.guest_gma,
|
||||||
|
workload->wa_ctx.indirect_ctx.size)) {
|
||||||
|
kmem_cache_free(s->workloads, workload);
|
||||||
|
gvt_vgpu_err("invalid wa_ctx at: 0x%lx\n",
|
||||||
|
workload->wa_ctx.indirect_ctx.guest_gma);
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
workload->wa_ctx.per_ctx.guest_gma =
|
workload->wa_ctx.per_ctx.guest_gma =
|
||||||
per_ctx & PER_CTX_ADDR_MASK;
|
per_ctx & PER_CTX_ADDR_MASK;
|
||||||
workload->wa_ctx.per_ctx.valid = per_ctx & 1;
|
workload->wa_ctx.per_ctx.valid = per_ctx & 1;
|
||||||
|
if (workload->wa_ctx.per_ctx.valid) {
|
||||||
|
if (!intel_gvt_ggtt_validate_range(vgpu,
|
||||||
|
workload->wa_ctx.per_ctx.guest_gma,
|
||||||
|
CACHELINE_BYTES)) {
|
||||||
|
kmem_cache_free(s->workloads, workload);
|
||||||
|
gvt_vgpu_err("invalid per_ctx at: 0x%lx\n",
|
||||||
|
workload->wa_ctx.per_ctx.guest_gma);
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gvt_dbg_el("workload %p ring id %d head %x tail %x start %x ctl %x\n",
|
gvt_dbg_el("workload %p ring id %d head %x tail %x start %x ctl %x\n",
|
||||||
|
|
|
@ -28,8 +28,6 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "trace.h"
|
|
||||||
|
|
||||||
#ifndef __CHECKER__
|
#ifndef __CHECKER__
|
||||||
#define CREATE_TRACE_POINTS
|
#define CREATE_TRACE_POINTS
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
|
|
@ -1674,8 +1674,9 @@ struct drm_i915_private {
|
||||||
} dram_info;
|
} dram_info;
|
||||||
|
|
||||||
struct intel_bw_info {
|
struct intel_bw_info {
|
||||||
int num_planes;
|
unsigned int deratedbw[3]; /* for each QGV point */
|
||||||
int deratedbw[3];
|
u8 num_qgv_points;
|
||||||
|
u8 num_planes;
|
||||||
} max_bw[6];
|
} max_bw[6];
|
||||||
|
|
||||||
struct drm_private_obj bw_obj;
|
struct drm_private_obj bw_obj;
|
||||||
|
|
|
@ -46,7 +46,6 @@
|
||||||
#include "gem/i915_gem_ioctls.h"
|
#include "gem/i915_gem_ioctls.h"
|
||||||
#include "gem/i915_gem_pm.h"
|
#include "gem/i915_gem_pm.h"
|
||||||
#include "gem/i915_gemfs.h"
|
#include "gem/i915_gemfs.h"
|
||||||
#include "gt/intel_engine_pm.h"
|
|
||||||
#include "gt/intel_gt_pm.h"
|
#include "gt/intel_gt_pm.h"
|
||||||
#include "gt/intel_mocs.h"
|
#include "gt/intel_mocs.h"
|
||||||
#include "gt/intel_reset.h"
|
#include "gt/intel_reset.h"
|
||||||
|
@ -1307,21 +1306,13 @@ int i915_gem_init_hw(struct drm_i915_private *dev_priv)
|
||||||
|
|
||||||
intel_mocs_init_l3cc_table(dev_priv);
|
intel_mocs_init_l3cc_table(dev_priv);
|
||||||
|
|
||||||
/* Only when the HW is re-initialised, can we replay the requests */
|
|
||||||
ret = intel_engines_resume(dev_priv);
|
|
||||||
if (ret)
|
|
||||||
goto cleanup_uc;
|
|
||||||
|
|
||||||
intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
|
intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
|
||||||
|
|
||||||
intel_engines_set_scheduler_caps(dev_priv);
|
intel_engines_set_scheduler_caps(dev_priv);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cleanup_uc:
|
|
||||||
intel_uc_fini_hw(dev_priv);
|
|
||||||
out:
|
out:
|
||||||
intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
|
intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1580,6 +1571,11 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_uc_init;
|
goto err_uc_init;
|
||||||
|
|
||||||
|
/* Only when the HW is re-initialised, can we replay the requests */
|
||||||
|
ret = intel_gt_resume(dev_priv);
|
||||||
|
if (ret)
|
||||||
|
goto err_init_hw;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Despite its name intel_init_clock_gating applies both display
|
* Despite its name intel_init_clock_gating applies both display
|
||||||
* clock gating workarounds; GT mmio workarounds and the occasional
|
* clock gating workarounds; GT mmio workarounds and the occasional
|
||||||
|
@ -1593,20 +1589,20 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
|
||||||
|
|
||||||
ret = intel_engines_verify_workarounds(dev_priv);
|
ret = intel_engines_verify_workarounds(dev_priv);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_init_hw;
|
goto err_gt;
|
||||||
|
|
||||||
ret = __intel_engines_record_defaults(dev_priv);
|
ret = __intel_engines_record_defaults(dev_priv);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_init_hw;
|
goto err_gt;
|
||||||
|
|
||||||
if (i915_inject_load_failure()) {
|
if (i915_inject_load_failure()) {
|
||||||
ret = -ENODEV;
|
ret = -ENODEV;
|
||||||
goto err_init_hw;
|
goto err_gt;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i915_inject_load_failure()) {
|
if (i915_inject_load_failure()) {
|
||||||
ret = -EIO;
|
ret = -EIO;
|
||||||
goto err_init_hw;
|
goto err_gt;
|
||||||
}
|
}
|
||||||
|
|
||||||
intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
|
intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
|
||||||
|
@ -1620,7 +1616,7 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
|
||||||
* HW as irrevisibly wedged, but keep enough state around that the
|
* HW as irrevisibly wedged, but keep enough state around that the
|
||||||
* driver doesn't explode during runtime.
|
* driver doesn't explode during runtime.
|
||||||
*/
|
*/
|
||||||
err_init_hw:
|
err_gt:
|
||||||
mutex_unlock(&dev_priv->drm.struct_mutex);
|
mutex_unlock(&dev_priv->drm.struct_mutex);
|
||||||
|
|
||||||
i915_gem_set_wedged(dev_priv);
|
i915_gem_set_wedged(dev_priv);
|
||||||
|
@ -1630,6 +1626,7 @@ err_init_hw:
|
||||||
i915_gem_drain_workqueue(dev_priv);
|
i915_gem_drain_workqueue(dev_priv);
|
||||||
|
|
||||||
mutex_lock(&dev_priv->drm.struct_mutex);
|
mutex_lock(&dev_priv->drm.struct_mutex);
|
||||||
|
err_init_hw:
|
||||||
intel_uc_fini_hw(dev_priv);
|
intel_uc_fini_hw(dev_priv);
|
||||||
err_uc_init:
|
err_uc_init:
|
||||||
intel_uc_fini(dev_priv);
|
intel_uc_fini(dev_priv);
|
||||||
|
|
|
@ -1444,9 +1444,11 @@ unwind_pd:
|
||||||
spin_lock(&pdp->lock);
|
spin_lock(&pdp->lock);
|
||||||
if (atomic_dec_and_test(&pd->used)) {
|
if (atomic_dec_and_test(&pd->used)) {
|
||||||
gen8_ppgtt_set_pdpe(pdp, vm->scratch_pd, pdpe);
|
gen8_ppgtt_set_pdpe(pdp, vm->scratch_pd, pdpe);
|
||||||
|
pdp->entry[pdpe] = vm->scratch_pd;
|
||||||
GEM_BUG_ON(!atomic_read(&pdp->used));
|
GEM_BUG_ON(!atomic_read(&pdp->used));
|
||||||
atomic_dec(&pdp->used);
|
atomic_dec(&pdp->used);
|
||||||
free_pd(vm, pd);
|
GEM_BUG_ON(alloc);
|
||||||
|
alloc = pd; /* defer the free to after the lock */
|
||||||
}
|
}
|
||||||
spin_unlock(&pdp->lock);
|
spin_unlock(&pdp->lock);
|
||||||
unwind:
|
unwind:
|
||||||
|
@ -1515,7 +1517,9 @@ unwind_pdp:
|
||||||
spin_lock(&pml4->lock);
|
spin_lock(&pml4->lock);
|
||||||
if (atomic_dec_and_test(&pdp->used)) {
|
if (atomic_dec_and_test(&pdp->used)) {
|
||||||
gen8_ppgtt_set_pml4e(pml4, vm->scratch_pdp, pml4e);
|
gen8_ppgtt_set_pml4e(pml4, vm->scratch_pdp, pml4e);
|
||||||
free_pd(vm, pdp);
|
pml4->entry[pml4e] = vm->scratch_pdp;
|
||||||
|
GEM_BUG_ON(alloc);
|
||||||
|
alloc = pdp; /* defer the free until after the lock */
|
||||||
}
|
}
|
||||||
spin_unlock(&pml4->lock);
|
spin_unlock(&pml4->lock);
|
||||||
unwind:
|
unwind:
|
||||||
|
|
|
@ -1418,6 +1418,7 @@ static void gem_record_rings(struct i915_gpu_state *error)
|
||||||
struct intel_engine_cs *engine = i915->engine[i];
|
struct intel_engine_cs *engine = i915->engine[i];
|
||||||
struct drm_i915_error_engine *ee = &error->engine[i];
|
struct drm_i915_error_engine *ee = &error->engine[i];
|
||||||
struct i915_request *request;
|
struct i915_request *request;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
ee->engine_id = -1;
|
ee->engine_id = -1;
|
||||||
|
|
||||||
|
@ -1429,10 +1430,11 @@ static void gem_record_rings(struct i915_gpu_state *error)
|
||||||
error_record_engine_registers(error, engine, ee);
|
error_record_engine_registers(error, engine, ee);
|
||||||
error_record_engine_execlists(engine, ee);
|
error_record_engine_execlists(engine, ee);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&engine->active.lock, flags);
|
||||||
request = intel_engine_find_active_request(engine);
|
request = intel_engine_find_active_request(engine);
|
||||||
if (request) {
|
if (request) {
|
||||||
struct i915_gem_context *ctx = request->gem_context;
|
struct i915_gem_context *ctx = request->gem_context;
|
||||||
struct intel_ring *ring;
|
struct intel_ring *ring = request->ring;
|
||||||
|
|
||||||
ee->vm = ctx->vm ?: &ggtt->vm;
|
ee->vm = ctx->vm ?: &ggtt->vm;
|
||||||
|
|
||||||
|
@ -1462,7 +1464,6 @@ static void gem_record_rings(struct i915_gpu_state *error)
|
||||||
ee->rq_post = request->postfix;
|
ee->rq_post = request->postfix;
|
||||||
ee->rq_tail = request->tail;
|
ee->rq_tail = request->tail;
|
||||||
|
|
||||||
ring = request->ring;
|
|
||||||
ee->cpu_ring_head = ring->head;
|
ee->cpu_ring_head = ring->head;
|
||||||
ee->cpu_ring_tail = ring->tail;
|
ee->cpu_ring_tail = ring->tail;
|
||||||
ee->ringbuffer =
|
ee->ringbuffer =
|
||||||
|
@ -1470,6 +1471,7 @@ static void gem_record_rings(struct i915_gpu_state *error)
|
||||||
|
|
||||||
engine_record_requests(engine, request, ee);
|
engine_record_requests(engine, request, ee);
|
||||||
}
|
}
|
||||||
|
spin_unlock_irqrestore(&engine->active.lock, flags);
|
||||||
|
|
||||||
ee->hws_page =
|
ee->hws_page =
|
||||||
i915_error_object_create(i915,
|
i915_error_object_create(i915,
|
||||||
|
|
|
@ -1567,28 +1567,10 @@ static void config_oa_regs(struct drm_i915_private *dev_priv,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hsw_enable_metric_set(struct i915_perf_stream *stream)
|
static void delay_after_mux(void)
|
||||||
{
|
{
|
||||||
struct drm_i915_private *dev_priv = stream->dev_priv;
|
/*
|
||||||
const struct i915_oa_config *oa_config = stream->oa_config;
|
* It apparently takes a fairly long time for a new MUX
|
||||||
|
|
||||||
/* PRM:
|
|
||||||
*
|
|
||||||
* OA unit is using “crclk” for its functionality. When trunk
|
|
||||||
* level clock gating takes place, OA clock would be gated,
|
|
||||||
* unable to count the events from non-render clock domain.
|
|
||||||
* Render clock gating must be disabled when OA is enabled to
|
|
||||||
* count the events from non-render domain. Unit level clock
|
|
||||||
* gating for RCS should also be disabled.
|
|
||||||
*/
|
|
||||||
I915_WRITE(GEN7_MISCCPCTL, (I915_READ(GEN7_MISCCPCTL) &
|
|
||||||
~GEN7_DOP_CLOCK_GATE_ENABLE));
|
|
||||||
I915_WRITE(GEN6_UCGCTL1, (I915_READ(GEN6_UCGCTL1) |
|
|
||||||
GEN6_CSUNIT_CLOCK_GATE_DISABLE));
|
|
||||||
|
|
||||||
config_oa_regs(dev_priv, oa_config->mux_regs, oa_config->mux_regs_len);
|
|
||||||
|
|
||||||
/* It apparently takes a fairly long time for a new MUX
|
|
||||||
* configuration to be be applied after these register writes.
|
* configuration to be be applied after these register writes.
|
||||||
* This delay duration was derived empirically based on the
|
* This delay duration was derived empirically based on the
|
||||||
* render_basic config but hopefully it covers the maximum
|
* render_basic config but hopefully it covers the maximum
|
||||||
|
@ -1610,6 +1592,30 @@ static int hsw_enable_metric_set(struct i915_perf_stream *stream)
|
||||||
* a delay at this location would mitigate any invalid reports.
|
* a delay at this location would mitigate any invalid reports.
|
||||||
*/
|
*/
|
||||||
usleep_range(15000, 20000);
|
usleep_range(15000, 20000);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hsw_enable_metric_set(struct i915_perf_stream *stream)
|
||||||
|
{
|
||||||
|
struct drm_i915_private *dev_priv = stream->dev_priv;
|
||||||
|
const struct i915_oa_config *oa_config = stream->oa_config;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PRM:
|
||||||
|
*
|
||||||
|
* OA unit is using “crclk” for its functionality. When trunk
|
||||||
|
* level clock gating takes place, OA clock would be gated,
|
||||||
|
* unable to count the events from non-render clock domain.
|
||||||
|
* Render clock gating must be disabled when OA is enabled to
|
||||||
|
* count the events from non-render domain. Unit level clock
|
||||||
|
* gating for RCS should also be disabled.
|
||||||
|
*/
|
||||||
|
I915_WRITE(GEN7_MISCCPCTL, (I915_READ(GEN7_MISCCPCTL) &
|
||||||
|
~GEN7_DOP_CLOCK_GATE_ENABLE));
|
||||||
|
I915_WRITE(GEN6_UCGCTL1, (I915_READ(GEN6_UCGCTL1) |
|
||||||
|
GEN6_CSUNIT_CLOCK_GATE_DISABLE));
|
||||||
|
|
||||||
|
config_oa_regs(dev_priv, oa_config->mux_regs, oa_config->mux_regs_len);
|
||||||
|
delay_after_mux();
|
||||||
|
|
||||||
config_oa_regs(dev_priv, oa_config->b_counter_regs,
|
config_oa_regs(dev_priv, oa_config->b_counter_regs,
|
||||||
oa_config->b_counter_regs_len);
|
oa_config->b_counter_regs_len);
|
||||||
|
@ -1835,6 +1841,7 @@ static int gen8_enable_metric_set(struct i915_perf_stream *stream)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
config_oa_regs(dev_priv, oa_config->mux_regs, oa_config->mux_regs_len);
|
config_oa_regs(dev_priv, oa_config->mux_regs, oa_config->mux_regs_len);
|
||||||
|
delay_after_mux();
|
||||||
|
|
||||||
config_oa_regs(dev_priv, oa_config->b_counter_regs,
|
config_oa_regs(dev_priv, oa_config->b_counter_regs,
|
||||||
oa_config->b_counter_regs_len);
|
oa_config->b_counter_regs_len);
|
||||||
|
@ -2515,6 +2522,9 @@ static int i915_perf_release(struct inode *inode, struct file *file)
|
||||||
i915_perf_destroy_locked(stream);
|
i915_perf_destroy_locked(stream);
|
||||||
mutex_unlock(&dev_priv->perf.lock);
|
mutex_unlock(&dev_priv->perf.lock);
|
||||||
|
|
||||||
|
/* Release the reference the perf stream kept on the driver. */
|
||||||
|
drm_dev_put(&dev_priv->drm);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2650,6 +2660,11 @@ i915_perf_open_ioctl_locked(struct drm_i915_private *dev_priv,
|
||||||
if (!(param->flags & I915_PERF_FLAG_DISABLED))
|
if (!(param->flags & I915_PERF_FLAG_DISABLED))
|
||||||
i915_perf_enable_locked(stream);
|
i915_perf_enable_locked(stream);
|
||||||
|
|
||||||
|
/* Take a reference on the driver that will be kept with stream_fd
|
||||||
|
* until its release.
|
||||||
|
*/
|
||||||
|
drm_dev_get(&dev_priv->drm);
|
||||||
|
|
||||||
return stream_fd;
|
return stream_fd;
|
||||||
|
|
||||||
err_open:
|
err_open:
|
||||||
|
@ -3477,9 +3492,13 @@ void i915_perf_init(struct drm_i915_private *dev_priv)
|
||||||
dev_priv->perf.oa.ops.enable_metric_set = gen8_enable_metric_set;
|
dev_priv->perf.oa.ops.enable_metric_set = gen8_enable_metric_set;
|
||||||
dev_priv->perf.oa.ops.disable_metric_set = gen10_disable_metric_set;
|
dev_priv->perf.oa.ops.disable_metric_set = gen10_disable_metric_set;
|
||||||
|
|
||||||
dev_priv->perf.oa.ctx_oactxctrl_offset = 0x128;
|
if (IS_GEN(dev_priv, 10)) {
|
||||||
dev_priv->perf.oa.ctx_flexeu0_offset = 0x3de;
|
dev_priv->perf.oa.ctx_oactxctrl_offset = 0x128;
|
||||||
|
dev_priv->perf.oa.ctx_flexeu0_offset = 0x3de;
|
||||||
|
} else {
|
||||||
|
dev_priv->perf.oa.ctx_oactxctrl_offset = 0x124;
|
||||||
|
dev_priv->perf.oa.ctx_flexeu0_offset = 0x78e;
|
||||||
|
}
|
||||||
dev_priv->perf.oa.gen8_valid_ctx_bit = (1<<16);
|
dev_priv->perf.oa.gen8_valid_ctx_bit = (1<<16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,24 +21,22 @@
|
||||||
/* watermark/fifo updates */
|
/* watermark/fifo updates */
|
||||||
|
|
||||||
TRACE_EVENT(intel_pipe_enable,
|
TRACE_EVENT(intel_pipe_enable,
|
||||||
TP_PROTO(struct drm_i915_private *dev_priv, enum pipe pipe),
|
TP_PROTO(struct intel_crtc *crtc),
|
||||||
TP_ARGS(dev_priv, pipe),
|
TP_ARGS(crtc),
|
||||||
|
|
||||||
TP_STRUCT__entry(
|
TP_STRUCT__entry(
|
||||||
__array(u32, frame, 3)
|
__array(u32, frame, 3)
|
||||||
__array(u32, scanline, 3)
|
__array(u32, scanline, 3)
|
||||||
__field(enum pipe, pipe)
|
__field(enum pipe, pipe)
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_fast_assign(
|
TP_fast_assign(
|
||||||
enum pipe _pipe;
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||||
for_each_pipe(dev_priv, _pipe) {
|
struct intel_crtc *it__;
|
||||||
__entry->frame[_pipe] =
|
for_each_intel_crtc(&dev_priv->drm, it__) {
|
||||||
dev_priv->drm.driver->get_vblank_counter(&dev_priv->drm, _pipe);
|
__entry->frame[it__->pipe] = intel_crtc_get_vblank_counter(it__);
|
||||||
__entry->scanline[_pipe] =
|
__entry->scanline[it__->pipe] = intel_get_crtc_scanline(it__);
|
||||||
intel_get_crtc_scanline(intel_get_crtc_for_pipe(dev_priv, _pipe));
|
|
||||||
}
|
}
|
||||||
__entry->pipe = pipe;
|
__entry->pipe = crtc->pipe;
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_printk("pipe %c enable, pipe A: frame=%u, scanline=%u, pipe B: frame=%u, scanline=%u, pipe C: frame=%u, scanline=%u",
|
TP_printk("pipe %c enable, pipe A: frame=%u, scanline=%u, pipe B: frame=%u, scanline=%u, pipe C: frame=%u, scanline=%u",
|
||||||
|
@ -49,8 +47,8 @@ TRACE_EVENT(intel_pipe_enable,
|
||||||
);
|
);
|
||||||
|
|
||||||
TRACE_EVENT(intel_pipe_disable,
|
TRACE_EVENT(intel_pipe_disable,
|
||||||
TP_PROTO(struct drm_i915_private *dev_priv, enum pipe pipe),
|
TP_PROTO(struct intel_crtc *crtc),
|
||||||
TP_ARGS(dev_priv, pipe),
|
TP_ARGS(crtc),
|
||||||
|
|
||||||
TP_STRUCT__entry(
|
TP_STRUCT__entry(
|
||||||
__array(u32, frame, 3)
|
__array(u32, frame, 3)
|
||||||
|
@ -59,14 +57,13 @@ TRACE_EVENT(intel_pipe_disable,
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_fast_assign(
|
TP_fast_assign(
|
||||||
enum pipe _pipe;
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||||
for_each_pipe(dev_priv, _pipe) {
|
struct intel_crtc *it__;
|
||||||
__entry->frame[_pipe] =
|
for_each_intel_crtc(&dev_priv->drm, it__) {
|
||||||
dev_priv->drm.driver->get_vblank_counter(&dev_priv->drm, _pipe);
|
__entry->frame[it__->pipe] = intel_crtc_get_vblank_counter(it__);
|
||||||
__entry->scanline[_pipe] =
|
__entry->scanline[it__->pipe] = intel_get_crtc_scanline(it__);
|
||||||
intel_get_crtc_scanline(intel_get_crtc_for_pipe(dev_priv, _pipe));
|
|
||||||
}
|
}
|
||||||
__entry->pipe = pipe;
|
__entry->pipe = crtc->pipe;
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_printk("pipe %c disable, pipe A: frame=%u, scanline=%u, pipe B: frame=%u, scanline=%u, pipe C: frame=%u, scanline=%u",
|
TP_printk("pipe %c disable, pipe A: frame=%u, scanline=%u, pipe B: frame=%u, scanline=%u, pipe C: frame=%u, scanline=%u",
|
||||||
|
@ -89,8 +86,7 @@ TRACE_EVENT(intel_pipe_crc,
|
||||||
|
|
||||||
TP_fast_assign(
|
TP_fast_assign(
|
||||||
__entry->pipe = crtc->pipe;
|
__entry->pipe = crtc->pipe;
|
||||||
__entry->frame = crtc->base.dev->driver->get_vblank_counter(crtc->base.dev,
|
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
||||||
crtc->pipe);
|
|
||||||
__entry->scanline = intel_get_crtc_scanline(crtc);
|
__entry->scanline = intel_get_crtc_scanline(crtc);
|
||||||
memcpy(__entry->crcs, crcs, sizeof(__entry->crcs));
|
memcpy(__entry->crcs, crcs, sizeof(__entry->crcs));
|
||||||
),
|
),
|
||||||
|
@ -112,9 +108,10 @@ TRACE_EVENT(intel_cpu_fifo_underrun,
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_fast_assign(
|
TP_fast_assign(
|
||||||
|
struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
|
||||||
__entry->pipe = pipe;
|
__entry->pipe = pipe;
|
||||||
__entry->frame = dev_priv->drm.driver->get_vblank_counter(&dev_priv->drm, pipe);
|
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
||||||
__entry->scanline = intel_get_crtc_scanline(intel_get_crtc_for_pipe(dev_priv, pipe));
|
__entry->scanline = intel_get_crtc_scanline(crtc);
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_printk("pipe %c, frame=%u, scanline=%u",
|
TP_printk("pipe %c, frame=%u, scanline=%u",
|
||||||
|
@ -134,9 +131,10 @@ TRACE_EVENT(intel_pch_fifo_underrun,
|
||||||
|
|
||||||
TP_fast_assign(
|
TP_fast_assign(
|
||||||
enum pipe pipe = pch_transcoder;
|
enum pipe pipe = pch_transcoder;
|
||||||
|
struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
|
||||||
__entry->pipe = pipe;
|
__entry->pipe = pipe;
|
||||||
__entry->frame = dev_priv->drm.driver->get_vblank_counter(&dev_priv->drm, pipe);
|
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
||||||
__entry->scanline = intel_get_crtc_scanline(intel_get_crtc_for_pipe(dev_priv, pipe));
|
__entry->scanline = intel_get_crtc_scanline(crtc);
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_printk("pch transcoder %c, frame=%u, scanline=%u",
|
TP_printk("pch transcoder %c, frame=%u, scanline=%u",
|
||||||
|
@ -156,12 +154,10 @@ TRACE_EVENT(intel_memory_cxsr,
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_fast_assign(
|
TP_fast_assign(
|
||||||
enum pipe pipe;
|
struct intel_crtc *crtc;
|
||||||
for_each_pipe(dev_priv, pipe) {
|
for_each_intel_crtc(&dev_priv->drm, crtc) {
|
||||||
__entry->frame[pipe] =
|
__entry->frame[crtc->pipe] = intel_crtc_get_vblank_counter(crtc);
|
||||||
dev_priv->drm.driver->get_vblank_counter(&dev_priv->drm, pipe);
|
__entry->scanline[crtc->pipe] = intel_get_crtc_scanline(crtc);
|
||||||
__entry->scanline[pipe] =
|
|
||||||
intel_get_crtc_scanline(intel_get_crtc_for_pipe(dev_priv, pipe));
|
|
||||||
}
|
}
|
||||||
__entry->old = old;
|
__entry->old = old;
|
||||||
__entry->new = new;
|
__entry->new = new;
|
||||||
|
@ -198,8 +194,7 @@ TRACE_EVENT(g4x_wm,
|
||||||
|
|
||||||
TP_fast_assign(
|
TP_fast_assign(
|
||||||
__entry->pipe = crtc->pipe;
|
__entry->pipe = crtc->pipe;
|
||||||
__entry->frame = crtc->base.dev->driver->get_vblank_counter(crtc->base.dev,
|
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
||||||
crtc->pipe);
|
|
||||||
__entry->scanline = intel_get_crtc_scanline(crtc);
|
__entry->scanline = intel_get_crtc_scanline(crtc);
|
||||||
__entry->primary = wm->pipe[crtc->pipe].plane[PLANE_PRIMARY];
|
__entry->primary = wm->pipe[crtc->pipe].plane[PLANE_PRIMARY];
|
||||||
__entry->sprite = wm->pipe[crtc->pipe].plane[PLANE_SPRITE0];
|
__entry->sprite = wm->pipe[crtc->pipe].plane[PLANE_SPRITE0];
|
||||||
|
@ -243,8 +238,7 @@ TRACE_EVENT(vlv_wm,
|
||||||
|
|
||||||
TP_fast_assign(
|
TP_fast_assign(
|
||||||
__entry->pipe = crtc->pipe;
|
__entry->pipe = crtc->pipe;
|
||||||
__entry->frame = crtc->base.dev->driver->get_vblank_counter(crtc->base.dev,
|
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
||||||
crtc->pipe);
|
|
||||||
__entry->scanline = intel_get_crtc_scanline(crtc);
|
__entry->scanline = intel_get_crtc_scanline(crtc);
|
||||||
__entry->level = wm->level;
|
__entry->level = wm->level;
|
||||||
__entry->cxsr = wm->cxsr;
|
__entry->cxsr = wm->cxsr;
|
||||||
|
@ -278,8 +272,7 @@ TRACE_EVENT(vlv_fifo_size,
|
||||||
|
|
||||||
TP_fast_assign(
|
TP_fast_assign(
|
||||||
__entry->pipe = crtc->pipe;
|
__entry->pipe = crtc->pipe;
|
||||||
__entry->frame = crtc->base.dev->driver->get_vblank_counter(crtc->base.dev,
|
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
||||||
crtc->pipe);
|
|
||||||
__entry->scanline = intel_get_crtc_scanline(crtc);
|
__entry->scanline = intel_get_crtc_scanline(crtc);
|
||||||
__entry->sprite0_start = sprite0_start;
|
__entry->sprite0_start = sprite0_start;
|
||||||
__entry->sprite1_start = sprite1_start;
|
__entry->sprite1_start = sprite1_start;
|
||||||
|
@ -310,8 +303,7 @@ TRACE_EVENT(intel_update_plane,
|
||||||
TP_fast_assign(
|
TP_fast_assign(
|
||||||
__entry->pipe = crtc->pipe;
|
__entry->pipe = crtc->pipe;
|
||||||
__entry->name = plane->name;
|
__entry->name = plane->name;
|
||||||
__entry->frame = crtc->base.dev->driver->get_vblank_counter(crtc->base.dev,
|
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
||||||
crtc->pipe);
|
|
||||||
__entry->scanline = intel_get_crtc_scanline(crtc);
|
__entry->scanline = intel_get_crtc_scanline(crtc);
|
||||||
memcpy(__entry->src, &plane->state->src, sizeof(__entry->src));
|
memcpy(__entry->src, &plane->state->src, sizeof(__entry->src));
|
||||||
memcpy(__entry->dst, &plane->state->dst, sizeof(__entry->dst));
|
memcpy(__entry->dst, &plane->state->dst, sizeof(__entry->dst));
|
||||||
|
@ -338,8 +330,7 @@ TRACE_EVENT(intel_disable_plane,
|
||||||
TP_fast_assign(
|
TP_fast_assign(
|
||||||
__entry->pipe = crtc->pipe;
|
__entry->pipe = crtc->pipe;
|
||||||
__entry->name = plane->name;
|
__entry->name = plane->name;
|
||||||
__entry->frame = crtc->base.dev->driver->get_vblank_counter(crtc->base.dev,
|
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
||||||
crtc->pipe);
|
|
||||||
__entry->scanline = intel_get_crtc_scanline(crtc);
|
__entry->scanline = intel_get_crtc_scanline(crtc);
|
||||||
),
|
),
|
||||||
|
|
||||||
|
@ -364,8 +355,7 @@ TRACE_EVENT(i915_pipe_update_start,
|
||||||
|
|
||||||
TP_fast_assign(
|
TP_fast_assign(
|
||||||
__entry->pipe = crtc->pipe;
|
__entry->pipe = crtc->pipe;
|
||||||
__entry->frame = crtc->base.dev->driver->get_vblank_counter(crtc->base.dev,
|
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
||||||
crtc->pipe);
|
|
||||||
__entry->scanline = intel_get_crtc_scanline(crtc);
|
__entry->scanline = intel_get_crtc_scanline(crtc);
|
||||||
__entry->min = crtc->debug.min_vbl;
|
__entry->min = crtc->debug.min_vbl;
|
||||||
__entry->max = crtc->debug.max_vbl;
|
__entry->max = crtc->debug.max_vbl;
|
||||||
|
|
|
@ -221,13 +221,11 @@ __untrack_all_wakerefs(struct intel_runtime_pm_debug *debug,
|
||||||
static void
|
static void
|
||||||
dump_and_free_wakeref_tracking(struct intel_runtime_pm_debug *debug)
|
dump_and_free_wakeref_tracking(struct intel_runtime_pm_debug *debug)
|
||||||
{
|
{
|
||||||
struct drm_printer p;
|
if (debug->count) {
|
||||||
|
struct drm_printer p = drm_debug_printer("i915");
|
||||||
|
|
||||||
if (!debug->count)
|
__print_intel_runtime_pm_wakeref(&p, debug);
|
||||||
return;
|
}
|
||||||
|
|
||||||
p = drm_debug_printer("i915");
|
|
||||||
__print_intel_runtime_pm_wakeref(&p, debug);
|
|
||||||
|
|
||||||
kfree(debug->owners);
|
kfree(debug->owners);
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,21 @@ intel_wakeref_get(struct intel_runtime_pm *rpm,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* intel_wakeref_get_if_in_use: Acquire the wakeref
|
||||||
|
* @wf: the wakeref
|
||||||
|
*
|
||||||
|
* Acquire a hold on the wakeref, but only if the wakeref is already
|
||||||
|
* active.
|
||||||
|
*
|
||||||
|
* Returns: true if the wakeref was acquired, false otherwise.
|
||||||
|
*/
|
||||||
|
static inline bool
|
||||||
|
intel_wakeref_get_if_active(struct intel_wakeref *wf)
|
||||||
|
{
|
||||||
|
return atomic_inc_not_zero(&wf->count);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* intel_wakeref_put: Release the wakeref
|
* intel_wakeref_put: Release the wakeref
|
||||||
* @i915: the drm_i915_private device
|
* @i915: the drm_i915_private device
|
||||||
|
|
|
@ -149,6 +149,8 @@ struct drm_client_buffer {
|
||||||
struct drm_client_buffer *
|
struct drm_client_buffer *
|
||||||
drm_client_framebuffer_create(struct drm_client_dev *client, u32 width, u32 height, u32 format);
|
drm_client_framebuffer_create(struct drm_client_dev *client, u32 width, u32 height, u32 format);
|
||||||
void drm_client_framebuffer_delete(struct drm_client_buffer *buffer);
|
void drm_client_framebuffer_delete(struct drm_client_buffer *buffer);
|
||||||
|
void *drm_client_buffer_vmap(struct drm_client_buffer *buffer);
|
||||||
|
void drm_client_buffer_vunmap(struct drm_client_buffer *buffer);
|
||||||
|
|
||||||
int drm_client_modeset_create(struct drm_client_dev *client);
|
int drm_client_modeset_create(struct drm_client_dev *client);
|
||||||
void drm_client_modeset_free(struct drm_client_dev *client);
|
void drm_client_modeset_free(struct drm_client_dev *client);
|
||||||
|
|
|
@ -852,6 +852,13 @@ struct drm_mode_config {
|
||||||
/* dumb ioctl parameters */
|
/* dumb ioctl parameters */
|
||||||
uint32_t preferred_depth, prefer_shadow;
|
uint32_t preferred_depth, prefer_shadow;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @prefer_shadow_fbdev:
|
||||||
|
*
|
||||||
|
* Hint to framebuffer emulation to prefer shadow-fb rendering.
|
||||||
|
*/
|
||||||
|
bool prefer_shadow_fbdev;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @quirk_addfb_prefer_xbgr_30bpp:
|
* @quirk_addfb_prefer_xbgr_30bpp:
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue