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

Commit 36d1701c authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge remote branch 'nouveau/for-airlied' of ../drm-nouveau-next into drm-testing

* 'nouveau/for-airlied' of ../drm-nouveau-next:
  drm/nv50: cast IGP memory location to u64 before shifting
  drm/nv50: use alternate source of SOR_MODE_CTRL for DP hack
  drm/nouveau: fix dual-link displays when plugged into single-link outputs
  drm/nv50: obey dcb->duallink_possible
  drm/nv50: fix duallink_possible calculation for DCB 4.0 cards
  drm/nouveau: don't execute INIT_GPIO unless we're really running the table
  drm/nv40: allow cold-booting of nv4x chipsets
  drm/nouveau: fix POST detection for certain chipsets
  drm/nouveau: Add getparam for current PTIMER time.
  drm/nouveau: allow cursor image and position to survive suspend
parents afa3b60c 8b281db5
Loading
Loading
Loading
Loading
+40 −11
Original line number Diff line number Diff line
@@ -2827,6 +2827,9 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)

		BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, gpio->entry);

		BIOSLOG(bios, "0x%04X: set gpio 0x%02x, state %d\n",
			offset, gpio->tag, gpio->state_default);
		if (bios->execute)
			nv50_gpio_set(bios->dev, gpio->tag, gpio->state_default);

		/* The NVIDIA binary driver doesn't appear to actually do
@@ -5553,12 +5556,6 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb,
	entry->bus = (conn >> 16) & 0xf;
	entry->location = (conn >> 20) & 0x3;
	entry->or = (conn >> 24) & 0xf;
	/*
	 * Normal entries consist of a single bit, but dual link has the
	 * next most significant bit set too
	 */
	entry->duallink_possible =
			((1 << (ffs(entry->or) - 1)) * 3 == entry->or);

	switch (entry->type) {
	case OUTPUT_ANALOG:
@@ -5642,6 +5639,16 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb,
		break;
	}

	if (dcb->version < 0x40) {
		/* Normal entries consist of a single bit, but dual link has
		 * the next most significant bit set too
		 */
		entry->duallink_possible =
			((1 << (ffs(entry->or) - 1)) * 3 == entry->or);
	} else {
		entry->duallink_possible = (entry->sorconf.link == 3);
	}

	/* unsure what DCB version introduces this, 3.0? */
	if (conf & 0x100000)
		entry->i2c_upper_default = true;
@@ -6225,6 +6232,30 @@ nouveau_bios_i2c_devices_takedown(struct drm_device *dev)
		nouveau_i2c_fini(dev, entry);
}

static bool
nouveau_bios_posted(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	bool was_locked;
	unsigned htotal;

	if (dev_priv->chipset >= NV_50) {
		if (NVReadVgaCrtc(dev, 0, 0x00) == 0 &&
		    NVReadVgaCrtc(dev, 0, 0x1a) == 0)
			return false;
		return true;
	}

	was_locked = NVLockVgaCrtcs(dev, false);
	htotal  = NVReadVgaCrtc(dev, 0, 0x06);
	htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x01) << 8;
	htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x20) << 4;
	htotal |= (NVReadVgaCrtc(dev, 0, 0x25) & 0x01) << 10;
	htotal |= (NVReadVgaCrtc(dev, 0, 0x41) & 0x01) << 11;
	NVLockVgaCrtcs(dev, was_locked);
	return (htotal != 0);
}

