Re: [Nouveau] [PATCH v2] ALSA: hda: Continue to probe when codec probe fails

2021-04-13 Thread Roy Spliet

Op 13-04-2021 om 10:48 schreef Karol Herbst:

On Tue, Apr 13, 2021 at 10:24 AM Roy Spliet  wrote:


Op 13-04-2021 om 01:10 schreef Karol Herbst:

On Mon, Apr 12, 2021 at 9:36 PM Roy Spliet  wrote:


Hello Aaron,

Thanks for your insights. A follow-up query and some observations in-line.

Op 12-04-2021 om 20:06 schreef Aaron Plattner:

On 4/10/21 1:48 PM, Roy Spliet wrote:

Op 10-04-2021 om 20:23 schreef Lukas Wunner:

On Sat, Apr 10, 2021 at 04:51:27PM +0100, Roy Spliet wrote:

Can I ask someone with more
technical knowledge of snd_hda_intel and vgaswitcheroo to brainstorm
about
the possible challenges of nouveau taking matters into its own hand
rather
than keeping this PCI quirk around?


It sounds to me like the HDA is not powered if no cable is plugged in.
What is reponsible then for powering it up or down, firmware code on
the GPU or in the host's BIOS?


Sometimes the BIOS, but definitely unconditionally the PCI quirk code:
https://github.com/torvalds/linux/blob/master/drivers/pci/quirks.c#L5289

(CC Aaron Plattner)


My basic understanding is that the audio function stops responding
whenever the graphics function is powered off. So the requirement here
is that the audio driver can't try to talk to the audio function while
the graphics function is asleep, and must trigger a graphics function
wakeup before trying to communicate with the audio function.


I believe that vgaswitcheroo takes care of this for us.



yeah, and also: why would the driver want to do stuff? If the GPU is
turned off, there is no point in communicating with the audio device
anyway. The driver should do the initial probe and leave the device be
unless it's actively used. Also there is no such thing as "use the
audio function, but not the graphics one"


I think
there are also requirements about the audio function needing to be awake
when the graphics driver is updating the ELD, but I'm not sure.



well, it's one physical device anyway, so technically the audio
function is powered on.


This is harder on Windows because the audio driver lives in its own
little world doing its own thing but on Linux we can do better.


Ideally, we should try to find out how to control HDA power from the
operating system rather than trying to cooperate with whatever firmware
is doing.  If we have that capability, the OS should power the HDA up
and down as it sees fit.


After system boot, I don't think there's any firmware involved, but I'm
not super familiar with the low-level details and it's possible the
situation changed since I last looked at it.

I think the problem with having nouveau write this quirk is that the
kernel will need to re-probe the PCI device to notice that it has
suddenly become a multi-function device with an audio function, and
hotplug the audio driver. I originally looked into trying to do that but
it was tricky because the PCI subsystem didn't really have a mechanism
for a single-function device to become a multi-function device on the
fly and it seemed easier to enable it early on during bus enumeration.
That way the kernel sees both functions all the time without anything
else having to be special about this configuration.


Well, we do have this pci/quirk.c thing, no? Nouveau does flip the
bit, but I am actually not sure if that's even doing something
anymore. Maybe in the runtime_resume case it's still relevant but not
sure _when_ DECLARE_PCI_FIXUP_CLASS_RESUME_EARLY is triggered, it does
seem to be called even in the runtime_resume case though.



Right, so for a little more context: a while ago I noticed that my
laptop (lucky me, Asus K501UB) has a 940M with HDA but no codec. Seems
legit, given how this GPU has no displays attached; they're all hooked
up to the Intel integrated GPU. That threw off the snd_hda_intel
mid-probe, and as a result didn't permit runpm, keeping the entire GPU,
PCIe bus and thus the CPU package awake. A bit of hackerly later we
decided to continue probing without a codec, and now my laptop is happy,
but...
A new problem popped up with several other NVIDIA GPUs that expose their
HDA subdevice, but somehow its inaccessible. Relevant lines from a
users' log:

[3.031222] MXM: GUID detected in BIOS
[3.031280] ACPI BIOS Error (bug): AE_AML_PACKAGE_LIMIT, Index
(0x3) is beyond end of object (length 0x0) (20200925/exoparg2-393)
[3.031352] ACPI Error: Aborting method \_SB.PCI0.GFX0._DSM due to
previous error (AE_AML_PACKAGE_LIMIT) (20200925/psparse-529)
[3.031419] ACPI: \_SB_.PCI0.GFX0: failed to evaluate _DSM (0x300b)
[3.031424] ACPI Warning: \_SB.PCI0.GFX0._DSM: Argument #4 type
mismatch - Found [Buffer], ACPI requires [Package] (20200925/nsarguments-61)
[3.031619] pci :00:02.0: optimus capabilities: enabled, status
dynamic power,
[3.031667] ACPI BIOS Error (bug): AE_AML_PACKAGE_LIMIT, Index
(0x3) is beyond end of object (length 0x0) (20200925/exoparg2-393)

Re: [Nouveau] [PATCH v2] ALSA: hda: Continue to probe when codec probe fails

2021-04-13 Thread Roy Spliet

Op 13-04-2021 om 01:10 schreef Karol Herbst:

On Mon, Apr 12, 2021 at 9:36 PM Roy Spliet  wrote:


Hello Aaron,

Thanks for your insights. A follow-up query and some observations in-line.

Op 12-04-2021 om 20:06 schreef Aaron Plattner:

On 4/10/21 1:48 PM, Roy Spliet wrote:

Op 10-04-2021 om 20:23 schreef Lukas Wunner:

On Sat, Apr 10, 2021 at 04:51:27PM +0100, Roy Spliet wrote:

Can I ask someone with more
technical knowledge of snd_hda_intel and vgaswitcheroo to brainstorm
about
the possible challenges of nouveau taking matters into its own hand
rather
than keeping this PCI quirk around?


It sounds to me like the HDA is not powered if no cable is plugged in.
What is reponsible then for powering it up or down, firmware code on
the GPU or in the host's BIOS?


Sometimes the BIOS, but definitely unconditionally the PCI quirk code:
https://github.com/torvalds/linux/blob/master/drivers/pci/quirks.c#L5289

(CC Aaron Plattner)


My basic understanding is that the audio function stops responding
whenever the graphics function is powered off. So the requirement here
is that the audio driver can't try to talk to the audio function while
the graphics function is asleep, and must trigger a graphics function
wakeup before trying to communicate with the audio function.


I believe that vgaswitcheroo takes care of this for us.



yeah, and also: why would the driver want to do stuff? If the GPU is
turned off, there is no point in communicating with the audio device
anyway. The driver should do the initial probe and leave the device be
unless it's actively used. Also there is no such thing as "use the
audio function, but not the graphics one"


I think
there are also requirements about the audio function needing to be awake
when the graphics driver is updating the ELD, but I'm not sure.



well, it's one physical device anyway, so technically the audio
function is powered on.


This is harder on Windows because the audio driver lives in its own
little world doing its own thing but on Linux we can do better.


Ideally, we should try to find out how to control HDA power from the
operating system rather than trying to cooperate with whatever firmware
is doing.  If we have that capability, the OS should power the HDA up
and down as it sees fit.


After system boot, I don't think there's any firmware involved, but I'm
not super familiar with the low-level details and it's possible the
situation changed since I last looked at it.

I think the problem with having nouveau write this quirk is that the
kernel will need to re-probe the PCI device to notice that it has
suddenly become a multi-function device with an audio function, and
hotplug the audio driver. I originally looked into trying to do that but
it was tricky because the PCI subsystem didn't really have a mechanism
for a single-function device to become a multi-function device on the
fly and it seemed easier to enable it early on during bus enumeration.
That way the kernel sees both functions all the time without anything
else having to be special about this configuration.


Well, we do have this pci/quirk.c thing, no? Nouveau does flip the
bit, but I am actually not sure if that's even doing something
anymore. Maybe in the runtime_resume case it's still relevant but not
sure _when_ DECLARE_PCI_FIXUP_CLASS_RESUME_EARLY is triggered, it does
seem to be called even in the runtime_resume case though.



Right, so for a little more context: a while ago I noticed that my
laptop (lucky me, Asus K501UB) has a 940M with HDA but no codec. Seems
legit, given how this GPU has no displays attached; they're all hooked
up to the Intel integrated GPU. That threw off the snd_hda_intel
mid-probe, and as a result didn't permit runpm, keeping the entire GPU,
PCIe bus and thus the CPU package awake. A bit of hackerly later we
decided to continue probing without a codec, and now my laptop is happy,
but...
A new problem popped up with several other NVIDIA GPUs that expose their
HDA subdevice, but somehow its inaccessible. Relevant lines from a
users' log:

[3.031222] MXM: GUID detected in BIOS
[3.031280] ACPI BIOS Error (bug): AE_AML_PACKAGE_LIMIT, Index
(0x3) is beyond end of object (length 0x0) (20200925/exoparg2-393)
[3.031352] ACPI Error: Aborting method \_SB.PCI0.GFX0._DSM due to
previous error (AE_AML_PACKAGE_LIMIT) (20200925/psparse-529)
[3.031419] ACPI: \_SB_.PCI0.GFX0: failed to evaluate _DSM (0x300b)
[3.031424] ACPI Warning: \_SB.PCI0.GFX0._DSM: Argument #4 type
mismatch - Found [Buffer], ACPI requires [Package] (20200925/nsarguments-61)
[3.031619] pci :00:02.0: optimus capabilities: enabled, status
dynamic power,
[3.031667] ACPI BIOS Error (bug): AE_AML_PACKAGE_LIMIT, Index
(0x3) is beyond end of object (length 0x0) (20200925/exoparg2-393)
[3.031731] ACPI Error: Aborting method \_SB.PCI0.GFX0._DSM due to
previous error (AE_AML_PACKAGE_LIMIT) 

Re: [Nouveau] [PATCH v2] ALSA: hda: Continue to probe when codec probe fails

2021-04-12 Thread Roy Spliet

Hello Aaron,

Thanks for your insights. A follow-up query and some observations in-line.

Op 12-04-2021 om 20:06 schreef Aaron Plattner:

On 4/10/21 1:48 PM, Roy Spliet wrote:

Op 10-04-2021 om 20:23 schreef Lukas Wunner:

On Sat, Apr 10, 2021 at 04:51:27PM +0100, Roy Spliet wrote:

Can I ask someone with more
technical knowledge of snd_hda_intel and vgaswitcheroo to brainstorm 
about
the possible challenges of nouveau taking matters into its own hand 
rather

than keeping this PCI quirk around?


It sounds to me like the HDA is not powered if no cable is plugged in.
What is reponsible then for powering it up or down, firmware code on
the GPU or in the host's BIOS?


Sometimes the BIOS, but definitely unconditionally the PCI quirk code: 
https://github.com/torvalds/linux/blob/master/drivers/pci/quirks.c#L5289


(CC Aaron Plattner)


My basic understanding is that the audio function stops responding 
whenever the graphics function is powered off. So the requirement here 
is that the audio driver can't try to talk to the audio function while 
the graphics function is asleep, and must trigger a graphics function 
wakeup before trying to communicate with the audio function.


I believe that vgaswitcheroo takes care of this for us.

I think 
there are also requirements about the audio function needing to be awake 
when the graphics driver is updating the ELD, but I'm not sure.


This is harder on Windows because the audio driver lives in its own 
little world doing its own thing but on Linux we can do better.



Ideally, we should try to find out how to control HDA power from the
operating system rather than trying to cooperate with whatever firmware
is doing.  If we have that capability, the OS should power the HDA up
and down as it sees fit.


After system boot, I don't think there's any firmware involved, but I'm 
not super familiar with the low-level details and it's possible the 
situation changed since I last looked at it.


I think the problem with having nouveau write this quirk is that the 
kernel will need to re-probe the PCI device to notice that it has 
suddenly become a multi-function device with an audio function, and 
hotplug the audio driver. I originally looked into trying to do that but 
it was tricky because the PCI subsystem didn't really have a mechanism 
for a single-function device to become a multi-function device on the 
fly and it seemed easier to enable it early on during bus enumeration. 
That way the kernel sees both functions all the time without anything 
else having to be special about this configuration.


Right, so for a little more context: a while ago I noticed that my 
laptop (lucky me, Asus K501UB) has a 940M with HDA but no codec. Seems 
legit, given how this GPU has no displays attached; they're all hooked 
up to the Intel integrated GPU. That threw off the snd_hda_intel 
mid-probe, and as a result didn't permit runpm, keeping the entire GPU, 
PCIe bus and thus the CPU package awake. A bit of hackerly later we 
decided to continue probing without a codec, and now my laptop is happy, 
but...
A new problem popped up with several other NVIDIA GPUs that expose their 
HDA subdevice, but somehow its inaccessible. Relevant lines from a 
users' log:


[3.031222] MXM: GUID detected in BIOS
[3.031280] ACPI BIOS Error (bug): AE_AML_PACKAGE_LIMIT, Index 
(0x3) is beyond end of object (length 0x0) (20200925/exoparg2-393)
[3.031352] ACPI Error: Aborting method \_SB.PCI0.GFX0._DSM due to 
previous error (AE_AML_PACKAGE_LIMIT) (20200925/psparse-529)

[3.031419] ACPI: \_SB_.PCI0.GFX0: failed to evaluate _DSM (0x300b)
[3.031424] ACPI Warning: \_SB.PCI0.GFX0._DSM: Argument #4 type 
mismatch - Found [Buffer], ACPI requires [Package] (20200925/nsarguments-61)
[3.031619] pci :00:02.0: optimus capabilities: enabled, status 
dynamic power,
[3.031667] ACPI BIOS Error (bug): AE_AML_PACKAGE_LIMIT, Index 
(0x3) is beyond end of object (length 0x0) (20200925/exoparg2-393)
[3.031731] ACPI Error: Aborting method \_SB.PCI0.GFX0._DSM due to 
previous error (AE_AML_PACKAGE_LIMIT) (20200925/psparse-529)
[3.031791] ACPI Error: Aborting method \_SB.PCI0.PEG0.PEGP._DSM due 
to previous error (AE_AML_PACKAGE_LIMIT) (20200925/psparse-529)

[3.031856] ACPI: \_SB_.PCI0.PEG0.PEGP: failed to evaluate _DSM (0x300b)
[3.031859] ACPI Warning: \_SB.PCI0.PEG0.PEGP._DSM: Argument #4 type 
mismatch - Found [Buffer], ACPI requires [Package] (20200925/nsarguments-61)
[3.032058] pci :01:00.0: optimus capabilities: enabled, status 
dynamic power,
[3.032061] VGA switcheroo: detected Optimus DSM method 
\_SB_.PCI0.PEG0.PEGP handle

[3.032323] checking generic (d000 41) vs hw (f600 100)
[3.032325] checking generic (d000 41) vs hw (e000 1000)
[3.032326] checking generic (d000 41) vs hw (f000 200)
[3.032410] nouveau :01:00.0: NVID

Re: [Nouveau] [PATCH v2] ALSA: hda: Continue to probe when codec probe fails

2021-04-10 Thread Roy Spliet

Op 10-04-2021 om 20:23 schreef Lukas Wunner:

On Sat, Apr 10, 2021 at 04:51:27PM +0100, Roy Spliet wrote:

Can I ask someone with more
technical knowledge of snd_hda_intel and vgaswitcheroo to brainstorm about
the possible challenges of nouveau taking matters into its own hand rather
than keeping this PCI quirk around?


It sounds to me like the HDA is not powered if no cable is plugged in.
What is reponsible then for powering it up or down, firmware code on
the GPU or in the host's BIOS?


Sometimes the BIOS, but definitely unconditionally the PCI quirk code: 
https://github.com/torvalds/linux/blob/master/drivers/pci/quirks.c#L5289


(CC Aaron Plattner)



Ideally, we should try to find out how to control HDA power from the
operating system rather than trying to cooperate with whatever firmware
is doing.  If we have that capability, the OS should power the HDA up
and down as it sees fit.

Thanks,

Lukas



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH v2] ALSA: hda: Continue to probe when codec probe fails

2021-04-10 Thread Roy Spliet
Reviving this thread as we have another user (rightfully) complaining on 
IRC about this.


The way I see it there's two issues:
1) snd_hda_intel not allowing runpm (or w/e vgaswitcheroo needs) when 
there's missing codecs, inhibiting the entire GPU from performing runpm. 
This needlessly wastes lots of battery power.
2) HDMI audio not working on such machines unless it was plugged in at 
boot-time.


The original workarounds proposed by Kai-Heng seem to fix 1), which is 
progress. I don't see a reason why that should be held off even if it 
doesn't fix 2).
To fix 2), more work is needed. On a high level, I suspect nouveau 
should start controlling the enabling/disabling of the HDA controller 
based on connector events and/or connector state at module load. 
Currently the PCI quirk seems to enable it wholesale, and I don't know 
why. If no GPU driver is loaded, it's pointless to turn the HDA device 
on. The blob presumably doesn't need this either, as it can control the 
device just as well as nouveau. If it doesn't, NVIDIA should fix it 
rather than rely on this quirk. The only reason I can think of is that 
snd_hda_intel or vgaswitcheroo isn't prepared for hot(un)plugging (or 
alternatively reprobing) devices. Without that, we presumably won't 
solve issue 2). Can I ask someone with more technical knowledge of 
snd_hda_intel and vgaswitcheroo to brainstorm about the possible 
challenges of nouveau taking matters into its own hand rather than 
keeping this PCI quirk around?


Roy

Op 04-01-2021 om 13:20 schreef Karol Herbst:

On Tue, Dec 22, 2020 at 3:50 AM Kai-Heng Feng
 wrote:


On Tue, Dec 22, 2020 at 1:56 AM Ilia Mirkin  wrote:


On Mon, Dec 21, 2020 at 11:33 AM Kai-Heng Feng
 wrote:


[+Cc nouveau]

On Fri, Dec 18, 2020 at 4:06 PM Takashi Iwai  wrote:
[snip]

Quite possibly the system doesn't power up HDA controller when there's
no external monitor.
So when it's connected to external monitor, it's still needed for HDMI audio.
Let me ask the user to confirm this.


Yeah, it's the basic question whether the HD-audio is supposed to work
on this machine at all.  If yes, the current approach we take makes
less sense - instead we should rather make the HD-audio controller
working.


Yea, confirmed that the Nvidia HDA works when HDMI is connected prior boot.


- The second problem is that pci_enable_device() ignores the error
   returned from pci_set_power_state() if it's -EIO.  And the
   inaccessible access error returns -EIO, although it's rather a fatal
   problem.  So the driver believes as the PCI device gets enabled
   properly.


This was introduced in 2005, by Alan's 11f3859b1e85 ("[PATCH] PCI: Fix
regression in pci_enable_device_bars") to fix UHCI controller.



- The third problem is that HD-audio driver blindly believes the
   codec_mask read from the register even if it's a read failure as I
   already showed.


This approach has least regression risk.


Yes, but it assumes that HD-audio is really non-existent.


I really don't know any good approach to address this.
On Windows, HDA PCI is "hidden" until HDMI cable is plugged, then the
driver will flag the magic bit to make HDA audio appear on the PCI
bus.
IIRC the current approach is to make nouveau and device link work.


I don't have the full context of this discussion, but the kernel
force-enables the HDA subfunction nowadays, irrespective of nouveau or
nvidia or whatever:


That's the problem.

The nvidia HDA controller on the affected system only gets its power
after HDMI cable plugged, so the probe on boot fails.



it might be that the code to enable the sub function is a bit broken
:/ but it should work. Maybe the quirk_nvidia_hda function needs to be
called on more occasions? No idea.


Kai-Heng



https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/pci/quirks.c?h=v5.10#n5267

Cheers,

   -ilia

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH] drm/nouveau/kms/nve4-nv108: Limit cursors to 128x128

2021-03-21 Thread Roy Spliet

Tested-by: Roy Spliet 

Op 08-03-2021 om 16:50 schreef Daniel Thompson:

On Thu, Mar 04, 2021 at 08:52:41PM -0500, Lyude Paul wrote:

While Kepler does technically support 256x256 cursors, it turns out that
Kepler actually has some additional requirements for scanout surfaces that
we're not enforcing correctly, which aren't present on Maxwell and later.
Cursor surfaces must always use small pages (4K), and overlay surfaces must
always use large pages (128K).

Fixing this correctly though will take a bit more work: as we'll need to
add some code in prepare_fb() to move cursor FBs in large pages to small
pages, and vice-versa for overlay FBs. So until we have the time to do
that, just limit cursor surfaces to 128x128 - a size small enough to always
default to small pages.

This means small ovlys are still broken on Kepler, but it is extremely
unlikely anyone cares about those anyway :).

Signed-off-by: Lyude Paul 
Fixes: d3b2f0f7921c ("drm/nouveau/kms/nv50-: Report max cursor size to 
userspace")
Cc:  # v5.11+


I was experiencing problems with the mouse cursor on my system in v5.11
and after a bisect to help me search the web I found my way to this
patch, which fixed the problem for me.

Mine is an Armv8 system but there is nothing particularly exotic from a
graphics card or software point of view: Debian bullseye/wayland
(gnome-shell 3.38.3, mesa-20.3.4) running on a GT-710.

However FWIW:
Tested-by: Daniel Thompson 


Daniel.



---
  drivers/gpu/drm/nouveau/dispnv50/disp.c | 13 -
  1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 196612addfd6..1c9c0cdf85db 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -2693,9 +2693,20 @@ nv50_display_create(struct drm_device *dev)
else
nouveau_display(dev)->format_modifiers = disp50xx_modifiers;
  
-	if (disp->disp->object.oclass >= GK104_DISP) {

+   /* FIXME: 256x256 cursors are supported on Kepler, however unlike 
Maxwell and later
+* generations Kepler requires that we use small pages (4K) for cursor 
scanout surfaces. The
+* proper fix for this is to teach nouveau to migrate fbs being used 
for the cursor plane to
+* small page allocations in prepare_fb(). When this is implemented, we 
should also force
+* large pages (128K) for ovly fbs in order to fix Kepler ovlys.
+* But until then, just limit cursors to 128x128 - which is small 
enough to avoid ever using
+* large pages.
+*/
+   if (disp->disp->object.oclass >= GM107_DISP) {
dev->mode_config.cursor_width = 256;
dev->mode_config.cursor_height = 256;
+   } else if (disp->disp->object.oclass >= GK104_DISP) {
+   dev->mode_config.cursor_width = 128;
+   dev->mode_config.cursor_height = 128;
} else {
dev->mode_config.cursor_width = 64;
dev->mode_config.cursor_height = 64;
--
2.29.2


___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH v2] drm/nouveau/kms/nve4-nv108: Don't advertise 256x256 cursor support yet

2021-03-21 Thread Roy Spliet

Tested-by: Roy Spliet 

Op 05-03-2021 om 22:21 schreef Lyude Paul:

While Kepler does technically support 256x256 cursors, it turns out that
in order for us to use these correctly we need to make sure that the cursor
plane uses a ctxdma that is set to use small (4K)/large (128K) pages -
whichever is applicable to the given cursor surface.

Right now however, we share the main kmsVramCtxDma that is used for all but
the ovly plane which defaults to small pages - resulting in artifacts when
we use 256x256 cursor surfaces. So until we teach nouveau to use a separate
ctxdma for the cursor, let's just stop advertising 256x256 cursors by
default - which should fix the issues that users were seeing.

Coincidentally - this is also why small ovlys don't work on Kepler: the
ctxdma we use for ovlys is set to large pages.

Changes since v2:
* Fix comments and patch description

Signed-off-by: Lyude Paul 
Fixes: d3b2f0f7921c ("drm/nouveau/kms/nv50-: Report max cursor size to 
userspace")
Cc:  # v5.11+
---
  drivers/gpu/drm/nouveau/dispnv50/disp.c | 12 +++-
  1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 196612addfd6..d92cf9e17ac3 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -2693,9 +2693,19 @@ nv50_display_create(struct drm_device *dev)
else
nouveau_display(dev)->format_modifiers = disp50xx_modifiers;
  
-	if (disp->disp->object.oclass >= GK104_DISP) {

+   /* FIXME: 256x256 cursors are supported on Kepler, however unlike 
Maxwell and later
+* generations Kepler requires that we specify the page type, small 
(4K) or large (128K),
+* correctly for the ctxdma being used on curs/ovly. We currently share 
a ctxdma across all
+* display planes (except ovly) that defaults to small pages, which 
results in artifacting
+* on 256x256 cursors. Until we teach nouveau to create an appropriate 
ctxdma for the cursor
+* fb in use, simply avoid advertising support for 256x256 cursors.
+*/
+   if (disp->disp->object.oclass >= GM107_DISP) {
dev->mode_config.cursor_width = 256;
dev->mode_config.cursor_height = 256;
+   } else if (disp->disp->object.oclass >= GK104_DISP) {
+   dev->mode_config.cursor_width = 128;
+   dev->mode_config.cursor_height = 128;
} else {
dev->mode_config.cursor_width = 64;
dev->mode_config.cursor_height = 64;


___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH] drivers: drm: nouveau: nvkm: Replace a word with a better phonetic word in the file macros.fuc

2021-02-05 Thread Roy Spliet

Op 05-02-2021 om 13:05 schreef Bhaskar Chowdhury:



s/fuck/heck/


Signed-off-by: Bhaskar Chowdhury 
---
  drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/macros.fuc | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/macros.fuc 
b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/macros.fuc
index 3737bd27f74e..1407a1b16d95 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/macros.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/macros.fuc
@@ -46,7 +46,7 @@
  #define NV_PPWR_INTR_EN_SET_SUBINTR  
0x0800
  #define NV_PPWR_INTR_EN_SET_WATCHDOG 
0x0002
  #define NV_PPWR_INTR_EN_CLR  
0x0014
-#define NV_PPWR_INTR_EN_CLR_MASK/* fuck i hate envyas */ -1
+#define NV_PPWR_INTR_EN_CLR_MASK/* heck, i hate envyas */ 
-1


Please make sure that the values remain properly right-justified when 
proposing such changes.

Best,

Roy


  #define NV_PPWR_INTR_ROUTE   
0x001c
  #define NV_PPWR_TIMER_LOW
0x002c
  #define NV_PPWR_WATCHDOG_TIME
0x0034
--
2.30.0

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] Request for help in adding a HDMI output

2021-01-23 Thread Roy Spliet

Op 23-01-2021 om 23:18 schreef o1bigtenor:


OK, so this is your 4k monitor. It is plugged into the *secondary*
GPU, and does not report any 4k@60 modes in the EDID (well, it does
report 4k@60 YUV 4:2:0 modes, but we don't support those in nouveau at
this time). Whether that's because the monitor itself doesn't support
HDMI 2.0, or you plugged it into your old GPU which does not support
HDMI 2.0, I couldn't say from just this output. What I can say is that
no amount of modelines will get you 4k@60 in this setup with nouveau.



[...]

If you would point out a suggestion that I haven't tried - - - please?


A quick DuckDuckGo for "Hisense 4K 60Hz only reports 30Hz" gives this 
thread: https://www.coolcomputing.com/article.php?sid=4659 . No idea 
whether this also applies to your 2016 model. Have you scavenged through 
the TVs menu's to make sure HDMI 2.0 is explicitly enabled?

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [RFC] Documentation: nouveau: Introduce some nouveau documentation

2020-09-24 Thread Roy Spliet




Op 24-09-2020 om 16:21 schreef Karol Herbst:

On Thu, Sep 24, 2020 at 3:06 PM Roy Spliet  wrote:



Op 23-09-2020 om 22:36 schreef Karol Herbst:

On Wed, Sep 23, 2020 at 10:39 PM Jeremy Cline  wrote:


On Wed, Sep 23, 2020 at 09:02:45PM +0200, Karol Herbst wrote:

On Fri, Sep 11, 2020 at 6:21 PM Jeremy Cline  wrote:





yeah, I think overall this file is a good idea and being able to get a
quick overview over the driver is helpful. I think if we focus on the
user facing things first, like the hwmon or other things users
generally interact with would be helpful. I think if we start to
document areas where there are many low hanging fruits, this could
help random people to start with easier tasks and get more used to the
driver overall, so I'd probably ignore most of the stuff which really
requires a fundamental understanding on how things work and focus more
on vbios parsing (which has annoying interfaces anyway and it might
make sense to make it more consistent and nicer to use) and/or simple
code interfacing with the mmio space.



I'll admit to being motivated by entirely selfish reasons. I know
practically nothing about nouveau and I'm the type of person who likes
to keep notes about how things work together, both free form and
structured in-line docs. All that to say, I think focusing on the
"low-hanging fruit" stuff will be very beneficial and I'm happy to do
that, but I'm also interested in documenting everything else I run
across.



yeah, that's fine. I was just giving a suggestion on where the initial
focus should be on.


Eg some users have problems with their fans as they are either always
ramping up to max, or not running at all... GPUs temperature or power
consumption is reporting incorrectly... all those things users hit
regularly, but which isn't really important enough so it just falls
under the table even if it gets reported.



This does bring up an interesting point about organization and target
audiences. Typically when I'm writing documentation I like to organize
things by target audiences, so we could have a layout like:

* General Introduction

* User Guide
  - Overview of supported hardware/features/etc


That's best to document in a wiki though. And we had plans to convert
the existing old wiki over to gitlab. And maybe It think we really
should do that and clean it up while we work on that. It's just a huge
project but maybe just starting with whatever you want to do would be
fine and after a while nothing is left. Anyway, I think we should
discuss this more openly with the others as well. i don't like the
current wiki anyway, as only approved developers can change things and
with a gitlab wiki we could even take MRs on stuff.


  - Installation


well.. I think this can be skipped ;) But still, also belongs more
into a wiki. I think what we could cover here is to how to clean up
remaining stuff from the blob driver as this is something which comes
up quite a lot on IRC though.


  - Configuration (module parameters and such)
  - Troubleshooting


that would be cool to have in the wiki as well. Just collecting the
most common issue and document it there. Especially if it is on
gitlab, users can just do that as well :)


  - Getting Involved (bug reporting, running tests, etc)


yeah, and we have some stuff on that on the old wiki already, it's
just very outdated and needs updating, which as said above can only be
done by developers and developers sadly have other things to do :)



* Developer Guide
  - Architecture Overview
  - External APIs (include/uapi/drm/nouveau_drm.h, any sysfs stuff)?
  - Internal APIs


Right, those things I'd like to see in the kernel tree actually.


  - Debugging and Development Tools
  - Contribution Guide



Those I think belong more into the wiki again. The latter is a bit
hard to split as there are kernel guides, but also community and
project guides. Mesa does things differently than let's say the
kernel. And Nouveau is still in this limbo state being on the old
infra, but also on the new one with mesa...


I'm not sure how much stuff people want to keep on the
nouveau.freedesktop.org wiki vs here.



I think the first step actually is to set up a proper nouveau project
on gitlab for dealing with issues and the wiki. I would be fine to do
that and we can also move the code there late. But maybe let's start
with the wiki :)


Risking to turn this into a "let's fix everything in one go" project
that ends up never getting finished, I just want to make sure that
everybody is also aware of the documentation generated from Envytools
[0]. Especially "architecture overview" (that is, if we're talking about
hardware architecture and not driver/software architecture) might be
better suited in envytools.

As for module parameters, IMHO modinfo is supposed to be the source of
information. It

Re: [Nouveau] [RFC] Documentation: nouveau: Introduce some nouveau documentation

2020-09-24 Thread Roy Spliet



Op 23-09-2020 om 22:36 schreef Karol Herbst:

On Wed, Sep 23, 2020 at 10:39 PM Jeremy Cline  wrote:


On Wed, Sep 23, 2020 at 09:02:45PM +0200, Karol Herbst wrote:

On Fri, Sep 11, 2020 at 6:21 PM Jeremy Cline  wrote:





yeah, I think overall this file is a good idea and being able to get a
quick overview over the driver is helpful. I think if we focus on the
user facing things first, like the hwmon or other things users
generally interact with would be helpful. I think if we start to
document areas where there are many low hanging fruits, this could
help random people to start with easier tasks and get more used to the
driver overall, so I'd probably ignore most of the stuff which really
requires a fundamental understanding on how things work and focus more
on vbios parsing (which has annoying interfaces anyway and it might
make sense to make it more consistent and nicer to use) and/or simple
code interfacing with the mmio space.



I'll admit to being motivated by entirely selfish reasons. I know
practically nothing about nouveau and I'm the type of person who likes
to keep notes about how things work together, both free form and
structured in-line docs. All that to say, I think focusing on the
"low-hanging fruit" stuff will be very beneficial and I'm happy to do
that, but I'm also interested in documenting everything else I run
across.



yeah, that's fine. I was just giving a suggestion on where the initial
focus should be on.


Eg some users have problems with their fans as they are either always
ramping up to max, or not running at all... GPUs temperature or power
consumption is reporting incorrectly... all those things users hit
regularly, but which isn't really important enough so it just falls
under the table even if it gets reported.



This does bring up an interesting point about organization and target
audiences. Typically when I'm writing documentation I like to organize
things by target audiences, so we could have a layout like:

* General Introduction

* User Guide
 - Overview of supported hardware/features/etc


That's best to document in a wiki though. And we had plans to convert
the existing old wiki over to gitlab. And maybe It think we really
should do that and clean it up while we work on that. It's just a huge
project but maybe just starting with whatever you want to do would be
fine and after a while nothing is left. Anyway, I think we should
discuss this more openly with the others as well. i don't like the
current wiki anyway, as only approved developers can change things and
with a gitlab wiki we could even take MRs on stuff.


 - Installation


well.. I think this can be skipped ;) But still, also belongs more
into a wiki. I think what we could cover here is to how to clean up
remaining stuff from the blob driver as this is something which comes
up quite a lot on IRC though.


 - Configuration (module parameters and such)
 - Troubleshooting


that would be cool to have in the wiki as well. Just collecting the
most common issue and document it there. Especially if it is on
gitlab, users can just do that as well :)


 - Getting Involved (bug reporting, running tests, etc)


yeah, and we have some stuff on that on the old wiki already, it's
just very outdated and needs updating, which as said above can only be
done by developers and developers sadly have other things to do :)



* Developer Guide
 - Architecture Overview
 - External APIs (include/uapi/drm/nouveau_drm.h, any sysfs stuff)?
 - Internal APIs


Right, those things I'd like to see in the kernel tree actually.


 - Debugging and Development Tools
 - Contribution Guide



Those I think belong more into the wiki again. The latter is a bit
hard to split as there are kernel guides, but also community and
project guides. Mesa does things differently than let's say the
kernel. And Nouveau is still in this limbo state being on the old
infra, but also on the new one with mesa...


I'm not sure how much stuff people want to keep on the
nouveau.freedesktop.org wiki vs here.



I think the first step actually is to set up a proper nouveau project
on gitlab for dealing with issues and the wiki. I would be fine to do
that and we can also move the code there late. But maybe let's start
with the wiki :)


Risking to turn this into a "let's fix everything in one go" project 
that ends up never getting finished, I just want to make sure that 
everybody is also aware of the documentation generated from Envytools 
[0]. Especially "architecture overview" (that is, if we're talking about 
hardware architecture and not driver/software architecture) might be 
better suited in envytools.


As for module parameters, IMHO modinfo is supposed to be the source of 
information. It's sadly lacking any "sub-"option inside nouveau.config 
and nouveau.debug, which may be by design. Perhaps expanding the modinfo 
explanations can help cover at least all the other options in a way that 
never gets out of sync wi

Re: [Nouveau] [PATCH 1/3] drm/radeon: remove AGP support

2020-05-12 Thread Roy Spliet

Op 12-05-2020 om 14:36 schreef Alex Deucher:

On Tue, May 12, 2020 at 4:16 AM Michel Dänzer  wrote:


On 2020-05-11 10:12 p.m., Alex Deucher wrote:

On Mon, May 11, 2020 at 1:17 PM Christian König
 wrote:


AGP is deprecated for 10+ years now and not used any more on modern hardware.

Old hardware should continue to work in PCI mode.


Might want to clarify that there is no loss of functionality here.
Something like:

"There is no loss of functionality here.  GPUs will continue to
function.  This just drops the use of the AGP MMU in the chipset in
favor of the MMU on the device which has proven to be much more
reliable.  Due to its unreliability, AGP support has been disabled on
PowerPC for years already so there is no change on PowerPC."


There's a difference between something being disabled by default or not
being available at all. We may decide it's worth it anyway, but let's do
it based on facts.



I didn't mean to imply that AGP GART support was already removed.  But
for the vast majority of users the end result is the same.  If you
knew enough re-enable AGP GART, you probably wouldn't have been as
confused about what this patch set does either.  To reiterate, this
patch set does not remove support for AGP cards, it only removes the
support for AGP GART.  The cards will still be functional using the
device GART.  There may be performance tradeoffs there in some cases.


I'll volunteer to be the one asking: how big is this performance 
difference? Have any benchmarks been run before and after removal of AGP 
GART code on affected nouveau/radeon systems? Or is this code being 
dropped _just_ because it's cumbersome, with no regard for metrics that 
determine the value of AGP GART support?


Roy



Alex
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH 4/4] drm/nouveau: Remove struct nouveau_framebuffer

2020-02-06 Thread Roy Spliet

(Re-sending to list rather than just to James)

Is this format modifier information not stored, or otherwise worth 
storing, directly in the nouveau_bo object associated with the 
framebuffer? I'm not particularly knowledgeable on the topic, but there 
already seem to exist some fields with very similar names in nouveau_bo.

Best,

Roy

