Bug 66176

Summary: nouveau.perflvl kernel parameter doesn't work
Product: xorg Reporter: Mr-4 <mr.dash.four>
Component: Driver/nouveauAssignee: Nouveau Project <nouveau>
Status: RESOLVED INVALID QA Contact: Xorg Project Team <xorg-team>
Severity: normal    
Priority: medium CC: sergio.pasra
Version: unspecified   
Hardware: Other   
OS: All   
Whiteboard:
i915 platform: i915 features:

Description Mr-4 2013-06-25 22:17:34 UTC
When I specify the following kernel parameter - "nouveau.perflvl=0,0" (that is in addition to "nouveau.perflvl_wr=7777"), I get the following error during boot up (and afterwards, when I try to make this change manually):

kernel: [drm] Initialized drm 1.1.0 20060810
kernel: nouveau  [  DEVICE][0000:01:00.0] BOOT0  : 0x049200a2
kernel: nouveau  [  DEVICE][0000:01:00.0] Chipset: G71 (NV49)
kernel: nouveau  [  DEVICE][0000:01:00.0] Family : NV40
kernel: nouveau  [   VBIOS][0000:01:00.0] checking PRAMIN for image...
kernel: nouveau  [   VBIOS][0000:01:00.0] ... checksum invalid
kernel: nouveau  [   VBIOS][0000:01:00.0] checking PROM for image...
kernel: nouveau  [   VBIOS][0000:01:00.0] ... appears to be valid
kernel: nouveau  [   VBIOS][0000:01:00.0] using image from PROM
kernel: nouveau  [   VBIOS][0000:01:00.0] BIT signature found
kernel: nouveau  [   VBIOS][0000:01:00.0] version 05.71.22.21.0a
kernel: nouveau  [     PFB][0000:01:00.0] RAM type: GDDR3
kernel: nouveau  [     PFB][0000:01:00.0] RAM size: 256 MiB
kernel: nouveau  [     PFB][0000:01:00.0]    ZCOMP: 294912 tags
kernel: nouveau  [  PTHERM][0000:01:00.0] FAN control: PWM
kernel: nouveau  [  PTHERM][0000:01:00.0] fan management: disabled
kernel: nouveau  [  PTHERM][0000:01:00.0] internal sensor: yes
kernel: nouveau  [  PTHERM][0000:01:00.0] programmed thresholds [ 90(3), 95(3), 115(2), 135(5) ]
kernel: agpgart-via 0000:00:00.0: AGP 3.5 bridge
kernel: agpgart: modprobe tried to set rate=x12. Setting to AGP3 x8 mode.
kernel: agpgart-via 0000:00:00.0: putting AGP V3 device into 8x mode
kernel: nouveau 0000:01:00.0: putting AGP V3 device into 8x mode
kernel: [TTM] Zone  kernel: Available graphics memory: 1026356 kiB
kernel: [TTM] Initializing pool allocator
kernel: [TTM] Initializing DMA pool allocator
kernel: nouveau  [     DRM] VRAM: 251 MiB
kernel: nouveau  [     DRM] GART: 256 MiB
kernel: nouveau  [     DRM] TMDS table version 1.1
kernel: nouveau W[     DRM] TMDS table script pointers not stubbed
kernel: nouveau  [     DRM] DCB version 3.0
kernel: nouveau  [     DRM] DCB outp 00: 04011310 00000028
kernel: nouveau  [     DRM] DCB outp 01: 0c011312 00000000
kernel: nouveau  [     DRM] DCB outp 02: 01000300 00000028
kernel: nouveau  [     DRM] DCB outp 03: 020223f1 00c0c083
kernel: nouveau  [     DRM] DCB conn 00: 0000
kernel: nouveau  [     DRM] DCB conn 01: 2130
kernel: nouveau  [     DRM] DCB conn 02: 0210
kernel: nouveau  [     DRM] DCB conn 03: 0211
kernel: nouveau  [     DRM] DCB conn 04: 0213
kernel: nouveau  [     DRM] Saving VGA fonts
kernel: [drm] Supports vblank timestamp caching Rev 1 (10.10.2010).
kernel: [drm] No driver support for vblank timestamp query.
kernel: nouveau  [     DRM] 0xD3FB: Parsing digital output script table
kernel: nouveau  [     DRM] 4 available performance level(s)
kernel: nouveau  [     DRM] 0: core 275MHz shader 275MHz memory 600MHz voltage 1050mV fanspeed 40%
kernel: nouveau  [     DRM] 1: core 400MHz shader 400MHz memory 625MHz voltage 1100mV fanspeed 70%
kernel: nouveau  [     DRM] 2: core 440MHz shader 440MHz memory 650MHz voltage 1100mV fanspeed 79%
kernel: nouveau  [     DRM] 3: core 487MHz shader 487MHz memory 695MHz voltage 1200mV fanspeed 100%
kernel: nouveau  [     DRM] c: core 275MHz shader 275MHz memory 600MHz voltage 1050mV fanspeed 100%
kernel: nouveau  [     DRM] setting performance level: 0
kernel: nouveau E[     DRM] fanspeed set failed: -22
kernel: nouveau  [     DRM] > reclocking failed: -34
kernel: 
kernel: nouveau  [     DRM] > reclocking took 83072ns
kernel: 
kernel: nouveau  [     DRM] MM: using M2MF for buffer copies
kernel: nouveau  [     DRM] Setting dpms mode 3 on TV encoder (output 3)
kernel: nouveau  [     DRM] allocated 1600x1200 fb: 0x9000, bo ffff8800375e6800
kernel: fbcon: nouveaufb (fb0) is primary device
kernel: nouveau  [     DRM] 0xD3FB: Parsing digital output script table
kernel: Console: switching to colour frame buffer device 200x75
kernel: nouveau 0000:01:00.0: fb0: nouveaufb frame buffer device
kernel: nouveau 0000:01:00.0: registered panic notifier
kernel: [drm] Initialized nouveau 1.1.0 20120801 for 0000:01:00.0 on minor 0

