Commit 274adbff authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'drm-fixes-2020-01-24' of git://anongit.freedesktop.org/drm/drm

Pull drm fixes from Dave Airlie:
 "This one has a core mst fix and two i915 fixes. amdgpu just enables
  some hw outside experimental.

  The panfrost fix is a little bigger than I'd like at this stage but it
  fixes a fairly fundamental problem with global shared buffers in that
  driver, and since it's confined to that driver and I've taken a look
  at it, I think it's fine to get into the tree now, so it can get
  stable propagated as well.

  core/mst:
   - Fix SST branch device handling

  amdgpu:
   - enable renoir outside experimental

  i915:
   - Avoid overflow with huge userptr objects
   - uAPI fix to correctly handle negative values in
     engine->uabi_class/instance (cc: stable)

  panfrost:
   - Fix mapping of globally visible BO's (Boris)"

* tag 'drm-fixes-2020-01-24' of git://anongit.freedesktop.org/drm/drm:
  drm/amdgpu: remove the experimental flag for renoir
  drm/panfrost: Add the panfrost_gem_mapping concept
  drm/i915: Align engine->uabi_class/instance with i915_drm.h
  drm/i915/userptr: fix size calculation
  drm/dp_mst: Handle SST-only branch device case
parents ab10ae1c 49412f66
...@@ -1004,7 +1004,7 @@ static const struct pci_device_id pciidlist[] = { ...@@ -1004,7 +1004,7 @@ static const struct pci_device_id pciidlist[] = {
{0x1002, 0x734F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI14}, {0x1002, 0x734F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI14},
/* Renoir */ /* Renoir */
{0x1002, 0x1636, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RENOIR|AMD_IS_APU|AMD_EXP_HW_SUPPORT}, {0x1002, 0x1636, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RENOIR|AMD_IS_APU},
/* Navi12 */ /* Navi12 */
{0x1002, 0x7360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI12|AMD_EXP_HW_SUPPORT}, {0x1002, 0x7360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI12|AMD_EXP_HW_SUPPORT},
......
...@@ -1916,73 +1916,90 @@ static u8 drm_dp_calculate_rad(struct drm_dp_mst_port *port, ...@@ -1916,73 +1916,90 @@ static u8 drm_dp_calculate_rad(struct drm_dp_mst_port *port,
return parent_lct + 1; return parent_lct + 1;
} }
static int drm_dp_port_set_pdt(struct drm_dp_mst_port *port, u8 new_pdt) static bool drm_dp_mst_is_dp_mst_end_device(u8 pdt, bool mcs)
{
switch (pdt) {
case DP_PEER_DEVICE_DP_LEGACY_CONV:
case DP_PEER_DEVICE_SST_SINK:
return true;
case DP_PEER_DEVICE_MST_BRANCHING:
/* For sst branch device */
if (!mcs)
return true;
return false;
}
return true;
}
static int
drm_dp_port_set_pdt(struct drm_dp_mst_port *port, u8 new_pdt,
bool new_mcs)
{ {
struct drm_dp_mst_topology_mgr *mgr = port->mgr; struct drm_dp_mst_topology_mgr *mgr = port->mgr;
struct drm_dp_mst_branch *mstb; struct drm_dp_mst_branch *mstb;
u8 rad[8], lct; u8 rad[8], lct;
int ret = 0; int ret = 0;
if (port->pdt == new_pdt) if (port->pdt == new_pdt && port->mcs == new_mcs)
return 0; return 0;
/* Teardown the old pdt, if there is one */ /* Teardown the old pdt, if there is one */
switch (port->pdt) { if (port->pdt != DP_PEER_DEVICE_NONE) {
case DP_PEER_DEVICE_DP_LEGACY_CONV: if (drm_dp_mst_is_dp_mst_end_device(port->pdt, port->mcs)) {
case DP_PEER_DEVICE_SST_SINK: /*
/* * If the new PDT would also have an i2c bus,
* If the new PDT would also have an i2c bus, don't bother * don't bother with reregistering it
* with reregistering it */
*/ if (new_pdt != DP_PEER_DEVICE_NONE &&
if (new_pdt == DP_PEER_DEVICE_DP_LEGACY_CONV || drm_dp_mst_is_dp_mst_end_device(new_pdt, new_mcs)) {
new_pdt == DP_PEER_DEVICE_SST_SINK) { port->pdt = new_pdt;
port->pdt = new_pdt; port->mcs = new_mcs;
return 0; return 0;
} }
/* remove i2c over sideband */ /* remove i2c over sideband */
drm_dp_mst_unregister_i2c_bus(&port->aux); drm_dp_mst_unregister_i2c_bus(&port->aux);
break; } else {
case DP_PEER_DEVICE_MST_BRANCHING: mutex_lock(&mgr->lock);
mutex_lock(&mgr->lock); drm_dp_mst_topology_put_mstb(port->mstb);
drm_dp_mst_topology_put_mstb(port->mstb); port->mstb = NULL;
port->mstb = NULL; mutex_unlock(&mgr->lock);
mutex_unlock(&mgr->lock); }
break;
} }
port->pdt = new_pdt; port->pdt = new_pdt;
switch (port->pdt) { port->mcs = new_mcs;
case DP_PEER_DEVICE_DP_LEGACY_CONV:
case DP_PEER_DEVICE_SST_SINK:
/* add i2c over sideband */
ret = drm_dp_mst_register_i2c_bus(&port->aux);
break;
case DP_PEER_DEVICE_MST_BRANCHING: if (port->pdt != DP_PEER_DEVICE_NONE) {
lct = drm_dp_calculate_rad(port, rad); if (drm_dp_mst_is_dp_mst_end_device(port->pdt, port->mcs)) {
mstb = drm_dp_add_mst_branch_device(lct, rad); /* add i2c over sideband */
if (!mstb) { ret = drm_dp_mst_register_i2c_bus(&port->aux);
ret = -ENOMEM; } else {
DRM_ERROR("Failed to create MSTB for port %p", port); lct = drm_dp_calculate_rad(port, rad);
goto out; mstb = drm_dp_add_mst_branch_device(lct, rad);
} if (!mstb) {
ret = -ENOMEM;
DRM_ERROR("Failed to create MSTB for port %p",
port);
goto out;
}
mutex_lock(&mgr->lock); mutex_lock(&mgr->lock);
port->mstb = mstb; port->mstb = mstb;
mstb->mgr = port->mgr; mstb->mgr = port->mgr;
mstb->port_parent = port; mstb->port_parent = port;
/* /*
* Make sure this port's memory allocation stays * Make sure this port's memory allocation stays
* around until its child MSTB releases it * around until its child MSTB releases it
*/ */
drm_dp_mst_get_port_malloc(port); drm_dp_mst_get_port_malloc(port);
mutex_unlock(&mgr->lock); mutex_unlock(&mgr->lock);
/* And make sure we send a link address for this */ /* And make sure we send a link address for this */
ret = 1; ret = 1;
break; }
} }
out: out:
...@@ -2135,9 +2152,8 @@ drm_dp_mst_port_add_connector(struct drm_dp_mst_branch *mstb, ...@@ -2135,9 +2152,8 @@ drm_dp_mst_port_add_connector(struct drm_dp_mst_branch *mstb,
goto error; goto error;
} }
if ((port->pdt == DP_PEER_DEVICE_DP_LEGACY_CONV || if (port->pdt != DP_PEER_DEVICE_NONE &&
port->pdt == DP_PEER_DEVICE_SST_SINK) && drm_dp_mst_is_dp_mst_end_device(port->pdt, port->mcs)) {
port->port_num >= DP_MST_LOGICAL_PORT_0) {
port->cached_edid = drm_get_edid(port->connector, port->cached_edid = drm_get_edid(port->connector,
&port->aux.ddc); &port->aux.ddc);
drm_connector_set_tile_property(port->connector); drm_connector_set_tile_property(port->connector);
...@@ -2201,6 +2217,7 @@ drm_dp_mst_handle_link_address_port(struct drm_dp_mst_branch *mstb, ...@@ -2201,6 +2217,7 @@ drm_dp_mst_handle_link_address_port(struct drm_dp_mst_branch *mstb,
struct drm_dp_mst_port *port; struct drm_dp_mst_port *port;
int old_ddps = 0, ret; int old_ddps = 0, ret;
u8 new_pdt = DP_PEER_DEVICE_NONE; u8 new_pdt = DP_PEER_DEVICE_NONE;
bool new_mcs = 0;
bool created = false, send_link_addr = false, changed = false; bool created = false, send_link_addr = false, changed = false;
port = drm_dp_get_port(mstb, port_msg->port_number); port = drm_dp_get_port(mstb, port_msg->port_number);
...@@ -2245,7 +2262,7 @@ drm_dp_mst_handle_link_address_port(struct drm_dp_mst_branch *mstb, ...@@ -2245,7 +2262,7 @@ drm_dp_mst_handle_link_address_port(struct drm_dp_mst_branch *mstb,
port->input = port_msg->input_port; port->input = port_msg->input_port;
if (!port->input) if (!port->input)
new_pdt = port_msg->peer_device_type; new_pdt = port_msg->peer_device_type;
port->mcs = port_msg->mcs; new_mcs = port_msg->mcs;
port->ddps = port_msg->ddps; port->ddps = port_msg->ddps;
port->ldps = port_msg->legacy_device_plug_status; port->ldps = port_msg->legacy_device_plug_status;
port->dpcd_rev = port_msg->dpcd_revision; port->dpcd_rev = port_msg->dpcd_revision;
...@@ -2272,7 +2289,7 @@ drm_dp_mst_handle_link_address_port(struct drm_dp_mst_branch *mstb, ...@@ -2272,7 +2289,7 @@ drm_dp_mst_handle_link_address_port(struct drm_dp_mst_branch *mstb,
} }
} }
ret = drm_dp_port_set_pdt(port, new_pdt); ret = drm_dp_port_set_pdt(port, new_pdt, new_mcs);
if (ret == 1) { if (ret == 1) {
send_link_addr = true; send_link_addr = true;
} else if (ret < 0) { } else if (ret < 0) {
...@@ -2286,7 +2303,8 @@ drm_dp_mst_handle_link_address_port(struct drm_dp_mst_branch *mstb, ...@@ -2286,7 +2303,8 @@ drm_dp_mst_handle_link_address_port(struct drm_dp_mst_branch *mstb,
* we're coming out of suspend. In this case, always resend the link * we're coming out of suspend. In this case, always resend the link
* address if there's an MSTB on this port * address if there's an MSTB on this port
*/ */
if (!created && port->pdt == DP_PEER_DEVICE_MST_BRANCHING) if (!created && port->pdt == DP_PEER_DEVICE_MST_BRANCHING &&
port->mcs)
send_link_addr = true; send_link_addr = true;
if (port->connector) if (port->connector)
...@@ -2323,6 +2341,7 @@ drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb, ...@@ -2323,6 +2341,7 @@ drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb,
struct drm_dp_mst_port *port; struct drm_dp_mst_port *port;
int old_ddps, old_input, ret, i; int old_ddps, old_input, ret, i;
u8 new_pdt; u8 new_pdt;
bool new_mcs;
bool dowork = false, create_connector = false; bool dowork = false, create_connector = false;
port = drm_dp_get_port(mstb, conn_stat->port_number); port = drm_dp_get_port(mstb, conn_stat->port_number);
...@@ -2354,7 +2373,6 @@ drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb, ...@@ -2354,7 +2373,6 @@ drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb,
old_ddps = port->ddps; old_ddps = port->ddps;
old_input = port->input; old_input = port->input;
port->input = conn_stat->input_port; port->input = conn_stat->input_port;
port->mcs = conn_stat->message_capability_status;
port->ldps = conn_stat->legacy_device_plug_status; port->ldps = conn_stat->legacy_device_plug_status;
port->ddps = conn_stat->displayport_device_plug_status; port->ddps = conn_stat->displayport_device_plug_status;
...@@ -2367,8 +2385,8 @@ drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb, ...@@ -2367,8 +2385,8 @@ drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb,
} }
new_pdt = port->input ? DP_PEER_DEVICE_NONE : conn_stat->peer_device_type; new_pdt = port->input ? DP_PEER_DEVICE_NONE : conn_stat->peer_device_type;
new_mcs = conn_stat->message_capability_status;
ret = drm_dp_port_set_pdt(port, new_pdt); ret = drm_dp_port_set_pdt(port, new_pdt, new_mcs);
if (ret == 1) { if (ret == 1) {
dowork = true; dowork = true;
} else if (ret < 0) { } else if (ret < 0) {
...@@ -3929,6 +3947,8 @@ drm_dp_mst_detect_port(struct drm_connector *connector, ...@@ -3929,6 +3947,8 @@ drm_dp_mst_detect_port(struct drm_connector *connector,
switch (port->pdt) { switch (port->pdt) {
case DP_PEER_DEVICE_NONE: case DP_PEER_DEVICE_NONE:
case DP_PEER_DEVICE_MST_BRANCHING: case DP_PEER_DEVICE_MST_BRANCHING:
if (!port->mcs)
ret = connector_status_connected;
break; break;
case DP_PEER_DEVICE_SST_SINK: case DP_PEER_DEVICE_SST_SINK:
...@@ -4541,7 +4561,7 @@ drm_dp_delayed_destroy_port(struct drm_dp_mst_port *port) ...@@ -4541,7 +4561,7 @@ drm_dp_delayed_destroy_port(struct drm_dp_mst_port *port)
if (port->connector) if (port->connector)
port->mgr->cbs->destroy_connector(port->mgr, port->connector); port->mgr->cbs->destroy_connector(port->mgr, port->connector);
drm_dp_port_set_pdt(port, DP_PEER_DEVICE_NONE); drm_dp_port_set_pdt(port, DP_PEER_DEVICE_NONE, port->mcs);
drm_dp_mst_put_port_malloc(port); drm_dp_mst_put_port_malloc(port);
} }
......
...@@ -9,16 +9,16 @@ ...@@ -9,16 +9,16 @@
#include "i915_gem_ioctls.h" #include "i915_gem_ioctls.h"
#include "i915_gem_object.h" #include "i915_gem_object.h"
static __always_inline u32 __busy_read_flag(u8 id) static __always_inline u32 __busy_read_flag(u16 id)
{ {
if (id == (u8)I915_ENGINE_CLASS_INVALID) if (id == (u16)I915_ENGINE_CLASS_INVALID)
return 0xffff0000u; return 0xffff0000u;
GEM_BUG_ON(id >= 16); GEM_BUG_ON(id >= 16);
return 0x10000u << id; return 0x10000u << id;
} }
static __always_inline u32 __busy_write_id(u8 id) static __always_inline u32 __busy_write_id(u16 id)
{ {
/* /*
* The uABI guarantees an active writer is also amongst the read * The uABI guarantees an active writer is also amongst the read
...@@ -29,14 +29,14 @@ static __always_inline u32 __busy_write_id(u8 id) ...@@ -29,14 +29,14 @@ static __always_inline u32 __busy_write_id(u8 id)
* last_read - hence we always set both read and write busy for * last_read - hence we always set both read and write busy for
* last_write. * last_write.
*/ */
if (id == (u8)I915_ENGINE_CLASS_INVALID) if (id == (u16)I915_ENGINE_CLASS_INVALID)
return 0xffffffffu; return 0xffffffffu;
return (id + 1) | __busy_read_flag(id); return (id + 1) | __busy_read_flag(id);
} }
static __always_inline unsigned int static __always_inline unsigned int
__busy_set_if_active(const struct dma_fence *fence, u32 (*flag)(u8 id)) __busy_set_if_active(const struct dma_fence *fence, u32 (*flag)(u16 id))
{ {
const struct i915_request *rq; const struct i915_request *rq;
...@@ -57,7 +57,7 @@ __busy_set_if_active(const struct dma_fence *fence, u32 (*flag)(u8 id)) ...@@ -57,7 +57,7 @@ __busy_set_if_active(const struct dma_fence *fence, u32 (*flag)(u8 id))
return 0; return 0;
/* Beware type-expansion follies! */ /* Beware type-expansion follies! */
BUILD_BUG_ON(!typecheck(u8, rq->engine->uabi_class)); BUILD_BUG_ON(!typecheck(u16, rq->engine->uabi_class));
return flag(rq->engine->uabi_class); return flag(rq->engine->uabi_class);
} }
......
...@@ -402,7 +402,7 @@ struct get_pages_work { ...@@ -402,7 +402,7 @@ struct get_pages_work {
static struct sg_table * static struct sg_table *
__i915_gem_userptr_alloc_pages(struct drm_i915_gem_object *obj, __i915_gem_userptr_alloc_pages(struct drm_i915_gem_object *obj,
struct page **pvec, int num_pages) struct page **pvec, unsigned long num_pages)
{ {
unsigned int max_segment = i915_sg_segment_size(); unsigned int max_segment = i915_sg_segment_size();
struct sg_table *st; struct sg_table *st;
...@@ -448,9 +448,10 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work) ...@@ -448,9 +448,10 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work)
{ {
struct get_pages_work *work = container_of(_work, typeof(*work), work); struct get_pages_work *work = container_of(_work, typeof(*work), work);
struct drm_i915_gem_object *obj = work->obj; struct drm_i915_gem_object *obj = work->obj;
const int npages = obj->base.size >> PAGE_SHIFT; const unsigned long npages = obj->base.size >> PAGE_SHIFT;
unsigned long pinned;
struct page **pvec; struct page **pvec;
int pinned, ret; int ret;
ret = -ENOMEM; ret = -ENOMEM;
pinned = 0; pinned = 0;
...@@ -553,7 +554,7 @@ __i915_gem_userptr_get_pages_schedule(struct drm_i915_gem_object *obj) ...@@ -553,7 +554,7 @@ __i915_gem_userptr_get_pages_schedule(struct drm_i915_gem_object *obj)
static int i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) static int i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj)
{ {
const int num_pages = obj->base.size >> PAGE_SHIFT; const unsigned long num_pages = obj->base.size >> PAGE_SHIFT;
struct mm_struct *mm = obj->userptr.mm->mm; struct mm_struct *mm = obj->userptr.mm->mm;
struct page **pvec; struct page **pvec;
struct sg_table *pages; struct sg_table *pages;
......
...@@ -274,8 +274,8 @@ struct intel_engine_cs { ...@@ -274,8 +274,8 @@ struct intel_engine_cs {
u8 class; u8 class;
u8 instance; u8 instance;
u8 uabi_class; u16 uabi_class;
u8 uabi_instance; u16 uabi_instance;
u32 uabi_capabilities; u32 uabi_capabilities;
u32 context_size; u32 context_size;
......
...@@ -1177,6 +1177,7 @@ gen8_ppgtt_insert_pte(struct i915_ppgtt *ppgtt, ...@@ -1177,6 +1177,7 @@ gen8_ppgtt_insert_pte(struct i915_ppgtt *ppgtt,
pd = i915_pd_entry(pdp, gen8_pd_index(idx, 2)); pd = i915_pd_entry(pdp, gen8_pd_index(idx, 2));
vaddr = kmap_atomic_px(i915_pt_entry(pd, gen8_pd_index(idx, 1))); vaddr = kmap_atomic_px(i915_pt_entry(pd, gen8_pd_index(idx, 1)));
do { do {
GEM_BUG_ON(iter->sg->length < I915_GTT_PAGE_SIZE);
vaddr[gen8_pd_index(idx, 0)] = pte_encode | iter->dma; vaddr[gen8_pd_index(idx, 0)] = pte_encode | iter->dma;
iter->dma += I915_GTT_PAGE_SIZE; iter->dma += I915_GTT_PAGE_SIZE;
...@@ -1660,6 +1661,7 @@ static void gen6_ppgtt_insert_entries(struct i915_address_space *vm, ...@@ -1660,6 +1661,7 @@ static void gen6_ppgtt_insert_entries(struct i915_address_space *vm,
vaddr = kmap_atomic_px(i915_pt_entry(pd, act_pt)); vaddr = kmap_atomic_px(i915_pt_entry(pd, act_pt));
do { do {
GEM_BUG_ON(iter.sg->length < I915_GTT_PAGE_SIZE);
vaddr[act_pte] = pte_encode | GEN6_PTE_ADDR_ENCODE(iter.dma); vaddr[act_pte] = pte_encode | GEN6_PTE_ADDR_ENCODE(iter.dma);
iter.dma += I915_GTT_PAGE_SIZE; iter.dma += I915_GTT_PAGE_SIZE;
......
...@@ -78,8 +78,10 @@ static int panfrost_ioctl_get_param(struct drm_device *ddev, void *data, struct ...@@ -78,8 +78,10 @@ static int panfrost_ioctl_get_param(struct drm_device *ddev, void *data, struct
static int panfrost_ioctl_create_bo(struct drm_device *dev, void *data, static int panfrost_ioctl_create_bo(struct drm_device *dev, void *data,
struct drm_file *file) struct drm_file *file)
{ {
struct panfrost_file_priv *priv = file->driver_priv;
struct panfrost_gem_object *bo; struct panfrost_gem_object *bo;
struct drm_panfrost_create_bo *args = data; struct drm_panfrost_create_bo *args = data;
struct panfrost_gem_mapping *mapping;
if (!args->size || args->pad || if (!args->size || args->pad ||
(args->flags & ~(PANFROST_BO_NOEXEC | PANFROST_BO_HEAP))) (args->flags & ~(PANFROST_BO_NOEXEC | PANFROST_BO_HEAP)))
...@@ -95,7 +97,14 @@ static int panfrost_ioctl_create_bo(struct drm_device *dev, void *data, ...@@ -95,7 +97,14 @@ static int panfrost_ioctl_create_bo(struct drm_device *dev, void *data,
if (IS_ERR(bo)) if (IS_ERR(bo))
return PTR_ERR(bo); return PTR_ERR(bo);
args->offset = bo->node.start << PAGE_SHIFT; mapping = panfrost_gem_mapping_get(bo, priv);
if (!mapping) {
drm_gem_object_put_unlocked(&bo->base.base);
return -EINVAL;
}
args->offset = mapping->mmnode.start << PAGE_SHIFT;
panfrost_gem_mapping_put(mapping);
return 0; return 0;
} }
...@@ -119,6 +128,11 @@ panfrost_lookup_bos(struct drm_device *dev, ...@@ -119,6 +128,11 @@ panfrost_lookup_bos(struct drm_device *dev,
struct drm_panfrost_submit *args, struct drm_panfrost_submit *args,
struct panfrost_job *job) struct panfrost_job *job)
{ {
struct panfrost_file_priv *priv = file_priv->driver_priv;
struct panfrost_gem_object *bo;
unsigned int i;
int ret;
job->bo_count = args->bo_handle_count; job->bo_count = args->bo_handle_count;
if (!job->bo_count) if (!job->bo_count)
...@@ -130,9 +144,32 @@ panfrost_lookup_bos(struct drm_device *dev, ...@@ -130,9 +144,32 @@ panfrost_lookup_bos(struct drm_device *dev,
if (!job->implicit_fences) if (!job->implicit_fences)
return -ENOMEM; return -ENOMEM;
return drm_gem_objects_lookup(file_priv, ret = drm_gem_objects_lookup(file_priv,
(void __user *)(uintptr_t)args->bo_handles, (void __user *)(uintptr_t)args->bo_handles,
job->bo_count, &job->bos); job->bo_count, &job->bos);
if (ret)
return ret;
job->mappings = kvmalloc_array(job->bo_count,
sizeof(struct panfrost_gem_mapping *),
GFP_KERNEL | __GFP_ZERO);
if (!job->mappings)
return -ENOMEM;
for (i = 0; i < job->bo_count; i++) {
struct panfrost_gem_mapping *mapping;
bo = to_panfrost_bo(job->bos[i]);
mapping = panfrost_gem_mapping_get(bo, priv);
if (!mapping) {
ret = -EINVAL;
break;
}
job->mappings[i] = mapping;
}
return ret;
} }
/** /**
...@@ -320,7 +357,9 @@ out: ...@@ -320,7 +357,9 @@ out:
static int panfrost_ioctl_get_bo_offset(struct drm_device *dev, void *data, static int panfrost_ioctl_get_bo_offset(struct drm_device *dev, void *data,
struct drm_file *file_priv) struct drm_file *file_priv)
{ {
struct panfrost_file_priv *priv = file_priv->driver_priv;
struct drm_panfrost_get_bo_offset *args = data; struct drm_panfrost_get_bo_offset *args = data;
struct panfrost_gem_mapping *mapping;
struct drm_gem_object *gem_obj; struct drm_gem_object *gem_obj;
struct panfrost_gem_object *bo; struct panfrost_gem_object *bo;
...@@ -331,18 +370,26 @@ static int panfrost_ioctl_get_bo_offset(struct drm_device *dev, void *data, ...@@ -331,18 +370,26 @@ static int panfrost_ioctl_get_bo_offset(struct drm_device *dev, void *data,
} }
bo = to_panfrost_bo(gem_obj); bo = to_panfrost_bo(gem_obj);
args->offset = bo->node.start << PAGE_SHIFT; mapping = panfrost_gem_mapping_get(bo, priv);
drm_gem_object_put_unlocked(gem_obj); drm_gem_object_put_unlocked(gem_obj);
if (!mapping)
return -EINVAL;
args->offset = mapping->mmnode.start << PAGE_SHIFT;
panfrost_gem_mapping_put(mapping);
return 0; return 0;
} }
static int panfrost_ioctl_madvise(struct drm_device *dev, void *data, static int panfrost_ioctl_madvise(struct drm_device *dev, void *data,
struct drm_file *file_priv) struct drm_file *file_priv)