Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a703f42d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux

Pull more drm fixes from Dave Airlie:
 "Some more fixes trickled in:

  A bunch of VC4 ones since it's a pretty new driver not much chance of
  regressions, and it fixes GPU resets.

  Also one atomic fix, one set of fixes for a common bug in TTM cleanup,
  and one i915 hotplug fix"

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux:
  drm/nouveau: use post-decrement in error handling
  drm/atomic: Allow for holes in connector state, v2.
  drm/i915: Fix hpd live status bits for g4x
  drm/vc4: Use runtime PM to power cycle the device when the GPU hangs.
  drm/vc4: Enable runtime PM.
  drm/vc4: Fix spurious GPU resets due to BO reuse.
  drm/vc4: Drop error message on seqno wait timeouts.
  drm/vc4: Fix -ERESTARTSYS error return from BO waits.
  drm/vc4: Return an ERR_PTR from BO creation instead of NULL.
  drm/vc4: Fix the clear color for the first tile rendered.
  drm/vc4: Validate that WAIT_BO padding is cleared.
  drm/radeon: use post-decrement in error handling
  drm/amdgpu: use post-decrement in error handling
parents 59ceeaaf 4fbbed46
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -712,7 +712,7 @@ static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm)
						       0, PAGE_SIZE,
						       PCI_DMA_BIDIRECTIONAL);
		if (pci_dma_mapping_error(adev->pdev, gtt->ttm.dma_address[i])) {
			while (--i) {
			while (i--) {
				pci_unmap_page(adev->pdev, gtt->ttm.dma_address[i],
					       PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
				gtt->ttm.dma_address[i] = 0;
+20 −24
Original line number Diff line number Diff line
@@ -65,8 +65,6 @@ drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
	 */
	state->allow_modeset = true;

	state->num_connector = ACCESS_ONCE(dev->mode_config.num_connector);

	state->crtcs = kcalloc(dev->mode_config.num_crtc,
			       sizeof(*state->crtcs), GFP_KERNEL);
	if (!state->crtcs)
@@ -83,16 +81,6 @@ drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
				      sizeof(*state->plane_states), GFP_KERNEL);
	if (!state->plane_states)
		goto fail;
	state->connectors = kcalloc(state->num_connector,
				    sizeof(*state->connectors),
				    GFP_KERNEL);
	if (!state->connectors)
		goto fail;
	state->connector_states = kcalloc(state->num_connector,
					  sizeof(*state->connector_states),
					  GFP_KERNEL);
	if (!state->connector_states)
		goto fail;

	state->dev = dev;

@@ -823,19 +811,27 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state,

	index = drm_connector_index(connector);

	/*
	 * Construction of atomic state updates can race with a connector
	 * hot-add which might overflow. In this case flip the table and just
	 * restart the entire ioctl - no one is fast enough to livelock a cpu
	 * with physical hotplug events anyway.
	 *
	 * Note that we only grab the indexes once we have the right lock to
	 * prevent hotplug/unplugging of connectors. So removal is no problem,
	 * at most the array is a bit too large.
	 */
	if (index >= state->num_connector) {
		DRM_DEBUG_ATOMIC("Hot-added connector would overflow state array, restarting\n");
		return ERR_PTR(-EAGAIN);
		struct drm_connector **c;
		struct drm_connector_state **cs;
		int alloc = max(index + 1, config->num_connector);

		c = krealloc(state->connectors, alloc * sizeof(*state->connectors), GFP_KERNEL);
		if (!c)
			return ERR_PTR(-ENOMEM);

		state->connectors = c;
		memset(&state->connectors[state->num_connector], 0,
		       sizeof(*state->connectors) * (alloc - state->num_connector));

		cs = krealloc(state->connector_states, alloc * sizeof(*state->connector_states), GFP_KERNEL);
		if (!cs)
			return ERR_PTR(-ENOMEM);

		state->connector_states = cs;
		memset(&state->connector_states[state->num_connector], 0,
		       sizeof(*state->connector_states) * (alloc - state->num_connector));
		state->num_connector = alloc;
	}

	if (state->connector_states[index])
+1 −1
Original line number Diff line number Diff line
@@ -1493,7 +1493,7 @@ void drm_atomic_helper_swap_state(struct drm_device *dev,
{
	int i;

	for (i = 0; i < dev->mode_config.num_connector; i++) {
	for (i = 0; i < state->num_connector; i++) {
		struct drm_connector *connector = state->connectors[i];

		if (!connector)
+20 −29
Original line number Diff line number Diff line
@@ -918,12 +918,19 @@ int drm_connector_init(struct drm_device *dev,
	connector->base.properties = &connector->properties;
	connector->dev = dev;
	connector->funcs = funcs;

	connector->connector_id = ida_simple_get(&config->connector_ida, 0, 0, GFP_KERNEL);
	if (connector->connector_id < 0) {
		ret = connector->connector_id;
		goto out_put;
	}

	connector->connector_type = connector_type;
	connector->connector_type_id =
		ida_simple_get(connector_ida, 1, 0, GFP_KERNEL);
	if (connector->connector_type_id < 0) {
		ret = connector->connector_type_id;
		goto out_put;
		goto out_put_id;
	}
	connector->name =
		kasprintf(GFP_KERNEL, "%s-%d",
@@ -931,7 +938,7 @@ int drm_connector_init(struct drm_device *dev,
			  connector->connector_type_id);
	if (!connector->name) {
		ret = -ENOMEM;
		goto out_put;
		goto out_put_type_id;
	}

	INIT_LIST_HEAD(&connector->probed_modes);
@@ -959,7 +966,12 @@ int drm_connector_init(struct drm_device *dev,
	}

	connector->debugfs_entry = NULL;

out_put_type_id:
	if (ret)
		ida_remove(connector_ida, connector->connector_type_id);
out_put_id:
	if (ret)
		ida_remove(&config->connector_ida, connector->connector_id);
out_put:
	if (ret)
		drm_mode_object_put(dev, &connector->base);
@@ -996,6 +1008,9 @@ void drm_connector_cleanup(struct drm_connector *connector)
	ida_remove(&drm_connector_enum_list[connector->connector_type].ida,
		   connector->connector_type_id);

	ida_remove(&dev->mode_config.connector_ida,
		   connector->connector_id);

	kfree(connector->display_info.bus_formats);
	drm_mode_object_put(dev, &connector->base);
	kfree(connector->name);
@@ -1012,32 +1027,6 @@ void drm_connector_cleanup(struct drm_connector *connector)
}
EXPORT_SYMBOL(drm_connector_cleanup);

/**
 * drm_connector_index - find the index of a registered connector
 * @connector: connector to find index for
 *
 * Given a registered connector, return the index of that connector within a DRM
 * device's list of connectors.
 */
unsigned int drm_connector_index(struct drm_connector *connector)
{
	unsigned int index = 0;
	struct drm_connector *tmp;
	struct drm_mode_config *config = &connector->dev->mode_config;

	WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));

	drm_for_each_connector(tmp, connector->dev) {
		if (tmp == connector)
			return index;

		index++;
	}

	BUG();
}
EXPORT_SYMBOL(drm_connector_index);

/**
 * drm_connector_register - register a connector
 * @connector: the connector to register
@@ -5789,6 +5778,7 @@ void drm_mode_config_init(struct drm_device *dev)
	INIT_LIST_HEAD(&dev->mode_config.plane_list);
	idr_init(&dev->mode_config.crtc_idr);
	idr_init(&dev->mode_config.tile_idr);
	ida_init(&dev->mode_config.connector_ida);

	drm_modeset_lock_all(dev);
	drm_mode_create_standard_properties(dev);
@@ -5869,6 +5859,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)
		crtc->funcs->destroy(crtc);
	}

	ida_destroy(&dev->mode_config.connector_ida);
	idr_destroy(&dev->mode_config.tile_idr);
	idr_destroy(&dev->mode_config.crtc_idr);
	drm_modeset_lock_fini(&dev->mode_config.connection_mutex);
+8 −7
Original line number Diff line number Diff line
@@ -3287,19 +3287,20 @@ enum skl_disp_power_wells {

#define PORT_HOTPLUG_STAT	_MMIO(dev_priv->info.display_mmio_offset + 0x61114)
/*
 * HDMI/DP bits are gen4+
 * HDMI/DP bits are g4x+
 *
 * WARNING: Bspec for hpd status bits on gen4 seems to be completely confused.
 * Please check the detailed lore in the commit message for for experimental
 * evidence.
 */
#define   PORTD_HOTPLUG_LIVE_STATUS_G4X		(1 << 29)
/* Bspec says GM45 should match G4X/VLV/CHV, but reality disagrees */
#define   PORTD_HOTPLUG_LIVE_STATUS_GM45	(1 << 29)
#define   PORTC_HOTPLUG_LIVE_STATUS_GM45	(1 << 28)
#define   PORTB_HOTPLUG_LIVE_STATUS_GM45	(1 << 27)
/* G4X/VLV/CHV DP/HDMI bits again match Bspec */
#define   PORTD_HOTPLUG_LIVE_STATUS_G4X		(1 << 27)
#define   PORTC_HOTPLUG_LIVE_STATUS_G4X		(1 << 28)
#define   PORTB_HOTPLUG_LIVE_STATUS_G4X		(1 << 27)
/* VLV DP/HDMI bits again match Bspec */
#define   PORTD_HOTPLUG_LIVE_STATUS_VLV		(1 << 27)
#define   PORTC_HOTPLUG_LIVE_STATUS_VLV		(1 << 28)
#define   PORTB_HOTPLUG_LIVE_STATUS_VLV		(1 << 29)
#define   PORTB_HOTPLUG_LIVE_STATUS_G4X		(1 << 29)
#define   PORTD_HOTPLUG_INT_STATUS		(3 << 21)
#define   PORTD_HOTPLUG_INT_LONG_PULSE		(2 << 21)
#define   PORTD_HOTPLUG_INT_SHORT_PULSE		(1 << 21)
Loading