When I try to do this from the command line with "echo 0,0 > /sys/class/hwmon/hwmon0/device/performance_level" I get the exact same error:

kernel: nouveau  [     DRM] setting performance level: 0
kernel: nouveau E[     DRM] fanspeed set failed: -22
kernel: nouveau  [     DRM] > reclocking failed: -34
kernel: 
kernel: nouveau  [     DRM] > reclocking took 25088ns
kernel: 

The kernel in use is 3.9.6 with the stock-supplied nouveau driver.
Comment 1 Roy 2013-06-25 23:38:14 UTC
I'm sorry, but unfortunately reclocking is not implemented for this family of cards (NV4x) in nouveau. None of the developers has such a board capable of reclocking. I have marked this bug NEEDINFO because... well, we need a lot more info about the internals of this card to be able to implement reclocking. Given the amount of users actually still using NV49s (and the complete lack of developer manpower on reclocking) it will probably end up being a very-low-priority task though.
Comment 2 Mr-4 2013-06-26 14:03:46 UTC
I am willing to give you a hand in the development and/or testing, if needed.

I know for a fact that re-clocking is possible on this card - I do that (quite regularly) on Windows and if I remember correctly I've also done this "manually" using the pathscale tools.
Comment 3 Emil Velikov 2013-06-26 15:37:28 UTC
(In reply to comment #2)
> I am willing to give you a hand in the development and/or testing, if needed.
Glad to hear, there are a few notes further down that you can start with

> 
> I know for a fact that re-clocking is possible on this card - I do that
> (quite regularly) on Windows and if I remember correctly I've also done this
> "manually" using the pathscale tools.
Afaik Windows is another kettle of fish, although if it worked previously that's a good starting point

On the other from you can work from the current state and nitpick until it works

* The fanspeed set fails as the mode is not NOUVEAU_THERM_CTRL_MANUAL
Annoying but not crucial for the re-clocking to complete. Note I'm not entirely sure where it should be set

* pclk->pll_calc seems to return 0, causing nv40_calc_pll() to throw ERANGE
* Some of the functions called within nouveau_mem_timing_calc() may need tweaking depending on now well we generate the appropriate memory timings

Happy hacking :)