On 06/02/2020 15:17, James Jones wrote:
Note I'm adding some fields to nouveau_framebuffer in the series 
"drm/nouveau: Support NVIDIA format modifiers."  I sent out v3 of that 
yesterday.  It would probably still be possible to avoid them by 
re-extracting the relevant data from the format modifier on the fly when 
needed, but it is simpler and likely less error-prone with the wrapper 
struct.


Thanks,
-James

On 2/6/20 2:19 AM, Thomas Zimmermann wrote:

After its cleanup, struct nouveau_framebuffer is only a wrapper around
struct drm_framebuffer. Use the latter directly.

Signed-off-by: Thomas Zimmermann 
---
  drivers/gpu/drm/nouveau/dispnv50/wndw.c   | 26 +++
  drivers/gpu/drm/nouveau/nouveau_display.c | 14 ++--
  drivers/gpu/drm/nouveau/nouveau_display.h | 12 +--
  drivers/gpu/drm/nouveau/nouveau_fbcon.c   | 14 ++--
  4 files changed, 28 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c 
b/drivers/gpu/drm/nouveau/dispnv50/wndw.c

index ba1399965a1c..4a67a656e007 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c
@@ -40,11 +40,11 @@ nv50_wndw_ctxdma_del(struct nv50_wndw_ctxdma *ctxdma)
  }
  static struct nv50_wndw_ctxdma *
-nv50_wndw_ctxdma_new(struct nv50_wndw *wndw, struct 
nouveau_framebuffer *fb)

+nv50_wndw_ctxdma_new(struct nv50_wndw *wndw, struct drm_framebuffer *fb)
  {
-    struct nouveau_drm *drm = nouveau_drm(fb->base.dev);
+    struct nouveau_drm *drm = nouveau_drm(fb->dev);
  struct nv50_wndw_ctxdma *ctxdma;
-    struct nouveau_bo *nvbo = nouveau_gem_object(fb->base.obj[0]);
+    struct nouveau_bo *nvbo = nouveau_gem_object(fb->obj[0]);
  const u8    kind = nvbo->kind;
  const u32 handle = 0xfb00 | kind;
  struct {
@@ -236,16 +236,16 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw 
*wndw, bool modeset,

 struct nv50_wndw_atom *asyw,
 struct nv50_head_atom *asyh)
  {
-    struct nouveau_framebuffer *fb = 
nouveau_framebuffer(asyw->state.fb);

+    struct drm_framebuffer *fb = asyw->state.fb;
  struct nouveau_drm *drm = nouveau_drm(wndw->plane.dev);
-    struct nouveau_bo *nvbo = nouveau_gem_object(fb->base.obj[0]);
+    struct nouveau_bo *nvbo = nouveau_gem_object(fb->obj[0]);
  int ret;
  NV_ATOMIC(drm, "%s acquire\n", wndw->plane.name);
-    if (asyw->state.fb != armw->state.fb || !armw->visible || modeset) {
-    asyw->image.w = fb->base.width;
-    asyw->image.h = fb->base.height;
+    if (fb != armw->state.fb || !armw->visible || modeset) {
+    asyw->image.w = fb->width;
+    asyw->image.h = fb->height;
  asyw->image.kind = nvbo->kind;
  ret = nv50_wndw_atomic_check_acquire_rgb(asyw);
@@ -261,13 +261,13 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw 
*wndw, bool modeset,

  asyw->image.blockh = nvbo->mode >> 4;
  else
  asyw->image.blockh = nvbo->mode;
-    asyw->image.blocks[0] = fb->base.pitches[0] / 64;
+    asyw->image.blocks[0] = fb->pitches[0] / 64;
  asyw->image.pitch[0] = 0;
  } else {
  asyw->image.layout = 1;
  asyw->image.blockh = 0;
  asyw->image.blocks[0] = 0;
-    asyw->image.pitch[0] = fb->base.pitches[0];
+    asyw->image.pitch[0] = fb->pitches[0];
  }
  if (!asyh->state.async_flip)
@@ -486,16 +486,16 @@ nv50_wndw_cleanup_fb(struct drm_plane *plane, 
struct drm_plane_state *old_state)

  static int
  nv50_wndw_prepare_fb(struct drm_plane *plane, struct drm_plane_state 
*state)

  {
-    struct nouveau_framebuffer *fb = nouveau_framebuffer(state->fb);
+    struct drm_framebuffer *fb = state->fb;
  struct nouveau_drm *drm = nouveau_drm(plane->dev);
  struct nv50_wndw *wndw = nv50_wndw(plane);
  struct nv50_wndw_atom *asyw = nv50_wndw_atom(state);
-    struct nouveau_bo *nvbo = nouveau_gem_object(state->fb->obj[0]);
+    struct nouveau_bo *nvbo = nouveau_gem_object(fb->obj[0]);
  struct nv50_head_atom *asyh;
  struct nv50_wndw_ctxdma *ctxdma;
  int ret;
-    NV_ATOMIC(drm, "%s prepare: %p\n", plane->name, state->fb);
+    NV_ATOMIC(drm, "%s prepare: %p\n", plane->name, fb);
  if (!asyw->state.fb)
  return 0;
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c 
b/drivers/gpu/drm/nouveau/nouveau_display.c

index bbbff55eb5d5..94f7fd48e1cf 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -207,10 +207,10 @@ int
  nouveau_framebuffer_new(struct drm_device *dev,
   

Re: [Nouveau] [PATCH 1/2] drm/nouveau: move io_reserve_lru handling into the driver v2

2020-01-24 Thread Roy Spliet
Without diving in any of the details, your commit message has me curious 
and concerned... In a "manager" kind of way, despite being neither a 
manager nor an insider or active contributor. ;-)


On 24/01/2020 14:30, Christian König wrote:

From: Christian König 

While working on TTM cleanups I've found that the io_reserve_lru used by
Nouveau is actually not working at all.


What made you conclude this mechanism doesn't work? Does this imply that 
Nouveau is broken? If so: Does the migration of this code from TTM to 
Nouveau mean that Nouveau remains broken, but it's now simply no longer 
your problem? And what would it take to fix Nouveau?

Best,

Roy



In general we should remove driver specific handling from the memory
management, so this patch moves the io_reserve_lru handling into Nouveau
instead.

The patch should be functional correct, but is only compile tested!

v2: don't call ttm_bo_unmap_virtual in nouveau_ttm_io_mem_reserve

Signed-off-by: Christian König 
Acked-by: Daniel Vetter 
---
  drivers/gpu/drm/nouveau/nouveau_bo.c  | 107 --
  drivers/gpu/drm/nouveau/nouveau_bo.h  |   3 +
  drivers/gpu/drm/nouveau/nouveau_drv.h |   2 +
  drivers/gpu/drm/nouveau/nouveau_ttm.c |  43 ++-
  4 files changed, 131 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c 
b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 81668104595f..acee054f77ed 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -137,6 +137,7 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo)
struct nouveau_bo *nvbo = nouveau_bo(bo);
  
  	WARN_ON(nvbo->pin_refcnt > 0);

+   nouveau_bo_del_io_reserve_lru(bo);
nv10_bo_put_tile_region(dev, nvbo->tile, NULL);
  
  	/*

@@ -304,6 +305,7 @@ nouveau_bo_init(struct nouveau_bo *nvbo, u64 size, int 
align, u32 flags,
  
  	nvbo->bo.mem.num_pages = size >> PAGE_SHIFT;

nouveau_bo_placement_set(nvbo, flags, 0);
+   INIT_LIST_HEAD(&nvbo->io_reserve_lru);
  
  	ret = ttm_bo_init(nvbo->bo.bdev, &nvbo->bo, size, type,

  &nvbo->placement, align >> PAGE_SHIFT, false,
@@ -574,6 +576,26 @@ nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo)
PAGE_SIZE, DMA_FROM_DEVICE);
  }
  
+void nouveau_bo_add_io_reserve_lru(struct ttm_buffer_object *bo)

+{
+   struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
+   struct nouveau_bo *nvbo = nouveau_bo(bo);
+
+   mutex_lock(&drm->ttm.io_reserve_mutex);
+   list_move_tail(&nvbo->io_reserve_lru, &drm->ttm.io_reserve_lru);
+   mutex_unlock(&drm->ttm.io_reserve_mutex);
+}
+
+void nouveau_bo_del_io_reserve_lru(struct ttm_buffer_object *bo)
+{
+   struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
+   struct nouveau_bo *nvbo = nouveau_bo(bo);
+
+   mutex_lock(&drm->ttm.io_reserve_mutex);
+   list_del_init(&nvbo->io_reserve_lru);
+   mutex_unlock(&drm->ttm.io_reserve_mutex);
+}
+
  int
  nouveau_bo_validate(struct nouveau_bo *nvbo, bool interruptible,
bool no_wait_gpu)
@@ -675,8 +697,6 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, 
uint32_t type,
}
  
  			man->func = &nouveau_vram_manager;

-   man->io_reserve_fastpath = false;
-   man->use_io_reserve_lru = true;
} else {
man->func = &ttm_bo_manager_func;
}
@@ -1305,6 +1325,8 @@ nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, bool 
evict,
if (bo->destroy != nouveau_bo_del_ttm)
return;
  
+	nouveau_bo_del_io_reserve_lru(bo);

+
if (mem && new_reg->mem_type != TTM_PL_SYSTEM &&
mem->mem.page == nvbo->page) {
list_for_each_entry(vma, &nvbo->vma_list, head) {
@@ -1427,6 +1449,30 @@ nouveau_bo_verify_access(struct ttm_buffer_object *bo, 
struct file *filp)
  filp->private_data);
  }
  
+static void

+nouveau_ttm_io_mem_free_locked(struct nouveau_drm *drm, struct ttm_mem_reg 
*reg)
+{
+   struct nouveau_mem *mem = nouveau_mem(reg);
+
+   if (!reg->bus.base)
+   return; /* already freed */
+
+   if (drm->client.mem->oclass >= NVIF_CLASS_MEM_NV50) {
+   switch (reg->mem_type) {
+   case TTM_PL_TT:
+   if (mem->kind)
+   nvif_object_unmap_handle(&mem->mem.object);
+   break;
+   case TTM_PL_VRAM:
+   nvif_object_unmap_handle(&mem->mem.object);
+   break;
+   default:
+   break;
+   }
+   }
+   reg->bus.base = 0;
+}
+
  static int
  nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg 
*reg)
  {
@@ -1434,18 +1480,26 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, 
struct ttm_mem_reg *reg)
struct nouveau_drm *dr

Re: [Nouveau] [PATCH] drm/nouveau/bios: fix incorrect kfree in platform_init

2020-01-03 Thread Roy Spliet

(re-sending as plain text)

NACK. The before and after of this patch are functionally identical. The 
if-block returns unconditionally ("return priv;"), so the kfree will 
only ever be reached if the condition in the if-statement evaluates to 
false. Explicitly writing out an else-block is thus superfluous.


Op 03-01-2020 om 09:10 schreef wuxu.wu:

Hi, I think there has a incorrect kfree in pcirom_init function. In
pcirom_init function priv porinter could be free only when priv != null
and priv->rom is null.

Signed-off-by: wuxu.wu 
---
  drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c
index 9b91da0..d776e01 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c
@@ -70,8 +70,9 @@ pcirom_init(struct nvkm_bios *bios, const char *name)
(priv->rom = pci_map_rom(pdev, &priv->size))) {
priv->pdev = pdev;
return priv;
+   } else {
+   kfree(priv);
}
-   kfree(priv);
}
pci_disable_rom(pdev);
}


___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH] drm/nouveau/bios: fix incorrect kfree in platform_init

2020-01-03 Thread Roy Spliet
NACK. The before and after of this patch are functionally identical. The 
if-block returns unconditionally ("return priv;"), so the kfree will 
only ever be reached if the condition in the if-statement evaluates to 
false. Explicitly writing out an else-block is thus superfluous.


Op 03-01-2020 om 09:10 schreef wuxu.wu:

Hi, I think there has a incorrect kfree in pcirom_init function. In
pcirom_init function priv porinter could be free only when priv != null
and priv->rom is null.

Signed-off-by: wuxu.wu 
---
  drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c
index 9b91da0..d776e01 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c
@@ -70,8 +70,9 @@ pcirom_init(struct nvkm_bios *bios, const char *name)
(priv->rom = pci_map_rom(pdev, &priv->size))) {
priv->pdev = pdev;
return priv;
+   } else {
+   kfree(priv);
}
-   kfree(priv);
}
pci_disable_rom(pdev);
}
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH v3] clk: Restore BYPASS_PLL_CHECK from PLLs

2019-09-06 Thread Roy Spliet
(Accidentally replied in person instead of to the list. Here a ~verbatim 
copy of my e-mail earlier)


Briefly, the BYPASS_PLL_CHECK bit disables the PLL locking test when set 
to 1. PLLs should still lock (or not, if the params are wildly 
out-of-bounds), but the test is bypassed and disabled when the bit is set.
This bit was definitely used on NVA3/5/8 by the blob as I confirmed 
ploughing through traces. I recall seeing the same behaviour (disabling) 
on early Fermi's, but I'd have to dig a whole lot deeper through old 
trace to confirm. As for why NVIDIA disables this test after verifying 
the PLL locked, my highly speculative guess back then was just power 
savings. As to why nouveau does it: when in Rome...
The fact that this makes a difference in stability on GF119 makes me 
wonder whether the PLL control register has a different layout on these 
GPUs. The BYPASS_PLL_CHECK bit might no longer be a BYPASS_PLL_CHECK 
bit, but have a completely different meaning. As this gen was 
centimetring towards Kepler, you might want to:
1) investigate behaviour of this bit and the rest of the control bits on 
an idle GF119. Got a machine with an Intel/AMD IGP? Good, stick the 
GF119 in as a secondary GPU and you can trace while messing with the 
VDEC PLL or some other insignificant domain's PLL manually without 
hanging the card or your machine,
2) Look at Kepler code either in nouveau or nvgpu to see if their PLL 
reconfiguration code matches your traces closer,

3) Be cheeky and ask NVIDIA.

Depending on further investigation you may have to create a new 
clk/gf119.c subdev to facilitate potential differences between earlier 
Fermis and this one.


Roy


On 06/09/2019 12:43, Mark Menzynski wrote:

I have looked at problem with Fermi GPUs where changing to higher clock
led to really bad perfomance (with GpuTest 20x worse perfomance) and later also 
crashes of the nouveau. It seemed
to be affected by Shader Clock in Voltage Entries in the video BIOS. Disabling
BYPASS_PLL_CHECK in CLK0_CTRL seems to completely fix the issue. I have
tried to search this BYPASS_PLL_CHECK in Nvidia traces but seemed it
wasn't used nowhere for CLK settings.

Removing this works fine, but I don't know what it's really for.
Actual bit setting this BYPASS_PLL_CHECK is on 0x10:
lookup -ac0 0x137000 0x10
PCLOCK.CLK0_CTRL => { BYPASS_PLL_CHECK | UNK12 = 0 }
Also, disabling this bit on other CLKs doesn't seem to break anything.

v2: add back PLL lock test
v3: add restoring original value after PLL lock test

Signed-off-by: Mark Menzynski 
---
  drm/nouveau/nvkm/subdev/clk/gf100.c | 7 +--
  drm/nouveau/nvkm/subdev/clk/gk104.c | 5 -
  2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drm/nouveau/nvkm/subdev/clk/gf100.c 
b/drm/nouveau/nvkm/subdev/clk/gf100.c
index 7f67f9f5..a97af0e9 100644
--- a/drm/nouveau/nvkm/subdev/clk/gf100.c
+++ b/drm/nouveau/nvkm/subdev/clk/gf100.c
@@ -368,6 +368,7 @@ gf100_clk_prog_2(struct gf100_clk *clk, int idx)
struct gf100_clk_info *info = &clk->eng[idx];
struct nvkm_device *device = clk->base.subdev.device;
const u32 addr = 0x137000 + (idx * 0x20);
+   bool bypass_state = false;
if (idx <= 7) {
nvkm_mask(device, addr + 0x00, 0x0004, 0x);
nvkm_mask(device, addr + 0x00, 0x0001, 0x);
@@ -376,12 +377,14 @@ gf100_clk_prog_2(struct gf100_clk *clk, int idx)
nvkm_mask(device, addr + 0x00, 0x0001, 0x0001);
  
  			/* Test PLL lock */

+   bypass_state = nvkm_rd32(device, addr + 0x00) & 
0x0010;
nvkm_mask(device, addr + 0x00, 0x0010, 0x);
nvkm_msec(device, 2000,
if (nvkm_rd32(device, addr + 0x00) & 0x0002)
break;
);
-   nvkm_mask(device, addr + 0x00, 0x0010, 0x0010);
+   if (bypass_state)
+   nvkm_mask(device, addr + 0x00, 0x0010, 
0x0010);
  
  			/* Enable sync mode */

nvkm_mask(device, addr + 0x00, 0x0004, 0x0004);
@@ -476,5 +479,5 @@ gf100_clk_new(struct nvkm_device *device, int index, struct 
nvkm_clk **pclk)
return -ENOMEM;
*pclk = &clk->base;
  
-	return nvkm_clk_ctor(&gf100_clk, device, index, false, &clk->base);

+   return nvkm_clk_ctor(&gf100_clk, device, index, true, &clk->base);
  }
diff --git a/drm/nouveau/nvkm/subdev/clk/gk104.c 
b/drm/nouveau/nvkm/subdev/clk/gk104.c
index 0b37e3da..c9ede404 100644
--- a/drm/nouveau/nvkm/subdev/clk/gk104.c
+++ b/drm/nouveau/nvkm/subdev/clk/gk104.c
@@ -388,6 +388,7 @@ gk104_clk_prog_2(struct gk104_clk *clk, int idx)
struct gk104_clk_info *info = &clk->eng[idx];
struct nvkm_device *device = clk->base.subdev.device;
const u32 addr = 0x137000 + (idx * 0x20);
+   bool byp

Re: [Nouveau] [Piglit] X.Org GSoC 2019 - Student Application Period

2019-03-26 Thread Roy Spliet

Thanks for reaching out on the matter Ilia.
I am not to be relied on. If you're lucky, I might be able to take some 
questions about past work, but cannot make a solid time commitment that 
warrants being a mentor.
Of course, the mentor does not necessarily have to have the deepest 
understanding of the subject matter. *At the end of the GSOC* a good 
student should be trusted with having more knowledge on the specific 
topic than the mentor. That being said, DVFS is fidgetty and the outcome 
is binary (it either works or crashes your machine spectacularly), so 
it's difficult to get someone started and keep 'em motivated if as a 
mentor you don't have experience on the topic. As such, I'd consider it 
a high risk topic to promote unless one of the relative veteran 
developers (Ben, Martin, Karol, or Lyude in the case of clock/power 
gating) is keen to mentor.


Roy


On 26/03/2019 15:07, Ilia Mirkin wrote:

On Tue, Mar 26, 2019 at 10:56 AM Trevor Woerner  wrote:


On Tue 2019-03-26 @ 10:40:49 AM, Ilia Mirkin wrote:

Just looked over the projects... they all seem valid


Thank you for taking the time to have a look and provide feedback!


but are there
people who could realistically mentor a GSoC student for these? IMHO
unless mentors can be identified, these should all be archived.


Attracting mentors is probably the hardest part of running GSoC. Perhaps if a
student shows interest in a given topic, someone might be inspired to sign up
as a mentor?

Keeping the list of ideas up-to-date and finding mentors are the two things
I'm hoping to make a noticeable improvement to this year. It also ties in
strongly with:

 https://gitlab.freedesktop.org/freedesktop/freedesktop/issues/76

Best regards,
 Trevor


BTW - I meant my comment to only apply to nouveau-related projects.
Both in terms of validity, as well as mentorship-unavailability.

It sucks for a student to come in, think that some project is
available to work on, only to find that there's no one who can mentor
them. I don't know how often that happens, but I bet it's "sometimes".
Better to get them to dedicate themselves to projects that do have
mentors available.

[And yeah, I know these are meant as "ideas", but I think in practice
it's "here's a list of projects for you to select from". Only a very
rare student will come up with their own idea.]

   -ilia
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

Re: [Nouveau] Google's Chrome Team might Blacklist Nouveau on Chromium

2018-09-26 Thread Roy Spliet
I don't think any nouveau dev would disagree with the choice for a 
software rendered browser over an unreliable browser. Insofar I still 
count as a nouveau dev, I'll back this decision because it benefits user 
experience.
What is disappointing though is that when I perform a search on our bug 
tracker (see [0] and [1]), I find precisely _one_ relevant bug. Shame on 
us for not following up on that one, but shame on the Chrome developers 
to decide they'd rather blacklist a driver than publicly* reach out and 
ask what's going on. Blacklisting 3D rendering on nouveau isn't going to 
fix nouveau, it's a short-term improvement with no long term prospect.


On 26/09/18 11:25, Megaf wrote:

Well, I agree with them.
Nouveau is extremely unstable on my MacBook Pro with Nvidia 320M, 
freezing all the time and draining a lot of battery.

Performance wise is not too bad tho.
There's plenty of reported bugs already around the web if someone 
wants to investigate it.
Don't take this as personal criticism, I really appreciate the fact that 
you reach out and bring this to our attention. What I do wish to point 
out to anyone is that there are too many projects with too many bug 
trackers out there to track all of them. In reality nouveau devs monitor 
the nouveau bugtracker [2], and if you're lucky the tracker of their 
favourite distro. I don't believe it's feasible to expect driver devs to 
track more - we're already grossly under"staffed". Sure, Chrome is a 
popular piece of software, but so is Firefox, LibreOffice, VirtualBox, 
Wine, Dolphin, Gnome Shell etc. etc... So my advice to anyone: if you 
want bugs actually fixed in nouveau, do your civil duty and file them in 
the nouveau bugtracker.


Roy

[0] 
https://bugs.freedesktop.org/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_status=NEEDINFO&component=Driver%2Fnouveau&product=xorg&query_format=advanced&short_desc=chrome&short_desc_type=allwordssubstr
[1] 
https://bugs.freedesktop.org/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_status=NEEDINFO&component=Drivers%2FDRI%2Fnouveau&product=Mesa&query_format=advanced&short_desc=chrome&short_desc_type=allwordssubstr

[2] https://nouveau.freedesktop.org/wiki/Bugs/

* I'm aware that a sizeable portion of the workforce behind nouveau is 
currently employed by Red Hat. What happens behind their scenes is 
unknown to me and other contributors...


Thanks
Megaf
https://www.megaf.info/

email: mme...@gmail.com 
skype: eumegaf
discord: Megaf#6582


On Sun, 23 Sep 2018 at 04:06, Matthew Ary > wrote:



I thought you all would like to know that Google considers Nouveau
to be unstable and is now actively considering blacklisting.
Please see this issue on their issue tracker.

https://bugs.chromium.org/p/chromium/issues/detail?id=876523
___
Nouveau mailing list
Nouveau@lists.freedesktop.org 
https://lists.freedesktop.org/mailman/listinfo/nouveau



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH v3 5/6] kms/nv50: detect HDMI max MHz correctly

2018-08-03 Thread Roy Spliet


On 03/08/18 16:56, Karol Herbst wrote:

On Fri, Aug 3, 2018 at 4:08 PM, Ilia Mirkin  wrote:

On Fri, Aug 3, 2018 at 8:19 AM, Karol Herbst  wrote:

v2: clean up left over comments
 don't overwrite hdmimhz parameter
 cap to 297MHz

Signed-off-by: Karol Herbst 
---
  drm/nouveau/dispnv50/disp.c |  5 +
  drm/nouveau/nouveau_connector.c | 15 ++-
  drm/nouveau/nouveau_encoder.h   |  4 
  3 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/drm/nouveau/dispnv50/disp.c b/drm/nouveau/dispnv50/disp.c
index fa23d7a2..103433cb 100644
--- a/drm/nouveau/dispnv50/disp.c
+++ b/drm/nouveau/dispnv50/disp.c
@@ -1433,7 +1433,12 @@ nv50_sor_create(struct drm_connector *connector, struct 
dcb_output *dcbe,
 case DCB_OUTPUT_LVDS: type = DRM_MODE_ENCODER_LVDS; break;
 case DCB_OUTPUT_DP:
 nv_encoder->dp.no_interlace = caps->sor[or].dp.no_interlace;
+   type = DRM_MODE_ENCODER_TMDS;
+   break;
 case DCB_OUTPUT_TMDS:
+   nv_encoder->tmds.max_mhz = caps->sor[or].tmds.max_mhz;
+   type = DRM_MODE_ENCODER_TMDS;
+   break;
 default:
 type = DRM_MODE_ENCODER_TMDS;
 break;
diff --git a/drm/nouveau/nouveau_connector.c b/drm/nouveau/nouveau_connector.c
index 074e6d52..65fac604 100644
--- a/drm/nouveau/nouveau_connector.c
+++ b/drm/nouveau/nouveau_connector.c
@@ -980,15 +980,20 @@ static unsigned
  get_tmds_link_bandwidth(struct drm_connector *connector, bool hdmi)
  {
 struct nouveau_connector *nv_connector = nouveau_connector(connector);
+   struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
 struct nouveau_drm *drm = nouveau_drm(connector->dev);
 struct dcb_output *dcb = nv_connector->detected_encoder->dcb;

+   if (hdmi && nouveau_hdmimhz > 0)
+   return nouveau_hdmimhz * 1000;
+
+   if (nv_encoder->tmds.max_mhz)
+   /* no HDMI 2.0 for now and not quite clear if we can use
+ * higher HDMI clocks than 297MHz
+ */
+   return min(297, nv_encoder->tmds.max_mhz) * 1000;

So ... will you start reporting 297MHz single-link TMDS bandwidth over DVI now?

What values show up in max_mhz in practice, across the boards you've
tested (ideally a per-generation summary would be nice).


It is a bit silly that those limits are multiple of 10MHz though :/

Fermi (GF119, allthough those caps are there starting with GF110, but
changing the code for that is a bit more messy currently): 230
Kepler: 340
Maxwell+: 600


Do you have ideas on whether the limit shouldn't rather be the minimum 
of 1) the CAPS-indicated limit and 2) the pixel clock PLL limit derived 
from the PLL limits table (and/or other related VBIOS tables)? Is there 
a reason to believe NVIDIA deliberately hard-coded an upper bound of 
297MHz? Can you perhaps try really hard to nudge the official driver to 
set pixel clocks on Kepler somewhere between 297 and 340MHz by messing 
with the VBIOS tables and modelines (even if it fails to bring the 
display up because the PLL never locks or sth...)?


I really want to test this 340MHz limit on Kepler before though.

we also have a few more caps (which are unrelated to the max clock
over DVI, but maybe you have some ideas where we could use them or fix
potential issues we don't know yet how to fix them?):
SINGLE_LVDS18
SINGLE_LVDS24
DUAL_LVDS18
DUAL_LVDS24
SINGLE_TMDS_A
SINGLE_TMDS_B
DUAL_TMDS
DP_A
DP_B

besides that there is tons of stuff inside
open-gpu-doc/Display-Class-Methods/2/cl907d.h, it is the
CORE_NOTIFIER_3_CAPABILITIES stuff.


+
 if (hdmi) {
-   if (nouveau_hdmimhz > 0)
-   return nouveau_hdmimhz * 1000;
-   /* Note: these limits are conservative, some Fermi's
-* can do 297 MHz. Unclear how this can be determined.
-*/
 if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_KEPLER)
 return 297000;
 if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_FERMI)
diff --git a/drm/nouveau/nouveau_encoder.h b/drm/nouveau/nouveau_encoder.h
index f74af5ce..fbef9dc0 100644
--- a/drm/nouveau/nouveau_encoder.h
+++ b/drm/nouveau/nouveau_encoder.h
@@ -65,6 +65,10 @@ struct nouveau_encoder {
 int link_bw;
 bool no_interlace;
 } dp;
+
+   struct {
+   uint16_t max_mhz;
+   } tmds;
 };

 void (*enc_save)(struct drm_encoder *encoder);
--
2.17.1

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


__

Re: [Nouveau] trouble connecting to Panduit VGA adapter

2017-09-01 Thread Roy Spliet
If this doesn't work I suspect the converter is really blocking/damaging 
the EDID information. The official NVIDIA driver is willing to fall back 
to default modes, but this fall-back was handled less gracefully on 
nouveau last time I checked.


You might be able to use the xrandr tool to manually add a mode for the 
display. Forgive me for not knowing the exact syntax, but from what I 
recall you can use cvt to generate a modeline and copy-paste the 
parameters into an xrandr command to add, then use a second xrandr 
command to enable the display either in mirror mode or positioned 
relative to another display. If you're lucky, that mode corresponds well 
enough with what the projector will accept to just work.



Op 01-09-17 om 18:01 schreef Ilia Mirkin:

Are you running a v4.12-based kernel? If so, update to v4.13-rcN or
integrate 
https://github.com/skeggsb/linux/commit/13a86519202c5d119d83640d6f781f3181205d2c
into your kernel build.

On Fri, Sep 1, 2017 at 12:50 PM, Marko Schuetz-Schmuck
 wrote:

I want to connect to an InFocus projector that sits behind a Panduit VGA
adapter. I use a Thinkpad P51 with a mini display-port to VGA
converter. The laptop runs Manjaro and has the
video-hybrid-intel-nouveau-prime installed and it works with other
monitors. For some reason it does not detect the projector that is
connected through the Panduit. The keyboard shortcut to switch monitor
configuration says "No External Display". xrandr reports only the
built-in screen.

I talked to the technician for the room installation and he told me that
he had seen this before on a Ubuntu machine and that switching to the
proprietary nvidia driver solved that problem. For various reasons I'd
rather not switch to that driver.

I also found some lines with "DRM: DDC responded, but no EDID for DP-1"
in them from around the time I tried connecting to the projector. Could
they be related?

Is there some setting or configuration that can help in this case?

Best regards,

Marko

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH] drm/nouveau: Add support for clockgating on Fermi+

2017-04-25 Thread Roy Spliet

Thanks for the work so far.

A quick scan through the first NVC4 trace at hand, using upstream 
demmio, reveals at least 20 writes to the BLCG registers of PGRAPH and a 
few in PXBAR prior to altering the value of register 0x20200 (see 
below). We know that these are related to the clock gating you enable. 
Are you 110% sure that fiddling with 0x20200 bits without first setting 
these values can *never* cause any issues with stability or correctness, 
even under the weirdest of loads?



Roy

8<--

[0] 96.240915 MMIO32 W 0x4041f0 0xc646 PGRAPH.DISPATCH.HW_BLK.BLCG 
<= 0xc646

[0] 96.240925 MMIO32 W 0x409890 0x0045 PGRAPH.CTXCTL.HW_BLK.BLCG <= 0x45
[0] 96.240935 MMIO32 W 0x4078c0 0x4242 PGRAPH.TPBUS.HW_BLK.BLCG <= 
0x4242
[0] 96.240946 MMIO32 W 0x406000 0x4442 PGRAPH.UNK6000.HW_BLK0.BLCG 
<= 0x4442
[0] 96.240956 MMIO32 W 0x406010 0x4242 PGRAPH.UNK6000.HW_BLK1.BLCG 
<= 0x4242
[0] 96.240966 MMIO32 W 0x405860 0x4242 PGRAPH.UNK5800.HW_BLK.BLCG <= 
0x4242
[0] 96.240977 MMIO32 W 0x40590c 0xc242 PGRAPH.UNK5900.HW_CGBLK.BLCG 
<= 0xc242
[0] 96.240987 MMIO32 W 0x408040 0xc443 PGRAPH.CCACHE.HW_BLK.BLCG <= 
0xc443
[0] 96.240997 MMIO32 W 0x41a890 0x4242 
PGRAPH.GPC_BROADCAST.CTXCTL.HW_BLK.BLCG <= 0x4242
[0] 96.241007 MMIO32 W 0x418500 0xc242 
PGRAPH.GPC_BROADCAST.UNK500.HW_CGBLK.BLCG <= 0xc242
[0] 96.241018 MMIO32 W 0x418608 0xc242 
PGRAPH.GPC_BROADCAST.UNK600.HW_BLK.BLCG <= 0xc242
[0] 96.241028 MMIO32 W 0x418688 0xc242 
PGRAPH.GPC_BROADCAST.UNK680.HW_BLK.BLCG <= 0xc242
[0] 96.241038 MMIO32 W 0x418718 0x0042 
PGRAPH.GPC_BROADCAST.UNK700.HW_BLK.BLCG <= 0x42
[0] 96.241048 MMIO32 W 0x418828 0x8442 
PGRAPH.GPC_BROADCAST.ESETUP.HW_CGBLK.BLCG <= 0x8442
[0] 96.241058 MMIO32 W 0x418bbc 0xc242 
PGRAPH.GPC_BROADCAST.TPBUS.HW_BLK.BLCG <= 0xc242
[0] 96.241069 MMIO32 W 0x418970 0xc242 
PGRAPH.GPC_BROADCAST.ZCULL.HW_BLK.BLCG <= 0xc242
[0] 96.241079 MMIO32 W 0x418c70 0xc242 
PGRAPH.GPC_BROADCAST.TPCONF.HW_BLK.BLCG <= 0xc242
[0] 96.241089 MMIO32 W 0x418cf0 0xc242 
PGRAPH.GPC_BROADCAST.UNKC80.HW_BLK.BLCG <= 0xc242
[0] 96.241102 MMIO32 W 0x418d70 0xc242 
PGRAPH.GPC_BROADCAST.UNKD00.HW_BLK.BLCG <= 0xc242
[0] 96.241112 MMIO32 W 0x418f0c 0xc242 
PGRAPH.GPC_BROADCAST.UNKF00.HW_BLK.BLCG <= 0xc242
[0] 96.241122 MMIO32 W 0x418e0c 0xc242 
PGRAPH.GPC_BROADCAST.UNKE00.HW_BLK.BLCG <= 0xc242
[0] 96.241132 MMIO32 W 0x419020 0xc242 
PGRAPH.GPC_BROADCAST.CCACHE.HW_CGBLK0.BLCG <= 0xc242
[0] 96.241143 MMIO32 W 0x419038 0x0042 
PGRAPH.GPC_BROADCAST.CCACHE.HW_CGBLK1.BLCG <= 0x42
[0] 96.241153 MMIO32 W 0x418898 0x4242 PGRAPH.GPC_BROADCAST.FFB.BLCG 
<= 0x4242
[0] 96.241163 MMIO32 W 0x419a40 0xc242 
PGRAPH.GPC_BROADCAST.TPC_ALL.TEX.HW_CGBLK0.BLCG <= 0xc242
[0] 96.241173 MMIO32 W 0x419a48 0xc242 
PGRAPH.GPC_BROADCAST.TPC_ALL.TEX.HW_CGBLK1.BLCG <= 0xc242
[0] 96.241183 MMIO32 W 0x419a50 0xc242 
PGRAPH.GPC_BROADCAST.TPC_ALL.TEX.HW_CGBLK2.BLCG <= 0xc242
[0] 96.241194 MMIO32 W 0x419a58 0xc242 
PGRAPH.GPC_BROADCAST.TPC_ALL.TEX.HW_CGBLK3.BLCG <= 0xc242
[0] 96.241204 MMIO32 W 0x419a60 0xc242 
PGRAPH.GPC_BROADCAST.TPC_ALL.TEX.HW_CGBLK4.BLCG <= 0xc242
[0] 96.241214 MMIO32 W 0x419a68 0xc242 
PGRAPH.GPC_BROADCAST.TPC_ALL.TEX.HW_CGBLK5.BLCG <= 0xc242
[0] 96.241224 MMIO32 W 0x419a70 0xc242 
PGRAPH.GPC_BROADCAST.TPC_ALL.TEX.HW_CGBLK6.BLCG <= 0xc242
[0] 96.241235 MMIO32 W 0x419a78 0xc242 
PGRAPH.GPC_BROADCAST.TPC_ALL.TEX.HW_CGBLK7.BLCG <= 0xc242
[0] 96.241245 MMIO32 W 0x419a80 0xc242 
PGRAPH.GPC_BROADCAST.TPC_ALL.TEX.HW_CGBLK8.BLCG <= 0xc242
[0] 96.241255 MMIO32 W 0x419acc 0xc742 
PGRAPH.GPC_BROADCAST.TPC_ALL.TEX+0xcc <= 0xc742
[0] 96.241265 MMIO32 W 0x419868 0x8242 
PGRAPH.GPC_BROADCAST.TPC_ALL.POLY.HW_BLK.BLCG <= 0x8242
[0] 96.241275 MMIO32 W 0x419ccc 0x4242 
PGRAPH.GPC_BROADCAST.TPC_ALL.L1.BLCG0 <= 0x4242
[0] 96.241286 MMIO32 W 0x419cd4 0x4242 
PGRAPH.GPC_BROADCAST.TPC_ALL.L1.HW_CGBLK1.BLCG <= 0x4242
[0] 96.241296 MMIO32 W 0x419cdc 0x4242 
PGRAPH.GPC_BROADCAST.TPC_ALL.L1.HW_CGBLK2.BLCG <= 0x4242
[0] 96.241306 MMIO32 W 0x419be8 0xc242 
PGRAPH.GPC_BROADCAST.TPC_ALL.TPBUS.HW_BLK.BLCG <= 0xc242
[0] 96.241316 MMIO32 W 0x419d30 0xc242 
PGRAPH.GPC_BROADCAST.TPC_ALL.MASTER.HW_CGBLK.BLCG <= 0xc242
[0] 96.241326 MMIO32 W 0x419c70 0xc542 
PGRAPH.GPC_BROADCAST.TPC_ALL.UNK400.HW_BLK.BLCG <= 0xc542
[0] 96.241337 MMIO32 W 0x419fc0 0xd04b 
PGRAPH.GPC_BROADCAST.TPC_ALL.MP.HW_BLK0.BLCG <= 0xd04b
[0] 96.241347 MMIO32 W 0x419fd4 0xcb4b 
PGRAPH.GPC_BROADCAST.TPC_ALL.MP.HW_BLK1.BLCG <= 0xcb4b
[0] 96.241357 MMIO32 W 0x419fe8 0xcb4b 
PGRAPH.GPC_BROADCAST.TPC_ALL.MP.HW_BLK2.BLCG <= 0xcb4b
[0] 96.241367 MMIO32 W 0x408810 0xc242 
PGRAPH.ROP_BROADCAST.ZROP.HW_CGBLK0.BLCG <= 0xc242
[0] 96.241377 MMIO32 W 0x408818 0xc242 
PGRAPH.ROP_BROADCAST.ZROP.HW_CGBLK1.BLCG <= 0xc242
[0] 96.241388 MMIO32 W 0x408a80 0xc242 
PGRAPH.ROP_BROADCAST.HW_CGBLK0.BLCG <= 0xc242
[0] 96.241398 MMIO32 W 0x408a

