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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1004,7 +1004,7 @@ static const struct pci_device_id pciidlist[] = {
	{0x1002, 0x734F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI14},

	/* 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 */
	{0x1002, 0x7360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI12|AMD_EXP_HW_SUPPORT},
+80 −60
Original line number Diff line number Diff line
@@ -1916,55 +1916,72 @@ static u8 drm_dp_calculate_rad(struct drm_dp_mst_port *port,
	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_branch *mstb;
	u8 rad[8], lct;
	int ret = 0;

	if (port->pdt == new_pdt)
	if (port->pdt == new_pdt && port->mcs == new_mcs)
		return 0;

	/* Teardown the old pdt, if there is one */
	switch (port->pdt) {
	case DP_PEER_DEVICE_DP_LEGACY_CONV:
	case DP_PEER_DEVICE_SST_SINK:
	if (port->pdt != DP_PEER_DEVICE_NONE) {
		if (drm_dp_mst_is_dp_mst_end_device(port->pdt, port->mcs)) {
			/*
		 * If the new PDT would also have an i2c bus, don't bother
		 * with reregistering it
			 * If the new PDT would also have an i2c bus,
			 * don't bother with reregistering it
			 */
		if (new_pdt == DP_PEER_DEVICE_DP_LEGACY_CONV ||
		    new_pdt == DP_PEER_DEVICE_SST_SINK) {
			if (new_pdt != DP_PEER_DEVICE_NONE &&
			    drm_dp_mst_is_dp_mst_end_device(new_pdt, new_mcs)) {
				port->pdt = new_pdt;
				port->mcs = new_mcs;
				return 0;
			}

			/* remove i2c over sideband */
			drm_dp_mst_unregister_i2c_bus(&port->aux);
		break;
	case DP_PEER_DEVICE_MST_BRANCHING:
		} else {
			mutex_lock(&mgr->lock);
			drm_dp_mst_topology_put_mstb(port->mstb);
			port->mstb = NULL;
			mutex_unlock(&mgr->lock);
		break;
		}
	}

	port->pdt = new_pdt;
	switch (port->pdt) {
	case DP_PEER_DEVICE_DP_LEGACY_CONV:
	case DP_PEER_DEVICE_SST_SINK:
	port->mcs = new_mcs;

	if (port->pdt != DP_PEER_DEVICE_NONE) {
		if (drm_dp_mst_is_dp_mst_end_device(port->pdt, port->mcs)) {
			/* add i2c over sideband */
			ret = drm_dp_mst_register_i2c_bus(&port->aux);
		break;

	case DP_PEER_DEVICE_MST_BRANCHING:
		} else {
			lct = drm_dp_calculate_rad(port, rad);
			mstb = drm_dp_add_mst_branch_device(lct, rad);
			if (!mstb) {
				ret = -ENOMEM;
			DRM_ERROR("Failed to create MSTB for port %p", port);
				DRM_ERROR("Failed to create MSTB for port %p",
					  port);
				goto out;
			}

@@ -1982,7 +1999,7 @@ static int drm_dp_port_set_pdt(struct drm_dp_mst_port *port, u8 new_pdt)

			/* And make sure we send a link address for this */
			ret = 1;
		break;
		}
	}

out:
@@ -2135,9 +2152,8 @@ drm_dp_mst_port_add_connector(struct drm_dp_mst_branch *mstb,
		goto error;
	}

	if ((port->pdt == DP_PEER_DEVICE_DP_LEGACY_CONV ||
	     port->pdt == DP_PEER_DEVICE_SST_SINK) &&
	    port->port_num >= DP_MST_LOGICAL_PORT_0) {
	if (port->pdt != DP_PEER_DEVICE_NONE &&
	    drm_dp_mst_is_dp_mst_end_device(port->pdt, port->mcs)) {
		port->cached_edid = drm_get_edid(port->connector,
						 &port->aux.ddc);
		drm_connector_set_tile_property(port->connector);
@@ -2201,6 +2217,7 @@ drm_dp_mst_handle_link_address_port(struct drm_dp_mst_branch *mstb,
	struct drm_dp_mst_port *port;
	int old_ddps = 0, ret;
	u8 new_pdt = DP_PEER_DEVICE_NONE;
	bool new_mcs = 0;
	bool created = false, send_link_addr = false, changed = false;

	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,
	port->input = port_msg->input_port;
	if (!port->input)
		new_pdt = port_msg->peer_device_type;
	port->mcs = port_msg->mcs;
	new_mcs = port_msg->mcs;
	port->ddps = port_msg->ddps;
	port->ldps = port_msg->legacy_device_plug_status;
	port->dpcd_rev = port_msg->dpcd_revision;
@@ -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) {
		send_link_addr = true;
	} else if (ret < 0) {
@@ -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
	 * 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;

	if (port->connector)
@@ -2323,6 +2341,7 @@ drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb,
	struct drm_dp_mst_port *port;
	int old_ddps, old_input, ret, i;
	u8 new_pdt;
	bool new_mcs;
	bool dowork = false, create_connector = false;

	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,
	old_ddps = port->ddps;
	old_input = port->input;
	port->input = conn_stat->input_port;
	port->mcs = conn_stat->message_capability_status;
	port->ldps = conn_stat->legacy_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,
	}

	new_pdt = port->input ? DP_PEER_DEVICE_NONE : conn_stat->peer_device_type;

	ret = drm_dp_port_set_pdt(port, new_pdt);
	new_mcs = conn_stat->message_capability_status;
	ret = drm_dp_port_set_pdt(port, new_pdt, new_mcs);
	if (ret == 1) {
		dowork = true;
	} else if (ret < 0) {
@@ -3929,6 +3947,8 @@ drm_dp_mst_detect_port(struct drm_connector *connector,
	switch (port->pdt) {
	case DP_PEER_DEVICE_NONE:
	case DP_PEER_DEVICE_MST_BRANCHING:
		if (!port->mcs)
			ret = connector_status_connected;
		break;

	case DP_PEER_DEVICE_SST_SINK:
@@ -4541,7 +4561,7 @@ drm_dp_delayed_destroy_port(struct drm_dp_mst_port *port)
	if (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);
}

+6 −6
Original line number Diff line number Diff line
@@ -9,16 +9,16 @@
#include "i915_gem_ioctls.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;

	GEM_BUG_ON(id >= 16);
	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
@@ -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_write.
	 */
	if (id == (u8)I915_ENGINE_CLASS_INVALID)
	if (id == (u16)I915_ENGINE_CLASS_INVALID)
		return 0xffffffffu;

	return (id + 1) | __busy_read_flag(id);
}

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;

@@ -57,7 +57,7 @@ __busy_set_if_active(const struct dma_fence *fence, u32 (*flag)(u8 id))
		return 0;

	/* 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);
}

+5 −4
Original line number Diff line number Diff line
@@ -402,7 +402,7 @@ struct get_pages_work {

static struct sg_table *
__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();
	struct sg_table *st;
@@ -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 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;
	int pinned, ret;
	int ret;

	ret = -ENOMEM;
	pinned = 0;
@@ -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)
{
	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 page **pvec;
	struct sg_table *pages;
+2 −2
Original line number Diff line number Diff line
@@ -274,8 +274,8 @@ struct intel_engine_cs {
	u8 class;
	u8 instance;

	u8 uabi_class;
	u8 uabi_instance;
	u16 uabi_class;
	u16 uabi_instance;

	u32 uabi_capabilities;
	u32 context_size;
Loading