All of lore.kernel.org
 help / color / mirror / Atom feed
From: Maarten Lankhorst <maarten.lankhorst-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org>
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
Subject: Re: [PATCH] [RFC] drm/nouveau: bring back hdmi audio device after switcheroo power down
Date: Wed, 24 Jul 2013 15:38:35 +0200	[thread overview]
Message-ID: <51EFD8DB.10206@canonical.com> (raw)
In-Reply-To: <1374650022-17865-1-git-send-email-airlied-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Op 24-07-13 09:13, Dave Airlie schreef:
> After a full device powerdown via the optimus power switch, we seem
> to lose the HDMI device completely on power on, this keep track of
> whether we had a hdmi audio sub function device at power on, and
> pokes a magic register to make it reappear after the optimus power
> switch is thrown.
>
> This at least works on my NVC4 machine, probably needs testing on
> a few other laptops with other nvidia GPUs.
>
> Signed-off-by: Dave Airlie <airlied-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
>  drivers/gpu/drm/nouveau/nouveau_drm.c | 32 ++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/nouveau/nouveau_drm.h |  2 ++
>  drivers/gpu/drm/nouveau/nouveau_vga.c | 17 +++++++++++++++++
>  3 files changed, 51 insertions(+)
>
> diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
> index 6197266..12a6240 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_drm.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
> @@ -296,6 +296,31 @@ static int nouveau_drm_probe(struct pci_dev *pdev,
>  	return 0;
>  }
>  
> +#define PCI_CLASS_MULTIMEDIA_HD_AUDIO 0x0403
> +
> +static void
> +nouveau_get_hdmi_dev(struct drm_device *dev)
> +{
> +	struct nouveau_drm *drm = dev->dev_private;
> +	struct pci_dev *pdev = dev->pdev;
> +
> +	/* subfunction one is a hdmi audio device? */
> +	drm->hdmi_device = pci_get_bus_and_slot((unsigned int)pdev->bus->number,
> +						PCI_DEVFN(PCI_SLOT(pdev->devfn), 1));
> +
> +	if (!drm->hdmi_device) {
> +		DRM_INFO("hdmi device  not found %d %d %d\n", pdev->bus->number, PCI_SLOT(pdev->devfn), 1);
> +		return;
> +	}
> +
> +	if ((drm->hdmi_device->class >> 8) != PCI_CLASS_MULTIMEDIA_HD_AUDIO) {
> +		DRM_INFO("possible hdmi device  not audio %d\n", drm->hdmi_device->class);
> +		pci_dev_put(drm->hdmi_device);
> +		drm->hdmi_device = NULL;
> +		return;
> +	}
> +}
> +
>  static int
>  nouveau_drm_load(struct drm_device *dev, unsigned long flags)
>  {
> @@ -314,6 +339,8 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
>  	INIT_LIST_HEAD(&drm->clients);
>  	spin_lock_init(&drm->tile.lock);
>  
> +	nouveau_get_hdmi_dev(dev);
> +
>  	/* make sure AGP controller is in a consistent state before we
>  	 * (possibly) execute vbios init tables (see nouveau_agp.h)
>  	 */
> @@ -400,6 +427,9 @@ fail_ttm:
>  	nouveau_agp_fini(drm);
>  	nouveau_vga_fini(drm);
>  fail_device:
> +	if (drm->hdmi_device)
> +		pci_dev_put(drm->hdmi_device);
> +
>  	nouveau_cli_destroy(&drm->client);
>  	return ret;
>  }
> @@ -424,6 +454,8 @@ nouveau_drm_unload(struct drm_device *dev)
>  	nouveau_agp_fini(drm);
>  	nouveau_vga_fini(drm);
>  
> +	if (drm->hdmi_device)
> +		pci_dev_put(drm->hdmi_device);
>  	nouveau_cli_destroy(&drm->client);
>  	return 0;
>  }
> diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.h b/drivers/gpu/drm/nouveau/nouveau_drm.h
> index 41ff7e0..f276e37 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_drm.h
> +++ b/drivers/gpu/drm/nouveau/nouveau_drm.h
> @@ -129,6 +129,8 @@ struct nouveau_drm {
>  
>  	/* power management */
>  	struct nouveau_pm *pm;
> +
> +	struct pci_dev *hdmi_device;
>  };
>  
>  static inline struct nouveau_drm *
> diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c b/drivers/gpu/drm/nouveau/nouveau_vga.c
> index 25d3495..d8af49c 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_vga.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_vga.c
> @@ -27,6 +27,22 @@ nouveau_vga_set_decode(void *priv, bool state)
>  }
>  
>  static void
> +nouveau_reenable_hdmi_device(struct drm_device *dev)
> +{
> +	struct nouveau_drm *drm = nouveau_drm(dev);
> +	struct nouveau_device *device = nv_device(drm->device);
> +	uint32_t val;
> +
> +	if (!drm->hdmi_device)
> +		return;
> +
> +	/* write magic value into magic place */
> +	val = nv_rd32(device, 0x88488);
> +	val |= (1 << 25);
> +	nv_wr32(device, 0x88488, val);
> +}
use nv_mask(dev, 0x88488, 0x02000000, 0x02000000);

Could this be added in core/engine/disp/hdminv84.c nv84_hdmi_ctrl to get the same effect?

~Maarten

  parent reply	other threads:[~2013-07-24 13:38 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-24  7:13 [PATCH] [RFC] drm/nouveau: bring back hdmi audio device after switcheroo power down Dave Airlie
2013-07-24  8:45 ` Paul Menzel
2013-07-24 12:06 ` Pasi Kärkkäinen
     [not found] ` <1374650022-17865-1-git-send-email-airlied-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2013-07-24 13:38   ` Maarten Lankhorst [this message]
     [not found]     ` <51EFD8DB.10206-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org>
2013-07-25  0:05       ` Dave Airlie

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=51EFD8DB.10206@canonical.com \
    --to=maarten.lankhorst-z7wlfzj8ewms+fvcfc7uqw@public.gmane.org \
    --cc=nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.