Re: [Nouveau] [PATCH] volt: Improve min/max deteaction of range based volting

2017-04-22 Thread Roy Spliet

Response in-line:


Op 22-04-17 om 13:22 schreef Karol Herbst:

info.min and info.max doesn't always represent the actual voltage range we
can use. Do the same as with the entry based volting.

Fixes "ERROR: Can't get value of subfeature in0_min: Can't read" errors
in sensors.

Signed-off-by: Karol Herbst 
---
  drm/nouveau/nvkm/subdev/volt/base.c | 6 --
  1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drm/nouveau/nvkm/subdev/volt/base.c 
b/drm/nouveau/nvkm/subdev/volt/base.c
index e344901c..61b29c7a 100644
--- a/drm/nouveau/nvkm/subdev/volt/base.c
+++ b/drm/nouveau/nvkm/subdev/volt/base.c
@@ -195,14 +195,16 @@ nvkm_volt_parse_bios(struct nvkm_bios *bios, struct 
nvkm_volt *volt)
data = nvbios_volt_parse(bios, &ver, &hdr, &cnt, &len, &info);
if (data && info.vidmask && info.base && info.step && info.ranged) {
nvkm_debug(subdev, "found ranged based VIDs\n");
-   volt->min_uv = info.min;
-   volt->max_uv = info.max;
+   volt->min_uv = 0x;
+   volt->max_uv = 0;
for (i = 0; i < info.vidmask + 1; i++) {
if (info.base >= info.min &&
info.base <= info.max) {
How bogus are info.min and info.max when you get that error? Is this 
if-statement still valid?

volt->vid[volt->vid_nr].uv = info.base;
volt->vid[volt->vid_nr].vid = i;
volt->vid_nr++;
+   volt->min_uv = min(volt->min_uv, info.base);
+   volt->max_uv = max(volt->max_uv, info.base);
}
info.base += info.step;
}


___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH 0/4] nouveau_hwmon: migrate to hwmon_device_register_with_info

2017-04-13 Thread Roy Spliet
Just a non-technical (but important!) point: if you send four patches, 
make sure their title (the first line of your git commit messages) 
describes the content. Given you re-used the same title four times, I 
dare to say it's too generic.
Also, I noticed that this is not the standard git patch format as 
produced by git format-patch. I don't know whether this is a concern (or 
whether you tweaked the format yourself), but in the off chance that you 
are relatively new to git, I recommend you to look up the "git 
format-patch" and "git send-email" commands. They make life a lot easier 
in our mailing-list based work-flow!
This being said, thanks for the work! I'm sure with a bit of minor 
tweaking this is suitable for upstream.


Roy

Op 13-04-17 om 10:07 schreef Oscar Salvador:

Hi again,

I've split the patches as Karol Herbst suggested.
I hope now it's fine.

This series of patches introduce the new hwmon_device_register_with_info
and gets rid of the old hwmon_device_register.

This patch adds the default sensors with their possible config values.
Just to prepare for the next patches


--- linux/drivers/gpu/drm/nouveau/nouveau_hwmon.c.orig  2017-04-12 
19:18:09.638073562 +0200
+++ linux/drivers/gpu/drm/nouveau/nouveau_hwmon.c   2017-04-12 
19:19:44.244797202 +0200
@@ -692,6 +692,78 @@ static const struct attribute_group hwmo
  static const struct attribute_group hwmon_power_caps_attrgroup = {
.attrs = hwmon_power_caps_attributes,
  };
+
+static const u32 nouveau_config_chip[] = {
+   HWMON_C_UPDATE_INTERVAL,
+   0
+};
+
+static const u32 nouveau_config_in[] = {
+   HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_LABEL,
+   0
+};
+
+static const u32 nouveau_config_temp[] = {
+   HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST |
+   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_EMERGENCY |
+   HWMON_T_EMERGENCY_HYST,
+   0
+};
+
+static const u32 nouveau_config_fan[] = {
+   HWMON_F_INPUT,
+   0
+};
+
+static const u32 nouveau_config_pwm[] = {
+   HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
+   0
+};
+
+static const u32 nouveau_config_power[] = {
+   HWMON_P_INPUT | HWMON_P_CAP_MAX | HWMON_P_CRIT,
+   0
+};
+
+static const struct hwmon_channel_info nouveau_chip = {
+   .type = hwmon_chip,
+   .config = nouveau_config_chip,
+};
+
+static const struct hwmon_channel_info nouveau_temp = {
+   .type = hwmon_temp,
+   .config = nouveau_config_temp,
+};
+
+static const struct hwmon_channel_info nouveau_fan = {
+   .type = hwmon_fan,
+   .config = nouveau_config_fan,
+};
+
+static const struct hwmon_channel_info nouveau_in = {
+   .type = hwmon_in,
+   .config = nouveau_config_in,
+};
+
+static const struct hwmon_channel_info nouveau_pwm = {
+   .type = hwmon_pwm,
+   .config = nouveau_config_pwm,
+};
+
+static const struct hwmon_channel_info nouveau_power = {
+   .type = hwmon_power,
+   .config = nouveau_config_power,
+};
+
+static const struct hwmon_channel_info *nouveau_info[] = {
+   &nouveau_chip,
+   &nouveau_temp,
+   &nouveau_fan,
+   &nouveau_in,
+   &nouveau_pwm,
+   &nouveau_power,
+   NULL
+};
  #endif
  
  int

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 13/13] nvkm/bios/perf: Retreive pointer to unk1c script

2017-04-10 Thread Roy Spliet
Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/perf.h |  1 +
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/perf.c | 14 ++
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c   |  1 +
 3 files changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/perf.h 
b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/perf.h
index 478b1c0..28555d6 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/perf.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/perf.h
@@ -40,4 +40,5 @@ struct nvbios_perf_fan {
 };
 
 int nvbios_perf_fan_parse(struct nvkm_bios *, struct nvbios_perf_fan *);
+u16 nvbios_perf_script_unk1c(struct nvkm_bios *bios);
 #endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/perf.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/perf.c
index c306835..55c1f36 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/perf.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/perf.c
@@ -213,3 +213,17 @@ nvbios_perf_fan_parse(struct nvkm_bios *bios,
 
return 0;
 }
+
+u16
+nvbios_perf_script_unk1c(struct nvkm_bios *bios)
+{
+   struct bit_entry bit_P;
+
+   if (!bit_entry(bios, 'P', &bit_P)) {
+   if (bit_P.version == 2) {
+   return nvbios_rd16(bios, bit_P.offset + 0x1c);
+   }
+   }
+
+   return 0x;
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index eebd20b..def119c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
-- 
2.9.3

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 11/13] nvkm/ramgf100: Hook up ram training pattern init for NVC0+

2017-04-10 Thread Roy Spliet
Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index a469719..eebd20b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -653,8 +653,7 @@ gf100_ram_init(struct nvkm_ram *base)
/* XXX Why does the blob do this? */
nvkm_mask(device, 0x137360, 0x0002, 0x);
 
-   /* XXX: Don't hook up yet for bisectability */
-   return 0;
+   return gf100_ram_train_init(base);
 }
 
 static const struct nvkm_ram_func
-- 
2.9.3

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 06/13] nvkm/ramgt215: Move ram training up the chain

2017-04-10 Thread Roy Spliet
Parts are re-used even on NVA3, others from GF100 on

Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h  |  17 +++
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c |  92 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c | 140 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c |  61 ++
 4 files changed, 140 insertions(+), 170 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h
index b60068b..ce8a98e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h
@@ -1,6 +1,7 @@
 #ifndef __NVKM_FB_RAM_PRIV_H__
 #define __NVKM_FB_RAM_PRIV_H__
 #include "priv.h"
+#include 
 
 int  nvkm_ram_ctor(const struct nvkm_ram_func *, struct nvkm_fb *,
   enum nvkm_ram_type, u64 size, u32 tags,
@@ -24,6 +25,22 @@ int  gf100_ram_ctor(const struct nvkm_ram_func *, struct 
nvkm_fb *,
 int  gf100_ram_get(struct nvkm_ram *, u64, u32, u32, u32, struct nvkm_mem **);
 void gf100_ram_put(struct nvkm_ram *, struct nvkm_mem **);
 
+/* Training */
+struct gt215_ram_train {
+   u16 mask;
+   struct nvbios_M0209S remap;
+   struct nvbios_M0209S type00;
+   struct nvbios_M0209S type01;
+   struct nvbios_M0209S type04;
+   struct nvbios_M0209S type06;
+   struct nvbios_M0209S type07;
+   struct nvbios_M0209S type08;
+   struct nvbios_M0209S type09;
+};
+int gt215_ram_train_type(struct nvkm_ram *ram, int i, u8 ramcfg,
+struct gt215_ram_train *train);
+int  gf100_ram_train_init(struct nvkm_ram *ram);
+
 int  gk104_ram_ctor(struct nvkm_fb *, struct nvkm_ram **, u32);
 int  gk104_ram_init(struct nvkm_ram *ram);
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index b4fe3bb..38a7e2b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -549,45 +550,74 @@ gf100_ram_get(struct nvkm_ram *ram, u64 size, u32 align, 
u32 ncmin,
 }
 
 static int
-gf100_ram_init(struct nvkm_ram *base)
+gf100_ram_train_init_0(struct nvkm_ram *ram, struct gt215_ram_train *train)
 {
-   static const u8  train0[] = {
-   0x00, 0xff, 0x55, 0xaa, 0x33, 0xcc,
-   0x00, 0xff, 0xff, 0x00, 0xff, 0x00,
-   };
-   static const u32 train1[] = {
-   0x, 0x,
-   0x, 0x,
-   0x, 0x,
-   0xf0f0f0f0, 0x0f0f0f0f,
-   0x00ff00ff, 0xff00ff00,
-   0x, 0x,
-   };
-   struct gf100_ram *ram = gf100_ram(base);
-   struct nvkm_device *device = ram->base.fb->subdev.device;
-   int i;
+   struct nvkm_subdev *subdev = &ram->fb->subdev;
+   struct nvkm_device *device = subdev->device;
+   int i, j;
 
-   switch (ram->base.type) {
+   if ((train->mask & 0x03d3) != 0x03d3) {
+   nvkm_warn(subdev, "missing link training data\n");
+   return -EINVAL;
+   }
+
+   for (i = 0; i < 0x30; i++) {
+   for (j = 0; j < 8; j += 4) {
+   nvkm_wr32(device, 0x10f968 + j, 0x | (i << 8));
+   nvkm_wr32(device, 0x10f920 + j, 0x |
+  train->type08.data[i] << 4 |
+  train->type06.data[i]);
+   nvkm_wr32(device, 0x10f918 + j, train->type00.data[i]);
+   nvkm_wr32(device, 0x10f920 + j, 0x0100 |
+  train->type09.data[i] << 4 |
+  train->type07.data[i]);
+   nvkm_wr32(device, 0x10f918 + j, train->type01.data[i]);
+   }
+   }
+
+   for (j = 0; j < 8; j += 4) {
+   for (i = 0; i < 0x100; i++) {
+   nvkm_wr32(device, 0x10f968 + j, i);
+   nvkm_wr32(device, 0x10f900 + j, train->type04.data[i]);
+   }
+   }
+
+   return 0;
+}
+
+int
+gf100_ram_train_init(struct nvkm_ram *ram)
+{
+   u8 ramcfg = nvbios_ramcfg_index(&ram->fb->subdev);
+   struct gt215_ram_train *train;
+   int ret, i;
+
+   if (!(train = kzalloc(sizeof(*train), GFP_KERNEL)))
+   return -ENOMEM;
+
+   for (i = 0; i < 0x100; i++) {
+   ret = gt215_ram_train_type(ram, i, ramcfg, train);
+   if (ret && ret != -ENOENT)
+   break;
+   }
+
+   switch (ram->type) {
case NVKM_RAM_TYPE_GDDR5:
+   ret = g

[Nouveau] [PATCH 12/13] nvkm/pmu/memx: init script -> memx translation

2017-04-10 Thread Roy Spliet
Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h |  2 +
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h   |  8 +++
 drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c| 66 +++
 3 files changed, 76 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h 
b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h
index f37538eb..b9c46ef 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h
@@ -50,4 +50,6 @@ void nvkm_memx_train(struct nvkm_memx *);
 int  nvkm_memx_train_result(struct nvkm_pmu *, u32 *, int);
 void nvkm_memx_block(struct nvkm_memx *);
 void nvkm_memx_unblock(struct nvkm_memx *);
+void nvkm_memx_init_run(struct nvkm_memx *memx, struct nvkm_bios *bios,
+   u16 offset, u8 ramcfg);
 #endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h
index 9ef9d6a..614e716 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h
@@ -160,6 +160,13 @@ ramfuc_unblock(struct ramfuc *ram)
nvkm_memx_unblock(ram->memx);
 }
 
+static inline void
+ramfuc_init_run(struct ramfuc *ram, struct nvkm_bios *bios, u16 offset,
+   u8 ramcfg)
+{
+   nvkm_memx_init_run(ram->memx, bios, offset, ramcfg);
+}
+
 #define ram_init(s,p)ramfuc_init(&(s)->base, (p))
 #define ram_exec(s,e)ramfuc_exec(&(s)->base, (e))
 #define ram_have(s,r)((s)->r_##r.addr != 0x00)
@@ -174,4 +181,5 @@ ramfuc_unblock(struct ramfuc *ram)
 #define ram_train_result(s,r,l) ramfuc_train_result((s), (r), (l))
 #define ram_block(s) ramfuc_block(&(s)->base)
 #define ram_unblock(s)   ramfuc_unblock(&(s)->base)
+#define ram_init_run(s,b,o,r) ramfuc_init_run(&(s)->base, (b), (o), (r))
 #endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c
index e6f7416..c58a51d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c
@@ -1,6 +1,9 @@
 #ifndef __NVKM_PMU_MEMX_H__
 #define __NVKM_PMU_MEMX_H__
 #include "priv.h"
+#include 
+#include 
+#include 
 
 struct nvkm_memx {
struct nvkm_pmu *pmu;
@@ -200,4 +203,67 @@ nvkm_memx_unblock(struct nvkm_memx *memx)
nvkm_debug(&memx->pmu->subdev, "   HOST UNBLOCKED\n");
memx_cmd(memx, MEMX_LEAVE, 0, NULL);
 }
+
+/**
+ * Turn VBIOS init script into memx command stream. Not-quite as feature rich
+ * as subdev/bios/init.c
+ */
+
+static void
+nvkm_memx_init_ram_restrict(struct nvkm_memx *memx, struct nvbios_init *init)
+{
+   struct nvkm_bios *bios = init->bios;
+   struct nvkm_subdev *subdev = &memx->pmu->subdev;
+struct nvkm_device *device = subdev->device;
+   u32 addr = nvbios_rd32(bios, init->offset + 1);
+   u8  incr = nvbios_rd08(bios, init->offset + 5);
+   u8   num = nvbios_rd08(bios, init->offset + 6);
+   u8 count = nvbios_ramcfg_count(init->bios);
+   u8 index = init->ramcfg;
+   u8 i;
+   u32 oldval, newval;
+
+   init->offset += 7;
+
+   for (i = 0; i < num; i++) {
+   oldval  = nvkm_rd32(device, addr);
+   newval = nvbios_rd32(bios, init->offset + (4 * index));
+
+   if (oldval != newval) {
+   nvkm_memx_wr32(memx, addr, newval);
+   }
+   init->offset += 4 * count;
+   addr += incr;
+   }
+}
+
+void
+nvkm_memx_init_run(struct nvkm_memx *memx, struct nvkm_bios *bios, u16 offset,
+   u8 ramcfg)
+{
+   struct nvbios_init init = {
+   .subdev = &bios->subdev,
+   .bios = bios,
+   .offset = offset,
+   .outp = NULL,
+   .execute = 1,
+   .ramcfg = ramcfg,
+   };
+   u8 op;
+
+   while (init.offset)
+   {
+   op = nvbios_rd08(bios, init.offset);
+   switch (op)
+   {
+   case 0x8f:
+   nvkm_memx_init_ram_restrict(memx, &init);
+   break;
+   case 0x71:
+   default:
+   return;
+   }
+   }
+}
+
 #endif
-- 
2.9.3

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 07/13] nvkm/ramgf100: Don't mandate training pattern 4

2017-04-10 Thread Roy Spliet
It's not found on Fermi.

Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index 38a7e2b..eef09bf 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -556,7 +556,7 @@ gf100_ram_train_init_0(struct nvkm_ram *ram, struct 
gt215_ram_train *train)
struct nvkm_device *device = subdev->device;
int i, j;
 
-   if ((train->mask & 0x03d3) != 0x03d3) {
+   if ((train->mask & 0x03c3) != 0x03c3) {
nvkm_warn(subdev, "missing link training data\n");
return -EINVAL;
}
@@ -575,10 +575,13 @@ gf100_ram_train_init_0(struct nvkm_ram *ram, struct 
gt215_ram_train *train)
}
}
 
-   for (j = 0; j < 8; j += 4) {
-   for (i = 0; i < 0x100; i++) {
-   nvkm_wr32(device, 0x10f968 + j, i);
-   nvkm_wr32(device, 0x10f900 + j, train->type04.data[i]);
+   if (train->mask & 0x10) {
+   for (j = 0; j < 8; j += 4) {
+   for (i = 0; i < 0x100; i++) {
+   nvkm_wr32(device, 0x10f968 + j, i);
+   nvkm_wr32(device, 0x10f900 + j,
+   train->type04.data[i]);
+   }
}
}
 
-- 
2.9.3

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 03/13] nvkm/ramgf100: Get rid of (size, data) pairs for rammap, ramcfg, timing

2017-04-10 Thread Roy Spliet
In correspondence with the other ram_calc implementations.

Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c | 37 ---
 1 file changed, 19 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index 093223d..fffd01a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -133,21 +133,22 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq)
struct nvkm_device *device = subdev->device;
struct nvkm_clk *clk = device->clk;
struct nvkm_bios *bios = device->bios;
-   struct nvbios_ramcfg cfg;
-   u8  ver, cnt, len, strap;
-   struct {
-   u32 data;
-   u8  size;
-   } rammap, ramcfg, timing;
+   struct nvkm_ram_data *next;
+   u8  ver, hdr, cnt, len, strap;
+   u32 data;
int ref, div, out;
int from, mode;
int N1, M1, P;
int ret;
 
+   next = &ram->base.target;
+   next->freq = freq;
+   ram->base.next = next;
+
/* lookup memory config data relevant to the target frequency */
-   rammap.data = nvbios_rammapEm(bios, freq / 1000, &ver, &rammap.size,
- &cnt, &ramcfg.size, &cfg);
-   if (!rammap.data || ver != 0x10 || rammap.size < 0x0e) {
+   data = nvbios_rammapEm(bios, freq / 1000, &ver, &hdr,
+ &cnt, &len, &next->bios);
+   if (!data || ver != 0x10 || len < 0x0e) {
nvkm_error(subdev, "invalid/missing rammap entry\n");
return -EINVAL;
}
@@ -159,23 +160,23 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq)
return -EINVAL;
}
 
-   ramcfg.data = rammap.data + rammap.size + (strap * ramcfg.size);
-   if (!ramcfg.data || ver != 0x10 || ramcfg.size < 0x0e) {
+   data = nvbios_rammapSp(bios, data, ver, hdr, cnt, len, strap,
+  &ver, &hdr, &next->bios);
+   if (!data || ver != 0x10 || hdr < 0x0e) {
nvkm_error(subdev, "invalid/missing ramcfg entry\n");
return -EINVAL;
}
 
/* lookup memory timings, if bios says they're present */
-   strap = nvbios_rd08(bios, ramcfg.data + 0x01);
-   if (strap != 0xff) {
-   timing.data = nvbios_timingEe(bios, strap, &ver, &timing.size,
- &cnt, &len);
-   if (!timing.data || ver != 0x10 || timing.size < 0x19) {
+   strap = nvbios_rd08(bios, data + 0x01);
+   if (next->bios.ramcfg_timing != 0xff) {
+   data = nvbios_timingEp(bios, next->bios.ramcfg_timing,
+  &ver, &hdr, &cnt, &len,
+  &next->bios);
+   if (!data || ver != 0x10 || hdr < 0x17) {
nvkm_error(subdev, "invalid/missing timing entry\n");
return -EINVAL;
}
-   } else {
-   timing.data = 0;
}
 
ret = ram_init(fuc, ram->base.fb);
-- 
2.9.3

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 02/13] nvkm/ramnv50: Split up various ramcfg bytes in nibbles

2017-04-10 Thread Roy Spliet
In preparation for Fermi

Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h |  9 ++---
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c |  9 ++---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c | 12 
 3 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h 
b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
index d8a7c04..4560a52 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
@@ -66,9 +66,12 @@ struct nvbios_ramcfg {
unsigned ramcfg_10_02_20:1;
unsigned ramcfg_10_03_0f:4;
unsigned ramcfg_10_04_01:1;
-   unsigned ramcfg_10_05:8;
-   unsigned ramcfg_10_06:8;
-   unsigned ramcfg_10_07:8;
+   unsigned ramcfg_10_05_0f:4;
+   unsigned ramcfg_10_05_f0:8;
+   unsigned ramcfg_10_06_0f:4;
+   unsigned ramcfg_10_06_f0:4;
+   unsigned ramcfg_10_07_0f:4;
+   unsigned ramcfg_10_07_f0:4;
unsigned ramcfg_10_08:8;
unsigned ramcfg_10_09_0f:4;
unsigned ramcfg_10_09_f0:4;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
index b57c370..131d967 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
@@ -207,9 +207,12 @@ nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
p->ramcfg_10_03_0f = (nvbios_rd08(bios, data + 0x03) & 0x0f) >> 
0;
p->ramcfg_10_04_01 = (nvbios_rd08(bios, data + 0x04) & 0x01) >> 
0;
p->ramcfg_FBVDDQ   = (nvbios_rd08(bios, data + 0x04) & 0x08) >> 
3;
-   p->ramcfg_10_05= (nvbios_rd08(bios, data + 0x05) & 0xff) >> 
0;
-   p->ramcfg_10_06= (nvbios_rd08(bios, data + 0x06) & 0xff) >> 
0;
-   p->ramcfg_10_07= (nvbios_rd08(bios, data + 0x07) & 0xff) >> 
0;
+   p->ramcfg_10_05_0f = (nvbios_rd08(bios, data + 0x05) & 0x0f) >> 
0;
+   p->ramcfg_10_05_f0 = (nvbios_rd08(bios, data + 0x05) & 0xf0) >> 
4;
+   p->ramcfg_10_06_0f = (nvbios_rd08(bios, data + 0x06) & 0x0f) >> 
0;
+   p->ramcfg_10_06_f0 = (nvbios_rd08(bios, data + 0x06) & 0xf0) >> 
4;
+   p->ramcfg_10_07_0f = (nvbios_rd08(bios, data + 0x07) & 0x0f) >> 
0;
+   p->ramcfg_10_07_f0 = (nvbios_rd08(bios, data + 0x07) & 0xf0) >> 
4;
p->ramcfg_10_08= (nvbios_rd08(bios, data + 0x08) & 0xff) >> 
0;
p->ramcfg_10_09_0f = (nvbios_rd08(bios, data + 0x09) & 0x0f) >> 
0;
p->ramcfg_10_09_f0 = (nvbios_rd08(bios, data + 0x09) & 0xf0) >> 
4;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
index dd80de1..8454899 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
@@ -705,11 +705,15 @@ gt215_ram_calc(struct nvkm_ram *base, u32 freq)
ram_nsec(fuc, 2);
 
if (next->bios.rammap_10_04_08) {
-   ram_wr32(fuc, 0x1005a0, next->bios.ramcfg_10_06 << 16 |
-   next->bios.ramcfg_10_05 << 8 |
-   next->bios.ramcfg_10_05);
+   ram_wr32(fuc, 0x1005a0, next->bios.ramcfg_10_06_f0 << 20 |
+   next->bios.ramcfg_10_06_0f << 16 |
+   next->bios.ramcfg_10_05_f0 << 12 |
+   next->bios.ramcfg_10_05_0f << 8 |
+   next->bios.ramcfg_10_05_f0 << 4 |
+   next->bios.ramcfg_10_05_0f);
ram_wr32(fuc, 0x1005a4, next->bios.ramcfg_10_08 << 8 |
-   next->bios.ramcfg_10_07);
+   next->bios.ramcfg_10_07_f0 << 4 |
+   next->bios.ramcfg_10_07_0f);
ram_wr32(fuc, 0x10f804, next->bios.ramcfg_10_09_f0 << 20 |
next->bios.ramcfg_10_03_0f << 16 |
next->bios.ramcfg_10_09_0f |
-- 
2.9.3

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 04/13] nvkm/ramgf100: Calculate timings

2017-04-10 Thread Roy Spliet
Todo:
- Determine source of R[10f298] & 0x11

Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c | 115 ++
 1 file changed, 76 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index fffd01a..6ebdc4c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -48,11 +48,7 @@ struct gf100_ramfuc {
 
struct ramfuc_reg r_0x137390;
 
-   struct ramfuc_reg r_0x10f290;
-   struct ramfuc_reg r_0x10f294;
-   struct ramfuc_reg r_0x10f298;
-   struct ramfuc_reg r_0x10f29c;
-   struct ramfuc_reg r_0x10f2a0;
+   struct ramfuc_reg r_0x10f290[5];
 
struct ramfuc_reg r_0x10f300;
struct ramfuc_reg r_0x10f338;
@@ -104,6 +100,50 @@ struct gf100_ram {
struct nvbios_pll mempll;
 };
 
+#define T(t) cfg->timing_10_##t
+static int
+gf100_ram_timing_calc(struct gf100_ram *ram, u32 *timing)
+{
+   struct nvbios_ramcfg *cfg = &ram->base.target.bios;
+   struct nvkm_subdev *subdev = &ram->base.fb->subdev;
+   struct nvkm_device *device = subdev->device;
+   u32 cur1, cur2, cur4;
+
+   cur1 = nvkm_rd32(device, 0x10f294);
+   cur2 = nvkm_rd32(device, 0x10f298);
+   cur4 = nvkm_rd32(device, 0x10f2a0);
+
+   /* XXX: (G)DDR3? */
+   switch ((!T(CWL)) * ram->base.type) {
+   case NVKM_RAM_TYPE_GDDR5:
+   T(CWL) = (cur1 & 0x0380) >> 7;
+   break;
+   }
+
+   timing[0] = (T(RP) << 24 | T(RAS) << 17 | T(RFC) << 8 | T(RC));
+   timing[1] = (cur1 & ~0x03ffc07f) |
+   (T(RCDWR) << 20) |
+   (T(RCDRD) << 14) |
+   (T(CWL) << 7) |
+   (T(CL));
+   /* XXX: lower 8 bytes are two bits indicating "feature(s) X" */
+   timing[2] = (cur2 & ~0x00ff) |
+   (T(WR) << 16) |
+   (T(WTR) << 8);
+   timing[3] = (T(FAW)) << 9 |
+   (T(CKE)) << 5 |
+   (T(XPDLL));
+   timing[4] = (cur4 & ~0x001f8000) |
+   (T(RRD) << 15);
+
+   nvkm_debug(subdev, "Entry: 290: %08x %08x %08x %08x\n",
+  timing[0], timing[1], timing[2], timing[3]);
+   nvkm_debug(subdev, "  2a0: %08x\n",
+  timing[4]);
+   return 0;
+}
+#undef T
+
 static void
 gf100_ram_train(struct gf100_ramfuc *fuc, u32 magic)
 {
@@ -136,10 +176,11 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq)
struct nvkm_ram_data *next;
u8  ver, hdr, cnt, len, strap;
u32 data;
+   u32 timing[5];
int ref, div, out;
int from, mode;
int N1, M1, P;
-   int ret;
+   int i, ret;
 
next = &ram->base.target;
next->freq = freq;
@@ -179,6 +220,8 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq)
}
}
 
+   gf100_ram_timing_calc(ram, timing);
+
ret = ram_init(fuc, ram->base.fb);
if (ret)
return ret;
@@ -314,28 +357,6 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq)
ram_wr32(fuc, 0x10f338, 0x00300220);
ram_wr32(fuc, 0x10f300, 0x011d);
ram_nsec(fuc, 1000);
-   ram_wr32(fuc, 0x10f290, 0x02060505);
-   ram_wr32(fuc, 0x10f294, 0x34208288);
-   ram_wr32(fuc, 0x10f298, 0x44050411);
-   ram_wr32(fuc, 0x10f29c, 0x114c);
-   ram_wr32(fuc, 0x10f2a0, 0x42e10069);
-   ram_wr32(fuc, 0x10f614, 0x40044f77);
-   ram_wr32(fuc, 0x10f610, 0x40044f77);
-   ram_wr32(fuc, 0x10f344, 0x0069);
-   ram_nsec(fuc, 1000);
-   ram_wr32(fuc, 0x10f348, 0x0078);
-   ram_wr32(fuc, 0x61c140, 0x1924);
-   ram_wr32(fuc, 0x10f830, 0x00300017);
-   gf100_ram_train(fuc, 0x80021001);
-   gf100_ram_train(fuc, 0x80081001);
-   ram_wr32(fuc, 0x10f340, 0x0054);
-   ram_nsec(fuc, 1000);
-   ram_wr32(fuc, 0x10f830, 0x01300017);
-   ram_wr32(fuc, 0x10f830, 0x00300017);
-// 0x00030020 // 0x // 0x
-// 0x00020034 // 0x000b
-   ram_wr32(fuc, 0x100b0c, 0x00080028);
-   ram_wr32(fuc, 0x611200, 0x3330);
} else {
ram_wr32(fuc, 0x10f800, 0x1800);
ram_wr32(fuc, 0x13d8f4, 0x);
@@ -364,11 +385,30 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq)
ram_wr32(fuc, 0x10f338, 0x00300200);
ram_wr32(fuc, 0x10f300, 0x084d);
ram_nsec(fuc, 1000);
-   ram_wr32(fuc, 0x10f290, 0x0b343825);
-   ram_wr32(fuc, 0x10f2

[Nouveau] [PATCH 08/13] nvkm/ramgf100: Unset bit before uploading train values

2017-04-10 Thread Roy Spliet
Just because the blob does it too...

Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index eef09bf..62359c2 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -620,6 +620,12 @@ gf100_ram_train_init(struct nvkm_ram *ram)
 static int
 gf100_ram_init(struct nvkm_ram *base)
 {
+   struct nvkm_subdev *subdev = &base->fb->subdev;
+   struct nvkm_device *device = subdev->device;
+
+   /* XXX Why does the blob do this? */
+   nvkm_mask(device, 0x137360, 0x0002, 0x);
+
/* XXX: Don't hook up yet for bisectability */
return 0;
 }
-- 
2.9.3

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 10/13] nvkm/ramgt215: Add train ptrn upload for GDDR5

2017-04-10 Thread Roy Spliet
Signed-off-by: Roy Spliet 
Tested-by: Ilia Mirkin 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h  |   1 +
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c | 128 +-
 2 files changed, 99 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h