P.S.
Only one zero is required to change the perflvl - "0" rather than "0,0"
Comment 4 Mr-4 2013-06-26 23:04:47 UTC
(In reply to comment #3)
> * The fanspeed set fails as the mode is not NOUVEAU_THERM_CTRL_MANUAL
> Annoying but not crucial for the re-clocking to complete. Note I'm not
> entirely sure where it should be set
So, the logical solution to this particular problem would be for that mode to be *forced* to MANUAL, regardless of its previous state (which I suspect is NONE) and then try and set the fan speed.

> * pclk->pll_calc seems to return 0, causing nv40_calc_pll() to throw ERANGE
> * Some of the functions called within nouveau_mem_timing_calc() may need
> tweaking depending on now well we generate the appropriate memory timings
You've lost me! I am no expert in Nouveau development, although I am a (willing) developer, so you need to explain the above a little bit.

> P.S.
> Only one zero is required to change the perflvl - "0" rather than "0,0"
Well, by looking at the code, the performance level consists of 2 parts - AC (power) and DC (battery) separated by a comma (","), so I used "0,0" for the sake of completeness.
Comment 5 Emil Velikov 2013-06-27 12:58:15 UTC
(In reply to comment #4)
...
> to be *forced* to MANUAL, regardless of its previous state (which I suspect
> is NONE) and then try and set the fan speed.

I would call it "set", rather than "forced"

In the second part you'll need a "reference point" - which can be one of
* The kernel and/or "...I've also done this "manually" using the pathscale tools"
* Mmio dump of the blob reclocking the card

Initially I would recommend the former

> 
> > * pclk->pll_calc seems to return 0, causing nv40_calc_pll() to throw ERANGE

Confirm if the function nv40_calc_pll() is the one throwing ERANGE. Then dwell into the function, and analyse any differences with your "reff point".  There may be a typo/inverted logic, as this code moved around in nouveau quite a few times

> > * Some of the functions called within nouveau_mem_timing_calc() may need
> > tweaking depending on now well we generate the appropriate memory timings

nouveau_mem_timing_calc()
* parses the memory timing table stored in vbios - nouveau_perf_timing()
* generates the appropriate values based on the card generation - nv**_mem_timing_calc()
* and the memory type - nouveau_mem_*ddr*()
* On newer cards (iirc nvc0+) it maps the timings with memory frequency range. On previous generations the timings are related to the performance level rather than the memory frequency (range)

> 
> > P.S.
> > Only one zero is required to change the perflvl - "0" rather than "0,0"
> Well, by looking at the code, the performance level consists of 2 parts - AC
> (power) and DC (battery) separated by a comma (","), so I used "0,0" for the
> sake of completeness.

You got me there, I have no recollection when AC/DC got introduced ^_^
Comment 6 Emil Velikov 2013-06-27 13:04:53 UTC
Although that seems too much as a start. Thus it would be nice to get the non-memory engine(s) reclock first and then deal with memory/timings/etc

This can be done by forcing current code to ignore the memory clock stored in vbios, i.e.

diff --git a/drm/nv40_pm.c b/drm/nv40_pm.c
index 3af5bcd..0be61db 100644
--- a/drm/nv40_pm.c
+++ b/drm/nv40_pm.c
@@ -191,7 +191,7 @@ nv40_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
 	}
 
 	/* memory clock */
-	if (!perflvl->memory) {
+	if (1) {
 		info->mpll_ctrl = 0x00000000;
 		goto out;
 	}
Comment 7 Ilia Mirkin 2013-08-21 06:10:50 UTC
Note that a NV40 reclocking fix just went into the nouveau/linux-2.6 tree: http://cgit.freedesktop.org/nouveau/linux-2.6/commit/?id=dde3164f85035787ce7c63b791ce3c565ff3e3ff

Can you re-test with this fix in place?
Comment 8 Ilia Mirkin 2013-09-21 19:01:49 UTC
No response to re-test request in a month. Closing as invalid.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.