int
nouveau_bios_init(struct drm_device *dev)
{
@@ -6259,11 +6290,9 @@ nouveau_bios_init(struct drm_device *dev)
	bios->execute = false;

	/* ... unless card isn't POSTed already */
	if (dev_priv->card_type >= NV_10 &&
	    NVReadVgaCrtc(dev, 0, 0x00) == 0 &&
	    NVReadVgaCrtc(dev, 0, 0x1a) == 0) {
	if (!nouveau_bios_posted(dev)) {
		NV_INFO(dev, "Adaptor not initialised\n");
		if (dev_priv->card_type < NV_50) {
		if (dev_priv->card_type < NV_40) {
			NV_ERROR(dev, "Unable to POST this chipset\n");
			return -ENODEV;
		}
+18 −16
Original line number Diff line number Diff line
@@ -432,24 +432,27 @@ nouveau_connector_set_property(struct drm_connector *connector,
}

static struct drm_display_mode *
nouveau_connector_native_mode(struct nouveau_connector *connector)
nouveau_connector_native_mode(struct drm_connector *connector)
{
	struct drm_device *dev = connector->base.dev;
	struct drm_connector_helper_funcs *helper = connector->helper_private;
	struct nouveau_connector *nv_connector = nouveau_connector(connector);
	struct drm_device *dev = connector->dev;
	struct drm_display_mode *mode, *largest = NULL;
	int high_w = 0, high_h = 0, high_v = 0;

	list_for_each_entry(mode, &nv_connector->base.probed_modes, head) {
		if (helper->mode_valid(connector, mode) != MODE_OK)
			continue;

		/* Use preferred mode if there is one.. */
	list_for_each_entry(mode, &connector->base.probed_modes, head) {
		if (mode->type & DRM_MODE_TYPE_PREFERRED) {
			NV_DEBUG_KMS(dev, "native mode from preferred\n");
			return drm_mode_duplicate(dev, mode);
		}
	}

	/* Otherwise, take the resolution with the largest width, then height,
	 * then vertical refresh
		/* Otherwise, take the resolution with the largest width, then
		 * height, then vertical refresh
		 */
	list_for_each_entry(mode, &connector->base.probed_modes, head) {
		if (mode->hdisplay < high_w)
			continue;

@@ -553,7 +556,7 @@ nouveau_connector_get_modes(struct drm_connector *connector)
	 */
	if (!nv_connector->native_mode)
		nv_connector->native_mode =
			nouveau_connector_native_mode(nv_connector);
			nouveau_connector_native_mode(connector);
	if (ret == 0 && nv_connector->native_mode) {
		struct drm_display_mode *mode;

@@ -584,9 +587,9 @@ nouveau_connector_mode_valid(struct drm_connector *connector,

	switch (nv_encoder->dcb->type) {
	case OUTPUT_LVDS:
		BUG_ON(!nv_connector->native_mode);
		if (mode->hdisplay > nv_connector->native_mode->hdisplay ||
		    mode->vdisplay > nv_connector->native_mode->vdisplay)
		if (nv_connector->native_mode &&
		    (mode->hdisplay > nv_connector->native_mode->hdisplay ||
		     mode->vdisplay > nv_connector->native_mode->vdisplay))
			return MODE_PANEL;

		min_clock = 0;
@@ -594,8 +597,7 @@ nouveau_connector_mode_valid(struct drm_connector *connector,
		break;
	case OUTPUT_TMDS:
		if ((dev_priv->card_type >= NV_50 && !nouveau_duallink) ||
		    (dev_priv->card_type < NV_50 &&
		     !nv_encoder->dcb->duallink_possible))
		    !nv_encoder->dcb->duallink_possible)
			max_clock = 165000;
		else
			max_clock = 330000;
@@ -729,7 +731,7 @@ nouveau_connector_create_lvds(struct drm_device *dev,
	if (ret == 0)
		goto out;
	nv_connector->detected_encoder = nv_encoder;
	nv_connector->native_mode = nouveau_connector_native_mode(nv_connector);
	nv_connector->native_mode = nouveau_connector_native_mode(connector);
	list_for_each_entry_safe(mode, temp, &connector->probed_modes, head)
		drm_mode_remove(connector, mode);

+2 −0
Original line number Diff line number Diff line
@@ -40,6 +40,8 @@ struct nouveau_crtc {
	int sharpness;
	int last_dpms;

	int cursor_saved_x, cursor_saved_y;

	struct {
		int cpp;
		bool blanked;
+29 −0
Original line number Diff line number Diff line
@@ -175,6 +175,13 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
		nouveau_bo_unpin(nouveau_fb->nvbo);
	}

	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
		struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);

		nouveau_bo_unmap(nv_crtc->cursor.nvbo);
		nouveau_bo_unpin(nv_crtc->cursor.nvbo);
	}

	NV_INFO(dev, "Evicting buffers...\n");
	ttm_bo_evict_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM);

@@ -314,12 +321,34 @@ nouveau_pci_resume(struct pci_dev *pdev)
		nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM);
	}

	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
		struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
		int ret;

		ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM);
		if (!ret)
			ret = nouveau_bo_map(nv_crtc->cursor.nvbo);
		if (ret)
			NV_ERROR(dev, "Could not pin/map cursor.\n");
	}

	if (dev_priv->card_type < NV_50) {
		nv04_display_restore(dev);
		NVLockVgaCrtcs(dev, false);
	} else
		nv50_display_init(dev);

	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
		struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);

		nv_crtc->cursor.set_offset(nv_crtc,
					nv_crtc->cursor.nvbo->bo.offset -
					dev_priv->vm_vram_base);

		nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x,
			nv_crtc->cursor_saved_y);
	}

	/* Force CLUT to get re-loaded during modeset */
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
		struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+2 −1
Original line number Diff line number Diff line
@@ -540,7 +540,8 @@ nouveau_mem_detect(struct drm_device *dev)
		dev_priv->vram_size  = nv_rd32(dev, NV04_FIFO_DATA);
		dev_priv->vram_size &= NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK;
		if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac)
			dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10) << 12;
			dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10);
			dev_priv->vram_sys_base <<= 12;
	}

	NV_INFO(dev, "Detected %dMiB VRAM\n", (int)(dev_priv->vram_size >> 20));
Loading