mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-19 18:24:14 +08:00
i915, amdgpu and a single nouveau cleanup
-----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJbmxVCAAoJEAx081l5xIa+H0EP/2F5S+VeVX/GQB3hs5xdNubj fBGWorXefXRySPOtS0SdSjHnPnJCUgWnHnKOGrBAxtqRaImnqZLra9HztdV7WbBI mzhfw39cekWX6q2/5WoTP2IxaujVMEyCFX9lgW+96msFktuwvmNGA6QP9MtOfyfV oBzjrtoQSJYHx7uzDDiAzghMKm6EGbkDjqHnOuO3HGNc2N+mPlNd4cIaReAehOkG r1PqOn26CRi9y/bsDgERLEiQURS4kHLz6QaGotJtMVrQblFuNwwk4eBEL9FjkGur f9jNnRAW9MXk/lPkXjWCwPV5wYcHW7XpldL0pZKTnL/Od6Fm956Ecoda72cRquMe 4Rt+LOlZueNEcY4WyDnT9i5kYdE18TYvYNW5SpWXT2ZwhHmRgsblZsO+nTufndGT +GxGAalsLB8wSVh0m3h2TdJeULINzHoN287i6KXZOoc0tR4yXh3Bek3k5K1Sajiv 3Ehp4mzOEBcut7qR9P8KNoOtt5lExp8LwxHcpwbl+rYeFUhNUr1ffuLBV59bVLt7 sluZQ9+UVHu72XSXdXRtB9WeyKPToZBkh2+rwad4SPLpUKwJuyXJim/IHKfGt0O9 BeilehpFVerP4RyB7dK3PRRzKS0zQmfVlr5x1WDXwir1RHDjWdoyLvHFzwn5OKSH rIGf2J64oreok1UrCKyN =NZvZ -----END PGP SIGNATURE----- Merge tag 'drm-fixes-2018-09-14' of git://anongit.freedesktop.org/drm/drm Pull drm fixes from Dave Airlie: "This is the general drm fixes pull for rc4. i915: - Two GVT fixes (one for the mm reference issue you pointed out) - Gen 2 video playback fix - IPS timeout error suppression on Broadwell amdgpu: - Small memory leak - SR-IOV reset - locking fix - updated SDMA golden registers nouveau: - Remove some leftover debugging" * tag 'drm-fixes-2018-09-14' of git://anongit.freedesktop.org/drm/drm: drm/nouveau/devinit: fix warning when PMU/PRE_OS is missing drm/amdgpu: fix error handling in amdgpu_cs_user_fence_chunk drm/i915/overlay: Allocate physical registers from stolen drm/amdgpu: move PSP init prior to IH in gpu reset drm/amdgpu: Fix SDMA hang in prt mode v2 drm/amdgpu: fix amdgpu_mn_unlock() in the CS error path drm/i915/bdw: Increase IPS disable timeout to 100ms drm/i915/gvt: Fix the incorrect length of child_device_config issue drm/i915/gvt: Fix life cycle reference on KVM mm
This commit is contained in:
commit
0f9aeeac1d
@ -39,6 +39,7 @@ static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p,
|
||||
{
|
||||
struct drm_gem_object *gobj;
|
||||
unsigned long size;
|
||||
int r;
|
||||
|
||||
gobj = drm_gem_object_lookup(p->filp, data->handle);
|
||||
if (gobj == NULL)
|
||||
@ -50,20 +51,26 @@ static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p,
|
||||
p->uf_entry.tv.shared = true;
|
||||
p->uf_entry.user_pages = NULL;
|
||||
|
||||
drm_gem_object_put_unlocked(gobj);
|
||||
|
||||
size = amdgpu_bo_size(p->uf_entry.robj);
|
||||
if (size != PAGE_SIZE || (data->offset + 8) > size)
|
||||
return -EINVAL;
|
||||
if (size != PAGE_SIZE || (data->offset + 8) > size) {
|
||||
r = -EINVAL;
|
||||
goto error_unref;
|
||||
}
|
||||
|
||||
if (amdgpu_ttm_tt_get_usermm(p->uf_entry.robj->tbo.ttm)) {
|
||||
r = -EINVAL;
|
||||
goto error_unref;
|
||||
}
|
||||
|
||||
*offset = data->offset;
|
||||
|
||||
drm_gem_object_put_unlocked(gobj);
|
||||
|
||||
if (amdgpu_ttm_tt_get_usermm(p->uf_entry.robj->tbo.ttm)) {
|
||||
amdgpu_bo_unref(&p->uf_entry.robj);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_unref:
|
||||
amdgpu_bo_unref(&p->uf_entry.robj);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int amdgpu_cs_bo_handles_chunk(struct amdgpu_cs_parser *p,
|
||||
@ -1262,10 +1269,10 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
|
||||
error_abort:
|
||||
dma_fence_put(&job->base.s_fence->finished);
|
||||
job->base.s_fence = NULL;
|
||||
amdgpu_mn_unlock(p->mn);
|
||||
|
||||
error_unlock:
|
||||
amdgpu_job_free(job);
|
||||
amdgpu_mn_unlock(p->mn);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -2063,6 +2063,7 @@ static int amdgpu_device_ip_reinit_early_sriov(struct amdgpu_device *adev)
|
||||
static enum amd_ip_block_type ip_order[] = {
|
||||
AMD_IP_BLOCK_TYPE_GMC,
|
||||
AMD_IP_BLOCK_TYPE_COMMON,
|
||||
AMD_IP_BLOCK_TYPE_PSP,
|
||||
AMD_IP_BLOCK_TYPE_IH,
|
||||
};
|
||||
|
||||
@ -2093,7 +2094,6 @@ static int amdgpu_device_ip_reinit_late_sriov(struct amdgpu_device *adev)
|
||||
|
||||
static enum amd_ip_block_type ip_order[] = {
|
||||
AMD_IP_BLOCK_TYPE_SMC,
|
||||
AMD_IP_BLOCK_TYPE_PSP,
|
||||
AMD_IP_BLOCK_TYPE_DCE,
|
||||
AMD_IP_BLOCK_TYPE_GFX,
|
||||
AMD_IP_BLOCK_TYPE_SDMA,
|
||||
|
@ -70,6 +70,7 @@ static const struct soc15_reg_golden golden_settings_sdma_4[] = {
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC1_IB_CNTL, 0x800f0100, 0x00000100),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC1_RB_WPTR_POLL_CNTL, 0x0000fff0, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_WATERMK, 0xfc000000, 0x00000000),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_CHICKEN_BITS, 0xfe931f07, 0x02831f07),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_CLK_CTRL, 0xffffffff, 0x3f000100),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GFX_IB_CNTL, 0x800f0100, 0x00000100),
|
||||
@ -81,7 +82,8 @@ static const struct soc15_reg_golden golden_settings_sdma_4[] = {
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_RLC0_RB_WPTR_POLL_CNTL, 0x0000fff0, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_RLC1_IB_CNTL, 0x800f0100, 0x00000100),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_RLC1_RB_WPTR_POLL_CNTL, 0x0000fff0, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_UTCL1_PAGE, 0x000003ff, 0x000003c0)
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_UTCL1_PAGE, 0x000003ff, 0x000003c0),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_UTCL1_WATERMK, 0xfc000000, 0x00000000)
|
||||
};
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_sdma_vg10[] = {
|
||||
@ -109,7 +111,8 @@ static const struct soc15_reg_golden golden_settings_sdma_4_1[] =
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC0_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC1_IB_CNTL, 0x800f0111, 0x00000100),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC1_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0)
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_WATERMK, 0xfc000000, 0x00000000)
|
||||
};
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_sdma_4_2[] =
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/mmu_context.h>
|
||||
#include <linux/sched/mm.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/rbtree.h>
|
||||
@ -1792,16 +1793,21 @@ static int kvmgt_rw_gpa(unsigned long handle, unsigned long gpa,
|
||||
info = (struct kvmgt_guest_info *)handle;
|
||||
kvm = info->kvm;
|
||||
|
||||
if (kthread)
|
||||
if (kthread) {
|
||||
if (!mmget_not_zero(kvm->mm))
|
||||
return -EFAULT;
|
||||
use_mm(kvm->mm);
|
||||
}
|
||||
|
||||
idx = srcu_read_lock(&kvm->srcu);
|
||||
ret = write ? kvm_write_guest(kvm, gpa, buf, len) :
|
||||
kvm_read_guest(kvm, gpa, buf, len);
|
||||
srcu_read_unlock(&kvm->srcu, idx);
|
||||
|
||||
if (kthread)
|
||||
if (kthread) {
|
||||
unuse_mm(kvm->mm);
|
||||
mmput(kvm->mm);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -42,8 +42,6 @@
|
||||
#define DEVICE_TYPE_EFP3 0x20
|
||||
#define DEVICE_TYPE_EFP4 0x10
|
||||
|
||||
#define DEV_SIZE 38
|
||||
|
||||
struct opregion_header {
|
||||
u8 signature[16];
|
||||
u32 size;
|
||||
@ -63,6 +61,10 @@ struct bdb_data_header {
|
||||
u16 size; /* data size */
|
||||
} __packed;
|
||||
|
||||
/* For supporting windows guest with opregion, here hardcode the emulated
|
||||
* bdb header version as '186', and the corresponding child_device_config
|
||||
* length should be '33' but not '38'.
|
||||
*/
|
||||
struct efp_child_device_config {
|
||||
u16 handle;
|
||||
u16 device_type;
|
||||
@ -109,12 +111,6 @@ struct efp_child_device_config {
|
||||
u8 mipi_bridge_type; /* 171 */
|
||||
u16 device_class_ext;
|
||||
u8 dvo_function;
|
||||
u8 dp_usb_type_c:1; /* 195 */
|
||||
u8 skip6:7;
|
||||
u8 dp_usb_type_c_2x_gpio_index; /* 195 */
|
||||
u16 dp_usb_type_c_2x_gpio_pin; /* 195 */
|
||||
u8 iboost_dp:4; /* 196 */
|
||||
u8 iboost_hdmi:4; /* 196 */
|
||||
} __packed;
|
||||
|
||||
struct vbt {
|
||||
@ -155,7 +151,7 @@ static void virt_vbt_generation(struct vbt *v)
|
||||
v->header.bdb_offset = offsetof(struct vbt, bdb_header);
|
||||
|
||||
strcpy(&v->bdb_header.signature[0], "BIOS_DATA_BLOCK");
|
||||
v->bdb_header.version = 186; /* child_dev_size = 38 */
|
||||
v->bdb_header.version = 186; /* child_dev_size = 33 */
|
||||
v->bdb_header.header_size = sizeof(v->bdb_header);
|
||||
|
||||
v->bdb_header.bdb_size = sizeof(struct vbt) - sizeof(struct vbt_header)
|
||||
@ -169,11 +165,13 @@ static void virt_vbt_generation(struct vbt *v)
|
||||
|
||||
/* child device */
|
||||
num_child = 4; /* each port has one child */
|
||||
v->general_definitions.child_dev_size =
|
||||
sizeof(struct efp_child_device_config);
|
||||
v->general_definitions_header.id = BDB_GENERAL_DEFINITIONS;
|
||||
/* size will include child devices */
|
||||
v->general_definitions_header.size =
|
||||
sizeof(struct bdb_general_definitions) + num_child * DEV_SIZE;
|
||||
v->general_definitions.child_dev_size = DEV_SIZE;
|
||||
sizeof(struct bdb_general_definitions) +
|
||||
num_child * v->general_definitions.child_dev_size;
|
||||
|
||||
/* portA */
|
||||
v->child0.handle = DEVICE_TYPE_EFP1;
|
||||
|
@ -5079,10 +5079,14 @@ void hsw_disable_ips(const struct intel_crtc_state *crtc_state)
|
||||
mutex_lock(&dev_priv->pcu_lock);
|
||||
WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0));
|
||||
mutex_unlock(&dev_priv->pcu_lock);
|
||||
/* wait for pcode to finish disabling IPS, which may take up to 42ms */
|
||||
/*
|
||||
* Wait for PCODE to finish disabling IPS. The BSpec specified
|
||||
* 42ms timeout value leads to occasional timeouts so use 100ms
|
||||
* instead.
|
||||
*/
|
||||
if (intel_wait_for_register(dev_priv,
|
||||
IPS_CTL, IPS_ENABLE, 0,
|
||||
42))
|
||||
100))
|
||||
DRM_ERROR("Timed out waiting for IPS disable\n");
|
||||
} else {
|
||||
I915_WRITE(IPS_CTL, 0);
|
||||
|
@ -181,8 +181,9 @@ struct intel_overlay {
|
||||
u32 brightness, contrast, saturation;
|
||||
u32 old_xscale, old_yscale;
|
||||
/* register access */
|
||||
u32 flip_addr;
|
||||
struct drm_i915_gem_object *reg_bo;
|
||||
struct overlay_registers __iomem *regs;
|
||||
u32 flip_addr;
|
||||
/* flip handling */
|
||||
struct i915_gem_active last_flip;
|
||||
};
|
||||
@ -210,29 +211,6 @@ static void i830_overlay_clock_gating(struct drm_i915_private *dev_priv,
|
||||
PCI_DEVFN(0, 0), I830_CLOCK_GATE, val);
|
||||
}
|
||||
|
||||
static struct overlay_registers __iomem *
|
||||
intel_overlay_map_regs(struct intel_overlay *overlay)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = overlay->i915;
|
||||
struct overlay_registers __iomem *regs;
|
||||
|
||||
if (OVERLAY_NEEDS_PHYSICAL(dev_priv))
|
||||
regs = (struct overlay_registers __iomem *)overlay->reg_bo->phys_handle->vaddr;
|
||||
else
|
||||
regs = io_mapping_map_wc(&dev_priv->ggtt.iomap,
|
||||
overlay->flip_addr,
|
||||
PAGE_SIZE);
|
||||
|
||||
return regs;
|
||||
}
|
||||
|
||||
static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
|
||||
struct overlay_registers __iomem *regs)
|
||||
{
|
||||
if (!OVERLAY_NEEDS_PHYSICAL(overlay->i915))
|
||||
io_mapping_unmap(regs);
|
||||
}
|
||||
|
||||
static void intel_overlay_submit_request(struct intel_overlay *overlay,
|
||||
struct i915_request *rq,
|
||||
i915_gem_retire_fn retire)
|
||||
@ -784,13 +762,13 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
|
||||
struct drm_i915_gem_object *new_bo,
|
||||
struct put_image_params *params)
|
||||
{
|
||||
int ret, tmp_width;
|
||||
struct overlay_registers __iomem *regs;
|
||||
bool scale_changed = false;
|
||||
struct overlay_registers __iomem *regs = overlay->regs;
|
||||
struct drm_i915_private *dev_priv = overlay->i915;
|
||||
u32 swidth, swidthsw, sheight, ostride;
|
||||
enum pipe pipe = overlay->crtc->pipe;
|
||||
bool scale_changed = false;
|
||||
struct i915_vma *vma;
|
||||
int ret, tmp_width;
|
||||
|
||||
lockdep_assert_held(&dev_priv->drm.struct_mutex);
|
||||
WARN_ON(!drm_modeset_is_locked(&dev_priv->drm.mode_config.connection_mutex));
|
||||
@ -815,30 +793,19 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
|
||||
|
||||
if (!overlay->active) {
|
||||
u32 oconfig;
|
||||
regs = intel_overlay_map_regs(overlay);
|
||||
if (!regs) {
|
||||
ret = -ENOMEM;
|
||||
goto out_unpin;
|
||||
}
|
||||
|
||||
oconfig = OCONF_CC_OUT_8BIT;
|
||||
if (IS_GEN4(dev_priv))
|
||||
oconfig |= OCONF_CSC_MODE_BT709;
|
||||
oconfig |= pipe == 0 ?
|
||||
OCONF_PIPE_A : OCONF_PIPE_B;
|
||||
iowrite32(oconfig, ®s->OCONFIG);
|
||||
intel_overlay_unmap_regs(overlay, regs);
|
||||
|
||||
ret = intel_overlay_on(overlay);
|
||||
if (ret != 0)
|
||||
goto out_unpin;
|
||||
}
|
||||
|
||||
regs = intel_overlay_map_regs(overlay);
|
||||
if (!regs) {
|
||||
ret = -ENOMEM;
|
||||
goto out_unpin;
|
||||
}
|
||||
|
||||
iowrite32((params->dst_y << 16) | params->dst_x, ®s->DWINPOS);
|
||||
iowrite32((params->dst_h << 16) | params->dst_w, ®s->DWINSZ);
|
||||
|
||||
@ -882,8 +849,6 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
|
||||
|
||||
iowrite32(overlay_cmd_reg(params), ®s->OCMD);
|
||||
|
||||
intel_overlay_unmap_regs(overlay, regs);
|
||||
|
||||
ret = intel_overlay_continue(overlay, vma, scale_changed);
|
||||
if (ret)
|
||||
goto out_unpin;
|
||||
@ -901,7 +866,6 @@ out_pin_section:
|
||||
int intel_overlay_switch_off(struct intel_overlay *overlay)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = overlay->i915;
|
||||
struct overlay_registers __iomem *regs;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&dev_priv->drm.struct_mutex);
|
||||
@ -918,9 +882,7 @@ int intel_overlay_switch_off(struct intel_overlay *overlay)
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
regs = intel_overlay_map_regs(overlay);
|
||||
iowrite32(0, ®s->OCMD);
|
||||
intel_overlay_unmap_regs(overlay, regs);
|
||||
iowrite32(0, &overlay->regs->OCMD);
|
||||
|
||||
return intel_overlay_off(overlay);
|
||||
}
|
||||
@ -1305,7 +1267,6 @@ int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_intel_overlay_attrs *attrs = data;
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct intel_overlay *overlay;
|
||||
struct overlay_registers __iomem *regs;
|
||||
int ret;
|
||||
|
||||
overlay = dev_priv->overlay;
|
||||
@ -1345,15 +1306,7 @@ int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data,
|
||||
overlay->contrast = attrs->contrast;
|
||||
overlay->saturation = attrs->saturation;
|
||||
|
||||
regs = intel_overlay_map_regs(overlay);
|
||||
if (!regs) {
|
||||
ret = -ENOMEM;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
update_reg_attrs(overlay, regs);
|
||||
|
||||
intel_overlay_unmap_regs(overlay, regs);
|
||||
update_reg_attrs(overlay, overlay->regs);
|
||||
|
||||
if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) {
|
||||
if (IS_GEN2(dev_priv))
|
||||
@ -1386,12 +1339,47 @@ out_unlock:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int get_registers(struct intel_overlay *overlay, bool use_phys)
|
||||
{
|
||||
struct drm_i915_gem_object *obj;
|
||||
struct i915_vma *vma;
|
||||
int err;
|
||||
|
||||
obj = i915_gem_object_create_stolen(overlay->i915, PAGE_SIZE);
|
||||
if (obj == NULL)
|
||||
obj = i915_gem_object_create_internal(overlay->i915, PAGE_SIZE);
|
||||
if (IS_ERR(obj))
|
||||
return PTR_ERR(obj);
|
||||
|
||||
vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, PIN_MAPPABLE);
|
||||
if (IS_ERR(vma)) {
|
||||
err = PTR_ERR(vma);
|
||||
goto err_put_bo;
|
||||
}
|
||||
|
||||
if (use_phys)
|
||||
overlay->flip_addr = sg_dma_address(obj->mm.pages->sgl);
|
||||
else
|
||||
overlay->flip_addr = i915_ggtt_offset(vma);
|
||||
overlay->regs = i915_vma_pin_iomap(vma);
|
||||
i915_vma_unpin(vma);
|
||||
|
||||
if (IS_ERR(overlay->regs)) {
|
||||
err = PTR_ERR(overlay->regs);
|
||||
goto err_put_bo;
|
||||
}
|
||||
|
||||
overlay->reg_bo = obj;
|
||||
return 0;
|
||||
|
||||
err_put_bo:
|
||||
i915_gem_object_put(obj);
|
||||
return err;
|
||||
}
|
||||
|
||||
void intel_setup_overlay(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct intel_overlay *overlay;
|
||||
struct drm_i915_gem_object *reg_bo;
|
||||
struct overlay_registers __iomem *regs;
|
||||
struct i915_vma *vma = NULL;
|
||||
int ret;
|
||||
|
||||
if (!HAS_OVERLAY(dev_priv))
|
||||
@ -1401,46 +1389,8 @@ void intel_setup_overlay(struct drm_i915_private *dev_priv)
|
||||
if (!overlay)
|
||||
return;
|
||||
|
||||
mutex_lock(&dev_priv->drm.struct_mutex);
|
||||
if (WARN_ON(dev_priv->overlay))
|
||||
goto out_free;
|
||||
|
||||
overlay->i915 = dev_priv;
|
||||
|
||||
reg_bo = NULL;
|
||||
if (!OVERLAY_NEEDS_PHYSICAL(dev_priv))
|
||||
reg_bo = i915_gem_object_create_stolen(dev_priv, PAGE_SIZE);
|
||||
if (reg_bo == NULL)
|
||||
reg_bo = i915_gem_object_create(dev_priv, PAGE_SIZE);
|
||||
if (IS_ERR(reg_bo))
|
||||
goto out_free;
|
||||
overlay->reg_bo = reg_bo;
|
||||
|
||||
if (OVERLAY_NEEDS_PHYSICAL(dev_priv)) {
|
||||
ret = i915_gem_object_attach_phys(reg_bo, PAGE_SIZE);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to attach phys overlay regs\n");
|
||||
goto out_free_bo;
|
||||
}
|
||||
overlay->flip_addr = reg_bo->phys_handle->busaddr;
|
||||
} else {
|
||||
vma = i915_gem_object_ggtt_pin(reg_bo, NULL,
|
||||
0, PAGE_SIZE, PIN_MAPPABLE);
|
||||
if (IS_ERR(vma)) {
|
||||
DRM_ERROR("failed to pin overlay register bo\n");
|
||||
ret = PTR_ERR(vma);
|
||||
goto out_free_bo;
|
||||
}
|
||||
overlay->flip_addr = i915_ggtt_offset(vma);
|
||||
|
||||
ret = i915_gem_object_set_to_gtt_domain(reg_bo, true);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to move overlay register bo into the GTT\n");
|
||||
goto out_unpin_bo;
|
||||
}
|
||||
}
|
||||
|
||||
/* init all values */
|
||||
overlay->color_key = 0x0101fe;
|
||||
overlay->color_key_enabled = true;
|
||||
overlay->brightness = -19;
|
||||
@ -1449,44 +1399,51 @@ void intel_setup_overlay(struct drm_i915_private *dev_priv)
|
||||
|
||||
init_request_active(&overlay->last_flip, NULL);
|
||||
|
||||
regs = intel_overlay_map_regs(overlay);
|
||||
if (!regs)
|
||||
goto out_unpin_bo;
|
||||
mutex_lock(&dev_priv->drm.struct_mutex);
|
||||
|
||||
memset_io(regs, 0, sizeof(struct overlay_registers));
|
||||
update_polyphase_filter(regs);
|
||||
update_reg_attrs(overlay, regs);
|
||||
ret = get_registers(overlay, OVERLAY_NEEDS_PHYSICAL(dev_priv));
|
||||
if (ret)
|
||||
goto out_free;
|
||||
|
||||
intel_overlay_unmap_regs(overlay, regs);
|
||||
ret = i915_gem_object_set_to_gtt_domain(overlay->reg_bo, true);
|
||||
if (ret)
|
||||
goto out_reg_bo;
|
||||
|
||||
mutex_unlock(&dev_priv->drm.struct_mutex);
|
||||
|
||||
memset_io(overlay->regs, 0, sizeof(struct overlay_registers));
|
||||
update_polyphase_filter(overlay->regs);
|
||||
update_reg_attrs(overlay, overlay->regs);
|
||||
|
||||
dev_priv->overlay = overlay;
|
||||
mutex_unlock(&dev_priv->drm.struct_mutex);
|
||||
DRM_INFO("initialized overlay support\n");
|
||||
DRM_INFO("Initialized overlay support.\n");
|
||||
return;
|
||||
|
||||
out_unpin_bo:
|
||||
if (vma)
|
||||
i915_vma_unpin(vma);
|
||||
out_free_bo:
|
||||
i915_gem_object_put(reg_bo);
|
||||
out_reg_bo:
|
||||
i915_gem_object_put(overlay->reg_bo);
|
||||
out_free:
|
||||
mutex_unlock(&dev_priv->drm.struct_mutex);
|
||||
kfree(overlay);
|
||||
return;
|
||||
}
|
||||
|
||||
void intel_cleanup_overlay(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
if (!dev_priv->overlay)
|
||||
struct intel_overlay *overlay;
|
||||
|
||||
overlay = fetch_and_zero(&dev_priv->overlay);
|
||||
if (!overlay)
|
||||
return;
|
||||
|
||||
/* The bo's should be free'd by the generic code already.
|
||||
/*
|
||||
* The bo's should be free'd by the generic code already.
|
||||
* Furthermore modesetting teardown happens beforehand so the
|
||||
* hardware should be off already */
|
||||
WARN_ON(dev_priv->overlay->active);
|
||||
* hardware should be off already.
|
||||
*/
|
||||
WARN_ON(overlay->active);
|
||||
|
||||
i915_gem_object_put(dev_priv->overlay->reg_bo);
|
||||
kfree(dev_priv->overlay);
|
||||
i915_gem_object_put(overlay->reg_bo);
|
||||
|
||||
kfree(overlay);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
|
||||
@ -1498,37 +1455,11 @@ struct intel_overlay_error_state {
|
||||
u32 isr;
|
||||
};
|
||||
|
||||
static struct overlay_registers __iomem *
|
||||
intel_overlay_map_regs_atomic(struct intel_overlay *overlay)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = overlay->i915;
|
||||
struct overlay_registers __iomem *regs;
|
||||
|
||||
if (OVERLAY_NEEDS_PHYSICAL(dev_priv))
|
||||
/* Cast to make sparse happy, but it's wc memory anyway, so
|
||||
* equivalent to the wc io mapping on X86. */
|
||||
regs = (struct overlay_registers __iomem *)
|
||||
overlay->reg_bo->phys_handle->vaddr;
|
||||
else
|
||||
regs = io_mapping_map_atomic_wc(&dev_priv->ggtt.iomap,
|
||||
overlay->flip_addr);
|
||||
|
||||
return regs;
|
||||
}
|
||||
|
||||
static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay,
|
||||
struct overlay_registers __iomem *regs)
|
||||
{
|
||||
if (!OVERLAY_NEEDS_PHYSICAL(overlay->i915))
|
||||
io_mapping_unmap_atomic(regs);
|
||||
}
|
||||
|
||||
struct intel_overlay_error_state *
|
||||
intel_overlay_capture_error_state(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct intel_overlay *overlay = dev_priv->overlay;
|
||||
struct intel_overlay_error_state *error;
|
||||
struct overlay_registers __iomem *regs;
|
||||
|
||||
if (!overlay || !overlay->active)
|
||||
return NULL;
|
||||
@ -1541,18 +1472,9 @@ intel_overlay_capture_error_state(struct drm_i915_private *dev_priv)
|
||||
error->isr = I915_READ(ISR);
|
||||
error->base = overlay->flip_addr;
|
||||
|
||||
regs = intel_overlay_map_regs_atomic(overlay);
|
||||
if (!regs)
|
||||
goto err;
|
||||
|
||||
memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers));
|
||||
intel_overlay_unmap_regs_atomic(overlay, regs);
|
||||
memcpy_fromio(&error->regs, overlay->regs, sizeof(error->regs));
|
||||
|
||||
return error;
|
||||
|
||||
err:
|
||||
kfree(error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -86,10 +86,8 @@ pmu_load(struct nv50_devinit *init, u8 type, bool post,
|
||||
struct nvkm_bios *bios = subdev->device->bios;
|
||||
struct nvbios_pmuR pmu;
|
||||
|
||||
if (!nvbios_pmuRm(bios, type, &pmu)) {
|
||||
nvkm_error(subdev, "VBIOS PMU fuc %02x not found\n", type);
|
||||
if (!nvbios_pmuRm(bios, type, &pmu))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!post)
|
||||
return 0;
|
||||
@ -124,29 +122,30 @@ gm200_devinit_post(struct nvkm_devinit *base, bool post)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Upload DEVINIT application from VBIOS onto PMU. */
|
||||
ret = pmu_load(init, 0x04, post, &exec, &args);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
nvkm_error(subdev, "VBIOS PMU/DEVINIT not found\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* upload first chunk of init data */
|
||||
/* Upload tables required by opcodes in boot scripts. */
|
||||
if (post) {
|
||||
// devinit tables
|
||||
u32 pmu = pmu_args(init, args + 0x08, 0x08);
|
||||
u32 img = nvbios_rd16(bios, bit_I.offset + 0x14);
|
||||
u32 len = nvbios_rd16(bios, bit_I.offset + 0x16);
|
||||
pmu_data(init, pmu, img, len);
|
||||
}
|
||||
|
||||
/* upload second chunk of init data */
|
||||
/* Upload boot scripts. */
|
||||
if (post) {
|
||||
// devinit boot scripts
|
||||
u32 pmu = pmu_args(init, args + 0x08, 0x10);
|
||||
u32 img = nvbios_rd16(bios, bit_I.offset + 0x18);
|
||||
u32 len = nvbios_rd16(bios, bit_I.offset + 0x1a);
|
||||
pmu_data(init, pmu, img, len);
|
||||
}
|
||||
|
||||
/* execute init tables */
|
||||
/* Execute DEVINIT. */
|
||||
if (post) {
|
||||
nvkm_wr32(device, 0x10a040, 0x00005000);
|
||||
pmu_exec(init, exec);
|
||||
@ -157,7 +156,9 @@ gm200_devinit_post(struct nvkm_devinit *base, bool post)
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* load and execute some other ucode image (bios therm?) */
|
||||
/* Optional: Execute PRE_OS application on PMU, which should at
|
||||
* least take care of fans until a full PMU has been loaded.
|
||||
*/
|
||||
pmu_load(init, 0x01, post, NULL, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user