index ce8a98e..ef9edc5 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h
@@ -32,6 +32,7 @@ struct gt215_ram_train {
struct nvbios_M0209S type00;
struct nvbios_M0209S type01;
struct nvbios_M0209S type04;
+   struct nvbios_M0209S type05;
struct nvbios_M0209S type06;
struct nvbios_M0209S type07;
struct nvbios_M0209S type08;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
index 6abd0e3..fa85942 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
@@ -75,7 +75,7 @@ struct gt215_ramfuc {
struct ramfuc_reg r_gpio[4];
 };
 
-struct gt215_ltrain {
+struct gt215_ram_train_ddr3 {
enum {
NVA3_TRAIN_UNKNOWN,
NVA3_TRAIN_UNSUPPORTED,
@@ -92,11 +92,11 @@ struct gt215_ltrain {
 struct gt215_ram {
struct nvkm_ram base;
struct gt215_ramfuc fuc;
-   struct gt215_ltrain ltrain;
+   struct gt215_ram_train_ddr3 ltrain;
 };
 
 static void
-gt215_link_train_calc(u32 *vals, struct gt215_ltrain *train)
+gt215_link_train_calc(u32 *vals, struct gt215_ram_train_ddr3 *train)
 {
int i, lo, hi;
u8 median[8], bins[4] = {0, 0, 0, 0}, bin = 0, qty = 0;
@@ -152,7 +152,7 @@ gt215_link_train_calc(u32 *vals, struct gt215_ltrain *train)
 static int
 gt215_link_train(struct gt215_ram *ram)
 {
-   struct gt215_ltrain *train = &ram->ltrain;
+   struct gt215_ram_train_ddr3 *train = &ram->ltrain;
struct gt215_ramfuc *fuc = &ram->fuc;
struct nvkm_subdev *subdev = &ram->base.fb->subdev;
struct nvkm_device *device = subdev->device;
@@ -288,6 +288,7 @@ gt215_ram_train_type(struct nvkm_ram *ram, int i, u8 ramcfg,
case 0x00: value = &train->type00; break;
case 0x01: value = &train->type01; break;
case 0x04: value = &train->type04; break;
+   case 0x05: value = &train->type05; break;
case 0x06: value = &train->type06; break;
case 0x07: value = &train->type07; break;
case 0x08: value = &train->type08; break;
@@ -321,7 +322,7 @@ gt215_ram_train_type(struct nvkm_ram *ram, int i, u8 ramcfg,
for (i = 0; i < ARRAY_SIZE(value->data); i++)
value->data[i] = remap->data[value->data[i]];
} else
-   if (M0209E.v02_07 != 1)
+   if (M0209E.v02_07 > 2)
return -EINVAL;
 
train->mask |= 1 << M0205E.type;
@@ -329,7 +330,47 @@ gt215_ram_train_type(struct nvkm_ram *ram, int i, u8 
ramcfg,
 }
 
 static int
-gt215_link_train_init(struct gt215_ram *ram)
+gt215_ram_train_upload_gddr5(struct nvkm_ram *ram,
+   struct gt215_ram_train *train)
+{
+   struct nvkm_subdev *subdev = &ram->fb->subdev;
+   struct nvkm_device *device = subdev->device;
+   int i, j;
+
+   static const u32 off[] = {0x00, 0x20, 0x04, 0x24};
+
+   if ((train->mask & 0x03c3) != 0x03c3) {
+   nvkm_info(subdev,
+   "missing link training data, not uploading patterns\n");
+   return 0;
+   }
+
+   for (j = 0; j < 4; j++) {
+   for (i = 0; i < 0x80; i++) {
+   nvkm_wr32(device, 0x10f8c0 + off[j], (i << 8) | i);
+   if (i < 0x30) {
+   nvkm_wr32(device, 0x10f940 + off[j], 0x 
|
+   train->type08.data[i] << 4 |
+   train->type06.data[i]);
+   nvkm_wr32(device, 0x10f900 + off[j],
+   train->type00.data[i]);
+   nvkm_wr32(device, 0x10f940 + off[j], 0x0100 
|
+   train->type09.data[i] << 4 |
+   train->type07.data[i]);
+   nvkm_wr32(device, 0x10f900 + off[j],
+   train->type01.data[i]);
+   }
+   nvkm_wr32(device, 0x10f840 + off[j], 0x | i);
+   nvkm_wr32(device, 0x10f840 + off[j], 0x0100 | i);
+   }
+   }
+
+   return 0;
+}
+
+static int
+gt215_ram_train_upload_ddr3(struct nvkm_ram *ram,
+

[Nouveau] [PATCH 05/13] nvkm/gddr5: MR calculation for timing table v1.0

2017-04-10 Thread Roy Spliet
Merges in skeggsb's:
"fb/ram/gf10x: timing_10_0e_30"

Todo:
- find l3, rq
- triple-check

Signed-off-by: Roy Spliet 
---
 .../drm/nouveau/include/nvkm/subdev/bios/ramcfg.h  | 12 +++---
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c  | 22 --
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c  |  2 +
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c | 21 --
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c  | 49 --
 5 files changed, 71 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h 
b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
index 4560a52..44e4ca2 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
@@ -40,6 +40,10 @@ struct nvbios_ramcfg {
unsigned ramcfg_DLLoff;
unsigned ramcfg_RON;
unsigned ramcfg_FBVDDQ;
+   unsigned ramcfg_LowFreq;
+   unsigned ramcfg_WCKPin;
+   unsigned ramcfg_Hf_VREF;
+   unsigned ramcfg_VREFD_off;
union {
struct {
unsigned ramcfg_00_03_01:1;
@@ -82,12 +86,9 @@ struct nvbios_ramcfg {
unsigned ramcfg_11_01_04:1;
unsigned ramcfg_11_01_08:1;
unsigned ramcfg_11_01_10:1;
-   unsigned ramcfg_11_01_40:1;
-   unsigned ramcfg_11_01_80:1;
unsigned ramcfg_11_02_03:2;
unsigned ramcfg_11_02_04:1;
unsigned ramcfg_11_02_08:1;
-   unsigned ramcfg_11_02_10:1;
unsigned ramcfg_11_02_40:1;
unsigned ramcfg_11_02_80:1;
unsigned ramcfg_11_03_0f:4;
@@ -95,7 +96,6 @@ struct nvbios_ramcfg {
unsigned ramcfg_11_03_c0:2;
unsigned ramcfg_11_03_f0:4;
unsigned ramcfg_11_04:8;
-   unsigned ramcfg_11_06:8;
unsigned ramcfg_11_07_02:1;
unsigned ramcfg_11_07_04:1;
unsigned ramcfg_11_07_08:1;
@@ -132,6 +132,7 @@ struct nvbios_ramcfg {
unsigned timing_10_RRD:8;
unsigned timing_10_XPDLL:8;
unsigned timing_10_ODT:3;
+   unsigned timing_10_DS:2;
/* empty: 15 */
unsigned timing_10_10:8;
/* empty: 17 */
@@ -139,7 +140,8 @@ struct nvbios_ramcfg {
unsigned timing_10_CWL:8;
unsigned timing_10_FAW:8;
unsigned timing_10_CKE:8;
-   /* empty: 22, 23 */
+   unsigned timing_10_ADRCMD_T:8;  /* XXX: [3:2]? */
+   /* empty: 23 */
unsigned timing_10_18:8;
};
struct {
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
index 131d967..0d517a0 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
@@ -205,8 +205,11 @@ nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
p->ramcfg_10_02_20 = (nvbios_rd08(bios, data + 0x02) & 0x20) >> 
5;
p->ramcfg_DLLoff   = (nvbios_rd08(bios, data + 0x02) & 0x40) >> 
6;
p->ramcfg_10_03_0f = (nvbios_rd08(bios, data + 0x03) & 0x0f) >> 
0;
+   p->ramcfg_LowFreq  = (nvbios_rd08(bios, data + 0x03) & 0x20) >> 
5;
+   p->ramcfg_WCKPin   = (nvbios_rd08(bios, data + 0x03) & 0x40) >> 
6;
p->ramcfg_10_04_01 = (nvbios_rd08(bios, data + 0x04) & 0x01) >> 
0;
p->ramcfg_FBVDDQ   = (nvbios_rd08(bios, data + 0x04) & 0x08) >> 
3;
+   p->ramcfg_Hf_VREF  = (nvbios_rd08(bios, data + 0x04) & 0x20) >> 
5;
p->ramcfg_10_05_0f = (nvbios_rd08(bios, data + 0x05) & 0x0f) >> 
0;
p->ramcfg_10_05_f0 = (nvbios_rd08(bios, data + 0x05) & 0xf0) >> 
4;
p->ramcfg_10_06_0f = (nvbios_rd08(bios, data + 0x06) & 0x0f) >> 
0;
@@ -216,6 +219,17 @@ nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
p->ramcfg_10_08= (nvbios_rd08(bios, data + 0x08) & 0xff) >> 
0;
p->ramcfg_10_09_0f = (nvbios_rd08(bios, data + 0x09) & 0x0f) >> 
0;
p->ramcfg_10_09_f0 = (nvbios_rd08(bios, data + 0x09) & 0xf0) >> 
4;
+
+   switch (elen) {
+   case 0xe:
+   case 0xd:
+   p->ramcfg_VREFD_off = nvbios_rd08(bios, data + 0x0c);
+ 

[Nouveau] [PATCH 09/13] nvkm/ramgf100: Reinstate default ram train pattern

2017-04-10 Thread Roy Spliet
Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c | 59 +--
 1 file changed, 43 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index 62359c2..a469719 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -556,22 +556,49 @@ gf100_ram_train_init_0(struct nvkm_ram *ram, struct 
gt215_ram_train *train)
struct nvkm_device *device = subdev->device;
int i, j;
 
-   if ((train->mask & 0x03c3) != 0x03c3) {
-   nvkm_warn(subdev, "missing link training data\n");
-   return -EINVAL;
-   }
-
-   for (i = 0; i < 0x30; i++) {
-   for (j = 0; j < 8; j += 4) {
-   nvkm_wr32(device, 0x10f968 + j, 0x | (i << 8));
-   nvkm_wr32(device, 0x10f920 + j, 0x |
-  train->type08.data[i] << 4 |
-  train->type06.data[i]);
-   nvkm_wr32(device, 0x10f918 + j, train->type00.data[i]);
-   nvkm_wr32(device, 0x10f920 + j, 0x0100 |
-  train->type09.data[i] << 4 |
-  train->type07.data[i]);
-   nvkm_wr32(device, 0x10f918 + j, train->type01.data[i]);
+   static const u8  train0[] = {
+   0x00, 0xff, 0x55, 0xaa, 0x33, 0xcc,
+   0x00, 0xff, 0xff, 0x00, 0xff, 0x00,
+   };
+
+   static const u32 train1[] = {
+   0x, 0x,
+   0x, 0x,
+   0x, 0x,
+   0xf0f0f0f0, 0x0f0f0f0f,
+   0x00ff00ff, 0xff00ff00,
+   0x, 0x,
+   };
+
+   if ((train->mask & 0x03c3) == 0x03c3) {
+   for (i = 0; i < 0x30; i++) {
+   for (j = 0; j < 8; j += 4) {
+   nvkm_wr32(device, 0x10f968 + j, (i << 8));
+   nvkm_wr32(device, 0x10f920 + j, 0x |
+   train->type08.data[i] << 4 |
+   train->type06.data[i]);
+   nvkm_wr32(device, 0x10f918 + j,
+   train->type00.data[i]);
+   nvkm_wr32(device, 0x10f920 + j, 0x0100 |
+   train->type09.data[i] << 4 |
+   train->type07.data[i]);
+   nvkm_wr32(device, 0x10f918 + j,
+   train->type01.data[i]);
+   }
+   }
+   } else {
+   nvkm_info(subdev, "missing link training data, using 
defaults\n");
+
+   for (i = 0; i < 0x30; i++) {
+   for (j = 0; j < 8; j += 4) {
+   nvkm_wr32(device, 0x10f968 + j, (i << 8));
+   nvkm_wr32(device, 0x10f920 + j, 0x0100 |
+   train0[i % 12]);
+   nvkm_wr32(device, 0x10f918 + j, train1[i % 12]);
+   nvkm_wr32(device, 0x10f920 + j, 0x |
+   train0[i % 12]);
+   nvkm_wr32(device, 0x10f918 + j, train1[i % 12]);
+   }
}
}
 
-- 
2.9.3

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] RESEND Preparations for Fermi DRAM clock changes

2017-04-10 Thread Roy Spliet
Two patches went missing as a result of PEBCAK. No v2 marks as nothing
changed really. Just resending for easier enforcement of patch order
in other people's trees. Sorry for the noise.

Original message:

No, no, these will not implement Fermi reclocking. This set of patches
contains some of the preparatory work that I deem stable enough to
move upstream. Notable changes
- Training pattern upload routines from GK104+ now shared with GT215+
- Timing calculation for Fermi
- GDDR5 MR calculation from VBIOS timing table v1.0. Also useful for that
  pesky GT 240.
- A routine to translate a VBIOS init script to a set of memx writes.
  Used by both "that GT 240" and Fermi.
- Misc clean-up

Testers should expect no changes in behaviour before/after. Keen eyes
can double-check on their Tesla and Fermi GDDR5 graphics cards that
training patterns are uploaded on boot.

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 01/13] nvkm/bios: Give timings a name

2017-04-10 Thread Roy Spliet
tFAW, tCKE, tXPDLL, derived from datasheets. Merge skeggsb's:
"bios/rammap: make unknown timing 1.0 fields match 2.0's naming"

Signed-off-by: Roy Spliet 
---
 .../drm/nouveau/include/nvkm/subdev/bios/ramcfg.h  | 12 +++
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c  | 42 +++---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c  | 14 
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c   |  6 ++--
 4 files changed, 37 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h 
b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
index dca6c06..d8a7c04 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
@@ -127,17 +127,17 @@ struct nvbios_ramcfg {
unsigned timing_10_RCDRD:8;
unsigned timing_10_RCDWR:8;
unsigned timing_10_RRD:8;
-   unsigned timing_10_13:8;
+   unsigned timing_10_XPDLL:8;
unsigned timing_10_ODT:3;
/* empty: 15 */
-   unsigned timing_10_16:8;
+   unsigned timing_10_10:8;
/* empty: 17 */
-   unsigned timing_10_18:8;
+   unsigned timing_10_12:8;
unsigned timing_10_CWL:8;
-   unsigned timing_10_20:8;
-   unsigned timing_10_21:8;
+   unsigned timing_10_FAW:8;
+   unsigned timing_10_CKE:8;
/* empty: 22, 23 */
-   unsigned timing_10_24:8;
+   unsigned timing_10_18:8;
};
struct {
unsigned timing_20_2e_03:2;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c
index 7e83c39..c36be13 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c
@@ -100,34 +100,34 @@ nvbios_timingEp(struct nvkm_bios *bios, int idx,
p->timing_10_RCDRD = nvbios_rd08(bios, data + 0x0a);
p->timing_10_RCDWR = nvbios_rd08(bios, data + 0x0b);
p->timing_10_RRD   = nvbios_rd08(bios, data + 0x0c);
-   p->timing_10_13= nvbios_rd08(bios, data + 0x0d);
+   p->timing_10_XPDLL = nvbios_rd08(bios, data + 0x0d);
p->timing_10_ODT   = nvbios_rd08(bios, data + 0x0e) & 0x07;
if (p->ramcfg_ver >= 0x10)
p->ramcfg_RON = nvbios_rd08(bios, data + 0x0e) & 0x07;
 
-   p->timing_10_24  = 0xff;
-   p->timing_10_21  = 0;
-   p->timing_10_20  = 0;
+   p->timing_10_18  = 0xff;
+   p->timing_10_CKE = 0;
+   p->timing_10_FAW = 0;
p->timing_10_CWL = 0;
-   p->timing_10_18  = 0;
-   p->timing_10_16  = 0;
+   p->timing_10_12  = 0;
+   p->timing_10_10  = 0;
 
-   switch (min_t(u8, *hdr, 25)) {
-   case 25:
-   p->timing_10_24  = nvbios_rd08(bios, data + 0x18);
-   case 24:
-   case 23:
-   case 22:
-   p->timing_10_21  = nvbios_rd08(bios, data + 0x15);
-   case 21:
-   p->timing_10_20  = nvbios_rd08(bios, data + 0x14);
-   case 20:
+   switch (min_t(u8, *hdr, 0x19)) {
+   case 0x19:
+   p->timing_10_18  = nvbios_rd08(bios, data + 0x18);
+   case 0x18:
+   case 0x17:
+   case 0x16:
+   p->timing_10_CKE = nvbios_rd08(bios, data + 0x15);
+   case 0x15:
+   p->timing_10_FAW = nvbios_rd08(bios, data + 0x14);
+   case 0x14:
p->timing_10_CWL = nvbios_rd08(bios, data + 0x13);
-   case 19:
-   p->timing_10_18  = nvbios_rd08(bios, data + 0x12);
-   case 18:
-   case 17:
-   p->timing_10_16  = nvbios_rd08(bios, data + 0x10);
+   case 0x13:
+   p->timing_10_12  = nvbios_rd08(bios, data + 0x12);
+   case 0x12:
+   case 0x11:
+   p->timing_10_10  = nvbios_rd08(bios, data + 0x10);
}
 
break;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
index f106643..dd80de1 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c

[Nouveau] [PATCH 10/11] nvkm/pmu/memx: init script -> memx translation

2017-04-10 Thread Roy Spliet
Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h |  2 +
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h   |  8 +++
 drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c| 66 +++
 3 files changed, 76 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h 
b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h
index f37538eb..b9c46ef 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h
@@ -50,4 +50,6 @@ void nvkm_memx_train(struct nvkm_memx *);
 int  nvkm_memx_train_result(struct nvkm_pmu *, u32 *, int);
 void nvkm_memx_block(struct nvkm_memx *);
 void nvkm_memx_unblock(struct nvkm_memx *);
+void nvkm_memx_init_run(struct nvkm_memx *memx, struct nvkm_bios *bios,
+   u16 offset, u8 ramcfg);
 #endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h
index 9ef9d6a..614e716 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h
@@ -160,6 +160,13 @@ ramfuc_unblock(struct ramfuc *ram)
nvkm_memx_unblock(ram->memx);
 }
 
+static inline void
+ramfuc_init_run(struct ramfuc *ram, struct nvkm_bios *bios, u16 offset,
+   u8 ramcfg)
+{
+   nvkm_memx_init_run(ram->memx, bios, offset, ramcfg);
+}
+
 #define ram_init(s,p)ramfuc_init(&(s)->base, (p))
 #define ram_exec(s,e)ramfuc_exec(&(s)->base, (e))
 #define ram_have(s,r)((s)->r_##r.addr != 0x00)
@@ -174,4 +181,5 @@ ramfuc_unblock(struct ramfuc *ram)
 #define ram_train_result(s,r,l) ramfuc_train_result((s), (r), (l))
 #define ram_block(s) ramfuc_block(&(s)->base)
 #define ram_unblock(s)   ramfuc_unblock(&(s)->base)
+#define ram_init_run(s,b,o,r) ramfuc_init_run(&(s)->base, (b), (o), (r))
 #endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c
index e6f7416..c58a51d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c
@@ -1,6 +1,9 @@
 #ifndef __NVKM_PMU_MEMX_H__
 #define __NVKM_PMU_MEMX_H__
 #include "priv.h"
+#include 
+#include 
+#include 
 
 struct nvkm_memx {
struct nvkm_pmu *pmu;
@@ -200,4 +203,67 @@ nvkm_memx_unblock(struct nvkm_memx *memx)
nvkm_debug(&memx->pmu->subdev, "   HOST UNBLOCKED\n");
memx_cmd(memx, MEMX_LEAVE, 0, NULL);
 }
+
+/**
+ * Turn VBIOS init script into memx command stream. Not-quite as feature rich
+ * as subdev/bios/init.c
+ */
+
+static void
+nvkm_memx_init_ram_restrict(struct nvkm_memx *memx, struct nvbios_init *init)
+{
+   struct nvkm_bios *bios = init->bios;
+   struct nvkm_subdev *subdev = &memx->pmu->subdev;
+struct nvkm_device *device = subdev->device;
+   u32 addr = nvbios_rd32(bios, init->offset + 1);
+   u8  incr = nvbios_rd08(bios, init->offset + 5);
+   u8   num = nvbios_rd08(bios, init->offset + 6);
+   u8 count = nvbios_ramcfg_count(init->bios);
+   u8 index = init->ramcfg;
+   u8 i;
+   u32 oldval, newval;
+
+   init->offset += 7;
+
+   for (i = 0; i < num; i++) {
+   oldval  = nvkm_rd32(device, addr);
+   newval = nvbios_rd32(bios, init->offset + (4 * index));
+
+   if (oldval != newval) {
+   nvkm_memx_wr32(memx, addr, newval);
+   }
+   init->offset += 4 * count;
+   addr += incr;
+   }
+}
+
+void
+nvkm_memx_init_run(struct nvkm_memx *memx, struct nvkm_bios *bios, u16 offset,
+   u8 ramcfg)
+{
+   struct nvbios_init init = {
+   .subdev = &bios->subdev,
+   .bios = bios,
+   .offset = offset,
+   .outp = NULL,
+   .execute = 1,
+   .ramcfg = ramcfg,
+   };
+   u8 op;
+
+   while (init.offset)
+   {
+   op = nvbios_rd08(bios, init.offset);
+   switch (op)
+   {
+   case 0x8f:
+   nvkm_memx_init_ram_restrict(memx, &init);
+   break;
+   case 0x71:
+   default:
+   return;
+   }
+   }
+}
+
 #endif
-- 
2.9.3

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 09/11] nvkm/ramgf100: Hook up ram training pattern init for NVC0+

2017-04-10 Thread Roy Spliet
Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index a469719..eebd20b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -653,8 +653,7 @@ gf100_ram_init(struct nvkm_ram *base)
/* XXX Why does the blob do this? */
nvkm_mask(device, 0x137360, 0x0002, 0x);
 
-   /* XXX: Don't hook up yet for bisectability */
-   return 0;
+   return gf100_ram_train_init(base);
 }
 
 static const struct nvkm_ram_func
-- 
2.9.3

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 04/11] nvkm/ramgt215: Move ram training up the chain

2017-04-10 Thread Roy Spliet
Parts are re-used even on NVA3, others from GF100 on

Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h  |  17 +++
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c |  92 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c | 140 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c |  61 ++
 4 files changed, 140 insertions(+), 170 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h
index b60068b..ce8a98e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h
@@ -1,6 +1,7 @@
 #ifndef __NVKM_FB_RAM_PRIV_H__
 #define __NVKM_FB_RAM_PRIV_H__
 #include "priv.h"
+#include 
 
 int  nvkm_ram_ctor(const struct nvkm_ram_func *, struct nvkm_fb *,
   enum nvkm_ram_type, u64 size, u32 tags,
@@ -24,6 +25,22 @@ int  gf100_ram_ctor(const struct nvkm_ram_func *, struct 
nvkm_fb *,
 int  gf100_ram_get(struct nvkm_ram *, u64, u32, u32, u32, struct nvkm_mem **);
 void gf100_ram_put(struct nvkm_ram *, struct nvkm_mem **);
 
+/* Training */
+struct gt215_ram_train {
+   u16 mask;
+   struct nvbios_M0209S remap;
+   struct nvbios_M0209S type00;
+   struct nvbios_M0209S type01;
+   struct nvbios_M0209S type04;
+   struct nvbios_M0209S type06;
+   struct nvbios_M0209S type07;
+   struct nvbios_M0209S type08;
+   struct nvbios_M0209S type09;
+};
+int gt215_ram_train_type(struct nvkm_ram *ram, int i, u8 ramcfg,
+struct gt215_ram_train *train);
+int  gf100_ram_train_init(struct nvkm_ram *ram);
+
 int  gk104_ram_ctor(struct nvkm_fb *, struct nvkm_ram **, u32);
 int  gk104_ram_init(struct nvkm_ram *ram);
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index b4fe3bb..38a7e2b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -549,45 +550,74 @@ gf100_ram_get(struct nvkm_ram *ram, u64 size, u32 align, 
u32 ncmin,
 }
 
 static int
-gf100_ram_init(struct nvkm_ram *base)
+gf100_ram_train_init_0(struct nvkm_ram *ram, struct gt215_ram_train *train)
 {
-   static const u8  train0[] = {
-   0x00, 0xff, 0x55, 0xaa, 0x33, 0xcc,
-   0x00, 0xff, 0xff, 0x00, 0xff, 0x00,
-   };
-   static const u32 train1[] = {
-   0x, 0x,
-   0x, 0x,
-   0x, 0x,
-   0xf0f0f0f0, 0x0f0f0f0f,
-   0x00ff00ff, 0xff00ff00,
-   0x, 0x,
-   };
-   struct gf100_ram *ram = gf100_ram(base);
-   struct nvkm_device *device = ram->base.fb->subdev.device;
-   int i;
+   struct nvkm_subdev *subdev = &ram->fb->subdev;
+   struct nvkm_device *device = subdev->device;
+   int i, j;
 
-   switch (ram->base.type) {
+   if ((train->mask & 0x03d3) != 0x03d3) {
+   nvkm_warn(subdev, "missing link training data\n");
+   return -EINVAL;
+   }
+
+   for (i = 0; i < 0x30; i++) {
+   for (j = 0; j < 8; j += 4) {
+   nvkm_wr32(device, 0x10f968 + j, 0x | (i << 8));
+   nvkm_wr32(device, 0x10f920 + j, 0x |
+  train->type08.data[i] << 4 |
+  train->type06.data[i]);
+   nvkm_wr32(device, 0x10f918 + j, train->type00.data[i]);
+   nvkm_wr32(device, 0x10f920 + j, 0x0100 |
+  train->type09.data[i] << 4 |
+  train->type07.data[i]);
+   nvkm_wr32(device, 0x10f918 + j, train->type01.data[i]);
+   }
+   }
+
+   for (j = 0; j < 8; j += 4) {
+   for (i = 0; i < 0x100; i++) {
+   nvkm_wr32(device, 0x10f968 + j, i);
+   nvkm_wr32(device, 0x10f900 + j, train->type04.data[i]);
+   }
+   }
+
+   return 0;
+}
+
+int
+gf100_ram_train_init(struct nvkm_ram *ram)
+{
+   u8 ramcfg = nvbios_ramcfg_index(&ram->fb->subdev);
+   struct gt215_ram_train *train;
+   int ret, i;
+
+   if (!(train = kzalloc(sizeof(*train), GFP_KERNEL)))
+   return -ENOMEM;
+
+   for (i = 0; i < 0x100; i++) {
+   ret = gt215_ram_train_type(ram, i, ramcfg, train);
+   if (ret && ret != -ENOENT)
+   break;
+   }
+
+   switch (ram->type) {
case NVKM_RAM_TYPE_GDDR5:
+   ret = g

[Nouveau] [PATCH 02/11] nvkm/ramgf100: Calculate timings

2017-04-10 Thread Roy Spliet
Todo:
- Determine source of R[10f298] & 0x11

Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c | 115 ++
 1 file changed, 76 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index fffd01a..6ebdc4c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -48,11 +48,7 @@ struct gf100_ramfuc {
 
struct ramfuc_reg r_0x137390;
 
-   struct ramfuc_reg r_0x10f290;
-   struct ramfuc_reg r_0x10f294;
-   struct ramfuc_reg r_0x10f298;
-   struct ramfuc_reg r_0x10f29c;
-   struct ramfuc_reg r_0x10f2a0;
+   struct ramfuc_reg r_0x10f290[5];
 
struct ramfuc_reg r_0x10f300;
struct ramfuc_reg r_0x10f338;
@@ -104,6 +100,50 @@ struct gf100_ram {
struct nvbios_pll mempll;
 };
 
+#define T(t) cfg->timing_10_##t
+static int
+gf100_ram_timing_calc(struct gf100_ram *ram, u32 *timing)
+{
+   struct nvbios_ramcfg *cfg = &ram->base.target.bios;
+   struct nvkm_subdev *subdev = &ram->base.fb->subdev;
+   struct nvkm_device *device = subdev->device;
+   u32 cur1, cur2, cur4;
+
+   cur1 = nvkm_rd32(device, 0x10f294);
+   cur2 = nvkm_rd32(device, 0x10f298);
+   cur4 = nvkm_rd32(device, 0x10f2a0);
+
+   /* XXX: (G)DDR3? */
+   switch ((!T(CWL)) * ram->base.type) {
+   case NVKM_RAM_TYPE_GDDR5:
+   T(CWL) = (cur1 & 0x0380) >> 7;
+   break;
+   }
+
+   timing[0] = (T(RP) << 24 | T(RAS) << 17 | T(RFC) << 8 | T(RC));
+   timing[1] = (cur1 & ~0x03ffc07f) |
+   (T(RCDWR) << 20) |
+   (T(RCDRD) << 14) |
+   (T(CWL) << 7) |
+   (T(CL));
+   /* XXX: lower 8 bytes are two bits indicating "feature(s) X" */
+   timing[2] = (cur2 & ~0x00ff) |
+   (T(WR) << 16) |
+   (T(WTR) << 8);
+   timing[3] = (T(FAW)) << 9 |
+   (T(CKE)) << 5 |
+   (T(XPDLL));
+   timing[4] = (cur4 & ~0x001f8000) |
+   (T(RRD) << 15);
+
+   nvkm_debug(subdev, "Entry: 290: %08x %08x %08x %08x\n",
+  timing[0], timing[1], timing[2], timing[3]);
+   nvkm_debug(subdev, "  2a0: %08x\n",
+  timing[4]);
+   return 0;
+}
+#undef T
+
 static void
 gf100_ram_train(struct gf100_ramfuc *fuc, u32 magic)
 {
@@ -136,10 +176,11 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq)
struct nvkm_ram_data *next;
u8  ver, hdr, cnt, len, strap;
u32 data;
+   u32 timing[5];
int ref, div, out;
int from, mode;
int N1, M1, P;
-   int ret;
+   int i, ret;
 
next = &ram->base.target;
next->freq = freq;
@@ -179,6 +220,8 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq)
}
}
 
+   gf100_ram_timing_calc(ram, timing);
+
ret = ram_init(fuc, ram->base.fb);
if (ret)
return ret;
@@ -314,28 +357,6 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq)
ram_wr32(fuc, 0x10f338, 0x00300220);
ram_wr32(fuc, 0x10f300, 0x011d);
ram_nsec(fuc, 1000);
-   ram_wr32(fuc, 0x10f290, 0x02060505);
-   ram_wr32(fuc, 0x10f294, 0x34208288);
-   ram_wr32(fuc, 0x10f298, 0x44050411);
-   ram_wr32(fuc, 0x10f29c, 0x114c);
-   ram_wr32(fuc, 0x10f2a0, 0x42e10069);
-   ram_wr32(fuc, 0x10f614, 0x40044f77);
-   ram_wr32(fuc, 0x10f610, 0x40044f77);
-   ram_wr32(fuc, 0x10f344, 0x0069);
-   ram_nsec(fuc, 1000);
-   ram_wr32(fuc, 0x10f348, 0x0078);
-   ram_wr32(fuc, 0x61c140, 0x1924);
-   ram_wr32(fuc, 0x10f830, 0x00300017);
-   gf100_ram_train(fuc, 0x80021001);
-   gf100_ram_train(fuc, 0x80081001);
-   ram_wr32(fuc, 0x10f340, 0x0054);
-   ram_nsec(fuc, 1000);
-   ram_wr32(fuc, 0x10f830, 0x01300017);
-   ram_wr32(fuc, 0x10f830, 0x00300017);
-// 0x00030020 // 0x // 0x
-// 0x00020034 // 0x000b
-   ram_wr32(fuc, 0x100b0c, 0x00080028);
-   ram_wr32(fuc, 0x611200, 0x3330);
} else {
ram_wr32(fuc, 0x10f800, 0x1800);
ram_wr32(fuc, 0x13d8f4, 0x);
@@ -364,11 +385,30 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq)
ram_wr32(fuc, 0x10f338, 0x00300200);
ram_wr32(fuc, 0x10f300, 0x084d);
ram_nsec(fuc, 1000);
-   ram_wr32(fuc, 0x10f290, 0x0b343825);
-   ram_wr32(fuc, 0x10f2

[Nouveau] [PATCH 06/11] nvkm/ramgf100: Unset bit before uploading train values

2017-04-10 Thread Roy Spliet
Just because the blob does it too...

Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index eef09bf..62359c2 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -620,6 +620,12 @@ gf100_ram_train_init(struct nvkm_ram *ram)
 static int
 gf100_ram_init(struct nvkm_ram *base)
 {
+   struct nvkm_subdev *subdev = &base->fb->subdev;
+   struct nvkm_device *device = subdev->device;
+
+   /* XXX Why does the blob do this? */
+   nvkm_mask(device, 0x137360, 0x0002, 0x);
+
/* XXX: Don't hook up yet for bisectability */
return 0;
 }
-- 
2.9.3

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 03/11] nvkm/gddr5: MR calculation for timing table v1.0

2017-04-10 Thread Roy Spliet
Merges in skeggsb's:
"fb/ram/gf10x: timing_10_0e_30"

Todo:
- find l3, rq
- triple-check

Signed-off-by: Roy Spliet 
---
 .../drm/nouveau/include/nvkm/subdev/bios/ramcfg.h  | 12 +++---
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c  | 22 --
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c  |  2 +
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c | 21 --
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c  | 49 --
 5 files changed, 71 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h 
b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
index 4560a52..44e4ca2 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
@@ -40,6 +40,10 @@ struct nvbios_ramcfg {
unsigned ramcfg_DLLoff;
unsigned ramcfg_RON;
unsigned ramcfg_FBVDDQ;
+   unsigned ramcfg_LowFreq;
+   unsigned ramcfg_WCKPin;
+   unsigned ramcfg_Hf_VREF;
+   unsigned ramcfg_VREFD_off;
union {
struct {
unsigned ramcfg_00_03_01:1;
@@ -82,12 +86,9 @@ struct nvbios_ramcfg {
unsigned ramcfg_11_01_04:1;
unsigned ramcfg_11_01_08:1;
unsigned ramcfg_11_01_10:1;
-   unsigned ramcfg_11_01_40:1;
-   unsigned ramcfg_11_01_80:1;
unsigned ramcfg_11_02_03:2;
unsigned ramcfg_11_02_04:1;
unsigned ramcfg_11_02_08:1;
-   unsigned ramcfg_11_02_10:1;
unsigned ramcfg_11_02_40:1;
unsigned ramcfg_11_02_80:1;
unsigned ramcfg_11_03_0f:4;
@@ -95,7 +96,6 @@ struct nvbios_ramcfg {
unsigned ramcfg_11_03_c0:2;
unsigned ramcfg_11_03_f0:4;
unsigned ramcfg_11_04:8;
-   unsigned ramcfg_11_06:8;
unsigned ramcfg_11_07_02:1;
unsigned ramcfg_11_07_04:1;
unsigned ramcfg_11_07_08:1;
@@ -132,6 +132,7 @@ struct nvbios_ramcfg {
unsigned timing_10_RRD:8;
unsigned timing_10_XPDLL:8;
unsigned timing_10_ODT:3;
+   unsigned timing_10_DS:2;
/* empty: 15 */
unsigned timing_10_10:8;
/* empty: 17 */
@@ -139,7 +140,8 @@ struct nvbios_ramcfg {
unsigned timing_10_CWL:8;
unsigned timing_10_FAW:8;
unsigned timing_10_CKE:8;
-   /* empty: 22, 23 */
+   unsigned timing_10_ADRCMD_T:8;  /* XXX: [3:2]? */
+   /* empty: 23 */
unsigned timing_10_18:8;
};
struct {
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
index 131d967..0d517a0 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
@@ -205,8 +205,11 @@ nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
p->ramcfg_10_02_20 = (nvbios_rd08(bios, data + 0x02) & 0x20) >> 
5;
p->ramcfg_DLLoff   = (nvbios_rd08(bios, data + 0x02) & 0x40) >> 
6;
p->ramcfg_10_03_0f = (nvbios_rd08(bios, data + 0x03) & 0x0f) >> 
0;
+   p->ramcfg_LowFreq  = (nvbios_rd08(bios, data + 0x03) & 0x20) >> 
5;
+   p->ramcfg_WCKPin   = (nvbios_rd08(bios, data + 0x03) & 0x40) >> 
6;
p->ramcfg_10_04_01 = (nvbios_rd08(bios, data + 0x04) & 0x01) >> 
0;
p->ramcfg_FBVDDQ   = (nvbios_rd08(bios, data + 0x04) & 0x08) >> 
3;
+   p->ramcfg_Hf_VREF  = (nvbios_rd08(bios, data + 0x04) & 0x20) >> 
5;
p->ramcfg_10_05_0f = (nvbios_rd08(bios, data + 0x05) & 0x0f) >> 
0;
p->ramcfg_10_05_f0 = (nvbios_rd08(bios, data + 0x05) & 0xf0) >> 
4;
p->ramcfg_10_06_0f = (nvbios_rd08(bios, data + 0x06) & 0x0f) >> 
0;
@@ -216,6 +219,17 @@ nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
p->ramcfg_10_08= (nvbios_rd08(bios, data + 0x08) & 0xff) >> 
0;
p->ramcfg_10_09_0f = (nvbios_rd08(bios, data + 0x09) & 0x0f) >> 
0;
p->ramcfg_10_09_f0 = (nvbios_rd08(bios, data + 0x09) & 0xf0) >> 
4;
+
+   switch (elen) {
+   case 0xe:
+   case 0xd:
+   p->ramcfg_VREFD_off = nvbios_rd08(bios, data + 0x0c);
+ 

[Nouveau] Preparations for Fermi DRAM clock changes

2017-04-10 Thread Roy Spliet
No, no, these will not implement Fermi reclocking. This set of patches
contains some of the preparatory work that I deem stable enough to
move upstream. Notable changes
- Training pattern upload routines from GK104+ now shared with GT215+
- Timing calculation for Fermi
- GDDR5 MR calculation from VBIOS timing table v1.0. Also useful for that
  pesky GT 240.
- A routine to translate a VBIOS init script to a set of memx writes.
  Used by both "that GT 240" and Fermi.
- Misc clean-up

Testers should expect no changes in behaviour before/after. Keen eyes
can double-check on their Tesla and Fermi GDDR5 graphics cards that
training patterns are uploaded on boot.

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 11/11] nvkm/bios/perf: Retreive pointer to unk1c script

2017-04-10 Thread Roy Spliet
Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/perf.h |  1 +
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/perf.c | 14 ++
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c   |  1 +
 3 files changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/perf.h 
b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/perf.h
index 478b1c0..28555d6 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/perf.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/perf.h
@@ -40,4 +40,5 @@ struct nvbios_perf_fan {
 };
 
 int nvbios_perf_fan_parse(struct nvkm_bios *, struct nvbios_perf_fan *);
+u16 nvbios_perf_script_unk1c(struct nvkm_bios *bios);
 #endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/perf.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/perf.c
index c306835..55c1f36 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/perf.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/perf.c
@@ -213,3 +213,17 @@ nvbios_perf_fan_parse(struct nvkm_bios *bios,
 
return 0;
 }
+
+u16
+nvbios_perf_script_unk1c(struct nvkm_bios *bios)
+{
+   struct bit_entry bit_P;
+
+   if (!bit_entry(bios, 'P', &bit_P)) {
+   if (bit_P.version == 2) {
+   return nvbios_rd16(bios, bit_P.offset + 0x1c);
+   }
+   }
+
+   return 0x;
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index eebd20b..def119c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
-- 
2.9.3

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 08/11] nvkm/ramgt215: Add train ptrn upload for GDDR5

2017-04-10 Thread Roy Spliet
Signed-off-by: Roy Spliet 
Tested-by: Ilia Mirkin 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h  |   1 +
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c | 128 +-
 2 files changed, 99 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h
index ce8a98e..ef9edc5 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h
@@ -32,6 +32,7 @@ struct gt215_ram_train {
struct nvbios_M0209S type00;
struct nvbios_M0209S type01;
struct nvbios_M0209S type04;
+   struct nvbios_M0209S type05;
struct nvbios_M0209S type06;
struct nvbios_M0209S type07;
struct nvbios_M0209S type08;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
index 6abd0e3..fa85942 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
@@ -75,7 +75,7 @@ struct gt215_ramfuc {
struct ramfuc_reg r_gpio[4];
 };
 
-struct gt215_ltrain {
+struct gt215_ram_train_ddr3 {
enum {
NVA3_TRAIN_UNKNOWN,
NVA3_TRAIN_UNSUPPORTED,
@@ -92,11 +92,11 @@ struct gt215_ltrain {
 struct gt215_ram {
struct nvkm_ram base;
struct gt215_ramfuc fuc;
-   struct gt215_ltrain ltrain;
+   struct gt215_ram_train_ddr3 ltrain;
 };
 
 static void
-gt215_link_train_calc(u32 *vals, struct gt215_ltrain *train)
+gt215_link_train_calc(u32 *vals, struct gt215_ram_train_ddr3 *train)
 {
int i, lo, hi;
u8 median[8], bins[4] = {0, 0, 0, 0}, bin = 0, qty = 0;
@@ -152,7 +152,7 @@ gt215_link_train_calc(u32 *vals, struct gt215_ltrain *train)
 static int
 gt215_link_train(struct gt215_ram *ram)
 {
-   struct gt215_ltrain *train = &ram->ltrain;
+   struct gt215_ram_train_ddr3 *train = &ram->ltrain;
struct gt215_ramfuc *fuc = &ram->fuc;
struct nvkm_subdev *subdev = &ram->base.fb->subdev;
struct nvkm_device *device = subdev->device;
@@ -288,6 +288,7 @@ gt215_ram_train_type(struct nvkm_ram *ram, int i, u8 ramcfg,
case 0x00: value = &train->type00; break;
case 0x01: value = &train->type01; break;
case 0x04: value = &train->type04; break;
+   case 0x05: value = &train->type05; break;
case 0x06: value = &train->type06; break;
case 0x07: value = &train->type07; break;
case 0x08: value = &train->type08; break;
@@ -321,7 +322,7 @@ gt215_ram_train_type(struct nvkm_ram *ram, int i, u8 ramcfg,
for (i = 0; i < ARRAY_SIZE(value->data); i++)
value->data[i] = remap->data[value->data[i]];
} else
-   if (M0209E.v02_07 != 1)
+   if (M0209E.v02_07 > 2)
return -EINVAL;
 
train->mask |= 1 << M0205E.type;
@@ -329,7 +330,47 @@ gt215_ram_train_type(struct nvkm_ram *ram, int i, u8 
ramcfg,
 }
 
 static int
-gt215_link_train_init(struct gt215_ram *ram)
+gt215_ram_train_upload_gddr5(struct nvkm_ram *ram,
+   struct gt215_ram_train *train)
+{
+   struct nvkm_subdev *subdev = &ram->fb->subdev;
+   struct nvkm_device *device = subdev->device;
+   int i, j;
+
+   static const u32 off[] = {0x00, 0x20, 0x04, 0x24};
+
+   if ((train->mask & 0x03c3) != 0x03c3) {
+   nvkm_info(subdev,
+   "missing link training data, not uploading patterns\n");
+   return 0;
+   }
+
+   for (j = 0; j < 4; j++) {
+   for (i = 0; i < 0x80; i++) {
+   nvkm_wr32(device, 0x10f8c0 + off[j], (i << 8) | i);
+   if (i < 0x30) {
+   nvkm_wr32(device, 0x10f940 + off[j], 0x 
|
+   train->type08.data[i] << 4 |
+   train->type06.data[i]);
+   nvkm_wr32(device, 0x10f900 + off[j],
+   train->type00.data[i]);
+   nvkm_wr32(device, 0x10f940 + off[j], 0x0100 
|
+   train->type09.data[i] << 4 |
+   train->type07.data[i]);
+   nvkm_wr32(device, 0x10f900 + off[j],
+   train->type01.data[i]);
+   }
+   nvkm_wr32(device, 0x10f840 + off[j], 0x | i);
+   nvkm_wr32(device, 0x10f840 + off[j], 0x0100 | i);
+   }
+   }
+
+   return 0;
+}
+
+static int
+gt215_ram_train_upload_ddr3(struct nvkm_ram *ram,
+

[Nouveau] [PATCH 05/11] nvkm/ramgf100: Don't mandate training pattern 4

2017-04-10 Thread Roy Spliet
It's not found on Fermi.

Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index 38a7e2b..eef09bf 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -556,7 +556,7 @@ gf100_ram_train_init_0(struct nvkm_ram *ram, struct 
gt215_ram_train *train)
struct nvkm_device *device = subdev->device;
int i, j;
 
-   if ((train->mask & 0x03d3) != 0x03d3) {
+   if ((train->mask & 0x03c3) != 0x03c3) {
nvkm_warn(subdev, "missing link training data\n");
return -EINVAL;
}
@@ -575,10 +575,13 @@ gf100_ram_train_init_0(struct nvkm_ram *ram, struct 
gt215_ram_train *train)
}
}
 
-   for (j = 0; j < 8; j += 4) {
-   for (i = 0; i < 0x100; i++) {
-   nvkm_wr32(device, 0x10f968 + j, i);
-   nvkm_wr32(device, 0x10f900 + j, train->type04.data[i]);
+   if (train->mask & 0x10) {
+   for (j = 0; j < 8; j += 4) {
+   for (i = 0; i < 0x100; i++) {
+   nvkm_wr32(device, 0x10f968 + j, i);
+   nvkm_wr32(device, 0x10f900 + j,
+   train->type04.data[i]);
+   }
}
}
 
-- 
2.9.3

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 07/11] nvkm/ramgf100: Reinstate default ram train pattern

2017-04-10 Thread Roy Spliet
Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c | 59 +--
 1 file changed, 43 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index 62359c2..a469719 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -556,22 +556,49 @@ gf100_ram_train_init_0(struct nvkm_ram *ram, struct 
gt215_ram_train *train)
struct nvkm_device *device = subdev->device;
int i, j;
 
-   if ((train->mask & 0x03c3) != 0x03c3) {
-   nvkm_warn(subdev, "missing link training data\n");
-   return -EINVAL;
-   }
-
-   for (i = 0; i < 0x30; i++) {
-   for (j = 0; j < 8; j += 4) {
-   nvkm_wr32(device, 0x10f968 + j, 0x | (i << 8));
-   nvkm_wr32(device, 0x10f920 + j, 0x |
-  train->type08.data[i] << 4 |
-  train->type06.data[i]);
-   nvkm_wr32(device, 0x10f918 + j, train->type00.data[i]);
-   nvkm_wr32(device, 0x10f920 + j, 0x0100 |
-  train->type09.data[i] << 4 |
-  train->type07.data[i]);
-   nvkm_wr32(device, 0x10f918 + j, train->type01.data[i]);
+   static const u8  train0[] = {
+   0x00, 0xff, 0x55, 0xaa, 0x33, 0xcc,
+   0x00, 0xff, 0xff, 0x00, 0xff, 0x00,
+   };
+
+   static const u32 train1[] = {
+   0x, 0x,
+   0x, 0x,
+   0x, 0x,
+   0xf0f0f0f0, 0x0f0f0f0f,
+   0x00ff00ff, 0xff00ff00,
+   0x, 0x,
+   };
+
+   if ((train->mask & 0x03c3) == 0x03c3) {
+   for (i = 0; i < 0x30; i++) {
+   for (j = 0; j < 8; j += 4) {
+   nvkm_wr32(device, 0x10f968 + j, (i << 8));
+   nvkm_wr32(device, 0x10f920 + j, 0x |
+   train->type08.data[i] << 4 |
+   train->type06.data[i]);
+   nvkm_wr32(device, 0x10f918 + j,
+   train->type00.data[i]);
+   nvkm_wr32(device, 0x10f920 + j, 0x0100 |
+   train->type09.data[i] << 4 |
+   train->type07.data[i]);
+   nvkm_wr32(device, 0x10f918 + j,
+   train->type01.data[i]);
+   }
+   }
+   } else {
+   nvkm_info(subdev, "missing link training data, using 
defaults\n");
+
+   for (i = 0; i < 0x30; i++) {
+   for (j = 0; j < 8; j += 4) {
+   nvkm_wr32(device, 0x10f968 + j, (i << 8));
+   nvkm_wr32(device, 0x10f920 + j, 0x0100 |
+   train0[i % 12]);
+   nvkm_wr32(device, 0x10f918 + j, train1[i % 12]);
+   nvkm_wr32(device, 0x10f920 + j, 0x |
+   train0[i % 12]);
+   nvkm_wr32(device, 0x10f918 + j, train1[i % 12]);
+   }
}
}
 
-- 
2.9.3

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 01/11] nvkm/ramgf100: Get rid of (size, data) pairs for rammap, ramcfg, timing

2017-04-10 Thread Roy Spliet
In correspondence with the other ram_calc implementations.

Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c | 37 ---
 1 file changed, 19 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index 093223d..fffd01a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -133,21 +133,22 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq)
struct nvkm_device *device = subdev->device;
struct nvkm_clk *clk = device->clk;
struct nvkm_bios *bios = device->bios;
-   struct nvbios_ramcfg cfg;
-   u8  ver, cnt, len, strap;
-   struct {
-   u32 data;
-   u8  size;
-   } rammap, ramcfg, timing;
+   struct nvkm_ram_data *next;
+   u8  ver, hdr, cnt, len, strap;
+   u32 data;
int ref, div, out;
int from, mode;
int N1, M1, P;
int ret;
 
+   next = &ram->base.target;
+   next->freq = freq;
+   ram->base.next = next;
+
/* lookup memory config data relevant to the target frequency */
-   rammap.data = nvbios_rammapEm(bios, freq / 1000, &ver, &rammap.size,
- &cnt, &ramcfg.size, &cfg);
-   if (!rammap.data || ver != 0x10 || rammap.size < 0x0e) {
+   data = nvbios_rammapEm(bios, freq / 1000, &ver, &hdr,
+ &cnt, &len, &next->bios);
+   if (!data || ver != 0x10 || len < 0x0e) {
nvkm_error(subdev, "invalid/missing rammap entry\n");
return -EINVAL;
}
@@ -159,23 +160,23 @@ gf100_ram_calc(struct nvkm_ram *base, u32 freq)
return -EINVAL;
}
 
-   ramcfg.data = rammap.data + rammap.size + (strap * ramcfg.size);
-   if (!ramcfg.data || ver != 0x10 || ramcfg.size < 0x0e) {
+   data = nvbios_rammapSp(bios, data, ver, hdr, cnt, len, strap,
+  &ver, &hdr, &next->bios);
+   if (!data || ver != 0x10 || hdr < 0x0e) {
nvkm_error(subdev, "invalid/missing ramcfg entry\n");
return -EINVAL;
}
 
/* lookup memory timings, if bios says they're present */
-   strap = nvbios_rd08(bios, ramcfg.data + 0x01);
-   if (strap != 0xff) {
-   timing.data = nvbios_timingEe(bios, strap, &ver, &timing.size,
- &cnt, &len);
-   if (!timing.data || ver != 0x10 || timing.size < 0x19) {
+   strap = nvbios_rd08(bios, data + 0x01);
+   if (next->bios.ramcfg_timing != 0xff) {
+   data = nvbios_timingEp(bios, next->bios.ramcfg_timing,
+  &ver, &hdr, &cnt, &len,
+  &next->bios);
+   if (!data || ver != 0x10 || hdr < 0x17) {
nvkm_error(subdev, "invalid/missing timing entry\n");
return -EINVAL;
}
-   } else {
-   timing.data = 0;
}
 
ret = ram_init(fuc, ram->base.fb);
-- 
2.9.3

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] OpenGL context switching with Noveau

2017-02-08 Thread Roy Spliet
For details see my presentation on day 3 of XDC2016. TL;DW: A context 
switch on average takes ~25 microseconds, but depending on the display 
resolution and the load on the card times up to 130 microseconds have 
been observed. The average does not appear to differ much between cards 
as the (growing) size of the context is in balance with the increased 
DRAM bandwidth. Measured worst cases appear to get better for higher end 
cards, but no hard real-time guarantees given.


Roy

Op 08-02-17 om 18:41 schreef Ilia Mirkin:

Context switching = very slow on NVIDIA. Don't do it if you can avoid
it. Each context is like a megabyte of data, if not more. Each time it
has to get saved off and restored.

On Wed, Feb 8, 2017 at 1:38 PM, Sampsa Riikonen  wrote:

Dear Devs,

(I hope this question is not that much OT for this list..)

My question is about fast OpenGL context switching, i.e. when there are
several processes using the same nvidia card, each one with their own OpenGL
context.  In my specific case, I am trying to dump 720p video simultaneously
to multiple windows using OpenGL textures.

So, to begin with, I have a process that spans child processes (*not*
threads, i.e. using the fork system call)

Each one of these (multi)processes has a video decoder that produces bitmaps
at 25 fps rate.  I am dumping the bitmaps to openGL using pixel buffer
objects (PBOs) and textures.

Each time when uploading a PBO and later on, when showing the texture, each
(multi)process needs to change to its own context by performing the GLX call

glXMakeCurrent(display_id, window_id, context_id)

So there is quite a bit of context switching going on..!  If there are 30
windows, that's > 750 context switches per second.  I am able to pull this
off with intel and ati graphics cards, but not with any nvidia card (tried a
few of them), neither with the proprietary driver nor with noveau.

Are there any specific tricks to achieve this?  Or should I just use one
context from one process, i.e. use multithreading instead of multiprocessing
and avoid context switching alltogether?  (is there something fundamentally
wrong in my approach of multiprocesses and context switching?)

Interestingly, when using N>2 multiprocesses (spanned with fork), only one
of the textures is updating - the others freeze.  However, when using the
same code as independently launched programs, I can achieve N=10+.  However,
this seems not to be always stable (whole X server freezes sometimes).

On the other hand, I can also use, say, several vlc clients to create a same
kind of situation and it seems to work.

Ay insight highly appreciated..

Regards,

Sampsa Riikonen

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] NVAC "No Signal"

2017-01-09 Thread Roy Spliet

Op 09-01-17 om 00:24 schreef Ben Skeggs:

On 12/24/2016 07:48 PM, Roy Spliet wrote:

I've observed this regression on my NVAC board; a 1920x1080 TV on HDMI
(single monitor set-up) gets no signal with Fedora kernels from 4.8.
Trace sent to the mmio dumps mailbox. A brief scan already revealed that
register 0xe840 is never touched, so it appears that NVIDIA does
something different.
VBIOS for this board is in the usual place. Commenting out 0xac from the
workaround seems to solve the problem, as tested on a Fedora 4.9 kernel.
I hope that helps you get a little further with this issue. Cheers, and
happy holidays!

Thanks Roy,

NVIDIA told me that it applied to these boards, but, I can't see NVIDIA
attempting the workaround in your trace, so until there's evidence to
the contrary, I've disabled it for MCP7x for now.

Ben.
Thanks. Since your patch is the exact modification I made to verify the 
workaround was bugging me, consider it:


Tested-by: Roy Spliet 

Given "no display on HDMI since 4.8" is quite a serious regression 
(albeit for a small userbase), please consider submitting this to 4.10 
as well as a "back-port" to the upstream 4.8 and 4.9 trees.

Thanks again! Cheers,

Roy




Roy.

Op 22-11-16 om 15:04 schreef poma:

On 20.10.2016 00:46, Ben Skeggs wrote:
[...]

I'd like to see a mmiotrace of the NVIDIA binary driver on a system
where this WAR breaks things.  I applied it to all the GPUs that NVIDIA
told me required it.

Ben.


Still broken, more than four months,
tested with mainline 4.9-rc6.

According to Ben Skeggs,
since this is "told" by NVIDIA i.e. by you, or perhaps some other of your 
colleagues,
what's more that I don't see progress in this regard,
would you guys from NVIDIA R&D mind help him to finally solve this?

Thanks.


Ref.
https://lists.freedesktop.org/archives/nouveau/2016-October/026242.html
http://goo.gl/Gm4ffO
mmiotrace-nouveau/
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] NVAC "No Signal"

2016-12-24 Thread Roy Spliet
I've observed this regression on my NVAC board; a 1920x1080 TV on HDMI 
(single monitor set-up) gets no signal with Fedora kernels from 4.8. 
Trace sent to the mmio dumps mailbox. A brief scan already revealed that 
register 0xe840 is never touched, so it appears that NVIDIA does 
something different.
VBIOS for this board is in the usual place. Commenting out 0xac from the 
workaround seems to solve the problem, as tested on a Fedora 4.9 kernel. 
I hope that helps you get a little further with this issue. Cheers, and 
happy holidays!


Roy.

Op 22-11-16 om 15:04 schreef poma:

On 20.10.2016 00:46, Ben Skeggs wrote:
[...]

I'd like to see a mmiotrace of the NVIDIA binary driver on a system
where this WAR breaks things.  I applied it to all the GPUs that NVIDIA
told me required it.

Ben.


Still broken, more than four months,
tested with mainline 4.9-rc6.

According to Ben Skeggs,
since this is "told" by NVIDIA i.e. by you, or perhaps some other of your 
colleagues,
what's more that I don't see progress in this regard,
would you guys from NVIDIA R&D mind help him to finally solve this?

Thanks.


Ref.
https://lists.freedesktop.org/archives/nouveau/2016-October/026242.html
http://goo.gl/Gm4ffO
mmiotrace-nouveau/
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH 0/5] GPU-DRM-nouveau: Fine-tuning for five function implementations

2016-09-21 Thread Roy Spliet
Thanks for these style fixes. Patches 1 and 2 seem good at first sight. 
Not acking because I haven't tested the patches and the implementation 
of kmalloc_array() appears to slightly differ from kmalloc(). This 
difference *should* only affect allocations larger than the ones in 
patch 1 and 2, but I'd like to see these changes tested before I can 
sleep soundly!


Patches 4 and 5 are:

Reviewed-by: Roy Spliet 


Op 21-09-16 om 08:23 schreef SF Markus Elfring:

From: Markus Elfring
Date: Wed, 21 Sep 2016 09:09:09 +0200

A few update suggestions were taken into account
from static source code analysis.

Markus Elfring (5):
   Use kmalloc_array() in nvbios_iccsense_parse()
   Use kmalloc_array() in gt215_link_train()
   Delete unnecessary braces
   Adjust a kzalloc() call in gt215_ram_new()
   Add space after an "if"

  drivers/gpu/drm/nouveau/nvkm/subdev/bios/iccsense.c |  4 +++-
  drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c   | 21 +
  2 files changed, 12 insertions(+), 13 deletions(-)



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH 3/5] GPU-DRM-nouveau: Delete unnecessary braces

2016-09-21 Thread Roy Spliet

Comments in-line. Thanks.

Roy

Op 21-09-16 om 08:26 schreef SF Markus Elfring:

From: Markus Elfring 
Date: Wed, 21 Sep 2016 08:28:08 +0200

Do not use curly brackets at four source code places
where a single statement should be sufficient.

Signed-off-by: Markus Elfring 
---
  drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c | 14 +-
  1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
index dbaf577..cb50539 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
@@ -127,12 +127,11 @@ gt215_link_train_calc(u32 *vals, struct gt215_ltrain 
*train)
}
  
  	/* Find the best value for 0xe0 */

-   for (i = 0; i < 4; i++) {
+   for (i = 0; i < 4; i++)
if (bins[i] > qty) {
bin = i + 3;
qty = bins[i];
}
-   }
I'm not a fan of removing the braces around a multi-line statement, 
despite being functionally correct. It obscures the program structure on 
displays with a low effective vertical resolution.
  
  	train->r_100720 = 0;

for (i = 0; i < 8; i++) {
@@ -729,9 +728,8 @@ gt215_ram_calc(struct nvkm_ram *base, u32 freq)
ram_mask(fuc, 0x1007e0, 0x, r100760);
}
  
-	if (device->chipset == 0xa3 && freq > 50) {

+   if (device->chipset == 0xa3 && freq > 50)
ram_mask(fuc, 0x100700, 0x0006, 0x);
-   }
  
  	/* Final switch */

if (mclk.pll) {
@@ -745,12 +743,11 @@ gt215_ram_calc(struct nvkm_ram *base, u32 freq)
ram_nsec(fuc, 2000);
  
  	/* Set RAM MR parameters and timings */

-   for (i = 2; i >= 0; i--) {
+   for (i = 2; i >= 0; i--)
if (ram_rd32(fuc, mr[i]) != ram->base.mr[i]) {
ram_wr32(fuc, mr[i], ram->base.mr[i]);
ram_nsec(fuc, 1000);
}
-   }

Idem.
  
  	ram_wr32(fuc, 0x100220[3], timing[3]);

ram_wr32(fuc, 0x100220[1], timing[1]);
@@ -838,11 +835,10 @@ gt215_ram_calc(struct nvkm_ram *base, u32 freq)
if (!next->bios.ramcfg_DLLoff)
nvkm_sddr2_dll_reset(fuc);
  
-	if (ram->base.type == NVKM_RAM_TYPE_GDDR3) {

+   if (ram->base.type == NVKM_RAM_TYPE_GDDR3)
ram_nsec(fuc, 31000);
-   } else {
+   else
ram_nsec(fuc, 14000);
-   }
  
  	if (ram->base.type == NVKM_RAM_TYPE_DDR3) {

ram_wr32(fuc, 0x100264, 0x1);


___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH v2 1/2] nvkm/clk/gf100+: Clean up PLL locking test

2016-06-17 Thread Roy Spliet
Corresponds with GT215. Don't rely on the lock test logic being unconditionally
enabled, and disable test logic when done (presumably to save power).

v2: Remove warning, nvkm_msec already warns on time-out

Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c | 8 +++-
 drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk104.c | 8 +++-
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c
index 78c449b..026baff 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c
@@ -366,11 +366,17 @@ gf100_clk_prog_2(struct gf100_clk *clk, int idx)
if (info->coef) {
nvkm_wr32(device, addr + 0x04, info->coef);
nvkm_mask(device, addr + 0x00, 0x0001, 0x0001);
+
+   /* Test PLL lock */
+   nvkm_mask(device, addr + 0x00, 0x0010, 0x);
nvkm_msec(device, 2000,
if (nvkm_rd32(device, addr + 0x00) & 0x0002)
break;
);
-   nvkm_mask(device, addr + 0x00, 0x00020004, 0x0004);
+   nvkm_mask(device, addr + 0x00, 0x0010, 0x0010);
+
+   /* Enable sync mode */
+   nvkm_mask(device, addr + 0x00, 0x0004, 0x0004);
}
}
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk104.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk104.c
index 975c401..06bc0d2 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk104.c
@@ -393,11 +393,17 @@ gk104_clk_prog_2(struct gk104_clk *clk, int idx)
if (info->coef) {
nvkm_wr32(device, addr + 0x04, info->coef);
nvkm_mask(device, addr + 0x00, 0x0001, 0x0001);
+
+   /* Test PLL lock */
+   nvkm_mask(device, addr + 0x00, 0x0010, 0x);
nvkm_msec(device, 2000,
if (nvkm_rd32(device, addr + 0x00) & 0x0002)
break;
);
-   nvkm_mask(device, addr + 0x00, 0x00020004, 0x0004);
+   nvkm_mask(device, addr + 0x00, 0x0010, 0x0010);
+
+   /* Enable sync mode */
+   nvkm_mask(device, addr + 0x00, 0x0004, 0x0004);
}
 }
 
-- 
2.5.5

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH v2 2/2] nvkm/clk/gf100: Read secondary bypass postdiv when required

2016-06-17 Thread Roy Spliet
v2: fix typo it's -> its

Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c | 20 ++--
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c
index 026baff..89d5543 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c
@@ -99,7 +99,7 @@ read_div(struct gf100_clk *clk, int doff, u32 dsrc, u32 dctl)
 {
struct nvkm_device *device = clk->base.subdev.device;
u32 ssrc = nvkm_rd32(device, dsrc + (doff * 4));
-   u32 sctl = nvkm_rd32(device, dctl + (doff * 4));
+   u32 sclk, sctl, sdiv = 2;
 
switch (ssrc & 0x0003) {
case 0:
@@ -109,13 +109,21 @@ read_div(struct gf100_clk *clk, int doff, u32 dsrc, u32 
dctl)
case 2:
return 10;
case 3:
-   if (sctl & 0x8000) {
-   u32 sclk = read_vco(clk, dsrc + (doff * 4));
-   u32 sdiv = (sctl & 0x003f) + 2;
-   return (sclk * 2) / sdiv;
+   sclk = read_vco(clk, dsrc + (doff * 4));
+
+   /* Memclk has doff of 0 despite its alt. location */
+   if (doff <= 2) {
+   sctl = nvkm_rd32(device, dctl + (doff * 4));
+
+   if (sctl & 0x8000) {
+   if (ssrc & 0x100)
+   sctl >>= 8;
+
+   sdiv = (sctl & 0x3f) + 2;
+   }
}
 
-   return read_vco(clk, dsrc + (doff * 4));
+   return (sclk * 2) / sdiv;
default:
return 0;
}
-- 
2.5.5

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH] drm/nouveau/iccsense: fix memory leak

2016-06-13 Thread Roy Spliet
Thanks. It seems though that you are not the only one who spotted this 
bug. This patch appears to be obsolete since 7505fdf [1].


Roy

[1] 
https://github.com/skeggsb/nouveau/commit/7505fdfc2688e86f8e15069b611858f0dbe73a80


Op 06/12/16 om 15:56 schreef Sudip Mukherjee:

In the for loop we are allocating the memory for rail everytime but
in some cases we use "continue" and in those cases the memory already
allocated for rail is leaked and we again allocate new memory for it.
Lets free the memory before continuing with the loop.

Signed-off-by: Sudip Mukherjee 
---
  drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c | 13 ++---
  1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c
index 323c79a..756ff07 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c
@@ -290,21 +290,28 @@ nvkm_iccsense_oneinit(struct nvkm_subdev *subdev)
  
  		switch (sensor->type) {

case NVBIOS_EXTDEV_INA209:
-   if (r->rail != 0)
+   if (r->rail != 0) {
+   kfree(rail);
continue;
+   }
rail->read = nvkm_iccsense_ina209_read;
break;
case NVBIOS_EXTDEV_INA219:
-   if (r->rail != 0)
+   if (r->rail != 0) {
+   kfree(rail);
continue;
+   }
rail->read = nvkm_iccsense_ina219_read;
break;
case NVBIOS_EXTDEV_INA3221:
-   if (r->rail >= 3)
+   if (r->rail >= 3) {
+   kfree(rail);
continue;
+   }
rail->read = nvkm_iccsense_ina3221_read;
break;
default:
+   kfree(rail);
continue;
}
  



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 3/3] nvkm/init: Add support for opcode 0xaf

2016-06-04 Thread Roy Spliet
As seen in at least one NV134 VBIOS (... that I obviously don't own myself).

Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c | 27 +
 1 file changed, 27 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c
index 38ed09f..a18f8b4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c
@@ -2196,6 +2196,32 @@ init_gpio_ne(struct nvbios_init *init)
init->offset += count;
 }
 
+/**
+ * INIT_ZM_REG_SET_LOOP - opcode 0xaf
+ *
+ */
+static void
+init_zm_reg_set_loop(struct nvbios_init *init)
+{
+   struct nvkm_bios *bios = init->bios;
+   u8  sets = nvbios_rd08(bios, init->offset + 1);
+   u8  regs = nvbios_rd08(bios, init->offset + 2);
+   u32 reg_off = init->offset + 3;
+   u32 addr, data, i, j;
+
+   trace("ZM_REG_SET_LOOP 0x%02hhx 0x%02hhx\n", sets, regs);
+   init->offset += 3 + (regs * 4);
+
+   for (i = 0; i < sets; i++) {
+   for (j = 0; j < regs; j++, init->offset += 4) {
+   addr = nvbios_rd32(bios, reg_off + (j * 4));
+   data = nvbios_rd32(bios, init->offset);
+   init_wr32(init, addr, data);
+   trace("\tR[0x%06x] = 0x%08x\n", addr, data);
+   }
+   }
+}
+
 static struct nvbios_init_opcode {
void (*exec)(struct nvbios_init *);
 } init_opcode[] = {
@@ -2268,6 +2294,7 @@ static struct nvbios_init_opcode {
[0x9a] = { init_i2c_long_if },
[0xa9] = { init_gpio_ne },
[0xaa] = { init_reserved },
+   [0xaf] = { init_zm_reg_set_loop },
 };
 
 #define init_opcode_nr (sizeof(init_opcode) / sizeof(init_opcode[0]))
-- 
2.5.5

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 1/3] nvkm/clk/gf100+: Clean up PLL locking test

2016-06-04 Thread Roy Spliet
Corresponds with GT215. Don't rely on the lock test logic being unconditionally
enabled, and disable test logic when done (presumably to save power). Warn when
locking fails.

Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c | 15 ---
 drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk104.c | 15 ---
 2 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c
index 78c449b..f9a4918 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c
@@ -366,11 +366,20 @@ gf100_clk_prog_2(struct gf100_clk *clk, int idx)
if (info->coef) {
nvkm_wr32(device, addr + 0x04, info->coef);
nvkm_mask(device, addr + 0x00, 0x0001, 0x0001);
-   nvkm_msec(device, 2000,
+
+   /* Test PLL lock */
+   nvkm_mask(device, addr + 0x00, 0x0010, 0x);
+   if (nvkm_msec(device, 2000,
if (nvkm_rd32(device, addr + 0x00) & 0x0002)
break;
-   );
-   nvkm_mask(device, addr + 0x00, 0x00020004, 0x0004);
+   ) < 0) {
+   nvkm_warn(&clk->base.subdev,
+   "Could not lock PLL %d", idx);
+   }
+   nvkm_mask(device, addr + 0x00, 0x0010, 0x0010);
+
+   /* Enable sync mode */
+   nvkm_mask(device, addr + 0x00, 0x0004, 0x0004);
}
}
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk104.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk104.c
index 975c401..b650f0c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk104.c
@@ -393,11 +393,20 @@ gk104_clk_prog_2(struct gk104_clk *clk, int idx)
if (info->coef) {
nvkm_wr32(device, addr + 0x04, info->coef);
nvkm_mask(device, addr + 0x00, 0x0001, 0x0001);
-   nvkm_msec(device, 2000,
+
+   /* Test PLL lock */
+   nvkm_mask(device, addr + 0x00, 0x0010, 0x);
+   if (nvkm_msec(device, 2000,
if (nvkm_rd32(device, addr + 0x00) & 0x0002)
break;
-   );
-   nvkm_mask(device, addr + 0x00, 0x00020004, 0x0004);
+   ) < 0) {
+   nvkm_warn(&clk->base.subdev, "Could not lock PLL %d",
+   idx);
+   }
+   nvkm_mask(device, addr + 0x00, 0x0010, 0x0010);
+
+   /* Enable sync mode */
+   nvkm_mask(device, addr + 0x00, 0x0004, 0x0004);
}
 }
 
-- 
2.5.5

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] PM + Init work

2016-06-04 Thread Roy Spliet
Following a series of three patches, two of which have been sitting in my tree
for a while, the third is the result of some inspection of an NV134 BIOS that
seems to use the 0xaf upcode to upload training patterns. Please test!

Roy

Ps. Sorry they come from yet another e-mail address. My previous provider, 
eclipso, actively blocks users of git send-email. Inquiries fall on deaf
ears, hence I consider them hostile towards OSS developers. 


___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 2/3] nvkm/clk/gf100: Read secondary bypass postdiv when required

2016-06-04 Thread Roy Spliet
Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c | 20 ++--
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c
index f9a4918..80c6dd6 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c
@@ -99,7 +99,7 @@ read_div(struct gf100_clk *clk, int doff, u32 dsrc, u32 dctl)
 {
struct nvkm_device *device = clk->base.subdev.device;
u32 ssrc = nvkm_rd32(device, dsrc + (doff * 4));
-   u32 sctl = nvkm_rd32(device, dctl + (doff * 4));
+   u32 sclk, sctl, sdiv = 2;
 
switch (ssrc & 0x0003) {
case 0:
@@ -109,13 +109,21 @@ read_div(struct gf100_clk *clk, int doff, u32 dsrc, u32 
dctl)
case 2:
return 10;
case 3:
-   if (sctl & 0x8000) {
-   u32 sclk = read_vco(clk, dsrc + (doff * 4));
-   u32 sdiv = (sctl & 0x003f) + 2;
-   return (sclk * 2) / sdiv;
+   sclk = read_vco(clk, dsrc + (doff * 4));
+
+   /* Memclk has doff of 0 despite it's alt. location */
+   if (doff <= 2) {
+   sctl = nvkm_rd32(device, dctl + (doff * 4));
+
+   if (sctl & 0x8000) {
+   if (ssrc & 0x100)
+   sctl >>= 8;
+
+   sdiv = (sctl & 0x3f) + 2;
+   }
}
 
-   return read_vco(clk, dsrc + (doff * 4));
+   return (sclk * 2) / sdiv;
default:
return 0;
}
-- 
2.5.5

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH] gr/fuc: Store $r0 in interrupt handler

2016-03-12 Thread Roy Spliet
It's supposed to always be 0, but at least nv_iowr() temporarily violates
this. Since the ih touches $r0, it should be stored.

Signed-off-by: Roy Spliet 
---
 drm/nouveau/nvkm/engine/gr/fuc/gpc.fuc |   2 +
 drm/nouveau/nvkm/engine/gr/fuc/gpcgf100.fuc3.h |  80 
 drm/nouveau/nvkm/engine/gr/fuc/gpcgf117.fuc3.h |  82 
 drm/nouveau/nvkm/engine/gr/fuc/gpcgk104.fuc3.h |  82 
 drm/nouveau/nvkm/engine/gr/fuc/gpcgk110.fuc3.h |  82 
 drm/nouveau/nvkm/engine/gr/fuc/gpcgk208.fuc5.h |  68 +++
 drm/nouveau/nvkm/engine/gr/fuc/gpcgm107.fuc5.h |  70 +++
 drm/nouveau/nvkm/engine/gr/fuc/hub.fuc |   2 +
 drm/nouveau/nvkm/engine/gr/fuc/hubgf100.fuc3.h | 252 -
 drm/nouveau/nvkm/engine/gr/fuc/hubgf117.fuc3.h | 252 -
 drm/nouveau/nvkm/engine/gr/fuc/hubgk104.fuc3.h | 238 +++
 drm/nouveau/nvkm/engine/gr/fuc/hubgk110.fuc3.h | 238 +++
 drm/nouveau/nvkm/engine/gr/fuc/hubgk208.fuc5.h | 210 ++---
 drm/nouveau/nvkm/engine/gr/fuc/hubgm107.fuc5.h | 210 ++---
 14 files changed, 936 insertions(+), 932 deletions(-)

diff --git a/drm/nouveau/nvkm/engine/gr/fuc/gpc.fuc 
b/drm/nouveau/nvkm/engine/gr/fuc/gpc.fuc
index e168b83..dc60509 100644
--- a/drm/nouveau/nvkm/engine/gr/fuc/gpc.fuc
+++ b/drm/nouveau/nvkm/engine/gr/fuc/gpc.fuc
@@ -322,6 +322,7 @@ main:
 
 // interrupt handler
 ih:
+   push $r0
push $r8
mov $r8 $flags
push $r8
@@ -358,6 +359,7 @@ ih:
pop $r8
mov $flags $r8
pop $r8
+   pop $r0
bclr $flags $p0
iret
 
diff --git a/drm/nouveau/nvkm/engine/gr/fuc/gpcgf100.fuc3.h 
b/drm/nouveau/nvkm/engine/gr/fuc/gpcgf100.fuc3.h
index 231f696..5f4ddfe 100644
--- a/drm/nouveau/nvkm/engine/gr/fuc/gpcgf100.fuc3.h
+++ b/drm/nouveau/nvkm/engine/gr/fuc/gpcgf100.fuc3.h
@@ -382,56 +382,57 @@ uint32_t gf100_grgpc_code[] = {
0xb60412fd,
0x1efd01e4,
0x0018fe05,
-   0x05b021f5,
+   0x05b421f5,
 /* 0x04eb: main_not_ctx_xfer */
0x94d30ef4,
0xf5f010ef,
0x7e21f501,
0xc60ef403,
 /* 0x04f8: ih */
-   0x88fe80f9,
-   0xf980f901,
-   0xf9a0f990,
-   0xf9d0f9b0,
-   0xbdf0f9e0,
-   0x00a7f104,
-   0x00a3f002,
-   0xc400aacf,
-   0x0bf404ab,
-   0x1cd7f02c,
-   0x1a00e7f1,
-   0xcf00e3f0,
-   0xf7f100ee,
-   0xf3f01900,
-   0x00ffcf00,
-   0xf00421f4,
-   0x07f101e7,
-   0x03f01d00,
-   0x000ed000,
-/* 0x0546: ih_no_fifo */
-   0x07f104bd,
-   0x03f00100,
-   0x000ad000,
-   0xf0fc04bd,
-   0xd0fce0fc,
-   0xa0fcb0fc,
-   0x80fc90fc,
-   0xfc0088fe,
-   0x0032f480,
-/* 0x056a: hub_barrier_done */
+   0x80f900f9,
+   0xf90188fe,
+   0xf990f980,
+   0xf9b0f9a0,
+   0xf9e0f9d0,
+   0xf104bdf0,
+   0xf00200a7,
+   0xaacf00a3,
+   0x04abc400,
+   0xf02c0bf4,
+   0xe7f11cd7,
+   0xe3f01a00,
+   0x00eecf00,
+   0x1900f7f1,
+   0xcf00f3f0,
+   0x21f400ff,
+   0x01e7f004,
+   0x1d0007f1,
+   0xd3f0,
+   0x04bd000e,
+/* 0x0548: ih_no_fifo */
+   0x010007f1,
+   0xd3f0,
+   0x04bd000a,
+   0xe0fcf0fc,
+   0xb0fcd0fc,
+   0x90fca0fc,
+   0x88fe80fc,
+   0xfc80fc00,
+   0x0032f400,
+/* 0x056e: hub_barrier_done */
0xf7f001f8,
0x040e9801,
0xb904febb,
0xe7f102ff,
0xe3f09418,
0x9d21f440,
-/* 0x0582: ctx_redswitch */
+/* 0x0586: ctx_redswitch */
0xf7f000f8,
0x0007f120,
0x0103f085,
0xbd000fd0,
0x08e7f004,
-/* 0x0594: ctx_redswitch_delay */
+/* 0x0598: ctx_redswitch_delay */
0xf401e2b6,
0xf5f1fd1b,
0xf5f10800,
@@ -439,13 +440,13 @@ uint32_t gf100_grgpc_code[] = {
0x03f08500,
0x000fd001,
0x00f804bd,
-/* 0x05b0: ctx_xfer */
+/* 0x05b4: ctx_xfer */
0x810007f1,
0xd00203f0,
0x04bd000f,
0xf50711f4,
-/* 0x05c3: ctx_xfer_not_load */
-   0xf5058221,
+/* 0x05c7: ctx_xfer_not_load */
+   0xf5058621,
0xbd026a21,
0xfc07f124,
0x0203f047,
@@ -475,12 +476,11 @@ uint32_t gf100_grgpc_code[] = {
0x6f21f508,
0x5e21f501,
0x0601f402,
-/* 0x063b: ctx_xfer_post */
+/* 0x063f: ctx_xfer_post */
0xf50712f4,
-/* 0x063f: ctx_xfer_done */
+/* 0x0643: ctx_xfer_done */
0xf5027f21,
-   0xf8056a21,
-   0x,
+   0xf8056e21,
0x,
0x,
0x,
diff --git a/drm/nouveau/nvkm/engine/gr/fuc/gpcgf117.fuc3.h 
b/drm/nouveau/nvkm/engine/gr/fuc/gpcgf117.fuc3.h
index bb820ff..03381b1 100644
--- a/drm/nouveau/nvkm/engine/gr/fuc/gpcgf117.fuc3.h
+++ b/drm/nouveau/nvkm/engine/gr/fuc/gpcgf117.fuc3.h
@@ -408,56 +408,57 @@ uint32_t gf117_grgpc_code[] = {
0x0412fd20,
0xfd0

Re: [Nouveau] nouveau contributor dinner Friday evening before FOSDEM?

2016-01-21 Thread Roy Spliet

+1

or in layman terms, I'll be there ;-)

Roy

Op 21-01-16 om 15:29 schreef Karol Herbst:

Hi everybody,

yeah, sounds good

greetings

Karol


Pierre Moreau  hat am 21. Januar 2016 um 14:17
geschrieben:

Hello everyone,

I'm in for the dinner! As for the restaurant, since I never went to Brussels,
I'll follow the group's decision. Some time around 19:30–20:00? Most of us
should be in Brussels' centre by then I think.

Cheers,
Pierre

On 02:09 PM - Jan 21 2016, Hans de Goede wrote:

Hi All,

$subject says it pretty much all. AFAIk quite a few
nouveau contributors are coming to Fosdem, and I think it
would be nice to have dinner together Friday evening
before FOSDEM.

So any takers? If you want to join please reply to this
mail thread before coming Thursday, I will try to reserve a table at:

http://www.tripadvisor.com/Restaurant_Review-g188644-d802232-Reviews-Le_Falstaff-Brussels.html

Which is not as bad as the reviews there make it out to be,
note I'm open to better suggestions, esp. from locals, Le Falstaff
is sort of my fallback place to go to in Brussels.

Regards,

Hans

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH 2/2] clk: allow engine reclock on fermi

2016-01-13 Thread Roy Spliet

Hey Karol,

Until you can convince me that this (pending) progress-in-insight[1] is 
accounted for in the way nouveau configures the clock registers, I must 
NACK this patch.

Sorry.

Roy

[1] "nvkm/clk/gf100: Read secondary bypass postdiv when required" - 
currently on 
https://github.com/RSpliet/kernel-nouveau-nv50-pm/commit/d230af49bd0e25271161a9622337b01443214ec0


Op 13-01-16 om 12:25 schreef Karol Herbst:

this gives me on my 630M fermi card some speed improvements while on 0f:

pixmark_piano: ~800ms to ~500ms frame time
unigine_heaven (lowest setting, fullhd): 5.1 fps to 6.4 fps)

clocks for this gpu:
07: 270 MHz
0f: 475 MHz

Signed-off-by: Karol Herbst 
---
  drm/nouveau/nvkm/subdev/clk/gf100.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drm/nouveau/nvkm/subdev/clk/gf100.c 
b/drm/nouveau/nvkm/subdev/clk/gf100.c
index ad93350..2ce902f 100644
--- a/drm/nouveau/nvkm/subdev/clk/gf100.c
+++ b/drm/nouveau/nvkm/subdev/clk/gf100.c
@@ -535,6 +535,6 @@ gf100_clk_new(struct nvkm_device *device, int index, struct 
nvkm_clk **pclk)
return -ENOMEM;
*pclk = &clk->base;
  
-	return nvkm_clk_ctor(&gf100_clk, device, index, false, false,

+   return nvkm_clk_ctor(&gf100_clk, device, index, true, false,
 &clk->base);
  }


___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH 3/4] subdev/pmu/fuc: implement perf

2015-10-26 Thread Roy Spliet

See my tiny nit-pick below.

Op 26-10-15 om 18:13 schreef Karol Herbst:

From: Karol Herbst 

---
  drm/nouveau/nvkm/subdev/pmu/fuc/gf100.fuc3.h | 788 +++
  drm/nouveau/nvkm/subdev/pmu/fuc/gf119.fuc4.h | 740 ++---
  drm/nouveau/nvkm/subdev/pmu/fuc/gk104.fuc4.h | 740 ++---
  drm/nouveau/nvkm/subdev/pmu/fuc/gk208.fuc5.h | 710 ++--
  drm/nouveau/nvkm/subdev/pmu/fuc/gt215.fuc3.h | 755 ++---
  drm/nouveau/nvkm/subdev/pmu/fuc/os.h |   4 +
  drm/nouveau/nvkm/subdev/pmu/fuc/perf.fuc | 148 +
  7 files changed, 2267 insertions(+), 1618 deletions(-)

[snip]

diff --git a/drm/nouveau/nvkm/subdev/pmu/fuc/os.h 
b/drm/nouveau/nvkm/subdev/pmu/fuc/os.h
index c8b06cb..53508d9 100644
--- a/drm/nouveau/nvkm/subdev/pmu/fuc/os.h
+++ b/drm/nouveau/nvkm/subdev/pmu/fuc/os.h
@@ -49,4 +49,8 @@
  #define I2C__MSG_DATA0_WR08_REG 0:7
  #define I2C__MSG_DATA1_WR08_VAL 0:7
  
+

+/* PERF: message identifiers */
+#define PERF_MSG_LOAD 1
+
  #endif
diff --git a/drm/nouveau/nvkm/subdev/pmu/fuc/perf.fuc 
b/drm/nouveau/nvkm/subdev/pmu/fuc/perf.fuc
index 38eadf7..69a8f8d 100644
--- a/drm/nouveau/nvkm/subdev/pmu/fuc/perf.fuc
+++ b/drm/nouveau/nvkm/subdev/pmu/fuc/perf.fuc
@@ -30,6 +30,18 @@ process(PROC_PERF, #perf_init, #perf_recv)
   * PERF data segment
   
*/
  #ifdef INCLUDE_DATA
+perf_attr_start:
+// parameters
+perf_polling_period_us: .b32 10
+
+// engine usage percentage
+perf_eng_gr:   .b8 0
+perf_eng_vdec: .b8 0
+perf_eng_mc:   .b8 0
+#if NVKM_PPWR_CHIPSET >= GF100
+perf_eng_pcie: .b8 0
+#endif
+.align 4
  #endif
  
  /**

@@ -46,6 +58,78 @@ process(PROC_PERF, #perf_init, #perf_recv)
  // $r11 - data1
  // $r0  - zero
  perf_recv:
+   push $r1
+
+   imm32($r10, PROC_HOST)
+   cmp b32 $r14 $r10
+   bra ne #perf_recv_not_host
+   cmp b32 $r13 PERF_MSG_LOAD
+   bra e #perf_load
+   bra #perf_recv_exit
+
+perf_load:
+   clear b32 $r11
+   clear b32 $r12
+#if NVKM_PPWR_CHIPSET >= GF100
+   ld(b8, $r12, #perf_eng_pcie)
+   shl b32 $r12 8
+#endif
+   ld(b8, $r12, #perf_eng_mc)
+   shl b32 $r12 8
+   ld(b8, $r12, #perf_eng_vdec)
+   shl b32 $r12 8
+   ld(b8, $r12, #perf_eng_gr)
+   call(send)
+   bra #perf_recv_exit
+
+perf_recv_not_host:
+   call(perf_counter_readout)
+
+   ld(b32, $r14, #perf_polling_period_us)
+   call #ticks_from_us
+   call(timer)
+
+perf_recv_exit:
+   pop $r1
+   ret
+
+
+// description
+//
+// $r15 - current (perf)
+// $r0  - zero
+perf_counter_readout:
+   nv_iord($r14, NV_PPWR_COUNTER_COUNT(0))
+   div $r14 $r14 0xff
+
+   nv_iord($r13, NV_PPWR_COUNTER_COUNT(1))
+   div $r13 $r13 $r14
+   st(b8, #perf_eng_gr, $r13)
+
+   nv_iord($r13, NV_PPWR_COUNTER_COUNT(2))
+   div $r13 $r13 $r14
+   st(b8, #perf_eng_vdec, $r13)
+
+   nv_iord($r13, NV_PPWR_COUNTER_COUNT(3))
+   div $r13 $r13 $r14
+   st(b8, #perf_eng_mc, $r13)
+
+#if NVKM_PPWR_CHIPSET >= GF100
+   nv_iord($r13, NV_PPWR_COUNTER_COUNT(4))
+   div $r13 $r13 $r14
+   st(b8, #perf_eng_pcie, $r13)
+#endif
+
+   // reset the counters
+   imm32($r14, NV_PPWR_COUNTER_COUNT_RESET)
+   nv_iowr(NV_PPWR_COUNTER_COUNT(0), $r14)
+   nv_iowr(NV_PPWR_COUNTER_COUNT(1), $r14)
+   nv_iowr(NV_PPWR_COUNTER_COUNT(2), $r14)
+   nv_iowr(NV_PPWR_COUNTER_COUNT(3), $r14)
+#if NVKM_PPWR_CHIPSET >= GF100
+   nv_iowr(NV_PPWR_COUNTER_COUNT(4), $r14)
+#endif
+
ret
  
  // description

@@ -53,5 +137,69 @@ perf_recv:
  // $r15 - current (perf)
  // $r0  - zero
  perf_init:
+   // set up the total ticks counter first
+   imm32($r14, NV_PPWR_COUNTER_MODE_ALWAYS)
+   nv_iowr(NV_PPWR_COUNTER_MODE(0), $r14)
+
+   // set up the other counters, with fermi there are more
+   imm32($r14, NV_PPWR_COUNTER_MODE_IF_NOT_ALL)
+   nv_iowr(NV_PPWR_COUNTER_MODE(1), $r14)
+   nv_iowr(NV_PPWR_COUNTER_MODE(2), $r14)
+   nv_iowr(NV_PPWR_COUNTER_MODE(3), $r14)
+#if NVKM_PPWR_CHIPSET >= GF100
+   nv_iowr(NV_PPWR_COUNTER_MODE(4), $r14)
+#endif
+
+   // core load counter
+   imm32($r14,
+ NV_PPWR_COUNTER_SIG_GR_IDLE
+   | NV_PPWR_COUNTER_SIG_GR_GPC_IDLE
+   | NV_PPWR_COUNTER_SIG_GR_ROP_IDLE
+#if NVKM_PPWR_CHIPSET >= GF100
+   | NV_PPWR_COUNTER_SIG_GR_HUB_IDLE
+   | NV_PPWR_COUNTER_SIG_PCOPY0_IDLE
+   | NV_PPWR_COUNTER_SIG_PCOPY1_IDLE
+#if NVKM_PPWR_CHIPSET >= GK104
+   | NV_PPWR_COUNTER_SIG_PCOPY2_IDLE
+#endif
+#endif

I'm not a big fan of nes

Re: [Nouveau] [PATCH 9/9] perf: change pcie speed on pstate change

2015-10-12 Thread Roy Spliet

Comment in-line.
Cheers,

Roy

Op 12-10-15 om 21:27 schreef Karol Herbst:

Signed-off-by: Karol Herbst 
---
  drm/nouveau/nvkm/subdev/clk/base.c | 7 +++
  1 file changed, 7 insertions(+)

diff --git a/drm/nouveau/nvkm/subdev/clk/base.c 
b/drm/nouveau/nvkm/subdev/clk/base.c
index 7ae4f26..4e5122b 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -176,6 +176,7 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)
  {
struct nvkm_subdev *subdev = &clk->subdev;
struct nvkm_ram *ram = subdev->device->fb->ram;
+   struct nvkm_pci *pci = subdev->device->pci;
struct nvkm_pstate *pstate;
int ret, idx = 0;
  
@@ -187,6 +188,12 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)

nvkm_debug(subdev, "setting performance state %d\n", pstatei);
clk->pstate = pstatei;
  
+	if (pci) {

+   ret = nvkm_pci_set_pcie_link(pci, pstate->pcie_speed, 
pstate->pcie_width);
+   if (ret < 0)
+   nvkm_error(subdev, "failed changing pcie speed with: 
%i\n", ret);
Is this an error? It makes it sound like a serious issue, even though 
this is expected behaviour eg. when the motherboard doesn't support the 
desired PCIe speed. Maybe a "debug" message is more appropriate here.

+   }
+
if (ram && ram->func->calc) {
int khz = pstate->base.domain[nv_clk_src_mem];
do {


___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH 3/9] pci: implement generic code for PCIe speed change

2015-10-12 Thread Roy Spliet

Some more minor nitting!

Op 12-10-15 om 21:27 schreef Karol Herbst:

Signed-off-by: Karol Herbst 
---
  drm/nouveau/include/nvkm/subdev/pci.h |  12 +++
  drm/nouveau/nvkm/subdev/pci/Kbuild|   1 +
  drm/nouveau/nvkm/subdev/pci/base.c|   5 ++
  drm/nouveau/nvkm/subdev/pci/pcie.c| 159 ++
  drm/nouveau/nvkm/subdev/pci/priv.h|  12 +++
  5 files changed, 189 insertions(+)
  create mode 100644 drm/nouveau/nvkm/subdev/pci/pcie.c

diff --git a/drm/nouveau/include/nvkm/subdev/pci.h 
b/drm/nouveau/include/nvkm/subdev/pci.h
index 17fe7b7..e195736 100644
--- a/drm/nouveau/include/nvkm/subdev/pci.h
+++ b/drm/nouveau/include/nvkm/subdev/pci.h
@@ -2,6 +2,12 @@
  #define __NVKM_PCI_H__
  #include 
  
+enum nvkm_pcie_speed {

+   NVKM_PCIE_SPEED_2_5,
+   NVKM_PCIE_SPEED_5_0,
+   NVKM_PCIE_SPEED_8_0,
+};
+
  struct nvkm_pci {
const struct nvkm_pci_func *func;
struct nvkm_subdev subdev;
@@ -18,6 +24,11 @@ struct nvkm_pci {
bool acquired;
} agp;
  
+	struct {

+   enum nvkm_pcie_speed last_speed;
+   u8 last_width;
+   } pcie;
+
bool msi;
  };
  
@@ -26,6 +37,7 @@ void nvkm_pci_wr08(struct nvkm_pci *, u16 addr, u8 data);

  void nvkm_pci_wr32(struct nvkm_pci *, u16 addr, u32 data);
  u32 nvkm_pci_mask(struct nvkm_pci *, u16 addr, u32 mask, u32 value);
  void nvkm_pci_rom_shadow(struct nvkm_pci *, bool shadow);
+int nvkm_pci_set_pcie_link(struct nvkm_pci *, enum nvkm_pcie_speed, u8 width);
  
  int nv04_pci_new(struct nvkm_device *, int, struct nvkm_pci **);

  int nv40_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
diff --git a/drm/nouveau/nvkm/subdev/pci/Kbuild 
b/drm/nouveau/nvkm/subdev/pci/Kbuild
index 724afd4..3c2519f 100644
--- a/drm/nouveau/nvkm/subdev/pci/Kbuild
+++ b/drm/nouveau/nvkm/subdev/pci/Kbuild
@@ -1,5 +1,6 @@
  nvkm-y += nvkm/subdev/pci/agp.o
  nvkm-y += nvkm/subdev/pci/base.o
+nvkm-y += nvkm/subdev/pci/pcie.o
  nvkm-y += nvkm/subdev/pci/nv04.o
  nvkm-y += nvkm/subdev/pci/nv40.o
  nvkm-y += nvkm/subdev/pci/nv46.o
diff --git a/drm/nouveau/nvkm/subdev/pci/base.c 
b/drm/nouveau/nvkm/subdev/pci/base.c
index d671dcf..3895ab2 100644
--- a/drm/nouveau/nvkm/subdev/pci/base.c
+++ b/drm/nouveau/nvkm/subdev/pci/base.c
@@ -117,6 +117,9 @@ nvkm_pci_init(struct nvkm_subdev *subdev)
ret = nvkm_agp_init(pci);
if (ret)
return ret;
+   } else {
+   if (pci_is_pcie(pci->pdev))
+   nvkm_pci_pcie_init(pci);
}
  
  	if (pci->func->init)

@@ -160,6 +163,8 @@ nvkm_pci_new_(const struct nvkm_pci_func *func, struct 
nvkm_device *device,
pci->func = func;
pci->pdev = device->func->pci(device)->pdev;
pci->irq = -1;
+   pci->pcie.last_speed = -1;
+   pci->pcie.last_width = -1;
  
  	if (device->type == NVKM_DEVICE_AGP)

nvkm_agp_ctor(pci);
diff --git a/drm/nouveau/nvkm/subdev/pci/pcie.c 
b/drm/nouveau/nvkm/subdev/pci/pcie.c
new file mode 100644
index 000..05e9c55
--- /dev/null
+++ b/drm/nouveau/nvkm/subdev/pci/pcie.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2015 Karol Herbst
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Karol Herbst 
+ */
+#include "priv.h"
+
+static char *pcie_speed_strings[] = {
+   "2.5GT/s",
+   "5.0GT/s",
+   "8.0GT/s",
+};
+
+static enum nvkm_pcie_speed
+pci_bus_speed_to_nvkm_pcie_speed(enum pci_bus_speed speed)
+{
+   switch (speed) {
+   case PCIE_SPEED_2_5GT:
+   return NVKM_PCIE_SPEED_2_5;
+   case PCIE_SPEED_5_0GT:
+   return NVKM_PCIE_SPEED_5_0;
+   case PCIE_SPEED_8_0GT:
+   return NVKM_PCIE_SPEED_8_0;
+   default:
+   if (speed == 0x17) // 0x16 is 8_0, assume 0x17 will be 16_0 for 
now
Please stick to C-style /* blah */ comments. This particular could 
warrant an "XXX" label to indicate it's a 

Re: [Nouveau] [PATCH 4/9] pci: implement pcie speed change for tesla

2015-10-12 Thread Roy Spliet

Hey Karol.

Thanks, great work. A few questions and nit-picks in-line, but I reckon 
on the technical side all is fine.

Cheers,

Roy

Op 12-10-15 om 21:27 schreef Karol Herbst:

Signed-off-by: Karol Herbst 
---
  drm/nouveau/nvkm/subdev/pci/g84.c   | 113 
  drm/nouveau/nvkm/subdev/pci/g94.c   |  10 
  drm/nouveau/nvkm/subdev/pci/gf100.c |   5 ++
  drm/nouveau/nvkm/subdev/pci/gf106.c |   5 ++
  drm/nouveau/nvkm/subdev/pci/gk104.c |   2 +
  drm/nouveau/nvkm/subdev/pci/priv.h  |   9 +++
  6 files changed, 144 insertions(+)

diff --git a/drm/nouveau/nvkm/subdev/pci/g84.c 
b/drm/nouveau/nvkm/subdev/pci/g84.c
index 3faa6bf..e53208e 100644
--- a/drm/nouveau/nvkm/subdev/pci/g84.c
+++ b/drm/nouveau/nvkm/subdev/pci/g84.c
@@ -25,6 +25,109 @@
  
  #include 
  
+u8

Is there a particular reason for making this u8 over u32 or unsigned int?

+g84_get_pcie_version_supported(struct nvkm_pci *pci)
+{
+   u32 chipset = pci->subdev.device->chipset, reg_v;
+
+   /* these cards report wrong information about what they support */
+   if (chipset == 0x84 || chipset == 0x86)
+   return 1;
+
+   reg_v = nvkm_pci_rd32(pci, 0x460) & 0x200;
+   if (reg_v == 0x200)
+   return 2;
+   return 1;
+}
+
+void
+g84_set_pcie_version(struct nvkm_pci *pci, u8 ver)
+{
+   struct nvkm_device *device = pci->subdev.device;
+
+   if (ver > 1)
+   ver = 1;
+   else
+   ver = 0;
+
+   nvkm_mask(device, 0x00154c, 0x1, ver);

The above five lines can also be written as the following one-liner:
nvkm_mask(device, 0x00154c, 0x1, (ver > 1));
or alternatively
nvkm_mask(device, 0x00154c, 0x1, (ver >= 2 ? 0x1 : 0x0));

I'd personally find that easier to read. However, I accept this is also 
just a bit of bike-shedding..

+}
+
+u8
+g84_get_pcie_version(struct nvkm_pci *pci)
+{
+   struct nvkm_device *device = pci->subdev.device;
+   return (nvkm_rd32(device, 0x00154c) & 0x1) + 1;
+}
+
+static void
+g84_set_pcie_cap_speed(struct nvkm_pci *pci, bool full_speed)
+{
+   struct nvkm_device *device = pci->subdev.device;
+   nvkm_mask(device, 0x00154c, 0x80, full_speed ? 0x80 : 0x0);
+}
+
+enum nvkm_pcie_speed
+g84_get_real_speed(struct nvkm_pci *pci)
+{
+   u32 reg_v = nvkm_pci_rd32(pci, 0x88) & 0x3;
+   switch (reg_v) {
+   case 0x3:
+   return NVKM_PCIE_SPEED_8_0;
+   case 0x2:
+   return NVKM_PCIE_SPEED_5_0;
+   case 0x1:
+   default:
+   return NVKM_PCIE_SPEED_2_5;
+   }
+}
+
+enum nvkm_pcie_speed
+g84_get_pcie_max_speed(struct nvkm_pci *pci)
+{
+   u32 reg_v = nvkm_pci_rd32(pci, 0x460) & 0x3300;
+   if (reg_v == 0x2200)
+   return NVKM_PCIE_SPEED_5_0;
+   return NVKM_PCIE_SPEED_2_5;
+}
+
+void
+g84_set_pcie_sta_speed(struct nvkm_pci *pci, enum nvkm_pcie_speed speed)
+{
+   u32 mask_value;
+
+   if (speed == NVKM_PCIE_SPEED_5_0)
+   mask_value = 0x20;
+   else
+   mask_value = 0x10;
+
+   nvkm_pci_mask(pci, 0x460, 0x30, mask_value);
+   nvkm_pci_mask(pci, 0x460, 0x1, 0x1);
+}
+
+int
+g84_pcie_speed_init(struct nvkm_pci *pci)
+{
+   if (g84_get_real_speed(pci) == NVKM_PCIE_SPEED_2_5)
+   g84_set_pcie_cap_speed(pci, false);
+   else
+   g84_set_pcie_cap_speed(pci, true);
+   return 0;
+}
+
+int
+g84_pcie_speed_set(struct nvkm_pci *pci, enum nvkm_pcie_speed req_speed, u8 
req_width)
+{
+   if (req_speed == NVKM_PCIE_SPEED_5_0)
+   g84_set_pcie_cap_speed(pci, true);
+   else
+   g84_set_pcie_cap_speed(pci, false);
+
+   g84_set_pcie_sta_speed(pci, req_speed);
+
+   return 0;
+}
+
  void
  g84_pci_init(struct nvkm_pci *pci)
  {
@@ -55,6 +158,16 @@ g84_pci_func = {
.wr08 = nv40_pci_wr08,
.wr32 = nv40_pci_wr32,
.msi_rearm = nv46_pci_msi_rearm,
+
+   .pcie_speed_init = g84_pcie_speed_init,
+   .pcie_speed_set = g84_pcie_speed_set,
+
+   .pcie_max_speed = g84_get_pcie_max_speed,
+   .pcie_current_speed = g84_get_real_speed,
I'd aim for consistency here, by naming the function 
g84_get_current_speed(), or
if you like it short g84_get_cur_speed(). Either way, try to keep names 
consistent and descriptive.


As far as I can tell the same goes for gk104 and gf106.

+
+   .set_pcie_version = g84_set_pcie_version,
+   .get_pcie_version = g84_get_pcie_version,
+   .get_pcie_version_supported = g84_get_pcie_version_supported,
  };
  
  int

diff --git a/drm/nouveau/nvkm/subdev/pci/g94.c 
b/drm/nouveau/nvkm/subdev/pci/g94.c
index cd311ee..1431041 100644
--- a/drm/nouveau/nvkm/subdev/pci/g94.c
+++ b/drm/nouveau/nvkm/subdev/pci/g94.c
@@ -30,6 +30,16 @@ g94_pci_func = {
.wr08 = nv40_pci_wr08,
.wr32 = nv40_pci_wr32,
.msi_rearm = nv40_pci_msi_rearm,
+
+   .pcie_speed_init = g84_pcie_speed_i

Re: [Nouveau] [PATCH 7/9] fb/ramnv50: Script changes for G94 and up

2015-09-30 Thread Roy Spliet
Hey Ben,


--- original message ---
From: Ben Skeggs 
Date: 05:05:34 30-09-2015
To: Roy Spliet ,  Nouveau Mailinglist 

Subject: Re: [PATCH 7/9] fb/ramnv50: Script changes for G94 and up

> -BEGIN PGP SIGNED MESSAGE-
> Hash: SHA256
> 
> On 09/30/2015 09:23 AM, Roy Spliet wrote:
> > 10053c is not even read on some cards, and I have no idea exactly
> > what the criteria are. Likely NVIDIA pre-scans the VBIOS and in
> > their driver disables all features that are never used. The
> > practical effect should be the same as this implementation though.
> I haven't fully reviewed the series properly yet, but wanted to put my
> two cents worth in here.
> 
> If this works like it does on Kepler, you're going to get bitten here
> if you don't do this correctly.
> [snip]
> Depending on what DEVINIT did, this can leave something either enabled
> or disabled, you don't know which, you're just supposed to just not
> touch it.

Yes, this is precisely what I have observed, but thanks for restating.
I realise I have been living on the edge by ignoring this for now.
Quite honestly though, I haven't come across an example where this would
become a problem *yet*. I reckon this is something you could expect
a follow-up patch for once I have time for it.

> 
> I tried to ignore this on Kepler initially, but eventually got bitten
> by it and had to implement it properly (gk104_ram_ctor_data() handles
> this for the most part).
> 
> I'd *strongly* recommend you verify if the behaviour is the same on
> these boards, and implement it if it is.

Agreed, but given I am probably running out of time quite soon, I do
recommend taking the current work upstream as is or suggest minor
fixes, and not first wait for this proposed change. That's purely
from a practical stance: what I pushed to the ML are improvements.
Some people benefit from it and it'd be a shame to let that bit-rot.

Roy.

> 
> Ben.
> 
> > 
> > Signed-off-by: Roy Spliet  Tested-by: Pierre
> 
> > Moreau  --- 
> > drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c | 36
> >  1 file changed, 30 insertions(+), 6
> > deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
> > b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c index
> > 1c6ae6b..651b74a 100644 ---
> > a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c +++
> > b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c @@ -302,6 +302,9
> 
> > @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq) return ret; }
> > 
> > +   if (subdev->device->chipset <= 0x96 &&
> > !next->bios.ramcfg_00_03_02) +  ram_mask(hwsq, 0x100710,
> > 0x0200, 0x); + /* Always disable this bit during
> > reclock */ ram_mask(hwsq, 0x100200, 0x0800, 0x);
> > 
> > @@ -353,8 +356,11 @@ nv50_ram_calc(struct nvkm_ram *base, u32
> > freq) next->bios.rammap_00_16_40 << 14); ram_mask(hwsq, 0x00400c,
> 
> > 0x, (N1 << 8) | M1); ram_mask(hwsq, 0x004008, 0x91ff,
> 
> > r004008); - if (subdev->device->chipset >= 0x96) + +/* XXX:
> GDDR3
> > only? */ +  if (subdev->device->chipset >= 0x92) ram_wr32(hwsq,
> 
> > 0x100da0, r100da0); + nv50_ram_gpio(hwsq, 0x18,
> > !next->bios.ramcfg_FBVDDQ); ram_nsec(hwsq, 64000); /*XXX*/ 
> > ram_nsec(hwsq, 32000); /*XXX*/ @@ -397,19 +403,33 @@
> > nv50_ram_calc(struct nvkm_ram *base, u32 freq) ram_mask(hwsq,
> > 0x100200, 0x1000, !next->bios.ramcfg_00_04_02 << 12);
> > 
> > /* XXX: A lot of this could be "chipset"/"ram type"
> specific stuff
> > */ -unk710  = ram_rd32(hwsq, 0x100710) & ~0x0101; + unk710
>  =
> > ram_rd32(hwsq, 0x100710) & ~0x0100; unk714  = ram_rd32(hwsq,
> 
> > 0x100714) & ~0xf020; unk718  = ram_rd32(hwsq, 0x100718) &
> 
> > ~0x0100; unk71c  = ram_rd32(hwsq, 0x10071c) & ~0x0100; +
> if
> > (subdev->device->chipset <= 0x96) { +   unk710 &= ~0x006e;
> +
> > unk714 &= ~0x0100; + +  if (!next->bios.ramcfg_00_03_08)
> +
> > unk710 |= 0x0060; + if (!next->bios.ramcfg_FBVDDQ) +
> > unk714
> 
> > |= 0x0100; +if ( next->bios.ramcfg_00_04_04) +  
> > unk710 |=
> 
> > 0x000e; +   } else { +  unk710 &= ~0x0001; + +  
> > if
> > (!next->bios.ramcfg_00_03_08) + unk710 |= 0x0001; + 
> > }
> > 
> > if ( next->bios.ramcfg_00_03_

[Nouveau] [PATCH 5/9] fb/ramnv50: Voltage GPIOs

2015-09-29 Thread Roy Spliet
Does not seem to be necessary for NVA0, hence untested by me.

Signed-off-by: Roy Spliet 
Tested-by: Pierre Moreau 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c |  1 +
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c  | 41 +++
 2 files changed, 42 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
index 74a4ab5..d0ae745 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
@@ -171,6 +171,7 @@ nvbios_rammapSp_from_perf(struct nvkm_bios *bios, u32 data, 
u8 size, int idx,
p->ramcfg_DLLoff   = (nvbios_rd08(bios, data + 0x03) & 0x04) >> 2;
p->ramcfg_00_03_08 = (nvbios_rd08(bios, data + 0x03) & 0x08) >> 3;
p->ramcfg_RON  = (nvbios_rd08(bios, data + 0x03) & 0x10) >> 3;
+   p->ramcfg_FBVDDQ   = (nvbios_rd08(bios, data + 0x03) & 0x80) >> 7;
p->ramcfg_00_04_02 = (nvbios_rd08(bios, data + 0x04) & 0x02) >> 1;
p->ramcfg_00_04_04 = (nvbios_rd08(bios, data + 0x04) & 0x04) >> 2;
p->ramcfg_00_04_20 = (nvbios_rd08(bios, data + 0x04) & 0x20) >> 5;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
index 9197e0e..ae6b0c4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
@@ -33,6 +33,7 @@
 #include 
 #include 
 #include 
+#include 
 
 struct nv50_ramseq {
struct hwsq base;
@@ -59,6 +60,7 @@ struct nv50_ramseq {
struct hwsq_reg r_0x611200;
struct hwsq_reg r_timing[9];
struct hwsq_reg r_mr[4];
+   struct hwsq_reg r_gpio[4];
 };
 
 struct nv50_ram {
@@ -154,6 +156,33 @@ nvkm_sddr2_dll_reset(struct nv50_ramseq *hwsq)
ram_nsec(hwsq, 24000);
 }
 
+static void
+nv50_ram_gpio(struct nv50_ramseq *hwsq, u8 tag, u32 val)
+{
+   struct nvkm_gpio *gpio = hwsq->base.subdev->device->gpio;
+   struct dcb_gpio_func func;
+   u32 reg, sh, gpio_val;
+   int ret;
+
+   if (nvkm_gpio_get(gpio, 0, tag, DCB_GPIO_UNUSED) != val) {
+   ret = nvkm_gpio_find(gpio, 0, tag, DCB_GPIO_UNUSED, &func);
+   if (ret)
+   return;
+
+   reg = func.line >> 3;
+   sh = (func.line & 0x7) << 2;
+   gpio_val = ram_rd32(hwsq, gpio[reg]);
+
+   if (gpio_val & (8 << sh))
+   val = !val;
+   if (!(func.log[1] & 1))
+   val = !val;
+
+   ram_mask(hwsq, gpio[reg], (0x3 << sh), ((val | 0x2) << sh));
+   ram_nsec(hwsq, 2);
+   }
+}
+
 static int
 nv50_ram_calc(struct nvkm_ram *base, u32 freq)
 {
@@ -250,6 +279,9 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
ram_wait(hwsq, 0x00, 0x01); /* wait for fb disabled */
ram_nsec(hwsq, 2000);
 
+   if (next->bios.timing_10_ODT)
+   nv50_ram_gpio(hwsq, 0x2e, 1);
+
ram_wr32(hwsq, 0x1002d4, 0x0001); /* precharge */
ram_wr32(hwsq, 0x1002d0, 0x0001); /* refresh */
ram_wr32(hwsq, 0x1002d0, 0x0001); /* refresh */
@@ -288,6 +320,7 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
ram_mask(hwsq, 0x004008, 0x91ff, r004008);
if (subdev->device->chipset >= 0x96)
ram_wr32(hwsq, 0x100da0, r100da0);
+   nv50_ram_gpio(hwsq, 0x18, !next->bios.ramcfg_FBVDDQ);
ram_nsec(hwsq, 64000); /*XXX*/
ram_nsec(hwsq, 32000); /*XXX*/
 
@@ -364,6 +397,9 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
}
ram_mask(hwsq, mr[1], 0x, ram->base.mr[1]);
 
+   if (!next->bios.timing_10_ODT)
+   nv50_ram_gpio(hwsq, 0x2e, 0);
+
/* Reset DLL */
if (!next->bios.ramcfg_DLLoff)
nvkm_sddr2_dll_reset(hwsq);
@@ -634,5 +670,10 @@ nv50_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
ram->hwsq.r_mr[3] = hwsq_reg(0x1002e4);
}
 
+   ram->hwsq.r_gpio[0] = hwsq_reg(0x00e104);
+   ram->hwsq.r_gpio[1] = hwsq_reg(0x00e108);
+   ram->hwsq.r_gpio[2] = hwsq_reg(0x00e120);
+   ram->hwsq.r_gpio[3] = hwsq_reg(0x00e124);
+
return 0;
 }
-- 
2.4.3



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 3/9] fb/ramgt215: Change FBVDD/Q when BIOS asks for it

2015-09-29 Thread Roy Spliet
Signed-off-by: Roy Spliet 
---
 .../gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h  |  1 +
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c  |  1 +
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c  | 18 ++
 3 files changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h 
b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
index dd48db7..dca6c06 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
@@ -39,6 +39,7 @@ struct nvbios_ramcfg {
unsigned ramcfg_timing;
unsigned ramcfg_DLLoff;
unsigned ramcfg_RON;
+   unsigned ramcfg_FBVDDQ;
union {
struct {
unsigned ramcfg_00_03_01:1;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
index 3bbb1a7..74a4ab5 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
@@ -205,6 +205,7 @@ nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
p->ramcfg_DLLoff   = (nvbios_rd08(bios, data + 0x02) & 0x40) >> 
6;
p->ramcfg_10_03_0f = (nvbios_rd08(bios, data + 0x03) & 0x0f) >> 
0;
p->ramcfg_10_04_01 = (nvbios_rd08(bios, data + 0x04) & 0x01) >> 
0;
+   p->ramcfg_FBVDDQ   = (nvbios_rd08(bios, data + 0x04) & 0x08) >> 
3;
p->ramcfg_10_05= (nvbios_rd08(bios, data + 0x05) & 0xff) >> 
0;
p->ramcfg_10_06= (nvbios_rd08(bios, data + 0x06) & 0xff) >> 
0;
p->ramcfg_10_07= (nvbios_rd08(bios, data + 0x07) & 0xff) >> 
0;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
index 0c28f38..cb75de1 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
@@ -498,6 +498,7 @@ gt215_ram_calc(struct nvkm_ram *base, u32 freq)
struct nvkm_device *device = subdev->device;
struct nvkm_bios *bios = device->bios;
struct gt215_clk_info mclk;
+   struct nvkm_gpio *gpio = device->gpio;
struct nvkm_ram_data *next;
u8  ver, hdr, cnt, len, strap;
u32 data;
@@ -656,6 +657,23 @@ gt215_ram_calc(struct nvkm_ram *base, u32 freq)
if (device->chipset == 0xa3 && freq <= 50)
ram_mask(fuc, 0x100700, 0x0006, 0x0006);
 
+   /* Alter FBVDD/Q, apparently must be done with PLL disabled, thus
+* set it to bypass */
+   if (nvkm_gpio_get(gpio, 0, 0x18, DCB_GPIO_UNUSED) == 
+   next->bios.ramcfg_FBVDDQ) {
+   data = ram_rd32(fuc, 0x004000) & 0x9;
+
+   if (data == 0x1)
+   ram_mask(fuc, 0x004000, 0x8, 0x8);
+   if (data & 0x1)
+   ram_mask(fuc, 0x004000, 0x1, 0x0);
+
+   gt215_ram_gpio(fuc, 0x18, !next->bios.ramcfg_FBVDDQ);
+
+   if (data & 0x1)
+   ram_mask(fuc, 0x004000, 0x1, 0x1);
+   }
+
/* Fiddle with clocks */
/* There's 4 scenario's
 * pll->pll: first switch to a 324MHz clock, set up new PLL, switch
-- 
2.4.3



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 9/9] clk/g84: Enable reclocking for GDDR3 G94-G200

2015-09-29 Thread Roy Spliet
Your milage may vary, as it's only been tested on a single G94 and one G96.

Signed-off-by: Roy Spliet 
Tested-by: Pierre Moreau 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/clk/g84.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/g84.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/g84.c
index 347da9e..f97e3ec 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/g84.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/g84.c
@@ -44,5 +44,5 @@ int
 g84_clk_new(struct nvkm_device *device, int index, struct nvkm_clk **pclk)
 {
return nv50_clk_new_(&g84_clk, device, index,
-(device->chipset == 0xa0), pclk);
+(device->chipset >= 0x94), pclk);
 }
-- 
2.4.3



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] All-round reclocking improvements

2015-09-29 Thread Roy Spliet
In bulletpoints:
- Add some support for G94 and G96 reclocking. Has been tested on literally
  two cards, which is hardly adequate as "full coverage". On the other hand, 
  the changes were small enough to make me confident this might work for others
  as well.
- Fix NV50 wait for VBLANK when no monitor is plugged in.
- Voltage related inprovements for GT21x.
- Slightly improve Keplers handling of DDR3 cards where the DLL should be
  disabled. Lays the foundation for a similar improvement in GDDR5 cards, but
  lacking such a card I can't test any changes here.

If you don't feel confident about patch 9 feel free to drop it. But better:
test this series and report with me on IRC #nouveau when things don't work.
Cheers,

Roy



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 1/9] bios/rammap: Identify DLLoff for >= GF100

2015-09-29 Thread Roy Spliet
Signed-off-by: Roy Spliet 
---
 .../drm/nouveau/include/nvkm/subdev/bios/ramcfg.h  |  1 -
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c  |  2 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c |  3 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c  | 41 ++
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr3.c |  4 +--
 5 files changed, 39 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h 
b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
index 3a9abd3..dd48db7 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
@@ -78,7 +78,6 @@ struct nvbios_ramcfg {
unsigned ramcfg_11_01_04:1;
unsigned ramcfg_11_01_08:1;
unsigned ramcfg_11_01_10:1;
-   unsigned ramcfg_11_01_20:1;
unsigned ramcfg_11_01_40:1;
unsigned ramcfg_11_01_80:1;
unsigned ramcfg_11_02_03:2;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
index f0e1fc7..3bbb1a7 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
@@ -219,7 +219,7 @@ nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
p->ramcfg_11_01_04 = (nvbios_rd08(bios, data + 0x01) & 0x04) >> 
2;
p->ramcfg_11_01_08 = (nvbios_rd08(bios, data + 0x01) & 0x08) >> 
3;
p->ramcfg_11_01_10 = (nvbios_rd08(bios, data + 0x01) & 0x10) >> 
4;
-   p->ramcfg_11_01_20 = (nvbios_rd08(bios, data + 0x01) & 0x20) >> 
5;
+   p->ramcfg_DLLoff =   (nvbios_rd08(bios, data + 0x01) & 0x20) >> 
5;
p->ramcfg_11_01_40 = (nvbios_rd08(bios, data + 0x01) & 0x40) >> 
6;
p->ramcfg_11_01_80 = (nvbios_rd08(bios, data + 0x01) & 0x80) >> 
7;
p->ramcfg_11_02_03 = (nvbios_rd08(bios, data + 0x02) & 0x03) >> 
0;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c
index 24f83b0..2cc074d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c
@@ -38,11 +38,12 @@ nvkm_gddr5_calc(struct nvkm_ram *ram, bool nuts)
int WL, CL, WR, at[2], dt, ds;
int rq = ram->freq < 100; /* XXX */
 
+   xd = !ram->next->bios.ramcfg_DLLoff;
+
switch (ram->next->bios.ramcfg_ver) {
case 0x11:
pd =  ram->next->bios.ramcfg_11_01_80;
lf =  ram->next->bios.ramcfg_11_01_40;
-   xd = !ram->next->bios.ramcfg_11_01_20;
vh =  ram->next->bios.ramcfg_11_02_10;
vr =  ram->next->bios.ramcfg_11_02_04;
vo =  ram->next->bios.ramcfg_11_06;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c
index 9893556..0d20563 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c
@@ -673,6 +673,25 @@ gk104_ram_calc_gddr5(struct gk104_ram *ram, u32 freq)
  * DDR3
  
**/
 
+static void
+nvkm_sddr3_dll_reset(struct gk104_ramfuc *fuc)
+{
+   ram_nuke(fuc, mr[0]);
+   ram_mask(fuc, mr[0], 0x100, 0x100);
+   ram_mask(fuc, mr[0], 0x100, 0x000);
+}
+
+static void
+nvkm_sddr3_dll_disable(struct gk104_ramfuc *fuc)
+{
+   u32 mr1_old = ram_rd32(fuc, mr[1]);
+
+   if (!(mr1_old & 0x1)) {
+   ram_mask(fuc, mr[1], 0x1, 0x1);
+   ram_nsec(fuc, 1000);
+   }
+}
+
 static int
 gk104_ram_calc_sddr3(struct gk104_ram *ram, u32 freq)
 {
@@ -702,6 +721,10 @@ gk104_ram_calc_sddr3(struct gk104_ram *ram, u32 freq)
ram_mask(fuc, 0x10f808, 0x0400, 0x0400);
 
ram_wr32(fuc, 0x10f314, 0x0001); /* PRECHARGE */
+
+   if (next->bios.ramcfg_DLLoff)
+   nvkm_sddr3_dll_disable(fuc);
+
ram_wr32(fuc, 0x10f210, 0x); /* REFRESH_AUTO = 0 */
ram_wr32(fuc, 0x10f310, 0x0001); /* REFRESH */
ram_mask(fuc, 0x10f200, 0x8000, 0x8000);
@@ -879,17 +902,20 @@ gk104_ram_calc_sddr3(struct gk104_ram *ram, u32 freq)
ram_wr32(fuc, 0x10f210, 0x8000); /* REFRESH_AUTO = 1 */
ram_nsec(fuc, 1000);
 
-   ram_nuke(fuc, mr[0]);
-   ram_mask(fuc, mr[0], 0x100, 0x100);
-   ram_mask(fuc, mr[0], 0x100, 0x000);
+   if (!next->bios.ramcfg_DLLoff) {
+   ram_mask(fuc, mr[1], 0x1, 0x0);
+   nvkm_sddr3_dll_reset(fuc);
+   }
 
-   ram_mask(fuc, mr[2], 0xfff, ram->bas

[Nouveau] [PATCH 2/9] fb/ramgt215: Transform GPIO ramfuc method from FBVREF-specific to generic

2015-09-29 Thread Roy Spliet
In preparation of changing FBVDDQ, as observed on at least one GDDR3 card.
While at it, adhere to func.log[1] properly for consistency.

Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c | 41 ++-
 drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv50.c   |  2 +-
 2 files changed, 19 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
index 5c08ae8..0c28f38 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
@@ -34,9 +34,6 @@
 #include 
 #include 
 
-/* XXX: Remove when memx gains GPIO support */
-extern int nv50_gpio_location(int line, u32 *reg, u32 *shift);
-
 struct gt215_ramfuc {
struct ramfuc base;
struct ramfuc_reg r_0x001610;
@@ -75,7 +72,7 @@ struct gt215_ramfuc {
struct ramfuc_reg r_0x111400;
struct ramfuc_reg r_0x611200;
struct ramfuc_reg r_mr[4];
-   struct ramfuc_reg r_gpioFBVREF;
+   struct ramfuc_reg r_gpio[4];
 };
 
 struct gt215_ltrain {
@@ -466,24 +463,27 @@ gt215_ram_lock_pll(struct gt215_ramfuc *fuc, struct 
gt215_clk_info *mclk)
 }
 
 static void
-gt215_ram_fbvref(struct gt215_ramfuc *fuc, u32 val)
+gt215_ram_gpio(struct gt215_ramfuc *fuc, u8 tag, u32 val)
 {
struct nvkm_gpio *gpio = fuc->base.fb->subdev.device->gpio;
struct dcb_gpio_func func;
u32 reg, sh, gpio_val;
int ret;
 
-   if (nvkm_gpio_get(gpio, 0, 0x2e, DCB_GPIO_UNUSED) != val) {
-   ret = nvkm_gpio_find(gpio, 0, 0x2e, DCB_GPIO_UNUSED, &func);
+   if (nvkm_gpio_get(gpio, 0, tag, DCB_GPIO_UNUSED) != val) {
+   ret = nvkm_gpio_find(gpio, 0, tag, DCB_GPIO_UNUSED, &func);
if (ret)
return;
 
-   nv50_gpio_location(func.line, ®, &sh);
-   gpio_val = ram_rd32(fuc, gpioFBVREF);
+   reg = func.line >> 3;
+   sh = (func.line & 0x7) << 2;
+   gpio_val = ram_rd32(fuc, gpio[reg]);
if (gpio_val & (8 << sh))
val = !val;
+   if (!(func.log[1] & 1))
+   val = !val;
 
-   ram_mask(fuc, gpioFBVREF, (0x3 << sh), ((val | 0x2) << sh));
+   ram_mask(fuc, gpio[reg], (0x3 << sh), ((val | 0x2) << sh));
ram_nsec(fuc, 2);
}
 }
@@ -642,8 +642,8 @@ gt215_ram_calc(struct nvkm_ram *base, u32 freq)
break;
}
 
-   if (fuc->r_gpioFBVREF.addr && next->bios.timing_10_ODT)
-   gt215_ram_fbvref(fuc, 0);
+   if (next->bios.timing_10_ODT)
+   gt215_ram_gpio(fuc, 0x2e, 1);
 
/* Brace RAM for impact */
ram_wr32(fuc, 0x1002d4, 0x0001);
@@ -809,8 +809,8 @@ gt215_ram_calc(struct nvkm_ram *base, u32 freq)
ram_mask(fuc, 0x100718, 0x, unk718);
ram_mask(fuc, 0x00, 0x, r00);
 
-   if (fuc->r_gpioFBVREF.addr && !next->bios.timing_10_ODT)
-   gt215_ram_fbvref(fuc, 1);
+   if (!next->bios.timing_10_ODT)
+   gt215_ram_gpio(fuc, 0x2e, 0);
 
/* Reset DLL */
if (!next->bios.ramcfg_DLLoff)
@@ -919,10 +919,7 @@ gt215_ram_func = {
 int
 gt215_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
 {
-   struct nvkm_gpio *gpio = fb->subdev.device->gpio;
-   struct dcb_gpio_func func;
struct gt215_ram *ram;
-   u32 reg, shift;
int ret, i;
 
if (!(ram = kzalloc(sizeof(*ram), GFP_KERNEL)))
@@ -981,12 +978,10 @@ gt215_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
ram->fuc.r_mr[2] = ramfuc_reg(0x1002e0);
ram->fuc.r_mr[3] = ramfuc_reg(0x1002e4);
}
-
-   ret = nvkm_gpio_find(gpio, 0, 0x2e, DCB_GPIO_UNUSED, &func);
-   if (ret == 0) {
-   nv50_gpio_location(func.line, ®, &shift);
-   ram->fuc.r_gpioFBVREF = ramfuc_reg(reg);
-   }
+   ram->fuc.r_gpio[0] = ramfuc_reg(0x00e104);
+   ram->fuc.r_gpio[1] = ramfuc_reg(0x00e108);
+   ram->fuc.r_gpio[2] = ramfuc_reg(0x00e120);
+   ram->fuc.r_gpio[3] = ramfuc_reg(0x00e124);
 
return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv50.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv50.c
index 8996649..73923fd 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv50.c
@@ -54,7 +54,7 @@ nv50_gpio_reset(struct nvkm_gpio *gpio, u8 match)
}
 }
 
-int
+static int
 nv50_gpio_location(int line, u32 *reg, u32 *shift)
 {
const u32 nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
-- 
2.4.3



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 4/9] fb/ramgt215: Restructure r111100 calculation for DDR2

2015-09-29 Thread Roy Spliet
Seems to be mostly equal to DDR3 on < GT218, should improve stability for
DDR2 reclocks.

Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c | 70 ---
 1 file changed, 37 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
index cb75de1..52abcaf 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
@@ -771,41 +771,45 @@ gt215_ram_calc(struct nvkm_ram *base, u32 freq)
unk71c  = ram_rd32(fuc, 0x10071c) & ~0x0100;
r00 = ram_rd32(fuc, 0x00) & ~0x3a80;
 
-   if (next->bios.ramcfg_10_02_04) {
-   switch (ram->base.type) {
-   case NVKM_RAM_TYPE_DDR3:
-   if (device->chipset != 0xa8)
-   r00 |= 0x0004;
-   /* no break */
-   case NVKM_RAM_TYPE_DDR2:
-   r00 |= 0x0800;
-   break;
-   default:
-   break;
-   }
+   /* NVA8 seems to skip various bits related to ramcfg_10_02_04 */
+   if (device->chipset == 0xa8) {
+   r00 |= 0x0800;
+   if (!next->bios.ramcfg_10_02_04)
+   unk714  |= 0x0010;
} else {
-   switch (ram->base.type) {
-   case NVKM_RAM_TYPE_DDR2:
-   r00 |= 0x1a80;
-   unk714  |= 0x0010;
-   break;
-   case NVKM_RAM_TYPE_DDR3:
-   if (device->chipset == 0xa8) {
-   r00 |=  0x0800;
-   } else {
-   r00 &= ~0x0004;
-   r00 |=  0x1280;
+   if (next->bios.ramcfg_10_02_04) {
+   switch (ram->base.type) {
+   case NVKM_RAM_TYPE_DDR2:
+   case NVKM_RAM_TYPE_DDR3:
+   r00 &= ~0x0020;
+   if (next->bios.ramcfg_10_02_10)
+   r00 |= 0x0804;
+   else
+   r00 |= 0x0024;
+   break;
+   default:
+   break;
}
-   unk714  |= 0x0010;
-   break;
-   case NVKM_RAM_TYPE_GDDR3:
-   r00 |= 0x3000;
-   unk714  |= 0x0020;
-   break;
-   default:
-   break;
-   }
-   }
+   } else {
+   switch (ram->base.type) {
+   case NVKM_RAM_TYPE_DDR2:
+   case NVKM_RAM_TYPE_DDR3:
+   r00 &= ~0x0024;
+   r00 |=  0x1280;
+
+   if (next->bios.ramcfg_10_02_10)
+   r00 |= 0x0800;
+   unk714  |= 0x0010;
+   break;
+   case NVKM_RAM_TYPE_GDDR3:
+   r00 |= 0x3000;
+   unk714  |= 0x0020;
+   break;
+   default:
+   break;
+   }
+   }
+   }
 
unk714 |= (next->bios.ramcfg_10_04_01) << 8;
 
-- 
2.4.3



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 7/9] fb/ramnv50: Script changes for G94 and up

2015-09-29 Thread Roy Spliet
10053c is not even read on some cards, and I have no idea exactly what the
criteria are. Likely NVIDIA pre-scans the VBIOS and in their driver disables
all features that are never used. The practical effect should be the same
as this implementation though.

Signed-off-by: Roy Spliet 
Tested-by: Pierre Moreau 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c | 36 
 1 file changed, 30 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
index 1c6ae6b..651b74a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
@@ -302,6 +302,9 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
return ret;
}
 
+   if (subdev->device->chipset <= 0x96 && !next->bios.ramcfg_00_03_02)
+   ram_mask(hwsq, 0x100710, 0x0200, 0x);
+
/* Always disable this bit during reclock */
ram_mask(hwsq, 0x100200, 0x0800, 0x);
 
@@ -353,8 +356,11 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
next->bios.rammap_00_16_40 << 14);
ram_mask(hwsq, 0x00400c, 0x, (N1 << 8) | M1);
ram_mask(hwsq, 0x004008, 0x91ff, r004008);
-   if (subdev->device->chipset >= 0x96)
+
+   /* XXX: GDDR3 only? */
+   if (subdev->device->chipset >= 0x92)
ram_wr32(hwsq, 0x100da0, r100da0);
+
nv50_ram_gpio(hwsq, 0x18, !next->bios.ramcfg_FBVDDQ);
ram_nsec(hwsq, 64000); /*XXX*/
ram_nsec(hwsq, 32000); /*XXX*/
@@ -397,19 +403,33 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
ram_mask(hwsq, 0x100200, 0x1000, !next->bios.ramcfg_00_04_02 << 12);
 
/* XXX: A lot of this could be "chipset"/"ram type" specific stuff */
-   unk710  = ram_rd32(hwsq, 0x100710) & ~0x0101;
+   unk710  = ram_rd32(hwsq, 0x100710) & ~0x0100;
unk714  = ram_rd32(hwsq, 0x100714) & ~0xf020;
unk718  = ram_rd32(hwsq, 0x100718) & ~0x0100;
unk71c  = ram_rd32(hwsq, 0x10071c) & ~0x0100;
+   if (subdev->device->chipset <= 0x96) {
+   unk710 &= ~0x006e;
+   unk714 &= ~0x0100;
+
+   if (!next->bios.ramcfg_00_03_08)
+   unk710 |= 0x0060;
+   if (!next->bios.ramcfg_FBVDDQ)
+   unk714 |= 0x0100;
+   if ( next->bios.ramcfg_00_04_04)
+   unk710 |= 0x000e;
+   } else {
+   unk710 &= ~0x0001;
+
+   if (!next->bios.ramcfg_00_03_08)
+   unk710 |= 0x0001;
+   }
 
if ( next->bios.ramcfg_00_03_01)
unk71c |= 0x0100;
if ( next->bios.ramcfg_00_03_02)
unk710 |= 0x0100;
-   if (!next->bios.ramcfg_00_03_08) {
-   unk710 |= 0x1;
-   unk714 |= 0x20;
-   }
+   if (!next->bios.ramcfg_00_03_08)
+   unk714 |= 0x0020;
if ( next->bios.ramcfg_00_04_04)
unk714 |= 0x7000;
if ( next->bios.ramcfg_00_04_20)
@@ -420,6 +440,8 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
ram_mask(hwsq, 0x100718, 0x, unk718);
ram_mask(hwsq, 0x100710, 0x, unk710);
 
+   /* XXX: G94 does not even test these regs in trace. Harmless we do it,
+* but why is it omitted? */
if (next->bios.rammap_00_16_20) {
ram_wr32(hwsq, 0x1005a0, next->bios.ramcfg_00_07 << 16 |
 next->bios.ramcfg_00_06 << 8 |
@@ -450,6 +472,8 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
ram_mask(hwsq, 0x004008, 0x4000, 0x);
if (next->bios.ramcfg_00_03_02)
ram_mask(hwsq, 0x10021c, 0x0001, 0x0001);
+   if (subdev->device->chipset <= 0x96 && next->bios.ramcfg_00_03_02)
+   ram_mask(hwsq, 0x100710, 0x0200, 0x0200);
 
return 0;
 }
-- 
2.4.3



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 6/9] fb/ramnv50: Deal with cards without timing entries

2015-09-29 Thread Roy Spliet
Like Pierre's G94. We might want to structure Kepler similarly in a follow-up.

Signed-off-by: Roy Spliet 
Tested-by: Pierre Moreau 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c   | 10 +++---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c | 41 ++--
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr2.c   |  6 
 3 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
index 79b523a..60ece0a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
@@ -63,7 +63,7 @@ ramgddr3_wr_lo[] = {
{ 5, 2 }, { 7, 4 }, { 8, 5 }, { 9, 6 }, { 10, 7 },
{ 11, 0 }, { 13 , 1 },
/* the below are mentioned in some, but not all, gddr3 docs */
-   { 4, 1 }, { 6, 3 }, { 12, 1 },
+   { 4, 0 }, { 6, 3 }, { 12, 1 },
{ -1 }
 };
 
@@ -87,15 +87,17 @@ nvkm_gddr3_calc(struct nvkm_ram *ram)
WR  = (ram->next->bios.timing[2] & 0x007f) >> 16;
/* XXX: Get these values from the VBIOS instead */
DLL = !(ram->mr[1] & 0x1);
-   ODT =  (ram->mr[1] & 0x004) >> 2 |
-  (ram->mr[1] & 0x040) >> 5 |
-  (ram->mr[1] & 0x200) >> 7;
RON = !(ram->mr[1] & 0x300) >> 8;
break;
default:
return -ENOSYS;
}
 
+   if (ram->next->bios.timing_ver == 0x20 ||
+   ram->next->bios.ramcfg_timing == 0xff) {
+   ODT =  (ram->mr[1] & 0xc) >> 2;
+   }
+
hi = ram->mr[2] & 0x1;
CL  = ramxlat(hi ? ramgddr3_cl_hi : ramgddr3_cl_lo, CL);
WR  = ramxlat(ramgddr3_wr_lo, WR);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
index ae6b0c4..1c6ae6b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
@@ -146,6 +146,38 @@ nv50_ram_timing_calc(struct nv50_ram *ram, u32 *timing)
nvkm_debug(subdev, " 240: %08x\n", timing[8]);
return 0;
 }
+
+static int
+nv50_ram_timing_read(struct nv50_ram *ram, u32 *timing)
+{
+   unsigned int i;
+   struct nvbios_ramcfg *cfg = &ram->base.target.bios;
+   struct nvkm_subdev *subdev = &ram->base.fb->subdev;
+   struct nvkm_device *device = subdev->device;
+
+   for (i = 0; i <= 8; i++)
+   timing[i] = nvkm_rd32(device, 0x100220 + (i * 4));
+
+   /* Derive the bare minimum for the MR calculation to succeed */
+   cfg->timing_ver = 0x10;
+   T(CL) = (timing[3] & 0xff) + 1;
+
+   switch (ram->base.type) {
+   case NVKM_RAM_TYPE_DDR2:
+   T(CWL) = T(CL) - 1;
+   break;
+   case NVKM_RAM_TYPE_GDDR3:
+   T(CWL) = ((timing[2] & 0xff00) >> 24) + 1;
+   break;
+   default:
+   return -ENOSYS;
+   break;
+   }
+
+   T(WR) = ((timing[1] >> 24) & 0xff) - 1 - T(CWL);
+
+   return 0;
+}
 #undef T
 
 static void
@@ -242,10 +274,11 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
 strap, data, ver, hdr);
return -EINVAL;
}
+   nv50_ram_timing_calc(ram, timing);
+   } else {
+   nv50_ram_timing_read(ram, timing);
}
 
-   nv50_ram_timing_calc(ram, timing);
-
ret = ram_init(hwsq, subdev);
if (ret)
return ret;
@@ -264,8 +297,10 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
break;
}
 
-   if (ret)
+   if (ret) {
+   nvkm_error(subdev, "Could not calculate MR\n");
return ret;
+   }
 
/* Always disable this bit during reclock */
ram_mask(hwsq, 0x100200, 0x0800, 0x);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr2.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr2.c
index 86bf674..b9f1ffd 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr2.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr2.c
@@ -76,6 +76,12 @@ nvkm_sddr2_calc(struct nvkm_ram *ram)
return -ENOSYS;
}
 
+   if (ram->next->bios.timing_ver == 0x20 ||
+   ram->next->bios.ramcfg_timing == 0xff) {
+   ODT =  (ram->mr[1] & 0x004) >> 2 |
+  (ram->mr[1] & 0x040) >> 5;
+   }
+
CL  = ramxlat(ramddr2_cl, CL);
WR  = ramxlat(ramddr2_wr, WR);
if (CL < 0 || WR < 0)
-- 
2.4.3



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 8/9] bus/hwsq: Implement VBLANK waiting heuristic

2015-09-29 Thread Roy Spliet
Avoids waiting for VBLANKS that never arrive on headless or otherwise
unconventional set-ups. Strategy taken from MEMX.

Signed-off-by: Roy Spliet 
Tested-by: Pierre Moreau 
---
 drivers/gpu/drm/nouveau/include/nvkm/subdev/bus.h |  1 +
 drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.c| 32 +++
 drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.h|  6 +
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c  |  3 +--
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramseq.h   |  1 +
 5 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bus.h 
b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bus.h
index 6a04d9c..33a057c 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bus.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bus.h
@@ -14,6 +14,7 @@ int  nvkm_hwsq_fini(struct nvkm_hwsq **, bool exec);
 void nvkm_hwsq_wr32(struct nvkm_hwsq *, u32 addr, u32 data);
 void nvkm_hwsq_setf(struct nvkm_hwsq *, u8 flag, int data);
 void nvkm_hwsq_wait(struct nvkm_hwsq *, u8 flag, u8 data);
+void nvkm_hwsq_wait_vblank(struct nvkm_hwsq *);
 void nvkm_hwsq_nsec(struct nvkm_hwsq *, u32 nsec);
 
 int nv04_bus_new(struct nvkm_device *, int, struct nvkm_bus **);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.c
index 79f1cf5..2a56689 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.c
@@ -132,6 +132,38 @@ nvkm_hwsq_wait(struct nvkm_hwsq *hwsq, u8 flag, u8 data)
 }
 
 void
+nvkm_hwsq_wait_vblank(struct nvkm_hwsq *hwsq)
+{
+   struct nvkm_subdev *subdev = hwsq->subdev;
+   struct nvkm_device *device = subdev->device;
+   u32 heads, x, y, px = 0;
+   int i, head_sync;
+
+   heads = nvkm_rd32(device, 0x610050);
+   for (i = 0; i < 2; i++) {
+   /* Heuristic: sync to head with biggest resolution */
+   if (heads & (2 << (i << 3))) {
+   x = nvkm_rd32(device, 0x610b40 + (0x540 * i));
+   y = (x & 0x) >> 16;
+   x &= 0x;
+   if ((x * y) > px) {
+   px = (x * y);
+   head_sync = i;
+   }
+   }
+   }
+
+   if (px == 0) {
+   nvkm_debug(subdev, "WAIT VBLANK !NO ACTIVE HEAD\n");
+   return;
+   }
+
+   nvkm_debug(subdev, "WAIT VBLANK HEAD%d\n", head_sync);
+   nvkm_hwsq_wait(hwsq, head_sync ? 0x3 : 0x1, 0x0);
+   nvkm_hwsq_wait(hwsq, head_sync ? 0x3 : 0x1, 0x1);
+}
+
+void
 nvkm_hwsq_nsec(struct nvkm_hwsq *hwsq, u32 nsec)
 {
u8 shift = 0, usec = nsec / 1000;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.h 
b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.h
index 8117ec5..54ec3b1 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.h
@@ -134,6 +134,12 @@ hwsq_wait(struct hwsq *ram, u8 flag, u8 data)
 }
 
 static inline void
+hwsq_wait_vblank(struct hwsq *ram)
+{
+   nvkm_hwsq_wait_vblank(ram->hwsq);
+}
+
+static inline void
 hwsq_nsec(struct hwsq *ram, u32 nsec)
 {
nvkm_hwsq_nsec(ram->hwsq, nsec);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
index 651b74a..94b340f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
@@ -308,8 +308,7 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
/* Always disable this bit during reclock */
ram_mask(hwsq, 0x100200, 0x0800, 0x);
 
-   ram_wait(hwsq, 0x01, 0x00); /* wait for !vblank */
-   ram_wait(hwsq, 0x01, 0x01); /* wait for vblank */
+   ram_wait_vblank(hwsq);
ram_wr32(hwsq, 0x611200, 0x3300);
ram_wr32(hwsq, 0x002504, 0x0001); /* block fifo */
ram_nsec(hwsq, 8000);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramseq.h 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramseq.h
index 0f1f97c..8df7306 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramseq.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramseq.h
@@ -11,5 +11,6 @@
 #define ram_mask(s,r,m,d)   hwsq_mask(&(s)->base, &(s)->r_##r, (m), (d))
 #define ram_setf(s,f,d) hwsq_setf(&(s)->base, (f), (d))
 #define ram_wait(s,f,d) hwsq_wait(&(s)->base, (f), (d))
+#define ram_wait_vblank(s)  hwsq_wait_vblank(&(s)->base)
 #define ram_nsec(s,n)   hwsq_nsec(&(s)->base, (n))
 #endif
-- 
2.4.3



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH] clk/gt215: Unbreak engine pausing for GT21x/MCP7x

2015-09-02 Thread Roy Spliet
Typo that snuck in with commit 6979c6303a4abf263753cd9d577d79f05c6e8c47

Signed-off-by: Roy Spliet 
Reported-by: Pierre Moreau 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c
index 07feae6..c233e3f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c
@@ -326,7 +326,7 @@ gt215_clk_pre(struct nvkm_clk *clk, unsigned long *flags)
return -EIO;
 
if (nvkm_msec(device, 2000,
-   u32 tmp = nvkm_rd32(device, 0x002504) & 0x003f;
+   u32 tmp = nvkm_rd32(device, 0x00251c) & 0x003f;
if (tmp == 0x003f)
break;
) < 0)
-- 
2.4.3



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] Fix reclocking regression in drm-next

2015-09-02 Thread Roy Spliet
Attached patch fixes an issue reported by Pierre Moreau, that prevents
reclocking of GT21x and MCP7x from working after "the big rewrite". Please
review and push forward for kernel 4.3.
Thanks!

Roy



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [Cover letter] Identify DLLoff for >= GF100

2015-07-26 Thread Roy Spliet
Since the previously sent RFC resulted in no comments, I take it everything
is ok. I gave it a test-spin on my NVE7, no regressions there. GDDR5 can always
be worked on later; this patch does not regress anything in that area.
As far as I'm concerned it's ready for inclusion. Happy testing,

Roy



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH] bios/rammap: Identify DLLoff for >= GF100

2015-07-26 Thread Roy Spliet
Signed-off-by: Roy Spliet 
---
 .../drm/nouveau/include/nvkm/subdev/bios/ramcfg.h  |  1 -
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c  |  2 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c |  3 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c  | 41 ++
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr3.c |  4 +--
 5 files changed, 39 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h 
b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
index 3a9abd3..dd48db7 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
@@ -78,7 +78,6 @@ struct nvbios_ramcfg {
unsigned ramcfg_11_01_04:1;
unsigned ramcfg_11_01_08:1;
unsigned ramcfg_11_01_10:1;
-   unsigned ramcfg_11_01_20:1;
unsigned ramcfg_11_01_40:1;
unsigned ramcfg_11_01_80:1;
unsigned ramcfg_11_02_03:2;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
index 5815f42..aa93f4c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
@@ -219,7 +219,7 @@ nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
p->ramcfg_11_01_04 = (nv_ro08(bios, data + 0x01) & 0x04) >> 2;
p->ramcfg_11_01_08 = (nv_ro08(bios, data + 0x01) & 0x08) >> 3;
p->ramcfg_11_01_10 = (nv_ro08(bios, data + 0x01) & 0x10) >> 4;
-   p->ramcfg_11_01_20 = (nv_ro08(bios, data + 0x01) & 0x20) >> 5;
+   p->ramcfg_DLLoff = (nv_ro08(bios, data + 0x01) & 0x20) >> 5;
p->ramcfg_11_01_40 = (nv_ro08(bios, data + 0x01) & 0x40) >> 6;
p->ramcfg_11_01_80 = (nv_ro08(bios, data + 0x01) & 0x80) >> 7;
p->ramcfg_11_02_03 = (nv_ro08(bios, data + 0x02) & 0x03) >> 0;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c
index f6f9eee..3a97225 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c
@@ -38,11 +38,12 @@ nvkm_gddr5_calc(struct nvkm_ram *ram, bool nuts)
int WL, CL, WR, at[2], dt, ds;
int rq = ram->freq < 100; /* XXX */
 
+   xd = !ram->next->bios.ramcfg_DLLoff;
+
switch (ram->next->bios.ramcfg_ver) {
case 0x11:
pd =  ram->next->bios.ramcfg_11_01_80;
lf =  ram->next->bios.ramcfg_11_01_40;
-   xd = !ram->next->bios.ramcfg_11_01_20;
vh =  ram->next->bios.ramcfg_11_02_10;
vr =  ram->next->bios.ramcfg_11_02_04;
vo =  ram->next->bios.ramcfg_11_06;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c
index 1ef15c3..d3090de 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c
@@ -673,6 +673,25 @@ gk104_ram_calc_gddr5(struct nvkm_fb *pfb, u32 freq)
  * DDR3
  
**/
 
+static void
+nvkm_sddr3_dll_reset(struct gk104_ramfuc *fuc)
+{
+   ram_nuke(fuc, mr[0]);
+   ram_mask(fuc, mr[0], 0x100, 0x100);
+   ram_mask(fuc, mr[0], 0x100, 0x000);
+}
+
+static void
+nvkm_sddr3_dll_disable(struct gk104_ramfuc *fuc)
+{
+   u32 mr1_old = ram_rd32(fuc, mr[1]);
+
+   if (!(mr1_old & 0x1)) {
+   ram_mask(fuc, mr[1], 0x1, 0x1);
+   ram_nsec(fuc, 1000);
+   }
+}
+
 static int
 gk104_ram_calc_sddr3(struct nvkm_fb *pfb, u32 freq)
 {
@@ -703,6 +722,10 @@ gk104_ram_calc_sddr3(struct nvkm_fb *pfb, u32 freq)
ram_mask(fuc, 0x10f808, 0x0400, 0x0400);
 
ram_wr32(fuc, 0x10f314, 0x0001); /* PRECHARGE */
+
+   if (next->bios.ramcfg_DLLoff)
+   nvkm_sddr3_dll_disable(fuc);
+
ram_wr32(fuc, 0x10f210, 0x); /* REFRESH_AUTO = 0 */
ram_wr32(fuc, 0x10f310, 0x0001); /* REFRESH */
ram_mask(fuc, 0x10f200, 0x8000, 0x8000);
@@ -880,17 +903,20 @@ gk104_ram_calc_sddr3(struct nvkm_fb *pfb, u32 freq)
ram_wr32(fuc, 0x10f210, 0x8000); /* REFRESH_AUTO = 1 */
ram_nsec(fuc, 1000);
 
-   ram_nuke(fuc, mr[0]);
-   ram_mask(fuc, mr[0], 0x100, 0x100);
-   ram_mask(fuc, mr[0], 0x100, 0x000);
+   if (!next->bios.ramcfg_DLLoff) {
+   ram_mask(fuc, mr[1], 0x1, 0x0);
+   nvkm_sddr3_dll_reset(fuc);
+   }
 
-   ram_mask(fuc, mr[2], 0xfff, ram->base.mr[2]);
+   ram_mask(fuc, mr[2], 0x0fff, 

[Nouveau] [RFC] bios/rammap: Identify DLLoff for >= GF100

2015-07-05 Thread Roy Spliet
---
 .../drm/nouveau/include/nvkm/subdev/bios/ramcfg.h  |  1 -
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c  |  2 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c |  3 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c  | 41 ++
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr3.c |  4 +--
 5 files changed, 39 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h 
b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
index 3a9abd3..dd48db7 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
@@ -78,7 +78,6 @@ struct nvbios_ramcfg {
unsigned ramcfg_11_01_04:1;
unsigned ramcfg_11_01_08:1;
unsigned ramcfg_11_01_10:1;
-   unsigned ramcfg_11_01_20:1;
unsigned ramcfg_11_01_40:1;
unsigned ramcfg_11_01_80:1;
unsigned ramcfg_11_02_03:2;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
index 5815f42..aa93f4c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
@@ -219,7 +219,7 @@ nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
p->ramcfg_11_01_04 = (nv_ro08(bios, data + 0x01) & 0x04) >> 2;
p->ramcfg_11_01_08 = (nv_ro08(bios, data + 0x01) & 0x08) >> 3;
p->ramcfg_11_01_10 = (nv_ro08(bios, data + 0x01) & 0x10) >> 4;
-   p->ramcfg_11_01_20 = (nv_ro08(bios, data + 0x01) & 0x20) >> 5;
+   p->ramcfg_DLLoff = (nv_ro08(bios, data + 0x01) & 0x20) >> 5;
p->ramcfg_11_01_40 = (nv_ro08(bios, data + 0x01) & 0x40) >> 6;
p->ramcfg_11_01_80 = (nv_ro08(bios, data + 0x01) & 0x80) >> 7;
p->ramcfg_11_02_03 = (nv_ro08(bios, data + 0x02) & 0x03) >> 0;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c
index f6f9eee..3a97225 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c
@@ -38,11 +38,12 @@ nvkm_gddr5_calc(struct nvkm_ram *ram, bool nuts)
int WL, CL, WR, at[2], dt, ds;
int rq = ram->freq < 100; /* XXX */
 
+   xd = !ram->next->bios.ramcfg_DLLoff;
+
switch (ram->next->bios.ramcfg_ver) {
case 0x11:
pd =  ram->next->bios.ramcfg_11_01_80;
lf =  ram->next->bios.ramcfg_11_01_40;
-   xd = !ram->next->bios.ramcfg_11_01_20;
vh =  ram->next->bios.ramcfg_11_02_10;
vr =  ram->next->bios.ramcfg_11_02_04;
vo =  ram->next->bios.ramcfg_11_06;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c
index 1ef15c3..d3090de 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c
@@ -673,6 +673,25 @@ gk104_ram_calc_gddr5(struct nvkm_fb *pfb, u32 freq)
  * DDR3
  
**/
 
+static void
+nvkm_sddr3_dll_reset(struct gk104_ramfuc *fuc)
+{
+   ram_nuke(fuc, mr[0]);
+   ram_mask(fuc, mr[0], 0x100, 0x100);
+   ram_mask(fuc, mr[0], 0x100, 0x000);
+}
+
+static void
+nvkm_sddr3_dll_disable(struct gk104_ramfuc *fuc)
+{
+   u32 mr1_old = ram_rd32(fuc, mr[1]);
+
+   if (!(mr1_old & 0x1)) {
+   ram_mask(fuc, mr[1], 0x1, 0x1);
+   ram_nsec(fuc, 1000);
+   }
+}
+
 static int
 gk104_ram_calc_sddr3(struct nvkm_fb *pfb, u32 freq)
 {
@@ -703,6 +722,10 @@ gk104_ram_calc_sddr3(struct nvkm_fb *pfb, u32 freq)
ram_mask(fuc, 0x10f808, 0x0400, 0x0400);
 
ram_wr32(fuc, 0x10f314, 0x0001); /* PRECHARGE */
+
+   if (next->bios.ramcfg_DLLoff)
+   nvkm_sddr3_dll_disable(fuc);
+
ram_wr32(fuc, 0x10f210, 0x); /* REFRESH_AUTO = 0 */
ram_wr32(fuc, 0x10f310, 0x0001); /* REFRESH */
ram_mask(fuc, 0x10f200, 0x8000, 0x8000);
@@ -880,17 +903,20 @@ gk104_ram_calc_sddr3(struct nvkm_fb *pfb, u32 freq)
ram_wr32(fuc, 0x10f210, 0x8000); /* REFRESH_AUTO = 1 */
ram_nsec(fuc, 1000);
 
-   ram_nuke(fuc, mr[0]);
-   ram_mask(fuc, mr[0], 0x100, 0x100);
-   ram_mask(fuc, mr[0], 0x100, 0x000);
+   if (!next->bios.ramcfg_DLLoff) {
+   ram_mask(fuc, mr[1], 0x1, 0x0);
+   nvkm_sddr3_dll_reset(fuc);
+   }
 
-   ram_mask(fuc, mr[2], 0xfff, ram->base.mr[2]);
+   ram_mask(fuc, mr[2], 0x0fff, ram->base.mr[2]);
+   ram_mask(fuc, mr[1], 0x, ram->base.mr[1]);
ram_wr32(fuc, mr[0], ram->base.mr[0]);
ram_nsec(fuc, 1000);
 
-   ram_nuke(fuc, mr[0]);
-   ram_mas

[Nouveau] [RFC] Fermi/Kepler identify DLLoff

2015-07-05 Thread Roy Spliet
Hello,

Attached a small patch that correctly identifies the DLLoff bit for >=GF100.
Marked RFC because I haven't seen any GDDR5 samples that *enable* the DLL. I'd
like to verify whether the DLL should be reset when enabled. Could increase
likelihood of succesfull reclock.
Ben: could you do some experiments with this bit to see if GDDR5 needs some DLL
reset logic?
Thanks, and happy reviewing!

Roy



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH v2 08/10] fb/ramnv50: GDDR3 script for NVA0

2015-05-24 Thread Roy Spliet
This looks surprisingly similar to scripts on earlier cards as well
but they don't seem to work just yet. That... and I don't have any, which
makes it a tough job to reverse engineer.

Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c | 129 ++-
 1 file changed, 104 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
index 91e9cff..66db0a4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
@@ -39,10 +39,19 @@ struct nv50_ramseq {
struct hwsq_reg r_0x004008;
struct hwsq_reg r_0x00400c;
struct hwsq_reg r_0x00c040;
+   struct hwsq_reg r_0x100200;
struct hwsq_reg r_0x100210;
+   struct hwsq_reg r_0x10021c;
struct hwsq_reg r_0x1002d0;
struct hwsq_reg r_0x1002d4;
struct hwsq_reg r_0x1002dc;
+   struct hwsq_reg r_0x10053c;
+   struct hwsq_reg r_0x1005a0;
+   struct hwsq_reg r_0x1005a4;
+   struct hwsq_reg r_0x100710;
+   struct hwsq_reg r_0x100714;
+   struct hwsq_reg r_0x100718;
+   struct hwsq_reg r_0x10071c;
struct hwsq_reg r_0x100da0;
struct hwsq_reg r_0x100e20;
struct hwsq_reg r_0x100e24;
@@ -135,7 +144,13 @@ nv50_ram_timing_calc(struct nvkm_fb *pfb, u32 *timing)
 }
 #undef T
 
-#define QFX5800NVA0 1
+static void
+nvkm_sddr2_dll_reset(struct nv50_ramseq *hwsq)
+{
+   ram_mask(hwsq, mr[0], 0x100, 0x100);
+   ram_mask(hwsq, mr[0], 0x100, 0x000);
+   ram_nsec(hwsq, 24000);
+}
 
 static int
 nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
@@ -148,7 +163,7 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
struct nvkm_ram_data *next;
u8  ver, hdr, cnt, len, strap, size;
u32 data;
-   u32 r100da0;
+   u32 r100da0, r004008, unk710, unk714, unk718, unk71c;
int N1, M1, N2, M2, P;
int ret, i;
u32 timing[9];
@@ -220,12 +235,8 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
if (ret)
return ret;
 
-   /* XXX: 750MHz seems rather arbitrary */
-   if (freq <= 75) {
-   r100da0 = 0x0010;
-   } else {
-   r100da0 = 0x;
-   }
+   /* Always disable this bit during reclock */
+   ram_mask(hwsq, 0x100200, 0x0800, 0x);
 
ram_wait(hwsq, 0x01, 0x00); /* wait for !vblank */
ram_wait(hwsq, 0x01, 0x01); /* wait for vblank */
@@ -234,6 +245,7 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
ram_nsec(hwsq, 8000);
ram_setf(hwsq, 0x10, 0x00); /* disable fb */
ram_wait(hwsq, 0x00, 0x01); /* wait for fb disabled */
+   ram_nsec(hwsq, 2000);
 
ram_wr32(hwsq, 0x1002d4, 0x0001); /* precharge */
ram_wr32(hwsq, 0x1002d0, 0x0001); /* refresh */
@@ -253,18 +265,33 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
if (ret < 0)
return ret;
 
+   /* XXX: 750MHz seems rather arbitrary */
+   if (freq <= 75) {
+   r100da0 = 0x0010;
+   r004008 = 0x9000;
+   } else {
+   r100da0 = 0x;
+   r004008 = 0x8000;
+   }
+
+   r004008 |= (mpll.bias_p << 19) | (P << 22) | (P << 16);
+
ram_mask(hwsq, 0x00c040, 0xc000c000, 0xc000);
-   ram_mask(hwsq, 0x004008, 0x0200, 0x0200);
+   /* XXX: Is rammap_00_16_40 the DLL bit we've seen in GT215? Why does
+* it have a different rammap bit from DLLoff? */
+   ram_mask(hwsq, 0x004008, 0x4200, 0x0200 |
+   next->bios.rammap_00_16_40 << 14);
ram_mask(hwsq, 0x00400c, 0x, (N1 << 8) | M1);
-   ram_mask(hwsq, 0x004008, 0x81ff, 0x8000 | (mpll.bias_p << 19) |
-(P << 22) | (P << 16));
+   ram_mask(hwsq, 0x004008, 0x91ff, r004008);
+   if (nv_device(pfb)->chipset >= 0x96)
+   ram_wr32(hwsq, 0x100da0, r100da0);
+   ram_nsec(hwsq, 64000); /*XXX*/
+   ram_nsec(hwsq, 32000); /*XXX*/
 
-   if (nv_device(pfb)->chipset == 0xa0)
-   ram_wr32(hwsq, 0x100da0, r100da0); /*XXX: here?*/
-   ram_nsec(hwsq, 96000); /*XXX*/
ram_mask(hwsq, 0x004008, 0x2200, 0x2000);
 
ram_wr32(hwsq, 0x1002dc, 0x); /* disable self-refresh */
+   ram_wr32(hwsq, 0x1002d4, 0x0001); /* disable self-refresh */
ram_wr32(hwsq, 0x100210, 0x8000); /* enable auto-refresh */
 
ram_nsec(hwsq, 12000);
@@ -275,9 +302,10 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
ram_mask(hwsq, mr[0], 0x000, 0x000);
break;
case NV_MEM_TYPE_GDDR3:
-   ram_mask(hwsq, mr[2], 0x000, 0x000);
+   ram_nuke(hwsq, mr[1]); /* force update */
+  

[Nouveau] [PATCH v2 09/10] fb/gddr3: Add a few CL and WR entries observed on GTX260

2015-05-24 Thread Roy Spliet
Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
index 8d759f8a..4465446 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
@@ -42,9 +42,9 @@ ramxlat(const struct ramxlat *xlat, int id)
 
 static const struct ramxlat
 ramgddr3_cl_lo[] = {
-   { 7, 7 }, { 8, 0 }, { 9, 1 }, { 10, 2 }, { 11, 3 },
+   { 5, 5 }, { 7, 7 }, { 8, 0 }, { 9, 1 }, { 10, 2 }, { 11, 3 }, { 12, 8 },
/* the below are mentioned in some, but not all, gddr3 docs */
-   { 12, 4 }, { 13, 5 }, { 14, 6 },
+   { 13, 9 }, { 14, 6 },
/* XXX: Per Samsung docs, are these used? They overlap with Qimonda */
/* { 4, 4 }, { 5, 5 }, { 6, 6 }, { 12, 8 }, { 13, 9 }, { 14, 10 },
 * { 15, 11 }, */
@@ -61,9 +61,9 @@ ramgddr3_cl_hi[] = {
 static const struct ramxlat
 ramgddr3_wr_lo[] = {
{ 5, 2 }, { 7, 4 }, { 8, 5 }, { 9, 6 }, { 10, 7 },
-   { 11, 0 },
+   { 11, 0 }, { 13 , 1 },
/* the below are mentioned in some, but not all, gddr3 docs */
-   { 4, 1 }, { 6, 3 }, { 12, 1 }, { 13 , 2 },
+   { 4, 1 }, { 6, 3 }, { 12, 1 },
{ -1 }
 };
 
-- 
2.1.0



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH v2 10/10] clk/nv50: Enable user reclocking for NVA0

2015-05-24 Thread Roy Spliet
Tested on a few cards. Probably works quite well for most, given they should
all be GDDR3.

Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv50.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv50.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv50.c
index 9b4ffd6..89c5d88 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv50.c
@@ -509,7 +509,8 @@ nv50_clk_ctor(struct nvkm_object *parent, struct 
nvkm_object *engine,
int ret;
 
ret = nvkm_clk_create(parent, engine, oclass, pclass->domains,
- NULL, 0, false, &priv);
+ NULL, 0, nv_device(parent)->chipset == 0xa0,
+ &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
-- 
2.1.0



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH v2 07/10] bios/ramcfg: Separate out RON pull value

2015-05-24 Thread Roy Spliet
Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h | 1 +
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c | 3 ++-
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c | 2 ++
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c| 6 --
 4 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h 
b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
index 26e233a..3a9abd3 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
@@ -38,6 +38,7 @@ struct nvbios_ramcfg {
unsigned ramcfg_hdr;
unsigned ramcfg_timing;
unsigned ramcfg_DLLoff;
+   unsigned ramcfg_RON;
union {
struct {
unsigned ramcfg_00_03_01:1;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
index 8da8b26..5815f42 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
@@ -164,12 +164,13 @@ nvbios_rammapSp_from_perf(struct nvkm_bios *bios, u32 
data, u8 size, int idx,
if (size < 11)
return NULL;
 
+   p->ramcfg_ver = 0;
p->ramcfg_timing   =  nv_ro08(bios, data + 0x01);
p->ramcfg_00_03_01 = (nv_ro08(bios, data + 0x03) & 0x01) >> 0;
p->ramcfg_00_03_02 = (nv_ro08(bios, data + 0x03) & 0x02) >> 1;
p->ramcfg_DLLoff   = (nv_ro08(bios, data + 0x03) & 0x04) >> 2;
p->ramcfg_00_03_08 = (nv_ro08(bios, data + 0x03) & 0x08) >> 3;
-   p->ramcfg_00_03_10 = (nv_ro08(bios, data + 0x03) & 0x10) >> 4;
+   p->ramcfg_RON  = (nv_ro08(bios, data + 0x03) & 0x10) >> 3;
p->ramcfg_00_04_02 = (nv_ro08(bios, data + 0x04) & 0x02) >> 1;
p->ramcfg_00_04_04 = (nv_ro08(bios, data + 0x04) & 0x04) >> 2;
p->ramcfg_00_04_20 = (nv_ro08(bios, data + 0x04) & 0x20) >> 5;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c
index 763fd29..bacd433 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c
@@ -102,6 +102,8 @@ nvbios_timingEp(struct nvkm_bios *bios, int idx,
p->timing_10_RRD   = nv_ro08(bios, data + 0x0c);
p->timing_10_13= nv_ro08(bios, data + 0x0d);
p->timing_10_ODT   = nv_ro08(bios, data + 0x0e) & 0x07;
+   if (p->ramcfg_ver >= 0x10)
+   p->ramcfg_RON = nv_ro08(bios, data + 0x0e) & 0x07;
 
p->timing_10_24  = 0xff;
p->timing_10_21  = 0;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
index e1d11f7..8d759f8a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
@@ -70,7 +70,7 @@ ramgddr3_wr_lo[] = {
 int
 nvkm_gddr3_calc(struct nvkm_ram *ram)
 {
-   int CL, WR, CWL, DLL = 0, ODT = 0, hi;
+   int CL, WR, CWL, DLL = 0, ODT = 0, RON, hi;
 
switch (ram->next->bios.timing_ver) {
case 0x10:
@@ -79,6 +79,7 @@ nvkm_gddr3_calc(struct nvkm_ram *ram)
WR  = ram->next->bios.timing_10_WR;
DLL = !ram->next->bios.ramcfg_DLLoff;
ODT = ram->next->bios.timing_10_ODT;
+   RON = ram->next->bios.ramcfg_RON;
break;
case 0x20:
CWL = (ram->next->bios.timing[1] & 0x0f80) >> 7;
@@ -89,6 +90,7 @@ nvkm_gddr3_calc(struct nvkm_ram *ram)
ODT =  (ram->mr[1] & 0x004) >> 2 |
   (ram->mr[1] & 0x040) >> 5 |
   (ram->mr[1] & 0x200) >> 7;
+   RON = !(ram->mr[1] & 0x300) >> 8;
break;
default:
return -ENOSYS;
@@ -107,7 +109,7 @@ nvkm_gddr3_calc(struct nvkm_ram *ram)
 
ram->mr[1] &= ~0x3fc;
ram->mr[1] |= (ODT & 0x03) << 2;
-   ram->mr[1] |= (ODT & 0x03) << 8;
+   ram->mr[1] |= (RON & 0x03) << 8;
ram->mr[1] |= (WR  & 0x03) << 4;
ram->mr[1] |= (WR  & 0x04) << 5;
ram->mr[1] |= !DLL << 6;
-- 
2.1.0



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH v2 05/10] fb/ramnv50: Ressurect timing code, use proper timing/rammap handlers

2015-05-23 Thread Roy Spliet
Might need some generalisation to < GT200. For those: use at your own risk!

Signed-off-by: Roy Spliet 
---
 .../drm/nouveau/include/nvkm/subdev/bios/ramcfg.h  |  16 ++
 .../drm/nouveau/include/nvkm/subdev/bios/rammap.h  |   2 +
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c  |  29 
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c   | 168 +
 4 files changed, 182 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h 
b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
index c6fb6aa..f09b6bf 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
@@ -35,6 +35,22 @@ struct nvbios_ramcfg {
unsigned ramcfg_DLLoff;
union {
struct {
+   unsigned ramcfg_00_03_01:1;
+   unsigned ramcfg_00_03_02:1;
+   unsigned ramcfg_00_03_08:1;
+   unsigned ramcfg_00_03_10:1;
+   unsigned ramcfg_00_04_02:1;
+   unsigned ramcfg_00_04_04:1;
+   unsigned ramcfg_00_04_20:1;
+   unsigned ramcfg_00_05:8;
+   unsigned ramcfg_00_06:8;
+   unsigned ramcfg_00_07:8;
+   unsigned ramcfg_00_08:8;
+   unsigned ramcfg_00_09:8;
+   unsigned ramcfg_00_0a_0f:4;
+   unsigned ramcfg_00_0a_f0:4;
+   };
+   struct {
unsigned ramcfg_10_02_01:1;
unsigned ramcfg_10_02_02:1;
unsigned ramcfg_10_02_04:1;
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h 
b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h
index 609a905..2044fc9 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h
@@ -15,6 +15,8 @@ u32 nvbios_rammapEm(struct nvkm_bios *, u16 mhz,
 u32 nvbios_rammapSe(struct nvkm_bios *, u32 data,
u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
u8 *ver, u8 *hdr);
+u32 nvbios_rammapSp_from_perf(struct nvkm_bios *bios, u32 data, u8 size, int 
idx,
+   struct nvbios_ramcfg *p);
 u32 nvbios_rammapSp(struct nvkm_bios *, u32 data,
u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
u8 *ver, u8 *hdr, struct nvbios_ramcfg *);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
index a688d3b..4ec376a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
@@ -141,6 +141,35 @@ nvbios_rammapSe(struct nvkm_bios *bios, u32 data,
 }
 
 u32
+nvbios_rammapSp_from_perf(struct nvkm_bios *bios, u32 data, u8 size, int idx,
+   struct nvbios_ramcfg *p)
+{
+   data += (idx * size);
+
+   if (size < 11)
+   return NULL;
+
+   p->ramcfg_timing   =  nv_ro08(bios, data + 0x01);
+   p->ramcfg_00_03_01 = (nv_ro08(bios, data + 0x03) & 0x01) >> 0;
+   p->ramcfg_00_03_02 = (nv_ro08(bios, data + 0x03) & 0x02) >> 1;
+   p->ramcfg_DLLoff   = (nv_ro08(bios, data + 0x03) & 0x04) >> 2;
+   p->ramcfg_00_03_08 = (nv_ro08(bios, data + 0x03) & 0x08) >> 3;
+   p->ramcfg_00_03_10 = (nv_ro08(bios, data + 0x03) & 0x10) >> 4;
+   p->ramcfg_00_04_02 = (nv_ro08(bios, data + 0x04) & 0x02) >> 1;
+   p->ramcfg_00_04_04 = (nv_ro08(bios, data + 0x04) & 0x04) >> 2;
+   p->ramcfg_00_04_20 = (nv_ro08(bios, data + 0x04) & 0x20) >> 5;
+   p->ramcfg_00_05= (nv_ro08(bios, data + 0x05) & 0xff) >> 0;
+   p->ramcfg_00_06= (nv_ro08(bios, data + 0x06) & 0xff) >> 0;
+   p->ramcfg_00_07= (nv_ro08(bios, data + 0x07) & 0xff) >> 0;
+   p->ramcfg_00_08= (nv_ro08(bios, data + 0x08) & 0xff) >> 0;
+   p->ramcfg_00_09= (nv_ro08(bios, data + 0x09) & 0xff) >> 0;
+   p->ramcfg_00_0a_0f = (nv_ro08(bios, data + 0x0a) & 0x0f) >> 0;
+   p->ramcfg_00_0a_f0 = (nv_ro08(bios, data + 0x0a) & 0xf0) >> 4;
+
+   return data;
+}
+
+u32
 nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
u8 *ver, u8 *hdr, struct nvbios_ramcfg *p)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
index 67715c6..37ccc4d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -55,6 +56

[Nouveau] [PATCH v2] Add support for NVA0

2015-05-23 Thread Roy Spliet
V2:
- Slightly clarify the conditional timings in nv50_ram_timing_calc()
- now rated U, approved for general audiences



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH v2 03/10] fb/ramnv50: Make 0x100da0 per-partition

2015-05-23 Thread Roy Spliet
Like on GT215

Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c | 20 +---
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
index d2c81dd..67715c6 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
@@ -42,7 +42,7 @@ struct nv50_ramseq {
struct hwsq_reg r_0x1002d0;
struct hwsq_reg r_0x1002d4;
struct hwsq_reg r_0x1002dc;
-   struct hwsq_reg r_0x100da0[8];
+   struct hwsq_reg r_0x100da0;
struct hwsq_reg r_0x100e20;
struct hwsq_reg r_0x100e24;
struct hwsq_reg r_0x611200;
@@ -70,6 +70,7 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
u8  size;
} ramcfg, timing;
u8  ver, hdr, cnt, len, strap;
+   u32 r100da0;
int N1, M1, N2, M2, P;
int ret, i;
 
@@ -109,6 +110,13 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
timing.data = 0;
}
 
+   /* XXX: 750MHz seems rather arbitrary */
+   if (freq <= 75) {
+   r100da0 = 0x0010;
+   } else {
+   r100da0 = 0x;
+   }
+
ret = ram_init(hwsq, nv_subdev(pfb));
if (ret)
return ret;
@@ -144,10 +152,9 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
ram_mask(hwsq, 0x00400c, 0x, (N1 << 8) | M1);
ram_mask(hwsq, 0x004008, 0x81ff, 0x8000 | (mpll.bias_p << 19) |
 (P << 22) | (P << 16));
-#if QFX5800NVA0
-   for (i = 0; i < 8; i++)
-   ram_mask(hwsq, 0x100da0[i], 0x, 0x); /*XXX*/
-#endif
+
+   if (nv_device(pfb)->chipset == 0xa0)
+   ram_wr32(hwsq, 0x100da0, r100da0); /*XXX: here?*/
ram_nsec(hwsq, 96000); /*XXX*/
ram_mask(hwsq, 0x004008, 0x2200, 0x2000);
 
@@ -430,8 +437,7 @@ nv50_ram_ctor(struct nvkm_object *parent, struct 
nvkm_object *engine,
ram->hwsq.r_0x1002d0 = hwsq_reg(0x1002d0);
ram->hwsq.r_0x1002d4 = hwsq_reg(0x1002d4);
ram->hwsq.r_0x1002dc = hwsq_reg(0x1002dc);
-   for (i = 0; i < 8; i++)
-   ram->hwsq.r_0x100da0[i] = hwsq_reg(0x100da0 + (i * 0x04));
+   ram->hwsq.r_0x100da0 = hwsq_stride(0x100da0, 4, ram->base.part_mask);
ram->hwsq.r_0x100e20 = hwsq_reg(0x100e20);
ram->hwsq.r_0x100e24 = hwsq_reg(0x100e24);
ram->hwsq.r_0x611200 = hwsq_reg(0x611200);
-- 
2.1.0



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH v2 01/10] clk/gt215: u32->s32 for difference in req. and set clock

2015-05-23 Thread Roy Spliet
This difference can of course be negative too...

Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c
index 822d32a..065e9f5 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c
@@ -180,7 +180,8 @@ gt215_clk_info(struct nvkm_clk *clock, int clk, u32 khz,
   struct gt215_clk_info *info)
 {
struct gt215_clk_priv *priv = (void *)clock;
-   u32 oclk, sclk, sdiv, diff;
+   u32 oclk, sclk, sdiv;
+   s32 diff;
 
info->clk = 0;
 
-- 
2.1.0



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH v2 04/10] fb/ramgt215: No need to cuss like that

2015-05-23 Thread Roy Spliet
Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
index 47d53ed..bc36a4f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
@@ -579,7 +579,7 @@ gt215_ram_calc(struct nvkm_fb *pfb, u32 freq)
if (ret)
return ret;
 
-   /* XXX: where the fuck does 750MHz come from? */
+   /* XXX: 750MHz seems rather arbitrary */
if (freq <= 75) {
r004018 = 0x1000;
r100760 = 0x;
-- 
2.1.0



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH v2 06/10] bios/rammap: Parse perf mode as if it's a rammap entry

2015-05-23 Thread Roy Spliet
Some of the bits in there are similar to the bits in the gt215 rammap.

Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h |  5 +
 drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h |  2 ++
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c | 15 +++
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c  |  2 ++
 4 files changed, 24 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h 
b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
index f09b6bf..26e233a 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
@@ -7,6 +7,11 @@ struct nvbios_ramcfg {
unsigned rammap_max;
union {
struct {
+   unsigned rammap_00_16_20:1;
+   unsigned rammap_00_16_40:1;
+   unsigned rammap_00_17_02:1;
+   };
+   struct {
unsigned rammap_10_04_02:1;
unsigned rammap_10_04_08:1;
};
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h 
b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h
index 2044fc9..8d8ee13 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h
@@ -7,6 +7,8 @@ u32 nvbios_rammapTe(struct nvkm_bios *, u8 *ver, u8 *hdr,
 
 u32 nvbios_rammapEe(struct nvkm_bios *, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u32 nvbios_rammapEp_from_perf(struct nvkm_bios *bios, u32 data, u8 size,
+   struct nvbios_ramcfg *p);
 u32 nvbios_rammapEp(struct nvkm_bios *, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ramcfg *);
 u32 nvbios_rammapEm(struct nvkm_bios *, u16 mhz,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
index 4ec376a..8da8b26 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
@@ -72,6 +72,21 @@ nvbios_rammapEe(struct nvkm_bios *bios, int idx,
return 0x;
 }
 
+/* Pretend a performance mode is also a rammap entry, helps coalesce entries
+ * later on */
+u32
+nvbios_rammapEp_from_perf(struct nvkm_bios *bios, u32 data, u8 size,
+   struct nvbios_ramcfg *p)
+{
+   memset(p, 0x00, sizeof(*p));
+
+   p->rammap_00_16_20 = (nv_ro08(bios, data + 0x16) & 0x20) >> 5;
+   p->rammap_00_16_40 = (nv_ro08(bios, data + 0x16) & 0x40) >> 6;
+   p->rammap_00_17_02 = (nv_ro08(bios, data + 0x17) & 0x02) >> 1;
+
+   return data;
+}
+
 u32
 nvbios_rammapEp(struct nvkm_bios *bios, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ramcfg *p)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
index 37ccc4d..91e9cff 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
@@ -169,6 +169,8 @@ nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
}
} while (perfE.memory < freq);
 
+   nvbios_rammapEp_from_perf(bios, data, hdr, &next->bios);
+
/* locate specific data set for the attached memory */
strap = nvbios_ramcfg_index(nv_subdev(pfb));
if (strap >= cnt) {
-- 
2.1.0



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH v2 02/10] bios/rammap: Pull DLLoff bit out of version 0x10 struct

2015-05-23 Thread Roy Spliet
In preparation of NV50 reclocking, where there is no version

Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h | 2 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c | 2 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c| 2 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c | 6 +++---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr2.c| 2 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr3.c| 2 +-
 6 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h 
b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
index 4204267..c6fb6aa 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
@@ -32,6 +32,7 @@ struct nvbios_ramcfg {
unsigned ramcfg_ver;
unsigned ramcfg_hdr;
unsigned ramcfg_timing;
+   unsigned ramcfg_DLLoff;
union {
struct {
unsigned ramcfg_10_02_01:1;
@@ -40,7 +41,6 @@ struct nvbios_ramcfg {
unsigned ramcfg_10_02_08:1;
unsigned ramcfg_10_02_10:1;
unsigned ramcfg_10_02_20:1;
-   unsigned ramcfg_10_DLLoff:1;
unsigned ramcfg_10_03_0f:4;
unsigned ramcfg_10_04_01:1;
unsigned ramcfg_10_05:8;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
index 8b17bb4..a688d3b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
@@ -157,7 +157,7 @@ nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
p->ramcfg_10_02_08 = (nv_ro08(bios, data + 0x02) & 0x08) >> 3;
p->ramcfg_10_02_10 = (nv_ro08(bios, data + 0x02) & 0x10) >> 4;
p->ramcfg_10_02_20 = (nv_ro08(bios, data + 0x02) & 0x20) >> 5;
-   p->ramcfg_10_DLLoff = (nv_ro08(bios, data + 0x02) & 0x40) >> 6;
+   p->ramcfg_DLLoff   = (nv_ro08(bios, data + 0x02) & 0x40) >> 6;
p->ramcfg_10_03_0f = (nv_ro08(bios, data + 0x03) & 0x0f) >> 0;
p->ramcfg_10_04_01 = (nv_ro08(bios, data + 0x04) & 0x01) >> 0;
p->ramcfg_10_05= (nv_ro08(bios, data + 0x05) & 0xff) >> 0;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
index 15b462a..e1d11f7 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
@@ -77,7 +77,7 @@ nvkm_gddr3_calc(struct nvkm_ram *ram)
CWL = ram->next->bios.timing_10_CWL;
CL  = ram->next->bios.timing_10_CL;
WR  = ram->next->bios.timing_10_WR;
-   DLL = !ram->next->bios.ramcfg_10_DLLoff;
+   DLL = !ram->next->bios.ramcfg_DLLoff;
ODT = ram->next->bios.timing_10_ODT;
break;
case 0x20:
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
index 2417640..47d53ed 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
@@ -590,7 +590,7 @@ gt215_ram_calc(struct nvkm_fb *pfb, u32 freq)
r100da0 = 0x;
}
 
-   if (!next->bios.ramcfg_10_DLLoff)
+   if (!next->bios.ramcfg_DLLoff)
r004018 |= 0x4000;
 
/* pll2pll requires to switch to a safe clock first */
@@ -630,7 +630,7 @@ gt215_ram_calc(struct nvkm_fb *pfb, u32 freq)
}
 
/* If we're disabling the DLL, do it now */
-   switch (next->bios.ramcfg_10_DLLoff * ram->base.type) {
+   switch (next->bios.ramcfg_DLLoff * ram->base.type) {
case NV_MEM_TYPE_DDR3:
nvkm_sddr3_dll_disable(fuc, ram->base.mr);
break;
@@ -810,7 +810,7 @@ gt215_ram_calc(struct nvkm_fb *pfb, u32 freq)
gt215_ram_fbvref(fuc, 1);
 
/* Reset DLL */
-   if (!next->bios.ramcfg_10_DLLoff)
+   if (!next->bios.ramcfg_DLLoff)
nvkm_sddr2_dll_reset(fuc);
 
if (ram->base.type == NV_MEM_TYPE_GDDR3) {
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr2.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr2.c
index afab42d..86bf674 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr2.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr2.c
@@ -65,7 +65,7 @@ nvkm_sddr2_calc(struct nvkm_ram *ram)
case 0x10:
CL  = ram->next->bios.timing_10_CL;
WR  = ram->next->bios.timing_10_WR;
-   DLL = !ram-

Re: [Nouveau] [PATCH 4/9] nvkm/fb/ramnv50: Ressurect timing code, use proper timing/rammap handlers

2015-05-23 Thread Roy Spliet
Hello Tobias,

Reply inline.

--- original message ---
From: Tobias Klausmann 
Date: 01:00:17 23-05-2015
To: Roy Spliet , nouveau@lists.freedesktop.org
Subject: Re: [Nouveau] [PATCH 4/9] nvkm/fb/ramnv50: Ressurect timing code, use  
proper timing/rammap handlers

> On 23.05.2015 00:33, Roy Spliet wrote:
> > Might need some generalisation to < GT200. For those: use at your
> own risk!
> >
> > Signed-off-by: Roy Spliet 
> > ---
> >   .../drm/nouveau/include/nvkm/subdev/bios/ramcfg.h  |  16 ++
> >   .../drm/nouveau/include/nvkm/subdev/bios/rammap.h  |   2 +
> >   drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c  |  29 
> >   drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c   | 167 
> > +
> 
> >   4 files changed, 181 insertions(+), 33 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
> b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
> > index c6fb6aa..f09b6bf 100644
[...]
> > +   timing[0] = (T(RP) << 24 | T(RAS) << 16 | T(RFC) <<
> 8 | T(RC));
> > +   timing[1] = (T(WR) + 1 + T(CWL)) << 24 |
> > +   max_t(u8, T(18), 1) << 16 |
> > +   (T(WTR) + 1 + T(CWL)) << 8 |
> > +   (3 + T(CL) - T(CWL));
> > +   timing[2] = (T(CWL) - 1) << 24 |
> > +   (T(RRD) << 16) |
> > +   (T(RCDWR) << 8) |
> > +   T(RCDRD);
> > +   timing[3] = (unkt3b - 2 + T(CL)) << 24 |
> > +   unkt3b << 16 |
> > +   (T(CL) - 1) << 8 |
> > +   (T(CL) - 1);
> > +   timing[4] = (cur4 & 0x) |
> > +   T(13) << 8 |
> > +   T(13);
> > +   timing[5] = T(RFC) << 24 |
> > +   max_t(u8, T(RCDRD), T(RCDWR)) << 16 |
> > +   T(RP);
> > +   /* Timing 6 is already done above */
> > +   timing[7] = (cur7 & 0xff00) | (T(CL) - 1) << 16;
> > +   timing[8] = (cur8 & 0xff00);
> > +
> > +   /* XXX: P.version == 1 only has DDR2 and GDDR3? */
> 
> mh can you state both (DDR2/GDDR3) here and bail out on default as well?

This type of error checking is way earlier, in nv50_ram_ctor(). Hence, this 
code will
currently only be executed with GDDR3 cards, I just didn't feel it's justified 
to remove
DDR2 conditional code that I investigated years ago, otherwise it would have 
been even
slightly cleaner.

Roy


___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 8/9] nvkm/fb/gddr3: Add a few CL and WR entries observed on GTX260

2015-05-22 Thread Roy Spliet
Signed-off-by: Roy Spliet 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
index 8d759f8a..4465446 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
@@ -42,9 +42,9 @@ ramxlat(const struct ramxlat *xlat, int id)
 
 static const struct ramxlat
 ramgddr3_cl_lo[] = {
-   { 7, 7 }, { 8, 0 }, { 9, 1 }, { 10, 2 }, { 11, 3 },
+   { 5, 5 }, { 7, 7 }, { 8, 0 }, { 9, 1 }, { 10, 2 }, { 11, 3 }, { 12, 8 },
/* the below are mentioned in some, but not all, gddr3 docs */
-   { 12, 4 }, { 13, 5 }, { 14, 6 },
+   { 13, 9 }, { 14, 6 },
/* XXX: Per Samsung docs, are these used? They overlap with Qimonda */
/* { 4, 4 }, { 5, 5 }, { 6, 6 }, { 12, 8 }, { 13, 9 }, { 14, 10 },
 * { 15, 11 }, */
@@ -61,9 +61,9 @@ ramgddr3_cl_hi[] = {
 static const struct ramxlat
 ramgddr3_wr_lo[] = {
{ 5, 2 }, { 7, 4 }, { 8, 5 }, { 9, 6 }, { 10, 7 },
-   { 11, 0 },
+   { 11, 0 }, { 13 , 1 },
/* the below are mentioned in some, but not all, gddr3 docs */
-   { 4, 1 }, { 6, 3 }, { 12, 1 }, { 13 , 2 },
+   { 4, 1 }, { 6, 3 }, { 12, 1 },
{ -1 }
 };
 
-- 
2.1.0



___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 4/9] nvkm/fb/ramnv50: Ressurect timing code, use proper timing/rammap handlers

2015-05-22 Thread Roy Spliet
Might need some generalisation to < GT200. For those: use at your own risk!

Signed-off-by: Roy Spliet 
---
 .../drm/nouveau/include/nvkm/subdev/bios/ramcfg.h  |  16 ++
 .../drm/nouveau/include/nvkm/subdev/bios/rammap.h  |   2 +
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c  |  29 
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c   | 167 +
 4 files changed, 181 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h 
b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
index c6fb6aa..f09b6bf 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
@@ -35,6 +35,22 @@ struct nvbios_ramcfg {
unsigned ramcfg_DLLoff;
union {
struct {
+   unsigned ramcfg_00_03_01:1;
+   unsigned ramcfg_00_03_02:1;
+   unsigned ramcfg_00_03_08:1;
+   unsigned ramcfg_00_03_10:1;
+   unsigned ramcfg_00_04_02:1;
+   unsigned ramcfg_00_04_04:1;
+   unsigned ramcfg_00_04_20:1;
+   unsigned ramcfg_00_05:8;
+   unsigned ramcfg_00_06:8;
+   unsigned ramcfg_00_07:8;
+   unsigned ramcfg_00_08:8;
+   unsigned ramcfg_00_09:8;
+   unsigned ramcfg_00_0a_0f:4;
+   unsigned ramcfg_00_0a_f0:4;
+   };
+   struct {
unsigned ramcfg_10_02_01:1;
unsigned ramcfg_10_02_02:1;
unsigned ramcfg_10_02_04:1;
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h 
b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h
index 609a905..2044fc9 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h
@@ -15,6 +15,8 @@ u32 nvbios_rammapEm(struct nvkm_bios *, u16 mhz,
 u32 nvbios_rammapSe(struct nvkm_bios *, u32 data,
u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
u8 *ver, u8 *hdr);
+u32 nvbios_rammapSp_from_perf(struct nvkm_bios *bios, u32 data, u8 size, int 
idx,
+   struct nvbios_ramcfg *p);
 u32 nvbios_rammapSp(struct nvkm_bios *, u32 data,
u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
u8 *ver, u8 *hdr, struct nvbios_ramcfg *);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
index a688d3b..4ec376a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
@@ -141,6 +141,35 @@ nvbios_rammapSe(struct nvkm_bios *bios, u32 data,
 }
 
 u32
+nvbios_rammapSp_from_perf(struct nvkm_bios *bios, u32 data, u8 size, int idx,
+   struct nvbios_ramcfg *p)
+{
+   data += (idx * size);
+
+   if (size < 11)
+   return NULL;
+
+   p->ramcfg_timing   =  nv_ro08(bios, data + 0x01);
+   p->ramcfg_00_03_01 = (nv_ro08(bios, data + 0x03) & 0x01) >> 0;
+   p->ramcfg_00_03_02 = (nv_ro08(bios, data + 0x03) & 0x02) >> 1;
+   p->ramcfg_DLLoff   = (nv_ro08(bios, data + 0x03) & 0x04) >> 2;
+   p->ramcfg_00_03_08 = (nv_ro08(bios, data + 0x03) & 0x08) >> 3;
+   p->ramcfg_00_03_10 = (nv_ro08(bios, data + 0x03) & 0x10) >> 4;
+   p->ramcfg_00_04_02 = (nv_ro08(bios, data + 0x04) & 0x02) >> 1;
+   p->ramcfg_00_04_04 = (nv_ro08(bios, data + 0x04) & 0x04) >> 2;
+   p->ramcfg_00_04_20 = (nv_ro08(bios, data + 0x04) & 0x20) >> 5;
+   p->ramcfg_00_05= (nv_ro08(bios, data + 0x05) & 0xff) >> 0;
+   p->ramcfg_00_06= (nv_ro08(bios, data + 0x06) & 0xff) >> 0;
+   p->ramcfg_00_07= (nv_ro08(bios, data + 0x07) & 0xff) >> 0;
+   p->ramcfg_00_08= (nv_ro08(bios, data + 0x08) & 0xff) >> 0;
+   p->ramcfg_00_09= (nv_ro08(bios, data + 0x09) & 0xff) >> 0;
+   p->ramcfg_00_0a_0f = (nv_ro08(bios, data + 0x0a) & 0x0f) >> 0;
+   p->ramcfg_00_0a_f0 = (nv_ro08(bios, data + 0x0a) & 0xf0) >> 4;
+
+   return data;
+}
+
+u32
 nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
u8 *ver, u8 *hdr, struct nvbios_ramcfg *p)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
index a96e512..51f93a0 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -55,6 +56

  1   2   3   >