Re: [Nouveau] [TEST REQUEST] NV50/NV8x/NV9x/NVAx ctxprog and ctxvals generator

2010-02-23 Thread Martin PERES

Hello,

Sorry for not answering to the right message, I've just joined the 
mailing list.


I've tried this patch on my Quadro NVS 140M and it fails to load KDM.
It shows the background but fails to show the credential edit boxes.
It seems like the computer is locked up though the mouse can still move 
(can't do any VT switches) and

I still can ssh on it.

Needless to say this works without the patch ;)

Martin

dmesg:
[drm] Initialized drm 1.1.0 20060810
nouveau :01:00.0: power state changed by ACPI to D0
nouveau :01:00.0: PCI INT A - GSI 16 (level, low) - IRQ 16
nouveau :01:00.0: setting latency timer to 64
[drm] nouveau :01:00.0: failed to evaluate _DSM: 5
[drm] nouveau :01:00.0: Detected an NV50 generation card (0x086900a2)
[drm] nouveau :01:00.0: Attempting to load BIOS image from PRAMIN
[drm] nouveau :01:00.0: ... appears to be valid
[drm] nouveau :01:00.0: BIT BIOS found
[drm] nouveau :01:00.0: Bios version 60.86.3e.00
[drm] nouveau :01:00.0: TMDS table revision 2.0 not currently supported
[drm] nouveau :01:00.0: BIT table 'd' not found
[drm] nouveau :01:00.0: Found Display Configuration Block version 4.0
[drm] nouveau :01:00.0: DCB connector table: VHER 0x40 5 14 2
[drm] nouveau :01:00.0:   0: 0x0040: type 0x40 idx 0 tag 0xff
[drm] nouveau :01:00.0:   1: 0x0100: type 0x00 idx 1 tag 0xff
[drm] nouveau :01:00.0:   2: 0x1231: type 0x31 idx 2 tag 0x07
[drm] nouveau :01:00.0:   3: 0x0311: type 0x11 idx 3 tag 0xff
[drm] nouveau :01:00.0: Raw DCB entry 0: 01000323 00010034
[drm] nouveau :01:00.0: Raw DCB entry 1: 02811300 0028
[drm] nouveau :01:00.0: Raw DCB entry 2: 02822312 00010030
[drm] nouveau :01:00.0: Raw DCB entry 3: 014333f1 0080c080
[drm] nouveau :01:00.0: Raw DCB entry 4: 000e 
[drm] nouveau :01:00.0: Parsing VBIOS init table 0 at offset 0xDD0F
[drm] nouveau :01:00.0: Parsing VBIOS init table 1 at offset 0xE04F
[drm] nouveau :01:00.0: Parsing VBIOS init table 2 at offset 0xEAA4
[drm] nouveau :01:00.0: Parsing VBIOS init table 3 at offset 0xEB96
[drm] nouveau :01:00.0: Parsing VBIOS init table 4 at offset 0xED83
[drm] nouveau :01:00.0: Parsing VBIOS init table at offset 0xEDE8
[drm] nouveau :01:00.0: 0xEDE8: Condition still not met after 20ms, 
skipping following opcodes

[drm] nouveau :01:00.0: 0xCE7E: parsing output script 0
[drm] nouveau :01:00.0: 0xCFF4: parsing output script 0
[drm] nouveau :01:00.0: 0xC66A: parsing output script 0
[TTM] Zone  kernel: Available graphics memory: 443326 kiB.
[TTM] Zone highmem: Available graphics memory: 1036578 kiB.
[drm] nouveau :01:00.0: 128 MiB VRAM
[drm] nouveau :01:00.0: 512 MiB GART (aperture)
[drm] nouveau :01:00.0: Allocating FIFO number 1
[drm] nouveau :01:00.0: nouveau_channel_alloc: initialised FIFO 1
[drm] nouveau :01:00.0: Detected a LVDS output
[drm] nouveau :01:00.0: Detected a DAC output
[drm] nouveau :01:00.0: Detected a TMDS output
[drm] nouveau :01:00.0: DCB encoder 1 unknown
[drm] nouveau :01:00.0: Detected a LVDS connector
[drm] nouveau :01:00.0: Detected a VGA connector
[drm] nouveau :01:00.0: Detected a DVI-D connector
[drm] nouveau :01:00.0: allocated 1280x800 fb: 0x4025, bo f6813200
[drm] LVDS-7: set mode 1280x800 1a
[drm] nouveau :01:00.0: 0xCE82: parsing output script 1
[drm] nouveau :01:00.0: 0xCCE3: parsing clock script 0
Console: switching to colour frame buffer device 160x50
fb0: nouveaufb frame buffer device
registered panic notifier
[drm] Initialized nouveau 0.0.16 20090420 for :01:00.0 on minor 0
[drm] nouveau :01:00.0: 0xCE41: parsing clock script 1

...

# When loading KDM
[drm] nouveau :01:00.0: Allocating FIFO number 2
[drm] nouveau :01:00.0: nouveau_channel_alloc: initialised FIFO 2
[drm] nouveau :01:00.0: Allocating FIFO number 3
[drm] nouveau :01:00.0: nouveau_channel_alloc: initialised FIFO 3
# Stuck !
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [TEST REQUEST] NV50/NV8x/NV9x/NVAx ctxprog and ctxvals generator

2010-02-24 Thread Martin PERES

Le 24/02/2010 09:22, Marcin Kościelnicki a écrit :

Aiii... ok, I accidentally introduced a bug in pre-NVA0 branch during last-
minute cleanups... I just uploaded a new version at the same address that
should fix that issue.

Btw, to anyone reporting success/failure with the generator: please include
your chipset code number [NV50, NV96, NVA5, etc.]. If you don't know what it
is, just report the hex number in Detected an NV50 generation card
(0x086900a2) line

Sorry for that screwup

Marcin Kościelnicki
   

It works better now, I could not spot any regression.

Thanks,

Martin

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


[Nouveau] GtkPerf: Non linear Add text execution time

2010-03-12 Thread Martin Peres

Hello everyone,

I am a daily tester of the nouveau driver on my (nVidia Corporation 
Quadro NVS 140M (rev a1)).


Today, when trying to make compiz crash, I have tried to execute a lot 
of tests at the same time with both 2D and 3D. Well, I didn't bump into 
any crashes but I have discovered a really annoying performance issue.


Indeed, the gtkTextView - Add Text of gtkperf has non-linear execution 
times:


GtkPerf 0.40 - Starting testing: Fri Mar 12 13:57:19 2010

GtkTextView - Add text - time:  0,03 -- 10 executions
 ---
Total time:  0,04

GtkPerf 0.40 - Starting testing: Fri Mar 12 13:57:28 2010

GtkTextView - Add text - time:  0,99  -- 100 executions
 ---
Total time:  0,99

GtkPerf 0.40 - Starting testing: Fri Mar 12 13:57:34 2010

GtkTextView - Add text - time: 88,19 -- 1000 executions
 ---
Total time: 88,19

So, if results were linear, we would have had a 3 seconds execution time 
with 1000 executions while we got 88.19s.


Just to give you an idea. I was testing with even more iterations and 
adding just one single text can take more than one second.


I don't know if it is a performance regression or if it has always been 
here but this could explain some slow code-path I sometime encounter 
using nouveau on lengthy webpages.


What do you think about it ?

Also, one last question, do you have any idea why KWin doesn't let me 
activate the composite. Do you think the problem is from KWin or does 
Nouveau misses a few features to get it working ?


Anyway, I am an happy tester of the nouveau stack and I would be glad to 
help you in running tests/applying patches on my card.


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


[Nouveau] Gart to vram/vram to gart transfers broken on NVS 140M

2010-04-22 Thread Martin Peres

Hi Nouveau folks,

I've been encountering some corruption on pixmaps for a while now, and 
it seems like the problem comes from the DFS/UTS (Download From Screen / 
Upload To Screen).


In fact, I'm pretty sure the problem comes from there as screenshots are 
garbled and so does a few more things.


I may have time to dig this up, where should I start, is there some 
documentation on the NVS 140M ? Where is the gart2vram code located ?

Do you have any idea of where could be the problem ?

Thanks,

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


Re: [Nouveau] Gart to vram/vram to gart transfers broken on NVS 140M

2010-04-25 Thread Martin PERES

Le 22/04/2010 12:20, Stephane Marchesin a écrit :

On Thu, Apr 22, 2010 at 03:13, Martin Peresmartin.pe...@free.fr  wrote:
   

Hi Nouveau folks,

I've been encountering some corruption on pixmaps for a while now, and it
seems like the problem comes from the DFS/UTS (Download From Screen / Upload
To Screen).

In fact, I'm pretty sure the problem comes from there as screenshots are
garbled and so does a few more things.

I may have time to dig this up, where should I start, is there some
documentation on the NVS 140M ? Where is the gart2vram code located ?
Do you have any idea of where could be the problem ?

 

If you really think that's UTS/DFS, edit nouveau_exa.c and disable
them (change the UTS/DFS functions to return FALSE, that'll trigger
fallbacks to sw copying).

Stephane
   
In fact, following your advice triggers a lot more corruption. So, the 
problem comes from elsewhere. My corruption problem seems like  there is 
a codepath that copy a pixmap with wrong height and width.


I'll dig into it. I'll keep in touch.

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


Re: [Nouveau] Re-enable dithering after commit a7b9f9e5adef276c25584e28ce9e520045ff048b

2010-06-17 Thread Martin Peres

Le 16/06/2010 09:38, Martin Peres a écrit :

Hi everyone,

After commit a7b9f9e5adef276c25584e28ce9e520045ff048b, dithering has 
disappeared on LVDS (for those who needed it).


ThibG on IRC has bisected this behaviour to 
a7b9f9e5adef276c25584e28ce9e520045ff048b. Here is a patch that 
re-enables it.


Please comment on it.

Martin

Well, too late, Jerez already pushed a patch to do that :)

Do you have any idea of why it took almost 10 hours between the moment I 
sent this mail and the moment I actually received it from the list ? Is 
there a manual approbation somewhere to get rid of the spam ?


Thanks to Jerez for the patch anyway :) It works just as great and is 
better designed.


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


[Nouveau] [RFC] Initial power management vbios parsing, voltage clock setting to nouveau.

2010-09-15 Thread Martin Peres

 Hi folks,

I've been messing with PM management for a few days and I've accumulated 
an interesting volume of code.


I am now interested in comments on the overall architecture. For 
example, in this patch, I implement a proposition on how to split 
nouveau_bios.c I would really like you to comment. I have also 
introduced nouveau_pm.[hc] along with vbios/vbios_pm.[ch].


Another thing I would be interested in is the vbios parsing testing.
At the moment, it should work from nv40 to at least nv96 but it has 
really been tested only on an nv86 and an nv96. I'm expecting a lot of 
bug report.


Power mode setting is _not recommended for anything other than dev 
testing_.

There is still work to be done:
- Clock  voltage: It needs testing.
- Memory timings: It is being REed by RSpliet (please help him, he 
should be able to provide directions).

- Fan control: I have no information on this.

Despite these lacks, you should be able to safely try to downclock your 
card though. That's good news for laptop users, isn't it?


Please acknowledge that this work is almost entirely based on others's 
RE work and documentation work. Xexaxo's work has been impressive. 
RSpliet is also to be thanked as he is working on getting memory timing 
support. Darktama has also done some nice RE, we'll see how to merge his 
work. My work here has just been to implement the docs.


On a side note, I would like to say I will be out for 5 days to the XDS 
2010.
So, if you have questions I should discuss with some devs there, feel 
free to ask.


Best regards,

Martin Peres (aka mupuf), an happy new nouveau dev

 How to help for the vbios parsing ?
Thanks for wanting to help :)

First, grab the patch I've joined to this mail. It should cleanly apply 
on nouveau's master branch.

Compile, Install  Reboot.

$ cat /sys/class/drm/card0/device/pm_status
and compare the values to
# nvclock -i

If it differs, please follow the instructions here:
http://nouveau.freedesktop.org/wiki/PowerManagementDumps
If it works, then, you may want to try changing the clocks.

 How to test clock/voltage setting ?
Do not attempt anything if the vbios parsing is wrong, really.
If it did work as intended, you can continue.

** Warning ** Do not try to upclock your card, nothing good will happen.
  While playing with clocks, always check the 
current temperature


First, kill X (for safety reasons).
Then look for the wanted mode by doing:
$ cat /sys/class/drm/card0/device/pm_mode

It should give you a result like:
--- PM Modes ---
 0: core 169 MHz/shader 338 MHz/memory 100 MHz/1150 mV
*1: core 275 MHz/shader 550 MHz/memory 301 MHz/1150 mV
 2: core 400 MHz/shader 800 MHz/memory 600 MHz/1200 mV

The * means it is the currently used mode (it may also not be detected).

In this example, you should only stay between mode 0 and 1.
To set the wanted PM mode, please do so:
# echo 0  /sys/class/drm/card0/device/pm_mode
The command above will change the mode to the first mode.

There is another file for voltage control at 
/sys/class/drm/card0/device/pm_voltage that works the exact same way as 
pm_mode.


The other sysfs entries (temperature related) should be useless to you 
as they are just here for future work).


You're done, have fun.

From 38aba214268ecd0263b2a49af0698d84f6a364e6 Mon Sep 17 00:00:00 2001
From: Martin Peres martin.pe...@ensi-bourges.fr
Date: Wed, 15 Sep 2010 12:59:00 +0200
Subject: [PATCH] Add initial power management vbios parsing, voltage  clock setting to nouveau.
 It is not intented to be used by end-users (if it should be used at all),
 this commit is meant for devs to check the actual work and comment on it.

So, you may wondering what I'm asking you. I simply ask you to check the code
and see if you could improve this design.
Also, you can try:
$ cat /sys/class/drm/card0/device/pm_status
and comparing it to # nvclock -i.
If it doesn't match, please provide us with power management dumps  kernel logs:
http://nouveau.freedesktop.org/wiki/PowerManagementDumps
If it does match, report your success story also :)

Known issues: As no memory timing parsing/get/set is implemented yet (RSPliet
has been working on it but it is not complete yet), your card will likely hang
if you upclock the memory. Lowering the clocks should work fine though:
echo 0  /sys/class/drm/card0/device/pm_mode

WARNING: Use at your own risks. Please stop your machine after having fun with
this and reboot it after a minute in order to flush everything in the card.
Keep in mind how experimental it is ;)

Ack: Most of this work is based on xexaxo's documentation work and useful
advices.
---
 drivers/gpu/drm/nouveau/Makefile |2 +-
 drivers/gpu/drm/nouveau/nouveau_bios.c   |   67 +++-
 drivers/gpu/drm/nouveau/nouveau_bios.h   |   41 ++
 drivers/gpu/drm/nouveau/nouveau_biosP.h  |   44 ++
 drivers/gpu/drm/nouveau/nouveau_drv.h|2 +
 drivers/gpu/drm/nouveau/nouveau_pm.c |  677 ++
 drivers/gpu

Re: [Nouveau] [RFC] Initial power management vbios parsing, voltage clock setting to nouveau.

2010-09-16 Thread Martin Peres

 Le 15/09/2010 14:33, C. Bergström a écrit :

If you're an end users also feel free to pull the branch directly..

http://github.com/pathscale/pscnv/tree/pm-wip

We're in #pathscale if you need more help or hit bugs..

It is not a good idea as libpdrm isn't mainstream yet. As Ben said, it 
should be developped in nouveau. Pscnv isn't ready for X users yet even 
though we are working on it.


If people want to, I'll upload a complete kernel somewhere for end users 
to test. As for the moment, I only need developpers  people who know 
what they are doing, not end-users.


Anyway, count on me to keep pscnv  nouveau in sync as for power management.

thanks

./C

ps (Have a great trip Martin and good luck at the conference!)


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


Re: [Nouveau] [RFC] Initial power management vbios parsing, voltage clock setting to nouveau.

2010-09-19 Thread Martin Peres

 Le 15/09/2010 14:58, Robert Kaiser a écrit :
On an only slightly related note, what's the recommended way to read 
out the temperature of the GPU when using nouveau? (I have a NV4B 
card, but I think I read this is mostly the same for all NVidias, right?)
There is no way to get the temperature using nouveau at the moment. This 
feature should land in nouveau git some time this week.


Reading the temperature is not as straightforward as just reading a 
register. It works that way on nv84+, for earlier cards, you need to 
parse the vbios to set-up the sensor and then read the temperature (and 
change the value with some additional little calcultations). The 
documentation should be available soon, I'm working on merging all the 
doc we have.

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


[Nouveau] Add pause/unpause methods for PFIFO PGRAPH. Use them to get stable clock changes

2010-09-29 Thread Martin Peres

 Hi,

With these patches, I get reliable clock changes on my nv86. It should 
work from nv50 to nvc0 (non-included).


Now, we need to wait for vblank. This is on my TODO but if someone knows 
how to do so, please send me pointers to it or implement it yourself :)


Regards,

Martin
From a219259d5ea46fb18f8e36c6c5a2f9e9e63fe53e Mon Sep 17 00:00:00 2001
From: Martin Peres martin.pe...@ensi-bourges.fr
Date: Wed, 29 Sep 2010 14:56:37 +0200
Subject: [PATCH 1/3] Add pause/unpause methods to the PFIFO engine

Signed-off-by: Martin Peres martin.pe...@ensi-bourges.fr
---
 drivers/gpu/drm/nouveau/nouveau_drv.h   |8 
 drivers/gpu/drm/nouveau/nouveau_reg.h   |1 +
 drivers/gpu/drm/nouveau/nouveau_state.c |   14 ++
 drivers/gpu/drm/nouveau/nv50_fifo.c |   18 ++
 4 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 591254e..c256c0a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -304,6 +304,9 @@ struct nouveau_fifo_engine {
 	void (*destroy_context)(struct nouveau_channel *);
 	int  (*load_context)(struct nouveau_channel *);
 	int  (*unload_context)(struct drm_device *);
+
+	int  (*pause)(struct drm_device *);
+	int  (*unpause)(struct drm_device *);
 };
 
 struct nouveau_pgraph_object_method {
@@ -339,6 +342,9 @@ struct nouveau_pgraph_engine {
 
 	void (*set_region_tiling)(struct drm_device *dev, int i, uint32_t addr,
   uint32_t size, uint32_t pitch);
+
+	int  (*pause)(struct drm_device *);
+	int  (*unpause)(struct drm_device *);
 };
 
 struct nouveau_display_engine {
@@ -1036,6 +1042,8 @@ extern int  nv50_fifo_create_context(struct nouveau_channel *);
 extern void nv50_fifo_destroy_context(struct nouveau_channel *);
 extern int  nv50_fifo_load_context(struct nouveau_channel *);
 extern int  nv50_fifo_unload_context(struct drm_device *);
+extern int  nv50_fifo_pause(struct drm_device *);
+extern int  nv50_fifo_unpause(struct drm_device *);
 
 /* nvc0_fifo.c */
 extern int  nvc0_fifo_init(struct drm_device *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h
index 1b42541..ee6dae1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_reg.h
+++ b/drivers/gpu/drm/nouveau/nouveau_reg.h
@@ -701,6 +701,7 @@
 #define NV50_PGRAPH 0x0040
 #define NV50_PGRAPH__LEN   0x1
 #define NV50_PGRAPH__ESIZE 0x1
+#define NV50_PFIFO_FREEZE   0x2504
 
 #define NV50_PDISPLAY0x0061
 #define NV50_PDISPLAY_OBJECTS0x00610010
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index 75bce91..cfc34f5 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -86,6 +86,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
 		engine-fifo.destroy_context	= nv04_fifo_destroy_context;
 		engine-fifo.load_context	= nv04_fifo_load_context;
 		engine-fifo.unload_context	= nv04_fifo_unload_context;
+		engine-fifo.pause			= NULL;
+		engine-fifo.unpause		= NULL;
 		engine-display.early_init	= nv04_display_early_init;
 		engine-display.late_takedown	= nv04_display_late_takedown;
 		engine-display.create		= nv04_display_create;
@@ -140,6 +142,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
 		engine-fifo.destroy_context	= nv10_fifo_destroy_context;
 		engine-fifo.load_context	= nv10_fifo_load_context;
 		engine-fifo.unload_context	= nv10_fifo_unload_context;
+		engine-fifo.pause			= NULL;
+		engine-fifo.unpause		= NULL;
 		engine-display.early_init	= nv04_display_early_init;
 		engine-display.late_takedown	= nv04_display_late_takedown;
 		engine-display.create		= nv04_display_create;
@@ -194,6 +198,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
 		engine-fifo.destroy_context	= nv10_fifo_destroy_context;
 		engine-fifo.load_context	= nv10_fifo_load_context;
 		engine-fifo.unload_context	= nv10_fifo_unload_context;
+		engine-fifo.pause			= NULL;
+		engine-fifo.unpause		= NULL;
 		engine-display.early_init	= nv04_display_early_init;
 		engine-display.late_takedown	= nv04_display_late_takedown;
 		engine-display.create		= nv04_display_create;
@@ -248,6 +254,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
 		engine-fifo.destroy_context	= nv10_fifo_destroy_context;
 		engine-fifo.load_context	= nv10_fifo_load_context;
 		engine-fifo.unload_context	= nv10_fifo_unload_context;
+		engine-fifo.pause			= NULL;
+		engine-fifo.unpause		= NULL;
 		engine-display.early_init	= nv04_display_early_init;
 		engine-display.late_takedown	= nv04_display_late_takedown;
 		engine-display.create		= nv04_display_create;
@@ -305,6 +313,8 @@ static int

Re: [Nouveau] Add pause/unpause methods for PFIFO PGRAPH. Use them to get stable clock changes

2010-09-30 Thread Martin Peres

 Hi,

Here is an updated set of patches (in regards on comments got on IRC and 
an handling error when using several channels).


These updated patch allow me to run 5 glxgears at the same time and 
reclock the card almost 100 times per second without crashing.


Don't panic if you get theses in your logs:
PGRAPH: wait for idle fail:    0103!
PGRAPH: PGRAPH paused while running a ctxprog, NV40_PGRAPH_CTXCTL_0310 = 
0x11


It means that we tried to reclock during a context switch. It would be 
safe to continue as when the program is at 0x11, it means it waits for 
another process (which is stopped because we stopped PFIFO before). I 
could allow to get this value (ie continue and clock), but if someone 
changes the ctxprog, he would have to update it here.


For the moment, I don't mind if from time to time, setting the clocks fail.

Waiting for your comments.

Regards,

Martin
From a219259d5ea46fb18f8e36c6c5a2f9e9e63fe53e Mon Sep 17 00:00:00 2001
From: Martin Peres martin.pe...@ensi-bourges.fr
Date: Wed, 29 Sep 2010 14:56:37 +0200
Subject: [PATCH 1/3] Add pause/unpause methods to the PFIFO engine

---
 drivers/gpu/drm/nouveau/nouveau_drv.h   |8 
 drivers/gpu/drm/nouveau/nouveau_reg.h   |1 +
 drivers/gpu/drm/nouveau/nouveau_state.c |   14 ++
 drivers/gpu/drm/nouveau/nv50_fifo.c |   18 ++
 4 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 591254e..c256c0a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -304,6 +304,9 @@ struct nouveau_fifo_engine {
 	void (*destroy_context)(struct nouveau_channel *);
 	int  (*load_context)(struct nouveau_channel *);
 	int  (*unload_context)(struct drm_device *);
+
+	int  (*pause)(struct drm_device *);
+	int  (*unpause)(struct drm_device *);
 };
 
 struct nouveau_pgraph_object_method {
@@ -339,6 +342,9 @@ struct nouveau_pgraph_engine {
 
 	void (*set_region_tiling)(struct drm_device *dev, int i, uint32_t addr,
   uint32_t size, uint32_t pitch);
+
+	int  (*pause)(struct drm_device *);
+	int  (*unpause)(struct drm_device *);
 };
 
 struct nouveau_display_engine {
@@ -1036,6 +1042,8 @@ extern int  nv50_fifo_create_context(struct nouveau_channel *);
 extern void nv50_fifo_destroy_context(struct nouveau_channel *);
 extern int  nv50_fifo_load_context(struct nouveau_channel *);
 extern int  nv50_fifo_unload_context(struct drm_device *);
+extern int  nv50_fifo_pause(struct drm_device *);
+extern int  nv50_fifo_unpause(struct drm_device *);
 
 /* nvc0_fifo.c */
 extern int  nvc0_fifo_init(struct drm_device *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h
index 1b42541..ee6dae1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_reg.h
+++ b/drivers/gpu/drm/nouveau/nouveau_reg.h
@@ -701,6 +701,7 @@
 #define NV50_PGRAPH 0x0040
 #define NV50_PGRAPH__LEN   0x1
 #define NV50_PGRAPH__ESIZE 0x1
+#define NV50_PFIFO_FREEZE   0x2504
 
 #define NV50_PDISPLAY0x0061
 #define NV50_PDISPLAY_OBJECTS0x00610010
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index 75bce91..cfc34f5 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -86,6 +86,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
 		engine-fifo.destroy_context	= nv04_fifo_destroy_context;
 		engine-fifo.load_context	= nv04_fifo_load_context;
 		engine-fifo.unload_context	= nv04_fifo_unload_context;
+		engine-fifo.pause			= NULL;
+		engine-fifo.unpause		= NULL;
 		engine-display.early_init	= nv04_display_early_init;
 		engine-display.late_takedown	= nv04_display_late_takedown;
 		engine-display.create		= nv04_display_create;
@@ -140,6 +142,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
 		engine-fifo.destroy_context	= nv10_fifo_destroy_context;
 		engine-fifo.load_context	= nv10_fifo_load_context;
 		engine-fifo.unload_context	= nv10_fifo_unload_context;
+		engine-fifo.pause			= NULL;
+		engine-fifo.unpause		= NULL;
 		engine-display.early_init	= nv04_display_early_init;
 		engine-display.late_takedown	= nv04_display_late_takedown;
 		engine-display.create		= nv04_display_create;
@@ -194,6 +198,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
 		engine-fifo.destroy_context	= nv10_fifo_destroy_context;
 		engine-fifo.load_context	= nv10_fifo_load_context;
 		engine-fifo.unload_context	= nv10_fifo_unload_context;
+		engine-fifo.pause			= NULL;
+		engine-fifo.unpause		= NULL;
 		engine-display.early_init	= nv04_display_early_init;
 		engine-display.late_takedown	= nv04_display_late_takedown

Re: [Nouveau] Add pause/unpause methods for PFIFO PGRAPH. Use them to get stable clock changes

2010-10-06 Thread Martin Peres

 Hi,

Here is an updated version, all in one patch. When we agree on the code, 
I'll split it into 3 patches.


The new code is way better. As suggested on IRC, I also disable IRQs and 
PFIFO cache pull and push.


Please have a look and test it. This patch needs to get upstream as it 
gives a reliable way to change the clock even in the middle of a game.


It is not perfect yet, changing the clocks too often (like several 
thousand of times) lead to an hung card :)


Regards,

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


Re: [Nouveau] Add pause/unpause methods for PFIFO PGRAPH. Use them to get stable clock changes

2010-10-07 Thread Martin Peres

 Le 07/10/2010 03:33, Martin Peres a écrit :

 Hi,

Here is an updated version, all in one patch. When we agree on the 
code, I'll split it into 3 patches.



Sorry, I forgot to attach it. Here it is.
From 86e7dd89810b37a12ae189633de41aacf07355cb Mon Sep 17 00:00:00 2001
From: Martin Peres martin.pe...@ensi-bourges.fr
Date: Thu, 7 Oct 2010 05:20:38 +0200
Subject: [PATCH] Pause the card before reclocking

Signed-off-by: Martin Peres martin.pe...@ensi-bourges.fr
---
 drivers/gpu/drm/nouveau/nouveau_drv.h   |   10 ++
 drivers/gpu/drm/nouveau/nouveau_pm.c|   50 +-
 drivers/gpu/drm/nouveau/nouveau_reg.h   |3 ++
 drivers/gpu/drm/nouveau/nouveau_state.c |   35 +-
 drivers/gpu/drm/nouveau/nv50_fifo.c |   17 ++
 drivers/gpu/drm/nouveau/nv50_graph.c|   48 +
 6 files changed, 160 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 591254e..9317bc3 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -304,6 +304,9 @@ struct nouveau_fifo_engine {
 	void (*destroy_context)(struct nouveau_channel *);
 	int  (*load_context)(struct nouveau_channel *);
 	int  (*unload_context)(struct drm_device *);
+
+	int  (*pause)(struct drm_device *);
+	void  (*unpause)(struct drm_device *);
 };
 
 struct nouveau_pgraph_object_method {
@@ -339,6 +342,9 @@ struct nouveau_pgraph_engine {
 
 	void (*set_region_tiling)(struct drm_device *dev, int i, uint32_t addr,
   uint32_t size, uint32_t pitch);
+
+	int  (*pause)(struct drm_device *);
+	void  (*unpause)(struct drm_device *);
 };
 
 struct nouveau_display_engine {
@@ -1036,6 +1042,8 @@ extern int  nv50_fifo_create_context(struct nouveau_channel *);
 extern void nv50_fifo_destroy_context(struct nouveau_channel *);
 extern int  nv50_fifo_load_context(struct nouveau_channel *);
 extern int  nv50_fifo_unload_context(struct drm_device *);
+extern int  nv50_fifo_pause(struct drm_device *);
+extern void  nv50_fifo_unpause(struct drm_device *);
 
 /* nvc0_fifo.c */
 extern int  nvc0_fifo_init(struct drm_device *);
@@ -1113,6 +1121,8 @@ extern int  nv50_graph_load_context(struct nouveau_channel *);
 extern int  nv50_graph_unload_context(struct drm_device *);
 extern void nv50_graph_context_switch(struct drm_device *);
 extern int  nv50_grctx_init(struct nouveau_grctx *);
+extern int nv50_graph_pause(struct drm_device *dev);
+extern void nv50_graph_unpause(struct drm_device *dev);
 
 /* nvc0_graph.c */
 extern int  nvc0_graph_init(struct drm_device *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c
index 1c99c55..b546a4d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -55,6 +55,7 @@ nouveau_pm_perflvl_set(struct drm_device *dev, struct nouveau_pm_level *perflvl)
 {
 	struct drm_nouveau_private *dev_priv = dev-dev_private;
 	struct nouveau_pm_engine *pm = dev_priv-engine.pm;
+	uint32_t status;
 	int ret;
 
 	if (perflvl == pm-cur)
@@ -68,13 +69,58 @@ nouveau_pm_perflvl_set(struct drm_device *dev, struct nouveau_pm_level *perflvl)
 		}
 	}
 
+	/* TODO: Wait for vblank */
+
+	/* Disable interrupts */
+	nv_wr32(dev, 0x140, 0);
+
+	/* Pause the engines, if possible */
+	if (dev_priv-engine.fifo.pause(dev)) {
+		ret = -EIO;
+		goto out;
+	}
+	if (dev_priv-engine.graph.pause(dev)) {
+		ret = -EIO;
+		goto out;
+	}
+
+	/* Disable the PFIFO cache pulling */
+	status = nv_rd32(dev, 0x003250);
+	nv_wr32(dev, 0x003250, status0xfffe);
+
+	/* Disable the PFIFO cache dma push */
+	status = nv_rd32(dev, 0x003220);
+	nv_wr32(dev, 0x003220, status0xfffe);
+
+	/* Change the clocks */
 	nouveau_pm_clock_set(dev, perflvl, PLL_CORE, perflvl-core);
 	nouveau_pm_clock_set(dev, perflvl, PLL_SHADER, perflvl-shader);
 	nouveau_pm_clock_set(dev, perflvl, PLL_MEMORY, perflvl-memory);
 	nouveau_pm_clock_set(dev, perflvl, PLL_UNK05, perflvl-unk05);
 
+	/* Wait for PLLs to stabilize */
+	udelay(100);
+
 	pm-cur = perflvl;
-	return 0;
+	ret = 0;
+
+out:
+	/* Re-enable the PFIFO cache dma push */
+	status = nv_rd32(dev, 0x003220);
+	nv_wr32(dev, 0x003220, status|0x1);
+
+	/* Re-enable the PFIFO cache pulling */
+	status = nv_rd32(dev, 0x003250);
+	nv_wr32(dev, 0x003250, status|0x1);
+
+	/* Un-pause the engines */
+	dev_priv-engine.fifo.unpause(dev);
+	dev_priv-engine.graph.unpause(dev);
+
+	/* Re-enable interrupts */
+	nv_wr32(dev, 0x140, 1);
+
+	return ret;
 }
 
 static int
@@ -108,7 +154,7 @@ nouveau_pm_profile_set(struct drm_device *dev, const char *profile)
 			return -EINVAL;
 	}
 
-	NV_INFO(dev, setting performance level: %s\n, profile);
+	NV_INFO(dev, setting performance level: %s, profile);
 	return nouveau_pm_perflvl_set(dev, perflvl);
 }
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h
index 1b42541..346b77a 100644
--- a/drivers/gpu/drm/nouveau

Re: [Nouveau] Add pause/unpause methods for PFIFO PGRAPH. Use them to get stable clock changes

2010-10-07 Thread Martin Peres

 Le 07/10/2010 03:33, Martin Peres a écrit :

 Hi,

Here is an updated version, all in one patch. When we agree on the 
code, I'll split it into 3 patches.



Sorry, I forgot to attach it. Here it is.
From 86e7dd89810b37a12ae189633de41aacf07355cb Mon Sep 17 00:00:00 2001
From: Martin Peres martin.pe...@ensi-bourges.fr
Date: Thu, 7 Oct 2010 05:20:38 +0200
Subject: [PATCH] Pause the card before reclocking

Signed-off-by: Martin Peres martin.pe...@ensi-bourges.fr
---
 drivers/gpu/drm/nouveau/nouveau_drv.h   |   10 ++
 drivers/gpu/drm/nouveau/nouveau_pm.c|   50 +-
 drivers/gpu/drm/nouveau/nouveau_reg.h   |3 ++
 drivers/gpu/drm/nouveau/nouveau_state.c |   35 +-
 drivers/gpu/drm/nouveau/nv50_fifo.c |   17 ++
 drivers/gpu/drm/nouveau/nv50_graph.c|   48 +
 6 files changed, 160 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 591254e..9317bc3 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -304,6 +304,9 @@ struct nouveau_fifo_engine {
 	void (*destroy_context)(struct nouveau_channel *);
 	int  (*load_context)(struct nouveau_channel *);
 	int  (*unload_context)(struct drm_device *);
+
+	int  (*pause)(struct drm_device *);
+	void  (*unpause)(struct drm_device *);
 };
 
 struct nouveau_pgraph_object_method {
@@ -339,6 +342,9 @@ struct nouveau_pgraph_engine {
 
 	void (*set_region_tiling)(struct drm_device *dev, int i, uint32_t addr,
   uint32_t size, uint32_t pitch);
+
+	int  (*pause)(struct drm_device *);
+	void  (*unpause)(struct drm_device *);
 };
 
 struct nouveau_display_engine {
@@ -1036,6 +1042,8 @@ extern int  nv50_fifo_create_context(struct nouveau_channel *);
 extern void nv50_fifo_destroy_context(struct nouveau_channel *);
 extern int  nv50_fifo_load_context(struct nouveau_channel *);
 extern int  nv50_fifo_unload_context(struct drm_device *);
+extern int  nv50_fifo_pause(struct drm_device *);
+extern void  nv50_fifo_unpause(struct drm_device *);
 
 /* nvc0_fifo.c */
 extern int  nvc0_fifo_init(struct drm_device *);
@@ -1113,6 +1121,8 @@ extern int  nv50_graph_load_context(struct nouveau_channel *);
 extern int  nv50_graph_unload_context(struct drm_device *);
 extern void nv50_graph_context_switch(struct drm_device *);
 extern int  nv50_grctx_init(struct nouveau_grctx *);
+extern int nv50_graph_pause(struct drm_device *dev);
+extern void nv50_graph_unpause(struct drm_device *dev);
 
 /* nvc0_graph.c */
 extern int  nvc0_graph_init(struct drm_device *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c
index 1c99c55..b546a4d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -55,6 +55,7 @@ nouveau_pm_perflvl_set(struct drm_device *dev, struct nouveau_pm_level *perflvl)
 {
 	struct drm_nouveau_private *dev_priv = dev-dev_private;
 	struct nouveau_pm_engine *pm = dev_priv-engine.pm;
+	uint32_t status;
 	int ret;
 
 	if (perflvl == pm-cur)
@@ -68,13 +69,58 @@ nouveau_pm_perflvl_set(struct drm_device *dev, struct nouveau_pm_level *perflvl)
 		}
 	}
 
+	/* TODO: Wait for vblank */
+
+	/* Disable interrupts */
+	nv_wr32(dev, 0x140, 0);
+
+	/* Pause the engines, if possible */
+	if (dev_priv-engine.fifo.pause(dev)) {
+		ret = -EIO;
+		goto out;
+	}
+	if (dev_priv-engine.graph.pause(dev)) {
+		ret = -EIO;
+		goto out;
+	}
+
+	/* Disable the PFIFO cache pulling */
+	status = nv_rd32(dev, 0x003250);
+	nv_wr32(dev, 0x003250, status0xfffe);
+
+	/* Disable the PFIFO cache dma push */
+	status = nv_rd32(dev, 0x003220);
+	nv_wr32(dev, 0x003220, status0xfffe);
+
+	/* Change the clocks */
 	nouveau_pm_clock_set(dev, perflvl, PLL_CORE, perflvl-core);
 	nouveau_pm_clock_set(dev, perflvl, PLL_SHADER, perflvl-shader);
 	nouveau_pm_clock_set(dev, perflvl, PLL_MEMORY, perflvl-memory);
 	nouveau_pm_clock_set(dev, perflvl, PLL_UNK05, perflvl-unk05);
 
+	/* Wait for PLLs to stabilize */
+	udelay(100);
+
 	pm-cur = perflvl;
-	return 0;
+	ret = 0;
+
+out:
+	/* Re-enable the PFIFO cache dma push */
+	status = nv_rd32(dev, 0x003220);
+	nv_wr32(dev, 0x003220, status|0x1);
+
+	/* Re-enable the PFIFO cache pulling */
+	status = nv_rd32(dev, 0x003250);
+	nv_wr32(dev, 0x003250, status|0x1);
+
+	/* Un-pause the engines */
+	dev_priv-engine.fifo.unpause(dev);
+	dev_priv-engine.graph.unpause(dev);
+
+	/* Re-enable interrupts */
+	nv_wr32(dev, 0x140, 1);
+
+	return ret;
 }
 
 static int
@@ -108,7 +154,7 @@ nouveau_pm_profile_set(struct drm_device *dev, const char *profile)
 			return -EINVAL;
 	}
 
-	NV_INFO(dev, setting performance level: %s\n, profile);
+	NV_INFO(dev, setting performance level: %s, profile);
 	return nouveau_pm_perflvl_set(dev, perflvl);
 }
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h
index 1b42541..346b77a 100644
--- a/drivers/gpu/drm/nouveau

Re: [Nouveau] Add pause/unpause methods for PFIFO PGRAPH. Use them to get stable clock changes

2010-10-28 Thread Martin Peres

Hi,

Please merge this patch, it helps a lot when it comes to safe 
re-clocking. It isn't perfect yet but it will satisfy most users.


Cheers,

Martin
From 58605d78ec7a576502a8f46953f6e2f0092eb180 Mon Sep 17 00:00:00 2001
From: Martin Peres martin.pe...@ensi-bourges.fr
Date: Thu, 28 Oct 2010 20:27:08 +0200
Subject: [PATCH] Pause the card before reclocking

Signed-off-by: Martin Peres martin.pe...@ensi-bourges.fr
---
 drivers/gpu/drm/nouveau/nouveau_drv.h   |   10 ++
 drivers/gpu/drm/nouveau/nouveau_pm.c|   50 +-
 drivers/gpu/drm/nouveau/nouveau_reg.h   |3 ++
 drivers/gpu/drm/nouveau/nouveau_state.c |   35 +-
 drivers/gpu/drm/nouveau/nv50_fifo.c |   18 +++
 drivers/gpu/drm/nouveau/nv50_graph.c|   46 
 6 files changed, 159 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index fc162c2..6f3b81b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -338,6 +338,9 @@ struct nouveau_fifo_engine {
 	int  (*load_context)(struct nouveau_channel *);
 	int  (*unload_context)(struct drm_device *);
 	void (*tlb_flush)(struct drm_device *dev);
+
+	int  (*pause)(struct drm_device *);
+	void  (*unpause)(struct drm_device *);
 };
 
 struct nouveau_pgraph_engine {
@@ -361,6 +364,9 @@ struct nouveau_pgraph_engine {
 	void (*tlb_flush)(struct drm_device *dev);
 
 	void (*set_tile_region)(struct drm_device *dev, int i);
+
+	int  (*pause)(struct drm_device *);
+	void  (*unpause)(struct drm_device *);
 };
 
 struct nouveau_display_engine {
@@ -1076,6 +1082,8 @@ extern void nv50_fifo_destroy_context(struct nouveau_channel *);
 extern int  nv50_fifo_load_context(struct nouveau_channel *);
 extern int  nv50_fifo_unload_context(struct drm_device *);
 extern void nv50_fifo_tlb_flush(struct drm_device *dev);
+extern int  nv50_fifo_pause(struct drm_device *);
+extern void  nv50_fifo_unpause(struct drm_device *);
 
 /* nvc0_fifo.c */
 extern int  nvc0_fifo_init(struct drm_device *);
@@ -1148,6 +1156,8 @@ extern void nv50_graph_context_switch(struct drm_device *);
 extern int  nv50_grctx_init(struct nouveau_grctx *);
 extern void nv50_graph_tlb_flush(struct drm_device *dev);
 extern void nv86_graph_tlb_flush(struct drm_device *dev);
+extern int nv50_graph_pause(struct drm_device *dev);
+extern void nv50_graph_unpause(struct drm_device *dev);
 
 /* nvc0_graph.c */
 extern int  nvc0_graph_init(struct drm_device *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c
index 8ef1d5b..bc7c70e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -59,6 +59,7 @@ nouveau_pm_perflvl_set(struct drm_device *dev, struct nouveau_pm_level *perflvl)
 {
 	struct drm_nouveau_private *dev_priv = dev-dev_private;
 	struct nouveau_pm_engine *pm = dev_priv-engine.pm;
+	uint32_t status;
 	int ret;
 
 	if (perflvl == pm-cur)
@@ -72,13 +73,58 @@ nouveau_pm_perflvl_set(struct drm_device *dev, struct nouveau_pm_level *perflvl)
 		}
 	}
 
+	/* TODO: Wait for vblank */
+
+	/* Disable interrupts */
+	nv_wr32(dev, 0x140, 0);
+
+	/* Pause the engines, if possible */
+	if (dev_priv-engine.fifo.pause(dev)) {
+		ret = -EIO;
+		goto out;
+	}
+	if (dev_priv-engine.graph.pause(dev)) {
+		ret = -EIO;
+		goto out;
+	}
+
+	/* Disable the PFIFO cache pulling */
+	status = nv_rd32(dev, 0x003250);
+	nv_wr32(dev, 0x003250, status0xfffe);
+
+	/* Disable the PFIFO cache dma push */
+	status = nv_rd32(dev, 0x003220);
+	nv_wr32(dev, 0x003220, status0xfffe);
+
+	/* Change the clocks */
 	nouveau_pm_clock_set(dev, perflvl, PLL_CORE, perflvl-core);
 	nouveau_pm_clock_set(dev, perflvl, PLL_SHADER, perflvl-shader);
 	nouveau_pm_clock_set(dev, perflvl, PLL_MEMORY, perflvl-memory);
 	nouveau_pm_clock_set(dev, perflvl, PLL_UNK05, perflvl-unk05);
 
+	/* Wait for PLLs to stabilize */
+	udelay(100);
+
 	pm-cur = perflvl;
-	return 0;
+	ret = 0;
+
+out:
+	/* Re-enable the PFIFO cache dma push */
+	status = nv_rd32(dev, 0x003220);
+	nv_wr32(dev, 0x003220, status|0x1);
+
+	/* Re-enable the PFIFO cache pulling */
+	status = nv_rd32(dev, 0x003250);
+	nv_wr32(dev, 0x003250, status|0x1);
+
+	/* Un-pause the engines */
+	dev_priv-engine.fifo.unpause(dev);
+	dev_priv-engine.graph.unpause(dev);
+
+	/* Re-enable interrupts */
+	nv_wr32(dev, 0x140, 1);
+
+	return ret;
 }
 
 static int
@@ -112,7 +158,7 @@ nouveau_pm_profile_set(struct drm_device *dev, const char *profile)
 			return -EINVAL;
 	}
 
-	NV_INFO(dev, setting performance level: %s\n, profile);
+	NV_INFO(dev, setting performance level: %s, profile);
 	return nouveau_pm_perflvl_set(dev, perflvl);
 }
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h
index b6384d3..951c268 100644
--- a/drivers/gpu/drm/nouveau/nouveau_reg.h
+++ b/drivers/gpu/drm/nouveau/nouveau_reg.h
@@ -700,8 +700,11 @@
 #define

[Nouveau] [To developers and hardcore NV50+ users] Experimental patch to get safer clock changes

2010-11-02 Thread Martin Peres

Hi folks,

Please do not merge this patch. I'm just asking people with nv50+ to try 
this very experimental patch. Hopefully, the results are good and I can 
start rework the patch to make it run faster and, hopefully, flicker-free.


This patch introduces Ben Skeggs's PMS-based clock changing code that I 
reworked a little. It also introduces the use of the 0xc040 register 
(I'm still REing it, it seems like a PLL supervisor, it is really weird 
but gives dir1212's nv92 way more stability).
This should run fine on nv84 to nv94 but,I have no idea on how it will 
perform on later cards.


To test this patch, you should edit and use the (very small) script 
test_mode_changes.sh that is basically changing the clocks every 100ms.
Launch it and then, please do GPU intensive tasks like playing games. If 
it crashes, that's a fail.
I personally can leave my computer in openarena for minutes without 
crashes nor nasty messages in dmesg. I then get bored continue hacking.


So, please report success or failure accompanied with the mmiotrace of 
your card like explained here: 
http://github.com/pathscale/pscnv/wiki/pm_mmiotrace) in the case it fails.


Wish you luck :)

As for what is on my todo list:
 - I may generate a big PMS script to handle all the clock changes. The 
problem is that it takes a lot of time to execute scripts on my card and 
I really want clock changes to happen fast to lower the performance hit 
of the reclock (see the third item).

- If this patch works, I'll rework and send it for inclusion.
- I'll try working on nv40 a bit (see what I can backport).
- Try reverse engineering performance counters so as the clock can be 
changed according to the card's current load. This is supposed to be 
hard (IIRC), so, It should take me a while.


Kindly,

Martin

PS: I really don't want everyone to jump on this patch and try it. Only 
people actually aware of my work and understanding what are the changes 
I made should test this patch. I really don't want dozens of people 
testing this, it is not ready for people other than nouveau devs.
From 61a256a6fa171c7c310a5abedd7cf178c8403f8b Mon Sep 17 00:00:00 2001
From: Martin Peres martin.pe...@ensi-bourges.fr
Date: Wed, 3 Nov 2010 02:49:52 +0100
Subject: [PATCH] Pause the card before reclocking and use PMS to reclock the memory clocks.

This is a very experimental patch. Please test with caution. This should work on nv84 - nv94 (included), I don't know how it is supposed to behave on later cards.

How to test? Well, make a script (or use the one I attached to the mail) to change the clocks every 100ms, launch it and then go play open arena or anything else that is GPU intensive.
Please report every success or failure stories.

Pitfalls: Changing the clocks will result in a garbelled screen for a few ms. This is really anoying but shouldn't impact the card's stability.

Signed-off-by: Martin Peres martin.pe...@ensi-bourges.fr
---
 drivers/gpu/drm/nouveau/nouveau_drv.h   |   10 ++
 drivers/gpu/drm/nouveau/nouveau_pm.c|   60 +++-
 drivers/gpu/drm/nouveau/nouveau_pms.h   |   98 ++
 drivers/gpu/drm/nouveau/nouveau_reg.h   |3 +
 drivers/gpu/drm/nouveau/nouveau_state.c |   35 +++-
 drivers/gpu/drm/nouveau/nv50_fifo.c |   18 
 drivers/gpu/drm/nouveau/nv50_graph.c|   46 +
 drivers/gpu/drm/nouveau/nv50_pm.c   |  164 +++
 8 files changed, 412 insertions(+), 22 deletions(-)
 create mode 100644 drivers/gpu/drm/nouveau/nouveau_pms.h

diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index fc162c2..6f3b81b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -338,6 +338,9 @@ struct nouveau_fifo_engine {
 	int  (*load_context)(struct nouveau_channel *);
 	int  (*unload_context)(struct drm_device *);
 	void (*tlb_flush)(struct drm_device *dev);
+
+	int  (*pause)(struct drm_device *);
+	void  (*unpause)(struct drm_device *);
 };
 
 struct nouveau_pgraph_engine {
@@ -361,6 +364,9 @@ struct nouveau_pgraph_engine {
 	void (*tlb_flush)(struct drm_device *dev);
 
 	void (*set_tile_region)(struct drm_device *dev, int i);
+
+	int  (*pause)(struct drm_device *);
+	void  (*unpause)(struct drm_device *);
 };
 
 struct nouveau_display_engine {
@@ -1076,6 +1082,8 @@ extern void nv50_fifo_destroy_context(struct nouveau_channel *);
 extern int  nv50_fifo_load_context(struct nouveau_channel *);
 extern int  nv50_fifo_unload_context(struct drm_device *);
 extern void nv50_fifo_tlb_flush(struct drm_device *dev);
+extern int  nv50_fifo_pause(struct drm_device *);
+extern void  nv50_fifo_unpause(struct drm_device *);
 
 /* nvc0_fifo.c */
 extern int  nvc0_fifo_init(struct drm_device *);
@@ -1148,6 +1156,8 @@ extern void nv50_graph_context_switch(struct drm_device *);
 extern int  nv50_grctx_init(struct nouveau_grctx *);
 extern void nv50_graph_tlb_flush(struct drm_device *dev);
 extern void nv86_graph_tlb_flush(struct

Re: [Nouveau] hwmon directory structure bug

2010-11-05 Thread Martin Peres

Le 06/11/2010 01:34, Delan Azabani a écrit :

The sensors implementation of nouveau has a bug where the name file is
not in hwmonX/device, but in the root of the hwmonX directory. Normally,
the name file (contains driver name) of a sensor is placed:

/sys/class/hwmon/hwmonint/device/name

This holds true for coretemp, it8718 and all other sensors I've
encountered. Currently, with the latest nouveau from git, the name file
is placed as

/sys/class/hwmon/hwmonint/name

This is incorrect and goes against the convention for hwmon directory
structure. Not a major bug, but a fix would be very helpful.

oh, thanks for spotting this, I'll correct my mistake tomorrow.

Regards,

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


[Nouveau] [Patch] Add a custom power management perflvl

2010-11-20 Thread Martin Peres

Hi everyone,

Please comment on this patch allowing you to set all the PM-related 
clocks on the card. The patch is described in length in the commit log.


There is something some of you will like and some won't. The custom_* 
files will always contain the values of the current perflvl unless the 
user changed them after the latest reclock.
I may also add all the available voltage in sysfs in the same way Ben 
added all the available performance levels (performance_level_X).


If you no-one has anything against it, please push it to master.

Martin



From 1df2984f21ba0bf034684b1b1287fb86a255a15c Mon Sep 17 00:00:00 2001
From: Martin Peres mu...@mupuf.org
Date: Sat, 20 Nov 2010 18:29:45 +0100
Subject: [PATCH] Add a custom power management perflvl
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This is to allow people to tweak their clocks at will.
Marcin asked for something like this to help him REing.
I was personnaly interested to see if openarena fps rate would scale with the GPU clocks (it doesn't ... yet).
This patch will also allow overclockers to test their cards (On my NVS 140M: Memory +66%, core: +66%, shader: +25%).

This patch introduces a few sysfs files:
- custom_*: Get/set the current clock/voltage value (kHz or *10mV)

Once you've set all the values you wanted to change, just echo custom into performance_level.

WARNINGS:
1) Pay attention to your current temperature, my card's temperature rose by 9°C.
We'll need to use the thermal zones to be able to monitor that and downclock the card automatically (if someone wants to help here, he would be welcome).

2) Changing clocks isn't safe at the moment, I'm working on this but the reclocking process is really different accross the boards.
So far, nv84 and nv86 work perfectly (as in no flicker and being able to reclock while playing games).

By the time I get this patch ready, please stop 3D applications, switch to a tty, do the reclock and come back to X.

Signed-off-by: Martin Peres martin.pe...@ensi-bourges.fr
---
 drivers/gpu/drm/nouveau/nouveau_drv.h |1 +
 drivers/gpu/drm/nouveau/nouveau_pm.c  |  265 -
 2 files changed, 263 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index a52b1da..5928301 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -463,6 +463,7 @@ struct nouveau_pm_engine {
 	struct nouveau_pm_threshold_temp threshold_temp;
 
 	struct nouveau_pm_level boot;
+	struct nouveau_pm_level custom;
 	struct nouveau_pm_level *cur;
 
 	struct device *hwmon;
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c
index d938141..7bcb27f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -35,6 +35,10 @@
 #include linux/hwmon-sysfs.h
 
 static int
+nouveau_pm_perflvl_get(struct drm_device *dev,
+	struct nouveau_pm_level *perflvl);
+
+static int
 nouveau_pm_clock_set(struct drm_device *dev, struct nouveau_pm_level *perflvl,
 		 u8 id, u32 khz)
 {
@@ -61,7 +65,7 @@ nouveau_pm_perflvl_set(struct drm_device *dev, struct nouveau_pm_level *perflvl)
 	struct nouveau_pm_engine *pm = dev_priv-engine.pm;
 	int ret;
 
-	if (perflvl == pm-cur)
+	if (perflvl != pm-custom  perflvl == pm-cur)
 		return 0;
 
 	if (pm-voltage.supported  pm-voltage_set  perflvl-voltage) {
@@ -78,6 +82,10 @@ nouveau_pm_perflvl_set(struct drm_device *dev, struct nouveau_pm_level *perflvl)
 	nouveau_pm_clock_set(dev, perflvl, PLL_UNK05, perflvl-unk05);
 
 	pm-cur = perflvl;
+
+	/* Copy the new profile to the custom profile */
+	nouveau_pm_perflvl_get(dev, pm-custom);
+
 	return 0;
 }
 
@@ -97,6 +105,8 @@ nouveau_pm_profile_set(struct drm_device *dev, const char *profile)
 
 	if (!strncmp(profile, boot, 4))
 		perflvl = pm-boot;
+	else if (!strncmp(profile, custom, 6))
+		perflvl = pm-custom;
 	else {
 		int pl = simple_strtol(profile, NULL, 10);
 		int i;
@@ -208,6 +218,8 @@ nouveau_pm_get_perflvl(struct device *d, struct device_attribute *a, char *buf)
 		snprintf(ptr, len, setting: boot\n);
 	else if (pm-cur == pm-boot)
 		snprintf(ptr, len, setting: boot\nc: );
+	else if (pm-cur == pm-custom)
+		snprintf(ptr, len, setting: custom\nclocks: );
 	else
 		snprintf(ptr, len, setting: static %d\nc: , pm-cur-id);
 	ptr += strlen(buf);
@@ -221,7 +233,7 @@ nouveau_pm_get_perflvl(struct device *d, struct device_attribute *a, char *buf)
 
 static ssize_t
 nouveau_pm_set_perflvl(struct device *d, struct device_attribute *a,
-		   const char *buf, size_t count)
+	const char *buf, size_t count)
 {
 	struct drm_device *dev = pci_get_drvdata(to_pci_dev(d));
 	int ret;
@@ -233,7 +245,226 @@ nouveau_pm_set_perflvl(struct device *d, struct device_attribute *a,
 }
 
 static DEVICE_ATTR(performance_level, S_IRUGO | S_IWUSR,
-		   nouveau_pm_get_perflvl, nouveau_pm_set_perflvl);
+			nouveau_pm_get_perflvl

Re: [Nouveau] [Patch] Add a custom power management perflvl

2010-11-21 Thread Martin Peres

Le 21/11/2010 03:47, Martin Peres a écrit :

Hi everyone,

Please comment on this patch allowing you to set all the PM-related 
clocks on the card. The patch is described in length in the commit log.


There is something some of you will like and some won't. The custom_* 
files will always contain the values of the current perflvl unless the 
user changed them after the latest reclock.
I may also add all the available voltage in sysfs in the same way Ben 
added all the available performance levels (performance_level_X).


If you no-one has anything against it, please push it to master.

Martin


An updated patch taking into account the critics I've got on IRC.

Martin
From 8b29c05beb74060a7441a94b269ccc7a2ecdf250 Mon Sep 17 00:00:00 2001
From: Martin Peres mu...@mupuf.org
Date: Sat, 20 Nov 2010 18:29:45 +0100
Subject: [PATCH] Add a custom power management perflvl v2
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This is to allow people to tweak their clocks at will. Marcin asked for something like this to help him REing.

I was personnaly interested to see if openarena fps rate would scale with the GPU clocks (it doesn't ... yet).
This patch will also allow overclockers to test their cards (On my NVS 140M: Memory +66%, core: +66%, shader: +25%).

This patch introduces a few sysfs files:
- custom_*: Get/set the current clock/voltage value (kHz or *10mV)

Once you've set all the values you wanted to change, just echo custom into performance_level.

WARNINGS:
1) Pay attention to your current temperature, my card's temperature rose by 9°C.
We'll need to use the thermal zones to be able to monitor that and downclock the card automatically (if someone wants to help here, he would be welcome).

2) Changing clocks isn't safe at the moment, I'm working on this but the reclocking process is really different accross the boards.
So far, nv84 and nv86 work perfectly (as in no flicker and being able to reclock while playing games).

By the time I get this patch ready, please stop 3D applications, switch to a tty, do the reclock and come back to X.

Signed-off-by: Martin Peres martin.pe...@ensi-bourges.fr
---
 drivers/gpu/drm/nouveau/nouveau_drv.h |1 +
 drivers/gpu/drm/nouveau/nouveau_pm.c  |  207 -
 2 files changed, 207 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index a52b1da..5928301 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -463,6 +463,7 @@ struct nouveau_pm_engine {
 	struct nouveau_pm_threshold_temp threshold_temp;
 
 	struct nouveau_pm_level boot;
+	struct nouveau_pm_level custom;
 	struct nouveau_pm_level *cur;
 
 	struct device *hwmon;
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c
index d938141..49d8a17 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -35,6 +35,10 @@
 #include linux/hwmon-sysfs.h
 
 static int
+nouveau_pm_perflvl_get(struct drm_device *dev,
+   struct nouveau_pm_level *perflvl);
+
+static int
 nouveau_pm_clock_set(struct drm_device *dev, struct nouveau_pm_level *perflvl,
 		 u8 id, u32 khz)
 {
@@ -61,7 +65,7 @@ nouveau_pm_perflvl_set(struct drm_device *dev, struct nouveau_pm_level *perflvl)
 	struct nouveau_pm_engine *pm = dev_priv-engine.pm;
 	int ret;
 
-	if (perflvl == pm-cur)
+	if (perflvl != pm-custom  perflvl == pm-cur)
 		return 0;
 
 	if (pm-voltage.supported  pm-voltage_set  perflvl-voltage) {
@@ -78,6 +82,10 @@ nouveau_pm_perflvl_set(struct drm_device *dev, struct nouveau_pm_level *perflvl)
 	nouveau_pm_clock_set(dev, perflvl, PLL_UNK05, perflvl-unk05);
 
 	pm-cur = perflvl;
+
+	/* Copy the new profile to the custom profile */
+	nouveau_pm_perflvl_get(dev, pm-custom);
+
 	return 0;
 }
 
@@ -97,6 +105,8 @@ nouveau_pm_profile_set(struct drm_device *dev, const char *profile)
 
 	if (!strncmp(profile, boot, 4))
 		perflvl = pm-boot;
+	else if (!strncmp(profile, custom, 6))
+		perflvl = pm-custom;
 	else {
 		int pl = simple_strtol(profile, NULL, 10);
 		int i;
@@ -179,6 +189,45 @@ nouveau_pm_perflvl_info(struct nouveau_pm_level *perflvl, char *ptr, int len)
 }
 
 static ssize_t
+nouveau_set_custom_clock(struct device *d, u32 id,
+ const char *buf, size_t count)
+{
+	struct drm_device *dev = pci_get_drvdata(to_pci_dev(d));
+	struct drm_nouveau_private *dev_priv = dev-dev_private;
+	struct nouveau_pm_engine *pm = dev_priv-engine.pm;
+	u32 *custom_clock;
+	void *pre_state;
+	long sysfs_value;
+
+	if (id == PLL_CORE)
+		custom_clock = pm-custom.core;
+	else if(id == PLL_MEMORY)
+		custom_clock = pm-custom.memory;
+	else if(id == PLL_SHADER)
+		custom_clock = pm-custom.shader;
+	else if(id == PLL_UNK05)
+		custom_clock = pm-custom.unk05;
+	else
+		return -EINVAL;
+
+	if (strict_strtol(buf, 10, sysfs_value) == -EINVAL)
+		return -EINVAL

[Nouveau] [Patch] Add a way to list the available voltages

2010-11-22 Thread Martin Peres

Hi,

This patch makes it easy for people to set their custom_voltage file. 
Previously, they had to guess what was the available voltages.


This patch depends on my previous patch to add a custom perflvl.

Martin

From e9c880e0882bb609a9ce4ec0bf28ef99ea78714a Mon Sep 17 00:00:00 2001
From: Martin Peres mu...@mupuf.org
Date: Mon, 22 Nov 2010 09:59:16 +0100
Subject: [PATCH] Add a way to list the available voltages through sysfs

Signed-off-by: Martin Peres martin.pe...@ensi-bourges.fr
---
 drivers/gpu/drm/nouveau/nouveau_pm.c |   32 
 1 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c
index 49d8a17..b0d0691 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -412,6 +412,33 @@ static DEVICE_ATTR(custom_voltage, S_IRUGO | S_IWUSR,
nouveau_pm_get_custom_voltage,
nouveau_pm_set_custom_voltage);
 
+static ssize_t
+nouveau_pm_get_voltages(struct device *d, struct device_attribute *a, char *buf)
+{
+	struct drm_device *dev = pci_get_drvdata(to_pci_dev(d));
+	struct drm_nouveau_private *dev_priv = dev-dev_private;
+	struct nouveau_pm_engine *pm = dev_priv-engine.pm;
+	struct nouveau_pm_voltage *volt = pm-voltage;
+	int cur_voltage = nouveau_voltage_gpio_get(dev);
+	char *ptr = buf;
+	int len = PAGE_SIZE;
+	int i;
+
+	for (i = 0; i  volt-nr_level; i++) {
+		int size = snprintf(ptr, len, %c %d [*10mV]\n,
+		cur_voltage == volt-level[i].voltage ? '*' : ' ',
+		volt-level[i].voltage
+		   );
+
+		ptr += size;
+		len -= size;
+	}
+
+	return strlen(buf);
+}
+
+static DEVICE_ATTR(voltages, S_IRUGO, nouveau_pm_get_voltages, NULL);
+
 static int
 nouveau_sysfs_init(struct drm_device *dev)
 {
@@ -463,6 +490,10 @@ nouveau_sysfs_init(struct drm_device *dev)
 	if (ret)
 		return ret;
 
+	ret = device_create_file(d, dev_attr_voltages);
+	if (ret)
+		return ret;
+
 	return 0;
 }
 
@@ -488,6 +519,7 @@ nouveau_sysfs_fini(struct drm_device *dev)
 	device_remove_file(d, dev_attr_custom_shader);
 	device_remove_file(d, dev_attr_custom_unk05);
 	device_remove_file(d, dev_attr_custom_voltage);
+	device_remove_file(d, dev_attr_voltages);
 }
 
 #ifdef CONFIG_HWMON
-- 
1.7.3.2


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


[Nouveau] [PATCH] Add PFIFO and PGRAPH pausing methods

2011-01-09 Thread Martin Peres

Hi,

I'm still working on getting the reclocking work done right. There are 
several parts I identify:

- Pausing PFIFO (with its caches), pause PGRAPH and wait for idle
- Stop some PLL (I guess it is more, physically disconnect them from the 
engines) using the 0xc040 register.

- reclock memory
- reclock the other engines
- Make sure the display doesn't blow up
Depending on the cards, I have completed all of the steps or none.

Anyway, pausing PFIFO and PGRAPH works well on all the card I tested and 
so, I would like it to be pushed.
I have a new theory upon the PLL_SUPERVISOR(0xc040) that I want to test. 
When I'm done with this, I'll put together a patch for it and continue 
on the other steps.


Please provide me with some feedback on the patch or push it if nothing 
bothers you.


Martin

PS: I'm quite busy at the moment, I'll write an in-depth mail when I've 
verified my theories and got proper support on other cards than the nv86 
ones.
From f7ad98f4a857dd4b1892712d15f93c13eb0669e3 Mon Sep 17 00:00:00 2001
From: Martin Peres martin.pe...@ensi-bourges.fr
Date: Mon, 10 Jan 2011 00:44:05 +0100
Subject: [PATCH] Pause PFIFO and PGRAPH before reclocking

Signed-off-by: Martin Peres martin.pe...@ensi-bourges.fr
---
 drivers/gpu/drm/nouveau/nouveau_drv.h   |   15 +++
 drivers/gpu/drm/nouveau/nouveau_pm.c|   32 ++-
 drivers/gpu/drm/nouveau/nouveau_reg.h   |3 +
 drivers/gpu/drm/nouveau/nouveau_state.c |   51 +++-
 drivers/gpu/drm/nouveau/nv04_fifo.c |   16 +++
 drivers/gpu/drm/nouveau/nv50_fifo.c |   20 +
 drivers/gpu/drm/nouveau/nv50_graph.c|   66 +++
 7 files changed, 200 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 6d749b7..b0c52c7 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -359,6 +359,12 @@ struct nouveau_fifo_engine {
 	int  (*load_context)(struct nouveau_channel *);
 	int  (*unload_context)(struct drm_device *);
 	void (*tlb_flush)(struct drm_device *dev);
+
+	int  (*pause)(struct drm_device *);
+	void  (*unpause)(struct drm_device *);
+
+	int  (*cache_pause)(struct drm_device *);
+	void  (*cache_unpause)(struct drm_device *);
 };
 
 struct nouveau_pgraph_engine {
@@ -383,6 +389,9 @@ struct nouveau_pgraph_engine {
 	void (*tlb_flush)(struct drm_device *dev);
 
 	void (*set_tile_region)(struct drm_device *dev, int i);
+
+	int  (*pause)(struct drm_device *);
+	void  (*unpause)(struct drm_device *);
 };
 
 struct nouveau_display_engine {
@@ -1094,6 +1103,8 @@ extern void nv04_fifo_destroy_context(struct nouveau_channel *);
 extern int  nv04_fifo_load_context(struct nouveau_channel *);
 extern int  nv04_fifo_unload_context(struct drm_device *);
 extern void nv04_fifo_isr(struct drm_device *);
+extern void nv04_fifo_cache_pause(struct drm_device *dev);
+extern void nv04_fifo_cache_unpause(struct drm_device *dev);
 
 /* nv10_fifo.c */
 extern int  nv10_fifo_init(struct drm_device *);
@@ -1117,6 +1128,8 @@ extern void nv50_fifo_destroy_context(struct nouveau_channel *);
 extern int  nv50_fifo_load_context(struct nouveau_channel *);
 extern int  nv50_fifo_unload_context(struct drm_device *);
 extern void nv50_fifo_tlb_flush(struct drm_device *dev);
+extern int  nv50_fifo_pause(struct drm_device *);
+extern void nv50_fifo_unpause(struct drm_device *);
 
 /* nvc0_fifo.c */
 extern int  nvc0_fifo_init(struct drm_device *);
@@ -1189,6 +1202,8 @@ extern int  nv50_graph_unload_context(struct drm_device *);
 extern int  nv50_grctx_init(struct nouveau_grctx *);
 extern void nv50_graph_tlb_flush(struct drm_device *dev);
 extern void nv86_graph_tlb_flush(struct drm_device *dev);
+extern int  nv50_graph_pause(struct drm_device *dev);
+extern void nv50_graph_unpause(struct drm_device *dev);
 extern struct nouveau_enum nv50_data_error_names[];
 
 /* nvc0_graph.c */
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c
index fb846a3..233deec 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -59,6 +59,7 @@ nouveau_pm_perflvl_set(struct drm_device *dev, struct nouveau_pm_level *perflvl)
 {
 	struct drm_nouveau_private *dev_priv = dev-dev_private;
 	struct nouveau_pm_engine *pm = dev_priv-engine.pm;
+	unsigned long flags;
 	int ret;
 
 	if (perflvl == pm-cur)
@@ -72,13 +73,42 @@ nouveau_pm_perflvl_set(struct drm_device *dev, struct nouveau_pm_level *perflvl)
 		}
 	}
 
+	/* Do not allow the card to allocate/destroy a
+	 * new channel while reclocking.
+	 */
+	spin_lock_irqsave(dev_priv-context_switch_lock, flags);
+
+	/* Pause the engines, if possible */
+	if (dev_priv-engine.fifo.pause(dev)) {
+		ret = -EIO;
+		goto out;
+	}
+	dev_priv-engine.fifo.cache_pause(dev);
+	if (dev_priv-engine.graph.pause(dev)) {
+		ret = -EIO;
+		goto out;
+	}
+
 	nouveau_pm_clock_set(dev, perflvl, PLL_CORE, perflvl-core

[Nouveau] [Patch] Yet another version of the card pausing patch

2011-01-23 Thread Martin Peres

Hi everyone,

I would like devs to test this patch on all their cards(nvc0) and 
report bugs/instability. It shouldn't ever crash (but it may not always 
work and return -EAGAIN).


I've attached a little bash script that you need to modify according to 
the available perf levels. Please launch it and play, watch videos or 
browse the internet.


Also, if you could look at the hold_spin variable and tell me how you 
would deal with that, it would be kind of you. The problem is that 
PGRAPH may take an awful lot
of time to pause in certain conditions and holding the lock at this 
position isn't needed (as far as I can tell, the critical ressource is 
fifo_reassign).


Martin

PS: I'll be out in an hour for a week so I may be slower to answer messages.

From 1fd18aa03020f64567bc2a711babb190b49a1520 Mon Sep 17 00:00:00 2001
From: Martin Peres martin.pe...@ensi-bourges.fr
Date: Wed, 19 Jan 2011 10:03:08 +0100
Subject: [PATCH 1/2] Add pm.(un)pause functions

With this patch, cards without internal memory (IONs and other IGPs)
and cards with no memory reclock (a lot of nv40) should support
safe reclocking even in games.

Please test this patch on all your hardware( nvc0) and report bugs.

WARNING: This patch disables memory reclocking

Signed-off-by: Martin Peres martin.pe...@ensi-bourges.fr
---
 drivers/gpu/drm/nouveau/nouveau_drv.h   |9 ++
 drivers/gpu/drm/nouveau/nouveau_pm.c|   26 -
 drivers/gpu/drm/nouveau/nouveau_pm.h|4 +
 drivers/gpu/drm/nouveau/nouveau_reg.h   |3 +
 drivers/gpu/drm/nouveau/nouveau_state.c |   15 +++-
 drivers/gpu/drm/nouveau/nv04_pm.c   |  126 ++
 drivers/gpu/drm/nouveau/nv50_pm.c   |  172 +++
 7 files changed, 351 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 1c6279f..f70cc31 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -471,6 +471,10 @@ struct nouveau_pm_memtimings {
 	int nr_timing;
 };
 
+struct nouveau_pm_pause_card_state {
+	u32 reg_c040;
+};
+
 struct nouveau_pm_engine {
 	struct nouveau_pm_voltage voltage;
 	struct nouveau_pm_level perflvl[NOUVEAU_PM_MAX_LEVEL];
@@ -485,6 +489,11 @@ struct nouveau_pm_engine {
 	struct device *hwmon;
 	struct notifier_block acpi_nb;
 
+	struct nouveau_pm_pause_card_state pause_state;
+
+	int (*pause)(struct drm_device *);
+	void (*unpause)(struct drm_device *);
+
 	int (*clock_get)(struct drm_device *, u32 id);
 	void *(*clock_pre)(struct drm_device *, struct nouveau_pm_level *,
 			   u32 id, int khz);
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c
index fb846a3..96d2809 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -45,6 +45,10 @@ nouveau_pm_clock_set(struct drm_device *dev, struct nouveau_pm_level *perflvl,
 	if (khz == 0)
 		return 0;
 
+	/* Do no reclock the memory if the frequencies didn't change */
+	if (id == PLL_MEMORY  pm-cur-memory == khz)
+		return 0;
+
 	pre_state = pm-clock_pre(dev, perflvl, id, khz);
 	if (IS_ERR(pre_state))
 		return PTR_ERR(pre_state);
@@ -60,10 +64,13 @@ nouveau_pm_perflvl_set(struct drm_device *dev, struct nouveau_pm_level *perflvl)
 	struct drm_nouveau_private *dev_priv = dev-dev_private;
 	struct nouveau_pm_engine *pm = dev_priv-engine.pm;
 	int ret;
+	uint64_t start = nv04_timer_read(dev);
 
 	if (perflvl == pm-cur)
 		return 0;
 
+	NV_INFO(dev, setting performance level: %s\n, perflvl-name);
+
 	if (pm-voltage.supported  pm-voltage_set  perflvl-voltage) {
 		ret = pm-voltage_set(dev, perflvl-voltage);
 		if (ret) {
@@ -72,13 +79,27 @@ nouveau_pm_perflvl_set(struct drm_device *dev, struct nouveau_pm_level *perflvl)
 		}
 	}
 
+	ret = pm-pause(dev);
+	if (ret)
+		return ret;
+
 	nouveau_pm_clock_set(dev, perflvl, PLL_CORE, perflvl-core);
 	nouveau_pm_clock_set(dev, perflvl, PLL_SHADER, perflvl-shader);
-	nouveau_pm_clock_set(dev, perflvl, PLL_MEMORY, perflvl-memory);
+	/*nouveau_pm_clock_set(dev, perflvl, PLL_MEMORY, perflvl-memory);*/
 	nouveau_pm_clock_set(dev, perflvl, PLL_UNK05, perflvl-unk05);
 
+	/* Wait for PLLs to stabilize */
+	udelay(100);
+
 	pm-cur = perflvl;
-	return 0;
+	ret = 0;
+
+	pm-unpause(dev);
+
+	NV_DEBUG(dev, Reclocking took %lluµs\n,
+		 (nv04_timer_read(dev) - start)/1000);
+
+	return ret;
 }
 
 static int
@@ -112,7 +133,6 @@ nouveau_pm_profile_set(struct drm_device *dev, const char *profile)
 			return -EINVAL;
 	}
 
-	NV_INFO(dev, setting performance level: %s\n, profile);
 	return nouveau_pm_perflvl_set(dev, perflvl);
 }
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.h b/drivers/gpu/drm/nouveau/nouveau_pm.h
index 4a9838dd..566f72d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.h
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.h
@@ -51,12 +51,16 @@ int nv04_pm_clock_get(struct drm_device *, u32 id);
 void *nv04_pm_clock_pre(struct drm_device *, struct nouveau_pm_level *,
 			u32 id

Re: [Nouveau] [Patch] Yet another version of the card pausing patch

2011-02-02 Thread Martin Peres

Le 23/01/2011 15:14, Martin Peres a écrit :

Hi everyone,

I would like devs to test this patch on all their cards(nvc0) and 
report bugs/instability. It shouldn't ever crash (but it may not 
always work and return -EAGAIN).


I've attached a little bash script that you need to modify according 
to the available perf levels. Please launch it and play, watch videos 
or browse the internet.


Also, if you could look at the hold_spin variable and tell me how you 
would deal with that, it would be kind of you. The problem is that 
PGRAPH may take an awful lot
of time to pause in certain conditions and holding the lock at this 
position isn't needed (as far as I can tell, the critical ressource is 
fifo_reassign).


Martin

PS: I'll be out in an hour for a week so I may be slower to answer 
messages.

Patch 3: Don't forget to set the name of the boot perf level.

From a7bb68ea2f2aefffd6a1254658b0d424c45622b5 Mon Sep 17 00:00:00 2001
From: Martin Peres martin.pe...@ensi-bourges.fr
Date: Thu, 3 Feb 2011 00:51:00 +0100
Subject: [PATCH 3/3] Don't forget to name the boot perflvl boot

---
 drivers/gpu/drm/nouveau/nouveau_pm.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c
index de18bf2..201a15f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -510,6 +510,7 @@ nouveau_pm_init(struct drm_device *dev)
 	/* determine current (boot) performance level */
 	ret = nouveau_pm_perflvl_get(dev, pm-boot);
 	if (ret == 0) {
+		strcpy(pm-boot.name, boot);
 		pm-cur = pm-boot;
 
 		nouveau_pm_perflvl_info(pm-boot, info, sizeof(info));
-- 
1.7.4

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


Re: [Nouveau] [lm-sensors] hwmon API update

2011-03-03 Thread Martin Peres

Dave,

The answers are inlined.

Le 03/03/2011 10:36, Dave Airlie a écrit :

Martin,

you probably should have cc'ed Matthew since it was his patch you based this on,
and I think he can provide a good explaination.

I knew he was monitoring the nouveau ML. He provided a good explanation
but forgot to CC the nouveau ML.

Could someone in the lm-sensors mailing list forward the most important 
thread?

to clarify some points,

radeon does probably want something exactly like this, we just haven't gotten to
it completely yet, I'd rather not have two drivers in the kernel for
exact same hardware,
and I believe sharing the hwmon code to do what we want is a good plan since you
don't go around reinventing wheels, but if hwmon/i2c maintainers have
no interest
it leaves with little choice but to implement about 5-10 i2c drivers
again in drm codebase.

Maybe hwmon/i2c maintainers could suggest a cleaner way to implement
what we want,
which I think I can summarize as

a) access to monitored values in-kernel
b) no userspace access to the same values except via sanitised via the driver.

a) is mandatory, b) would be great!

though I'm not following this as closely as I should so I may have
missed something.

I don't think you missed anything but long argue on the lm-sensors ML.

Dave.
The reason why I didn't answer on this matter earlier was that I was in 
the process
of moving from one city to another. I only got the internet access on 
both my computers

yesterday evening and I was planing to restart the process this week end.

It's good to see you we are not the only one needing this.

Martin

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


Re: [Nouveau] [lm-sensors] hwmon API update

2011-03-03 Thread Martin Peres

Le 03/03/2011 16:22, Guenter Roeck a écrit :

On Thu, Mar 03, 2011 at 04:36:09AM -0500, Dave Airlie wrote:

On Mon, Feb 14, 2011 at 8:08 AM, Jean Delvarekh...@linux-fr.org  wrote:

On Sun, 13 Feb 2011 09:16:40 -0800, Guenter Roeck wrote:

On Sun, Feb 13, 2011 at 07:18:44AM -0500, Martin Peres wrote:

Hi,

I am working on power management on the nouveau driver and I need a way
to get data out of and send commands to the i2c drivers from the kernel
space.

Martin,

you probably should have cc'ed Matthew since it was his patch you based this on,
and I think he can provide a good explaination.

to clarify some points,

radeon does probably want something exactly like this, we just haven't gotten to
it completely yet, I'd rather not have two drivers in the kernel for
exact same hardware,
and I believe sharing the hwmon code to do what we want is a good plan since you
don't go around reinventing wheels, but if hwmon/i2c maintainers have
no interest
it leaves with little choice but to implement about 5-10 i2c drivers
again in drm codebase.

Maybe hwmon/i2c maintainers could suggest a cleaner way to implement
what we want,
which I think I can summarize as

a) access to monitored values in-kernel
b) no userspace access to the same values except via sanitised via the driver.


This is not a matter of no interest. Interest is there, but if one demands
too much one may get nothing.

Request for b) so far was no userspace access, period. This is unacceptable
since providing userspace access to monitored values is the whole point of 
hwmon.

I could imagine an API that covers both a) and b), as long as b) focuses
on the sanitize aspect and doesn't try to limit userspace access to 
attributes.

Guenter
b) was introduced by Dave, I never asked for it because I don't mind 
duplicating sensor data (one hwmon device named nouveau and one for the 
raw access to the i2c chip).
My only wish was to provide a simple way for users to read/change their 
fan speed and get the GPU temperature no matter if their card have an 
i2c controller or not.
I do agree that sanitizing could be of interest, I especially think 
about tweaking the temperature value with parameters stored inside the 
vbios.


I am fully open to suggestions as long as it involves sharing the code 
in one way or another.


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


Re: [Nouveau] [lm-sensors] hwmon API update

2011-03-03 Thread Martin Peres

Le 03/03/2011 23:03, Guenter Roeck a écrit :

On Thu, 2011-03-03 at 16:56 -0500, Lucas Stach wrote:

Am Donnerstag, den 03.03.2011, 13:19 -0800 schrieb Guenter Roeck:

On Thu, 2011-03-03 at 15:48 -0500, Lucas Stach wrote:

Am Donnerstag, den 03.03.2011, 18:29 +0100 schrieb Martin Peres:

Le 03/03/2011 16:22, Guenter Roeck a écrit :

On Thu, Mar 03, 2011 at 04:36:09AM -0500, Dave Airlie wrote:

On Mon, Feb 14, 2011 at 8:08 AM, Jean Delvarekh...@linux-fr.org   wrote:

On Sun, 13 Feb 2011 09:16:40 -0800, Guenter Roeck wrote:

On Sun, Feb 13, 2011 at 07:18:44AM -0500, Martin Peres wrote:

Hi,

I am working on power management on the nouveau driver and I need a way
to get data out of and send commands to the i2c drivers from the kernel
space.

Martin,

you probably should have cc'ed Matthew since it was his patch you based this on,
and I think he can provide a good explaination.

to clarify some points,

radeon does probably want something exactly like this, we just haven't gotten to
it completely yet, I'd rather not have two drivers in the kernel for
exact same hardware,
and I believe sharing the hwmon code to do what we want is a good plan since you
don't go around reinventing wheels, but if hwmon/i2c maintainers have
no interest
it leaves with little choice but to implement about 5-10 i2c drivers
again in drm codebase.

Maybe hwmon/i2c maintainers could suggest a cleaner way to implement
what we want,
which I think I can summarize as

a) access to monitored values in-kernel
b) no userspace access to the same values except via sanitised via the driver.


This is not a matter of no interest. Interest is there, but if one demands
too much one may get nothing.

Request for b) so far was no userspace access, period. This is unacceptable
since providing userspace access to monitored values is the whole point of 
hwmon.

And that is what we want to do. But it would be nice if the graphics
drivers could provide a _single_ interface to userspace. Not all boards
have i2c hardware monitoring chips and with a single interface we could
fall back to the internal gpu sensor, transparently for the user.


I could imagine an API that covers both a) and b), as long as b) focuses
on the sanitize aspect and doesn't try to limit userspace access to 
attributes.

Guenter

b) was introduced by Dave, I never asked for it because I don't mind
duplicating sensor data (one hwmon device named nouveau and one for the
raw access to the i2c chip).

Sorry for the confusion Martin, I brought up the point of limiting
userspace access and did not cc the nouveau mailing list. I think it is
bad behaviour to expose values to userspace which are totally off the
real values. This confuses users and should be avoided, especially since
we can provide sanitized values.

Why should we push the logic and api for sanitizing the values to many
hwmon drivers if we could easily do this at a single point in the
graphics driver, if we provide the userspace interface ourself and use
the hwmon driver only to instrument the monitoring chip?

I don't think the functionality (nor the internal API) should have to be
implemented in individual drivers. Instead, there should be a new API
between hwmon drivers and the hwmon core. Using this API, the hwmon core
would read/write raw values from/to hwmon drivers and make those values
available to userland and to other drivers (such as the nouveau driver).
The hwmon core would then also perform sanitizing if necessary, ie call
registered sanitizing functions.

With this approach, hwmon would report sanitized values, graphics
drivers would not have to support/generate hwmon sysfs ABI attributes,
and hwmon driver structure would be much simpler, since drivers could
concentrate on getting data from and to chips instead of having to deal
with sysfs attributes. That would be a win for everyone.

Guenter

This is a bigger change than we initially aimed for and I didn't dare to
ask for such a heavy modification, but I'm very happy with this solution
if you prefer and support it this way.

If done right, it should be much less invasive than the previous
approach - meaning existing drivers would not have to be modified and
can be converted as time permits.

The previous solution already permitted that, but anyway, it's good to
see you welcome change.

u have no objections I will try to hack something together by this
weekend so we could further discuss the issue with some real code at
hand.


Sure, go ahead. I started something too, but I don't really have much
time right now.

I'm eager to see the solutions both of you have come up with!

Guenter


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


Re: [Nouveau] [lm-sensors] hwmon API update

2011-03-04 Thread Martin Peres

Le 04/03/2011 01:59, Guenter Roeck a écrit :

On Thu, Mar 03, 2011 at 06:53:12PM -0500, Martin Peres wrote:
[ ... ]

Guenter

This is a bigger change than we initially aimed for and I didn't dare to
ask for such a heavy modification, but I'm very happy with this solution
if you prefer and support it this way.

If done right, it should be much less invasive than the previous
approach - meaning existing drivers would not have to be modified and
can be converted as time permits.

The previous solution already permitted that, but anyway, it's good to
see you welcome change.

It touched all drivers. It did not move anything out of drivers, forcing drivers
supporting the new functions to support both sysfs _and_ the new functions.
Significant difference.

The idea here - at least mine - is to move sysfs attribute management
into core hwmon code.

Guenter
oh, yes, It touched a bit every driver but I already proposed the sysfs 
management
to be in the hwmon core, the advantage of the solution Matthew Garrett 
proposed was
good because it allowed the transition from the old to the new API to 
happen smoothly.


Anyway, I'm really interested in the solution you'll come up with, I 
don't mean to say

Matthew's solution is the best possible ;)

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


Re: [Nouveau] [Patch] Yet another version of the card pausing patch

2011-03-13 Thread Martin Peres

Hi everyone,

This is another update following to Ben's feedback.

Looking forward to some testing on your side (nv30 - nva0).

Martin
From 84fd9da1e34c1bc863d0274b3928333e4db39a20 Mon Sep 17 00:00:00 2001
From: Martin Peres martin.pe...@ensi-bourges.fr
Date: Wed, 19 Jan 2011 10:03:08 +0100
Subject: [PATCH 1/3] Add pm.(un)pause functions

With this patch, cards without internal memory (IONs and other IGPs)
and cards with no memory reclock (a lot of nv40) should support
safe reclocking while gaming.

This should work on all hardware( nva3), report bugs if it doesn't.

Signed-off-by: Martin Peres martin.pe...@ensi-bourges.fr
---
 drivers/gpu/drm/nouveau/nouveau_drv.h   |9 ++
 drivers/gpu/drm/nouveau/nouveau_pm.c|   24 -
 drivers/gpu/drm/nouveau/nouveau_pm.h|4 +
 drivers/gpu/drm/nouveau/nouveau_reg.h   |3 +
 drivers/gpu/drm/nouveau/nouveau_state.c |   15 +++-
 drivers/gpu/drm/nouveau/nv04_pm.c   |  126 ++
 drivers/gpu/drm/nouveau/nv50_pm.c   |  172 +++
 7 files changed, 350 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 0611188..823aee3 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -474,6 +474,10 @@ struct nouveau_pm_memtimings {
 	int nr_timing;
 };
 
+struct nouveau_pm_pause_card_state {
+	u32 reg_c040;
+};
+
 struct nouveau_pm_engine {
 	struct nouveau_pm_voltage voltage;
 	struct nouveau_pm_level perflvl[NOUVEAU_PM_MAX_LEVEL];
@@ -488,6 +492,11 @@ struct nouveau_pm_engine {
 	struct device *hwmon;
 	struct notifier_block acpi_nb;
 
+	struct nouveau_pm_pause_card_state pause_state;
+
+	int (*pause)(struct drm_device *);
+	void (*unpause)(struct drm_device *);
+
 	int (*clock_get)(struct drm_device *, u32 id);
 	void *(*clock_pre)(struct drm_device *, struct nouveau_pm_level *,
 			   u32 id, int khz);
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c
index 4399e2f..e2cde2a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -45,6 +45,10 @@ nouveau_pm_clock_set(struct drm_device *dev, struct nouveau_pm_level *perflvl,
 	if (khz == 0)
 		return 0;
 
+	/* Do no reclock the memory if the frequencies didn't change */
+	if (id == PLL_MEMORY  pm-cur-memory == khz)
+		return 0;
+
 	pre_state = pm-clock_pre(dev, perflvl, id, khz);
 	if (IS_ERR(pre_state))
 		return PTR_ERR(pre_state);
@@ -60,10 +64,13 @@ nouveau_pm_perflvl_set(struct drm_device *dev, struct nouveau_pm_level *perflvl)
 	struct drm_nouveau_private *dev_priv = dev-dev_private;
 	struct nouveau_pm_engine *pm = dev_priv-engine.pm;
 	int ret;
+	uint64_t start = nv04_timer_read(dev);
 
 	if (perflvl == pm-cur)
 		return 0;
 
+	NV_INFO(dev, setting performance level: %s\n, perflvl-name);
+
 	if (pm-voltage.supported  pm-voltage_set  perflvl-voltage) {
 		ret = pm-voltage_set(dev, perflvl-voltage);
 		if (ret) {
@@ -72,13 +79,27 @@ nouveau_pm_perflvl_set(struct drm_device *dev, struct nouveau_pm_level *perflvl)
 		}
 	}
 
+	ret = pm-pause(dev);
+	if (ret)
+		return ret;
+
 	nouveau_pm_clock_set(dev, perflvl, PLL_CORE, perflvl-core);
 	nouveau_pm_clock_set(dev, perflvl, PLL_SHADER, perflvl-shader);
 	nouveau_pm_clock_set(dev, perflvl, PLL_MEMORY, perflvl-memory);
 	nouveau_pm_clock_set(dev, perflvl, PLL_UNK05, perflvl-unk05);
 
+	/* Wait for PLLs to stabilize */
+	udelay(100);
+
 	pm-cur = perflvl;
-	return 0;
+	ret = 0;
+
+	pm-unpause(dev);
+
+	NV_DEBUG(dev, Reclocking took %lluµs\n,
+		 (nv04_timer_read(dev) - start)/1000);
+
+	return ret;
 }
 
 static int
@@ -112,7 +133,6 @@ nouveau_pm_profile_set(struct drm_device *dev, const char *profile)
 			return -EINVAL;
 	}
 
-	NV_INFO(dev, setting performance level: %s\n, profile);
 	return nouveau_pm_perflvl_set(dev, perflvl);
 }
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.h b/drivers/gpu/drm/nouveau/nouveau_pm.h
index 4a9838dd..566f72d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.h
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.h
@@ -51,12 +51,16 @@ int nv04_pm_clock_get(struct drm_device *, u32 id);
 void *nv04_pm_clock_pre(struct drm_device *, struct nouveau_pm_level *,
 			u32 id, int khz);
 void nv04_pm_clock_set(struct drm_device *, void *);
+int nv04_pm_pause(struct drm_device *dev);
+void nv04_pm_unpause(struct drm_device *dev);
 
 /* nv50_pm.c */
 int nv50_pm_clock_get(struct drm_device *, u32 id);
 void *nv50_pm_clock_pre(struct drm_device *, struct nouveau_pm_level *,
 			u32 id, int khz);
 void nv50_pm_clock_set(struct drm_device *, void *);
+int nv50_pm_pause(struct drm_device *dev);
+void nv50_pm_unpause(struct drm_device *dev);
 
 /* nva3_pm.c */
 int nva3_pm_clock_get(struct drm_device *, u32 id);
diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h
index 04e8fb7..5cf817e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_reg.h
+++ b/drivers/gpu/drm/nouveau

[Nouveau] [PATCH] Name the boot perflvl boot

2011-03-19 Thread Martin Peres
Signed-off-by: Martin Peres martin.pe...@ensi-bourges.fr
---
 drivers/gpu/drm/nouveau/nouveau_pm.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c 
b/drivers/gpu/drm/nouveau/nouveau_pm.c
index 4399e2f..0b1caeb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -490,6 +490,7 @@ nouveau_pm_init(struct drm_device *dev)
/* determine current (boot) performance level */
ret = nouveau_pm_perflvl_get(dev, pm-boot);
if (ret == 0) {
+   strncpy(pm-boot.name, boot, 4);
pm-cur = pm-boot;
 
nouveau_pm_perflvl_info(pm-boot, info, sizeof(info));
-- 
1.7.4.1

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


[Nouveau] [PATCH 1/2] Add pm.(un)pause functions

2011-03-19 Thread Martin Peres
From: Martin Peres martin.pe...@ensi-bourges.fr

With this patch, cards without internal memory (IONs and other IGPs)
and cards with no memory reclock (a lot of nv40) should support
safe reclocking while gaming.

This should work on all hardware( nva3), report bugs if it doesn't.

v2: Fix missing symbol at compilation on x86_32 systems

Signed-off-by: Martin Peres martin.pe...@ensi-bourges.fr
---
 drivers/gpu/drm/nouveau/nouveau_drv.h   |9 ++
 drivers/gpu/drm/nouveau/nouveau_pm.c|   24 -
 drivers/gpu/drm/nouveau/nouveau_pm.h|4 +
 drivers/gpu/drm/nouveau/nouveau_reg.h   |3 +
 drivers/gpu/drm/nouveau/nouveau_state.c |   15 +++-
 drivers/gpu/drm/nouveau/nv04_pm.c   |  126 ++
 drivers/gpu/drm/nouveau/nv50_pm.c   |  172 +++
 7 files changed, 350 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h 
b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 0611188..823aee3 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -474,6 +474,10 @@ struct nouveau_pm_memtimings {
int nr_timing;
 };
 
+struct nouveau_pm_pause_card_state {
+   u32 reg_c040;
+};
+
 struct nouveau_pm_engine {
struct nouveau_pm_voltage voltage;
struct nouveau_pm_level perflvl[NOUVEAU_PM_MAX_LEVEL];
@@ -488,6 +492,11 @@ struct nouveau_pm_engine {
struct device *hwmon;
struct notifier_block acpi_nb;
 
+   struct nouveau_pm_pause_card_state pause_state;
+
+   int (*pause)(struct drm_device *);
+   void (*unpause)(struct drm_device *);
+
int (*clock_get)(struct drm_device *, u32 id);
void *(*clock_pre)(struct drm_device *, struct nouveau_pm_level *,
   u32 id, int khz);
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c 
b/drivers/gpu/drm/nouveau/nouveau_pm.c
index 0b1caeb..76ada6c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -45,6 +45,10 @@ nouveau_pm_clock_set(struct drm_device *dev, struct 
nouveau_pm_level *perflvl,
if (khz == 0)
return 0;
 
+   /* Do no reclock the memory if the frequencies didn't change */
+   if (id == PLL_MEMORY  pm-cur-memory == khz)
+   return 0;
+
pre_state = pm-clock_pre(dev, perflvl, id, khz);
if (IS_ERR(pre_state))
return PTR_ERR(pre_state);
@@ -60,10 +64,13 @@ nouveau_pm_perflvl_set(struct drm_device *dev, struct 
nouveau_pm_level *perflvl)
struct drm_nouveau_private *dev_priv = dev-dev_private;
struct nouveau_pm_engine *pm = dev_priv-engine.pm;
int ret;
+   uint64_t start = nv04_timer_read(dev);
 
if (perflvl == pm-cur)
return 0;
 
+   NV_INFO(dev, setting performance level: %s\n, perflvl-name);
+
if (pm-voltage.supported  pm-voltage_set  perflvl-voltage) {
ret = pm-voltage_set(dev, perflvl-voltage);
if (ret) {
@@ -72,13 +79,27 @@ nouveau_pm_perflvl_set(struct drm_device *dev, struct 
nouveau_pm_level *perflvl)
}
}
 
+   ret = pm-pause(dev);
+   if (ret)
+   return ret;
+
nouveau_pm_clock_set(dev, perflvl, PLL_CORE, perflvl-core);
nouveau_pm_clock_set(dev, perflvl, PLL_SHADER, perflvl-shader);
nouveau_pm_clock_set(dev, perflvl, PLL_MEMORY, perflvl-memory);
nouveau_pm_clock_set(dev, perflvl, PLL_UNK05, perflvl-unk05);
 
+   /* Wait for PLLs to stabilize */
+   udelay(100);
+
pm-cur = perflvl;
-   return 0;
+   ret = 0;
+
+   pm-unpause(dev);
+
+   NV_DEBUG(dev, Reclocking took %lluns\n,
+(nv04_timer_read(dev) - start));
+
+   return ret;
 }
 
 static int
@@ -112,7 +133,6 @@ nouveau_pm_profile_set(struct drm_device *dev, const char 
*profile)
return -EINVAL;
}
 
-   NV_INFO(dev, setting performance level: %s\n, profile);
return nouveau_pm_perflvl_set(dev, perflvl);
 }
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.h 
b/drivers/gpu/drm/nouveau/nouveau_pm.h
index 4a9838dd..566f72d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.h
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.h
@@ -51,12 +51,16 @@ int nv04_pm_clock_get(struct drm_device *, u32 id);
 void *nv04_pm_clock_pre(struct drm_device *, struct nouveau_pm_level *,
u32 id, int khz);
 void nv04_pm_clock_set(struct drm_device *, void *);
+int nv04_pm_pause(struct drm_device *dev);
+void nv04_pm_unpause(struct drm_device *dev);
 
 /* nv50_pm.c */
 int nv50_pm_clock_get(struct drm_device *, u32 id);
 void *nv50_pm_clock_pre(struct drm_device *, struct nouveau_pm_level *,
u32 id, int khz);
 void nv50_pm_clock_set(struct drm_device *, void *);
+int nv50_pm_pause(struct drm_device *dev);
+void nv50_pm_unpause(struct drm_device *dev);
 
 /* nva3_pm.c */
 int nva3_pm_clock_get(struct drm_device *, u32 id

[Nouveau] Memtimings improvements

2011-03-28 Thread Martin Peres
The first patch should allow the generation of correct memtimings (r100240 put 
aside) on the nv40-nv98.a1 interval.

The second one is associating the memtimings with the performance levels.

Please comment on it or push it
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 1/2] PM: NV50-NV98.a1 correct/implement many additional memtimings Nearly consistent with envytools. Added stepping to drm_nouveau_private to make sure newer NV98 (105M) is zero rathe

2011-03-28 Thread Martin Peres
From: Roy Spliet r.spl...@student.tudelft.nl

---
 drivers/gpu/drm/nouveau/nouveau_drv.h   |2 +
 drivers/gpu/drm/nouveau/nouveau_mem.c   |   42 +-
 drivers/gpu/drm/nouveau/nouveau_state.c |2 +
 3 files changed, 33 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h 
b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 383093e..aca960e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -466,6 +466,7 @@ struct nouveau_pm_memtiming {
u32 reg_100234;
u32 reg_100238;
u32 reg_10023c;
+   u32 reg_100240;
 };
 
 struct nouveau_pm_memtimings {
@@ -637,6 +638,7 @@ struct drm_nouveau_private {
enum nouveau_card_type card_type;
/* exact chipset, derived from NV_PMC_BOOT_0 */
int chipset;
+   int stepping;
int flags;
 
void __iomem *mmio;
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c 
b/drivers/gpu/drm/nouveau/nouveau_mem.c
index 405f990..3636529 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -597,9 +597,9 @@ nouveau_mem_timing_init(struct drm_device *dev)
if (!memtimings-timing)
return;
 
-   /* Get some number from the timing reg for NV_40
+   /* Get some number from the timing reg for NV_40 and NV_50
 * Used in calculations later */
-   if (dev_priv-card_type == NV_40) {
+   if (dev_priv-card_type = NV_40  dev_priv-chipset  0x98) {
magic_number = (nv_rd32(dev, 0x100228)  0x0f00)  24;
}
 
@@ -643,7 +643,7 @@ nouveau_mem_timing_init(struct drm_device *dev)
/* XXX: I don't trust the -1's and +1's... they must come
 *  from somewhere! */
timing-reg_100224 = (tUNK_0 + tUNK_19 + 1 + magic_number)  
24 |
- tUNK_18  16 |
+ max(tUNK_18, (u8) 1)  16 |
  (tUNK_1 + tUNK_19 + 1 + magic_number)  
8;
if (dev_priv-chipset == 0xa8) {
timing-reg_100224 |= (tUNK_2 - 1);
@@ -654,15 +654,25 @@ nouveau_mem_timing_init(struct drm_device *dev)
timing-reg_100228 = (tUNK_12  16 | tUNK_11  8 | tUNK_10);
if (dev_priv-chipset = 0xa3  dev_priv-chipset  0xaa) {
timing-reg_100228 |= (tUNK_19 - 1)  24;
-   }
+   } else {
+   timing-reg_100228 |= magic_number  24;
+}
 
if (dev_priv-card_type == NV_40) {
/* NV40: don't know what the rest of the regs are..
 * And don't need to know either */
-   timing-reg_100228 |= 0x2020 | magic_number  24;
+   timing-reg_100228 |= 0x2020;
} else if (dev_priv-card_type = NV_50) {
-   /* XXX: reg_10022c */
-   timing-reg_10022c = tUNK_2 - 1;
+   if(dev_priv-chipset  0x98 ||
+   (dev_priv-chipset == 0x98  
dev_priv-stepping = 0xa1)) {
+   timing-reg_10022c = (0x14 + tUNK_2)  24 |
+   0x16  16 |
+   (tUNK_2 - 1)  8 |
+   (tUNK_2 - 1);
+   } else {
+   /* XXX: reg_10022c for recentish cards */
+   timing-reg_10022c = tUNK_2 - 1;
+   }
 
timing-reg_100230 = (tUNK_20  24 | tUNK_21  16 |
  tUNK_13  8  | tUNK_13);
@@ -670,23 +680,27 @@ nouveau_mem_timing_init(struct drm_device *dev)
timing-reg_100234 = (tRAS  24 | tRC);
timing-reg_100234 += max(tUNK_10, tUNK_11)  16;
 
-   if (dev_priv-chipset  0xa3) {
+   if (dev_priv-chipset  0x98 ||
+   (dev_priv-chipset == 0x98  
dev_priv-stepping = 0xa1)) {
timing-reg_100234 |= (tUNK_2 + 2)  8;
} else {
/* XXX: +6? */
timing-reg_100234 |= (tUNK_19 + 6)  8;
}
 
-   /* XXX; reg_100238, reg_10023c
-* reg_100238: 0x00??
-* reg_10023c: 0x!!??0202 for NV50+ cards (empirical 
evidence) */
+   /* XXX; reg_100238
+* reg_100238: 0x00?? */
timing-reg_10023c = 0x202;
-   if (dev_priv-chipset  0xa3) {
+   if (dev_priv-chipset  0x98 ||
+   (dev_priv-chipset == 

[Nouveau] [PATCH 2/2] Associate memtimings with performance levels

2011-03-28 Thread Martin Peres
Signed-off-by: Martin Peres martin.pe...@ensi-bourges.fr
---
 drivers/gpu/drm/nouveau/nouveau_drv.h  |   26 ++
 drivers/gpu/drm/nouveau/nouveau_mem.c  |1 +
 drivers/gpu/drm/nouveau/nouveau_perf.c |   25 +
 drivers/gpu/drm/nouveau/nouveau_pm.c   |   14 +-
 4 files changed, 49 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h 
b/drivers/gpu/drm/nouveau/nouveau_drv.h
index aca960e..0d23671 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -426,6 +426,19 @@ struct nouveau_pm_voltage {
int nr_level;
 };
 
+struct nouveau_pm_memtiming {
+   int id;
+   u32 reg_100220;
+   u32 reg_100224;
+   u32 reg_100228;
+   u32 reg_10022c;
+   u32 reg_100230;
+   u32 reg_100234;
+   u32 reg_100238;
+   u32 reg_10023c;
+   u32 reg_100240;
+};
+
 #define NOUVEAU_PM_MAX_LEVEL 8
 struct nouveau_pm_level {
struct device_attribute dev_attr;
@@ -441,6 +454,7 @@ struct nouveau_pm_level {
u8 fanspeed;
 
u16 memscript;
+   struct nouveau_pm_memtiming *timing;
 };
 
 struct nouveau_pm_temp_sensor_constants {
@@ -457,18 +471,6 @@ struct nouveau_pm_threshold_temp {
s16 fan_boost;
 };
 
-struct nouveau_pm_memtiming {
-   u32 reg_100220;
-   u32 reg_100224;
-   u32 reg_100228;
-   u32 reg_10022c;
-   u32 reg_100230;
-   u32 reg_100234;
-   u32 reg_100238;
-   u32 reg_10023c;
-   u32 reg_100240;
-};
-
 struct nouveau_pm_memtimings {
bool supported;
struct nouveau_pm_memtiming *timing;
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c 
b/drivers/gpu/drm/nouveau/nouveau_mem.c
index 3636529..45b315c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -702,6 +702,7 @@ nouveau_mem_timing_init(struct drm_device *dev)
 
/* XXX: reg_100240? */
}
+   timing-id = i;
 
NV_DEBUG(dev, Entry %d: 220: %08x %08x %08x %08x\n, i,
 timing-reg_100220, timing-reg_100224,
diff --git a/drivers/gpu/drm/nouveau/nouveau_perf.c 
b/drivers/gpu/drm/nouveau/nouveau_perf.c
index 670e3cb..904d680 100644
--- a/drivers/gpu/drm/nouveau/nouveau_perf.c
+++ b/drivers/gpu/drm/nouveau/nouveau_perf.c
@@ -82,6 +82,7 @@ nouveau_perf_init(struct drm_device *dev)
u8 version, headerlen, recordlen, entries;
u8 *perf, *entry;
int vid, i;
+   uint8_t timing_entry = (nv_rd32(dev, NV_PEXTDEV_BOOT_0)  0x1c)  2;
 
if (bios-type == NVBIOS_BIT) {
if (bit_table(dev, 'P', P))
@@ -124,6 +125,8 @@ nouveau_perf_init(struct drm_device *dev)
for (i = 0; i  entries; i++) {
struct nouveau_pm_level *perflvl = pm-perflvl[pm-nr_perflvl];
 
+   perflvl-timing = NULL;
+
if (entry[0] == 0xff) {
entry += recordlen;
continue;
@@ -190,6 +193,28 @@ nouveau_perf_init(struct drm_device *dev)
}
}
 
+   /* get the corresponding memory timings */
+   if (pm-memtimings.supported) {
+   uint8_t timing_id = 0xff;
+
+   if (version  0x15  version  0x40 
+   timing_entry  perf[4]) {
+   uint16_t extra_data;
+   extra_data = perf[3] + (timing_entry * perf[5]);
+
+   timing_id = entry[extra_data + 1];
+   } else if (version == 0x40  timing_entry  perf[4]) {
+   uint16_t extra_data;
+   extra_data = perf[2] + (timing_entry * perf[3]);
+
+   timing_id = entry[extra_data + 1];
+   }
+
+   if (pm-memtimings.nr_timing  timing_id)
+   perflvl-timing =
+   pm-memtimings.timing[timing_id];
+   }
+
snprintf(perflvl-name, sizeof(perflvl-name),
 performance_level_%d, i);
perflvl-id = i;
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c 
b/drivers/gpu/drm/nouveau/nouveau_pm.c
index 0b1caeb..4e51404 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -156,7 +156,7 @@ nouveau_pm_perflvl_get(struct drm_device *dev, struct 
nouveau_pm_level *perflvl)
 static void
 nouveau_pm_perflvl_info(struct nouveau_pm_level *perflvl, char *ptr, int len)
 {
-   char c[16], s[16], v[16], f[16];
+   char c[16], s[16], v[16], f[16], t[16];
 
c[0] = '\0';
if (perflvl-core)
@@ -174,8 +174,12 @@ nouveau_pm_perflvl_info(struct nouveau_pm_level *perflvl, 
char *ptr, int len)
if (perflvl-fanspeed)
snprintf(f, sizeof(f

Re: [Nouveau] nouveau_pm.c: Build error

2011-04-11 Thread Martin Peres

Le 11/04/2011 15:22, Stratos Psomadakis a écrit :

In nouveau_pm.c, in the function nouveau_pm_acpi_event(), there's no
check for CONFIG_POWER_SUPPLY.

If CONFIG_POWER_SUPPLY is set to either n or m, the
power_supply_is_system_supplied() is 'missing' and there's a build error.

One solution is to add an #ifdef CONFIG_POWER_SUPPLY along with the
#ifdef CONFIG_ACPI before the function.

Thanks, I'll send a patch for that tonight.

Can I add a Reported-by: line with your name and email address?
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH] pm: fix a compilation failure when CONFIG_POWER_SUPPLY is not set

2011-04-11 Thread Martin Peres
Signed-off-by: Martin Peres martin.pe...@ensi-bourges.fr
Reported-by: Stratos Psomadakis pso...@ece.ntua.gr
---
 drivers/gpu/drm/nouveau/nouveau_pm.c |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c 
b/drivers/gpu/drm/nouveau/nouveau_pm.c
index 0b1caeb..dc8a0cc 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -449,7 +449,7 @@ nouveau_hwmon_fini(struct drm_device *dev)
 #endif
 }
 
-#ifdef CONFIG_ACPI
+#if defined(CONFIG_ACPI)  defined(CONFIG_POWER_SUPPLY)
 static int
 nouveau_pm_acpi_event(struct notifier_block *nb, unsigned long val, void *data)
 {
@@ -508,7 +508,7 @@ nouveau_pm_init(struct drm_device *dev)
 
nouveau_sysfs_init(dev);
nouveau_hwmon_init(dev);
-#ifdef CONFIG_ACPI
+#if defined(CONFIG_ACPI)  defined(CONFIG_POWER_SUPPLY)
pm-acpi_nb.notifier_call = nouveau_pm_acpi_event;
register_acpi_notifier(pm-acpi_nb);
 #endif
@@ -530,7 +530,7 @@ nouveau_pm_fini(struct drm_device *dev)
nouveau_perf_fini(dev);
nouveau_volt_fini(dev);
 
-#ifdef CONFIG_ACPI
+#if defined(CONFIG_ACPI)  defined(CONFIG_POWER_SUPPLY)
unregister_acpi_notifier(pm-acpi_nb);
 #endif
nouveau_hwmon_fini(dev);
-- 
1.7.4.4

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


[Nouveau] [PATCH] Associate memtimings with performance levels on cards = nv98

2011-04-11 Thread Martin Peres
Signed-off-by: Martin Peres martin.pe...@ensi-bourges.fr
---
 drivers/gpu/drm/nouveau/nouveau_drv.h  |   26 ++
 drivers/gpu/drm/nouveau/nouveau_mem.c  |3 ++-
 drivers/gpu/drm/nouveau/nouveau_perf.c |   25 +
 drivers/gpu/drm/nouveau/nouveau_pm.c   |   14 +-
 4 files changed, 50 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h 
b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 135d3b4..488eab7 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -409,6 +409,19 @@ struct nouveau_pm_voltage {
int nr_level;
 };
 
+struct nouveau_pm_memtiming {
+   int id;
+   u32 reg_100220;
+   u32 reg_100224;
+   u32 reg_100228;
+   u32 reg_10022c;
+   u32 reg_100230;
+   u32 reg_100234;
+   u32 reg_100238;
+   u32 reg_10023c;
+   u32 reg_100240;
+};
+
 #define NOUVEAU_PM_MAX_LEVEL 8
 struct nouveau_pm_level {
struct device_attribute dev_attr;
@@ -424,6 +437,7 @@ struct nouveau_pm_level {
u8 fanspeed;
 
u16 memscript;
+   struct nouveau_pm_memtiming *timing;
 };
 
 struct nouveau_pm_temp_sensor_constants {
@@ -440,18 +454,6 @@ struct nouveau_pm_threshold_temp {
s16 fan_boost;
 };
 
-struct nouveau_pm_memtiming {
-   u32 reg_100220;
-   u32 reg_100224;
-   u32 reg_100228;
-   u32 reg_10022c;
-   u32 reg_100230;
-   u32 reg_100234;
-   u32 reg_100238;
-   u32 reg_10023c;
-   u32 reg_100240;
-};
-
 struct nouveau_pm_memtimings {
bool supported;
struct nouveau_pm_memtiming *timing;
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c 
b/drivers/gpu/drm/nouveau/nouveau_mem.c
index 9c7bc3f..847d476 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -706,6 +706,7 @@ nouveau_mem_timing_init(struct drm_device *dev)
 
/* XXX: reg_100240? */
}
+   timing-id = i;
 
NV_DEBUG(dev, Entry %d: 220: %08x %08x %08x %08x\n, i,
 timing-reg_100220, timing-reg_100224,
@@ -717,7 +718,7 @@ nouveau_mem_timing_init(struct drm_device *dev)
}
 
memtimings-nr_timing = entries;
-   memtimings-supported = true;
+   memtimings-supported = (dev_priv-chipset = 0x98);
 }
 
 void
diff --git a/drivers/gpu/drm/nouveau/nouveau_perf.c 
b/drivers/gpu/drm/nouveau/nouveau_perf.c
index 670e3cb..904d680 100644
--- a/drivers/gpu/drm/nouveau/nouveau_perf.c
+++ b/drivers/gpu/drm/nouveau/nouveau_perf.c
@@ -82,6 +82,7 @@ nouveau_perf_init(struct drm_device *dev)
u8 version, headerlen, recordlen, entries;
u8 *perf, *entry;
int vid, i;
+   uint8_t timing_entry = (nv_rd32(dev, NV_PEXTDEV_BOOT_0)  0x1c)  2;
 
if (bios-type == NVBIOS_BIT) {
if (bit_table(dev, 'P', P))
@@ -124,6 +125,8 @@ nouveau_perf_init(struct drm_device *dev)
for (i = 0; i  entries; i++) {
struct nouveau_pm_level *perflvl = pm-perflvl[pm-nr_perflvl];
 
+   perflvl-timing = NULL;
+
if (entry[0] == 0xff) {
entry += recordlen;
continue;
@@ -190,6 +193,28 @@ nouveau_perf_init(struct drm_device *dev)
}
}
 
+   /* get the corresponding memory timings */
+   if (pm-memtimings.supported) {
+   uint8_t timing_id = 0xff;
+
+   if (version  0x15  version  0x40 
+   timing_entry  perf[4]) {
+   uint16_t extra_data;
+   extra_data = perf[3] + (timing_entry * perf[5]);
+
+   timing_id = entry[extra_data + 1];
+   } else if (version == 0x40  timing_entry  perf[4]) {
+   uint16_t extra_data;
+   extra_data = perf[2] + (timing_entry * perf[3]);
+
+   timing_id = entry[extra_data + 1];
+   }
+
+   if (pm-memtimings.nr_timing  timing_id)
+   perflvl-timing =
+   pm-memtimings.timing[timing_id];
+   }
+
snprintf(perflvl-name, sizeof(perflvl-name),
 performance_level_%d, i);
perflvl-id = i;
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c 
b/drivers/gpu/drm/nouveau/nouveau_pm.c
index 0b1caeb..4e51404 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -156,7 +156,7 @@ nouveau_pm_perflvl_get(struct drm_device *dev, struct 
nouveau_pm_level *perflvl)
 static void
 nouveau_pm_perflvl_info(struct nouveau_pm_level *perflvl, char *ptr, int len)
 {
-   char c[16], s[16], v[16], f[16];
+   char c[16], s[16], v[16], f[16], t[16

[Nouveau] [PATCH] drm/nouveau: Associate memtimings with performance levels on cards = nv98

2011-04-13 Thread Martin Peres
Signed-off-by: Martin Peres martin.pe...@ensi-bourges.fr
---
 drivers/gpu/drm/nouveau/nouveau_drv.h  |   26 ++
 drivers/gpu/drm/nouveau/nouveau_mem.c  |3 ++-
 drivers/gpu/drm/nouveau/nouveau_perf.c |   25 +
 drivers/gpu/drm/nouveau/nouveau_pm.c   |   14 +-
 4 files changed, 50 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h 
b/drivers/gpu/drm/nouveau/nouveau_drv.h
index d42088d..a2e2a15 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -410,6 +410,19 @@ struct nouveau_pm_voltage {
int nr_level;
 };
 
+struct nouveau_pm_memtiming {
+   int id;
+   u32 reg_100220;
+   u32 reg_100224;
+   u32 reg_100228;
+   u32 reg_10022c;
+   u32 reg_100230;
+   u32 reg_100234;
+   u32 reg_100238;
+   u32 reg_10023c;
+   u32 reg_100240;
+};
+
 #define NOUVEAU_PM_MAX_LEVEL 8
 struct nouveau_pm_level {
struct device_attribute dev_attr;
@@ -425,6 +438,7 @@ struct nouveau_pm_level {
u8 fanspeed;
 
u16 memscript;
+   struct nouveau_pm_memtiming *timing;
 };
 
 struct nouveau_pm_temp_sensor_constants {
@@ -441,18 +455,6 @@ struct nouveau_pm_threshold_temp {
s16 fan_boost;
 };
 
-struct nouveau_pm_memtiming {
-   u32 reg_100220;
-   u32 reg_100224;
-   u32 reg_100228;
-   u32 reg_10022c;
-   u32 reg_100230;
-   u32 reg_100234;
-   u32 reg_100238;
-   u32 reg_10023c;
-   u32 reg_100240;
-};
-
 struct nouveau_pm_memtimings {
bool supported;
struct nouveau_pm_memtiming *timing;
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c 
b/drivers/gpu/drm/nouveau/nouveau_mem.c
index 9c7bc3f..847d476 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -706,6 +706,7 @@ nouveau_mem_timing_init(struct drm_device *dev)
 
/* XXX: reg_100240? */
}
+   timing-id = i;
 
NV_DEBUG(dev, Entry %d: 220: %08x %08x %08x %08x\n, i,
 timing-reg_100220, timing-reg_100224,
@@ -717,7 +718,7 @@ nouveau_mem_timing_init(struct drm_device *dev)
}
 
memtimings-nr_timing = entries;
-   memtimings-supported = true;
+   memtimings-supported = (dev_priv-chipset = 0x98);
 }
 
 void
diff --git a/drivers/gpu/drm/nouveau/nouveau_perf.c 
b/drivers/gpu/drm/nouveau/nouveau_perf.c
index 670e3cb..904d680 100644
--- a/drivers/gpu/drm/nouveau/nouveau_perf.c
+++ b/drivers/gpu/drm/nouveau/nouveau_perf.c
@@ -82,6 +82,7 @@ nouveau_perf_init(struct drm_device *dev)
u8 version, headerlen, recordlen, entries;
u8 *perf, *entry;
int vid, i;
+   uint8_t timing_entry = (nv_rd32(dev, NV_PEXTDEV_BOOT_0)  0x1c)  2;
 
if (bios-type == NVBIOS_BIT) {
if (bit_table(dev, 'P', P))
@@ -124,6 +125,8 @@ nouveau_perf_init(struct drm_device *dev)
for (i = 0; i  entries; i++) {
struct nouveau_pm_level *perflvl = pm-perflvl[pm-nr_perflvl];
 
+   perflvl-timing = NULL;
+
if (entry[0] == 0xff) {
entry += recordlen;
continue;
@@ -190,6 +193,28 @@ nouveau_perf_init(struct drm_device *dev)
}
}
 
+   /* get the corresponding memory timings */
+   if (pm-memtimings.supported) {
+   uint8_t timing_id = 0xff;
+
+   if (version  0x15  version  0x40 
+   timing_entry  perf[4]) {
+   uint16_t extra_data;
+   extra_data = perf[3] + (timing_entry * perf[5]);
+
+   timing_id = entry[extra_data + 1];
+   } else if (version == 0x40  timing_entry  perf[4]) {
+   uint16_t extra_data;
+   extra_data = perf[2] + (timing_entry * perf[3]);
+
+   timing_id = entry[extra_data + 1];
+   }
+
+   if (pm-memtimings.nr_timing  timing_id)
+   perflvl-timing =
+   pm-memtimings.timing[timing_id];
+   }
+
snprintf(perflvl-name, sizeof(perflvl-name),
 performance_level_%d, i);
perflvl-id = i;
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c 
b/drivers/gpu/drm/nouveau/nouveau_pm.c
index dc8a0cc..da8d994 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -156,7 +156,7 @@ nouveau_pm_perflvl_get(struct drm_device *dev, struct 
nouveau_pm_level *perflvl)
 static void
 nouveau_pm_perflvl_info(struct nouveau_pm_level *perflvl, char *ptr, int len)
 {
-   char c[16], s[16], v[16], f[16];
+   char c[16], s[16], v[16], f[16], t[16

Re: [Nouveau] [PATCH] drm/nouveau: Associate memtimings with performance levels on cards = nv98

2011-04-13 Thread Martin Peres

Le 13/04/2011 09:35, Martin Peres a écrit :

Signed-off-by: Martin Peresmartin.pe...@ensi-bourges.fr
---
  drivers/gpu/drm/nouveau/nouveau_drv.h  |   26 ++
  drivers/gpu/drm/nouveau/nouveau_mem.c  |3 ++-
  drivers/gpu/drm/nouveau/nouveau_perf.c |   25 +
  drivers/gpu/drm/nouveau/nouveau_pm.c   |   14 +-
  4 files changed, 50 insertions(+), 18 deletions(-)

Updated to apply cleanly on master.

Also, I prefixed the commit name with drm/nouveau: .
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH] drm/nouveau: Associate memtimings with performance levels on cards = nv98

2011-04-13 Thread Martin Peres
Signed-off-by: Martin Peres martin.pe...@ensi-bourges.fr
---
 drivers/gpu/drm/nouveau/nouveau_drv.h  |   26 ++
 drivers/gpu/drm/nouveau/nouveau_mem.c  |3 ++-
 drivers/gpu/drm/nouveau/nouveau_perf.c |   25 +
 drivers/gpu/drm/nouveau/nouveau_pm.c   |   14 +-
 4 files changed, 50 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h 
b/drivers/gpu/drm/nouveau/nouveau_drv.h
index d42088d..a2e2a15 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -410,6 +410,19 @@ struct nouveau_pm_voltage {
int nr_level;
 };
 
+struct nouveau_pm_memtiming {
+   int id;
+   u32 reg_100220;
+   u32 reg_100224;
+   u32 reg_100228;
+   u32 reg_10022c;
+   u32 reg_100230;
+   u32 reg_100234;
+   u32 reg_100238;
+   u32 reg_10023c;
+   u32 reg_100240;
+};
+
 #define NOUVEAU_PM_MAX_LEVEL 8
 struct nouveau_pm_level {
struct device_attribute dev_attr;
@@ -425,6 +438,7 @@ struct nouveau_pm_level {
u8 fanspeed;
 
u16 memscript;
+   struct nouveau_pm_memtiming *timing;
 };
 
 struct nouveau_pm_temp_sensor_constants {
@@ -441,18 +455,6 @@ struct nouveau_pm_threshold_temp {
s16 fan_boost;
 };
 
-struct nouveau_pm_memtiming {
-   u32 reg_100220;
-   u32 reg_100224;
-   u32 reg_100228;
-   u32 reg_10022c;
-   u32 reg_100230;
-   u32 reg_100234;
-   u32 reg_100238;
-   u32 reg_10023c;
-   u32 reg_100240;
-};
-
 struct nouveau_pm_memtimings {
bool supported;
struct nouveau_pm_memtiming *timing;
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c 
b/drivers/gpu/drm/nouveau/nouveau_mem.c
index 9c7bc3f..847d476 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -706,6 +706,7 @@ nouveau_mem_timing_init(struct drm_device *dev)
 
/* XXX: reg_100240? */
}
+   timing-id = i;
 
NV_DEBUG(dev, Entry %d: 220: %08x %08x %08x %08x\n, i,
 timing-reg_100220, timing-reg_100224,
@@ -717,7 +718,7 @@ nouveau_mem_timing_init(struct drm_device *dev)
}
 
memtimings-nr_timing = entries;
-   memtimings-supported = true;
+   memtimings-supported = (dev_priv-chipset = 0x98);
 }
 
 void
diff --git a/drivers/gpu/drm/nouveau/nouveau_perf.c 
b/drivers/gpu/drm/nouveau/nouveau_perf.c
index 670e3cb..950caba 100644
--- a/drivers/gpu/drm/nouveau/nouveau_perf.c
+++ b/drivers/gpu/drm/nouveau/nouveau_perf.c
@@ -82,6 +82,7 @@ nouveau_perf_init(struct drm_device *dev)
u8 version, headerlen, recordlen, entries;
u8 *perf, *entry;
int vid, i;
+   u8 ramcfg = (nv_rd32(dev, NV_PEXTDEV_BOOT_0)  0x1c)  2;
 
if (bios-type == NVBIOS_BIT) {
if (bit_table(dev, 'P', P))
@@ -124,6 +125,8 @@ nouveau_perf_init(struct drm_device *dev)
for (i = 0; i  entries; i++) {
struct nouveau_pm_level *perflvl = pm-perflvl[pm-nr_perflvl];
 
+   perflvl-timing = NULL;
+
if (entry[0] == 0xff) {
entry += recordlen;
continue;
@@ -190,6 +193,28 @@ nouveau_perf_init(struct drm_device *dev)
}
}
 
+   /* get the corresponding memory timings */
+   if (pm-memtimings.supported) {
+   u8 timing_id = 0xff;
+
+   if (version  0x15  version  0x40 
+   ramcfg  perf[4]) {
+   u16 extra_data;
+   extra_data = perf[3] + (ramcfg * perf[5]);
+
+   timing_id = entry[extra_data + 1];
+   } else if (version == 0x40  ramcfg  perf[4]) {
+   u16 extra_data;
+   extra_data = perf[2] + (ramcfg * perf[3]);
+
+   timing_id = entry[extra_data + 1];
+   }
+
+   if (pm-memtimings.nr_timing  timing_id)
+   perflvl-timing =
+   pm-memtimings.timing[timing_id];
+   }
+
snprintf(perflvl-name, sizeof(perflvl-name),
 performance_level_%d, i);
perflvl-id = i;
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c 
b/drivers/gpu/drm/nouveau/nouveau_pm.c
index dc8a0cc..da8d994 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -156,7 +156,7 @@ nouveau_pm_perflvl_get(struct drm_device *dev, struct 
nouveau_pm_level *perflvl)
 static void
 nouveau_pm_perflvl_info(struct nouveau_pm_level *perflvl, char *ptr, int len)
 {
-   char c[16], s[16], v[16], f[16];
+   char c[16], s[16], v[16], f[16], t[16];
 
c[0] = '\0';
if (perflvl-core

[Nouveau] [PATCH] drm/nvc0/pm: read core/shader/memory clocks (more) correctly

2011-04-17 Thread Martin Peres
---
 drivers/gpu/drm/nouveau/nouveau_perf.c |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_perf.c 
b/drivers/gpu/drm/nouveau/nouveau_perf.c
index 950caba..d64a98a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_perf.c
+++ b/drivers/gpu/drm/nouveau/nouveau_perf.c
@@ -177,9 +177,9 @@ nouveau_perf_init(struct drm_device *dev)
 #define subent(n) entry[perf[2] + ((n) * perf[3])]
perflvl-fanspeed = 0; /*XXX*/
perflvl-voltage = entry[2];
-   perflvl-core = (ROM16(subent(0))  0xfff) * 1000;
-   perflvl-shader = (ROM16(subent(1))  0xfff) * 1000;
-   perflvl-memory = (ROM16(subent(2))  0xfff) * 1000;
+   perflvl-core = (ROM16(subent(3))  0xfff) * 1000;
+   perflvl-shader = (ROM16(subent(3))  0xfff) / 2 * 1000;
+   perflvl-memory = (ROM16(subent(5))  0xfff) * 1000;
break;
}
 
-- 
1.7.4.4

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


Re: [Nouveau] [PATCH] drm/nvc0/pm: read core/shader/memory clocks (more) correctly

2011-04-17 Thread Martin Peres

Le 18/04/2011 00:32, Ben Skeggs a écrit :

On Sun, 2011-04-17 at 17:10 +0200, Martin Peres wrote:

---
  drivers/gpu/drm/nouveau/nouveau_perf.c |6 +++---
  1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_perf.c 
b/drivers/gpu/drm/nouveau/nouveau_perf.c
index 950caba..d64a98a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_perf.c
+++ b/drivers/gpu/drm/nouveau/nouveau_perf.c
@@ -177,9 +177,9 @@ nouveau_perf_init(struct drm_device *dev)
  #define subent(n) entry[perf[2] + ((n) * perf[3])]
perflvl-fanspeed = 0; /*XXX*/
perflvl-voltage = entry[2];
-   perflvl-core = (ROM16(subent(0))  0xfff) * 1000;
-   perflvl-shader = (ROM16(subent(1))  0xfff) * 1000;
-   perflvl-memory = (ROM16(subent(2))  0xfff) * 1000;
+   perflvl-core = (ROM16(subent(3))  0xfff) * 1000;
+   perflvl-shader = (ROM16(subent(3))  0xfff) / 2 * 1000;
+   perflvl-memory = (ROM16(subent(5))  0xfff) * 1000;

Um, NACK.  This is *definitely* very very wrong on NVA8, which uses
version 0x40 of this table too.

Ben.
Crap, I would have sworn this table was introduced for Fermi! Sorry for 
the noise then, I'll try to find a fix for that (other than looking at 
the codename).

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


Re: [Nouveau] [PATCH] drm/nvc0/pm: read core/shader/memory clocks (more) correctly

2011-04-17 Thread Martin Peres

Le 18/04/2011 00:56, Ben Skeggs a écrit :

On Mon, 2011-04-18 at 00:54 +0200, Martin Peres wrote:

Le 18/04/2011 00:32, Ben Skeggs a écrit :

On Sun, 2011-04-17 at 17:10 +0200, Martin Peres wrote:

---
   drivers/gpu/drm/nouveau/nouveau_perf.c |6 +++---
   1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_perf.c 
b/drivers/gpu/drm/nouveau/nouveau_perf.c
index 950caba..d64a98a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_perf.c
+++ b/drivers/gpu/drm/nouveau/nouveau_perf.c
@@ -177,9 +177,9 @@ nouveau_perf_init(struct drm_device *dev)
   #define subent(n) entry[perf[2] + ((n) * perf[3])]
perflvl-fanspeed = 0; /*XXX*/
perflvl-voltage = entry[2];
-   perflvl-core = (ROM16(subent(0))   0xfff) * 1000;
-   perflvl-shader = (ROM16(subent(1))   0xfff) * 1000;
-   perflvl-memory = (ROM16(subent(2))   0xfff) * 1000;
+   perflvl-core = (ROM16(subent(3))   0xfff) * 1000;
+   perflvl-shader = (ROM16(subent(3))   0xfff) / 2 * 
1000;
+   perflvl-memory = (ROM16(subent(5))   0xfff) * 1000;

Um, NACK.  This is *definitely* very very wrong on NVA8, which uses
version 0x40 of this table too.

Ben.

Crap, I would have sworn this table was introduced for Fermi! Sorry for
the noise then, I'll try to find a fix for that (other than looking at
the codename).

I'm highly skeptical that it's correct on fermi too, but, I can't check
that myself right now.  I shall do it during the week however.

Ben.
I was also highly skeptical about this, but I looked at all the vbios 
and it seemed good on all of them.


Then, I looked at tools like nibitor or Fermi bios editor 
(http://www.xtremesystems.org/forums/showthread.php?t=256367) which also 
highlights the subentries 3 and 5.


I'll look further and try to see if ramcfg could help us select the 
right subentries.

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


Re: [Nouveau] [PATCH 0/2] Safer reclocking

2011-04-19 Thread Martin Peres

Le 19/04/2011 04:45, Maxim Levitsky a écrit :

On Sat, 2011-03-19 at 23:14 +0100, Martin Peres wrote:

This version corrects the missing symbol linking error you could get by 
compiling on a x86_32 kernel:
ERROR: __udivdi3 [drivers/gpu/drm/nouveau/nouveau.ko] undefined!

Again, please test it on hw ranging from nv30 to nva0 (nvac/ION is supported)

Martin Peres, Hi!

Any update on this support?

Yes, I have a patch pending. I'll release it in a few days if you want.

The old patch of yours that works fine on my card surely doesn't apply
to latest git. I am going to forward-port it so I could switch to next
kernel, but I was thinking that maybe you have a new version of this
patch, so I won't waste my time.

Please, don't. I already have done it ;)

Without this patch, reclocking is very very unstable as you know, but I
need it to keep card temperature within reasonable bounds.

(And pref level 0 gives me ~50 FPS in compiz)

Speaking of performance, offtopic, nouvaeu + kwin isn't usable at all,
but compiz really is.

KWin works great for me on nouveau.

Kwin on the other hand is dead slow even on perf level 2, and
surprisingly, even if I start compiz in KDE it is significantly slower
that same compiz in Gnome (but usable).

And when I move mouse over any Qt application, FPS drops below 5 FPS,
probably due to mixture of Xrender and GL calls.
So nouveau + kwin is absolutely not usable.

compiz + gnome without any open windows shows ~300 FPS on perf level 2
slightly higher that nvidia blob.
I don't know if I have 300 fps because I cap it at 60fps, this isn't 
useful to draw faster than that.

I own quite slow card, nvidia geforce 8400M GS, codename NV86

I am looking forward to switch to KDE in near future.

Well, really, I don't understand what's slow on your card :s

Best regards,
Maxim Levitsky



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


Re: [Nouveau] Any effort on tegra?

2011-04-20 Thread Martin Peres

Le 20/04/2011 02:11, Hanno Böck a écrit :

Am Wed, 20 Apr 2011 01:28:30 +0200
schrieb Lucas Stachd...@lynxeye.de:


No, sorry. Tegras are significantly different from normal nvidia
chipsets. Some knowledge can be applied, but it's likely easier to
write a new driver for tegras than adapting nouveau. So there are no
efforts in supporting tegra within nouveau.

Ok, thanks anyway for the info (and keep on your good work).

As I may not be the only one asking that, I've added your answer to the
FAQ on your webpage/wiki.

Very good! Thanks!
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH 2/2] drm/nouveau/nv50: reclock memory using PMS on nv50

2011-04-27 Thread Martin Peres
From: Martin Peres martin.pe...@ensi-bourges.fr

Signed-off-by: Martin Peres martin.pe...@ensi-bourges.fr
---
 drivers/gpu/drm/nouveau/nouveau_pm.c  |7 +-
 drivers/gpu/drm/nouveau/nouveau_pms.h |   98 +
 drivers/gpu/drm/nouveau/nv50_pm.c |  153 ++---
 3 files changed, 243 insertions(+), 15 deletions(-)
 create mode 100644 drivers/gpu/drm/nouveau/nouveau_pms.h

diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c 
b/drivers/gpu/drm/nouveau/nouveau_pm.c
index 3bffe60..abc0ef9 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -79,13 +79,16 @@ nouveau_pm_perflvl_set(struct drm_device *dev, struct 
nouveau_pm_level *perflvl)
}
}
 
+   nouveau_pm_clock_set(dev, perflvl, PLL_MEMORY, perflvl-memory);
+
ret = pm-pause(dev);
-   if (ret)
+   if (ret) {
+   nouveau_pm_clock_set(dev, pm-cur, PLL_MEMORY, perflvl-memory);
return ret;
+   }
 
nouveau_pm_clock_set(dev, perflvl, PLL_CORE, perflvl-core);
nouveau_pm_clock_set(dev, perflvl, PLL_SHADER, perflvl-shader);
-   nouveau_pm_clock_set(dev, perflvl, PLL_MEMORY, perflvl-memory);
nouveau_pm_clock_set(dev, perflvl, PLL_UNK05, perflvl-unk05);
 
/* Wait for PLLs to stabilize */
diff --git a/drivers/gpu/drm/nouveau/nouveau_pms.h 
b/drivers/gpu/drm/nouveau/nouveau_pms.h
new file mode 100644
index 000..d7a445b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_pms.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2010 Red Hat Inc.
+ *
+ * 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: Ben Skeggs
+ */
+
+#ifndef __NOUVEAU_PMS_H__
+#define __NOUVEAU_PMS_H__
+
+struct pms_ucode {
+   u8 data[256];
+   union {
+   u8  *u08;
+   u16 *u16;
+   u32 *u32;
+   } ptr;
+   u16 len;
+
+   u32 reg;
+   u32 val;
+};
+
+static inline void
+pms_init(struct pms_ucode *pms)
+{
+   pms-ptr.u08 = pms-data;
+   pms-reg = 0x;
+   pms-val = 0x;
+}
+
+static inline void
+pms_fini(struct pms_ucode *pms)
+{
+   do {
+   *pms-ptr.u08++ = 0x7f;
+   pms-len = pms-ptr.u08 - pms-data;
+   } while (pms-len  3);
+   pms-ptr.u08 = pms-data;
+}
+
+static inline void
+pms_unkn(struct pms_ucode *pms, u8 v0)
+{
+   *pms-ptr.u08++ = v0;
+}
+
+static inline void
+pms_op5f(struct pms_ucode *pms, u8 v0, u8 v1)
+{
+   *pms-ptr.u08++ = 0x5f;
+   *pms-ptr.u08++ = v0;
+   *pms-ptr.u08++ = v1;
+}
+
+static inline void
+pms_wr32(struct pms_ucode *pms, u32 reg, u32 val)
+{
+   if (val != pms-val) {
+   if ((val  0x) == (pms-val  0x)) {
+   *pms-ptr.u08++ = 0x42;
+   *pms-ptr.u16++ = (val  0x);
+   } else {
+   *pms-ptr.u08++ = 0xe2;
+   *pms-ptr.u32++ = val;
+   }
+
+   pms-val = val;
+   }
+
+   if ((reg  0x) == (pms-reg  0x)) {
+   *pms-ptr.u08++ = 0x40;
+   *pms-ptr.u16++ = (reg  0x);
+   } else {
+   *pms-ptr.u08++ = 0xe0;
+   *pms-ptr.u32++ = reg;
+   }
+   pms-reg = reg;
+}
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/nv50_pm.c 
b/drivers/gpu/drm/nouveau/nv50_pm.c
index 4dd2d76..9b81f03 100644
--- a/drivers/gpu/drm/nouveau/nv50_pm.c
+++ b/drivers/gpu/drm/nouveau/nv50_pm.c
@@ -26,9 +26,11 @@
 #include nouveau_drv.h
 #include nouveau_bios.h
 #include nouveau_pm.h
+#include nouveau_pms.h
 
 struct nv50_pm_state {
struct nouveau_pm_level *perflvl;
+   struct pms_ucode ucode;
struct pll_lims pll;
enum pll_types type;
int N, M, P;
@@ -73,14 +75,20 @@ void *
 nv50_pm_clock_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl,
  u32 id, int khz

Re: [Nouveau] [PATCH 0/2] reclocking stability improvements

2011-04-28 Thread Martin Peres

Le 28/04/2011 12:32, Maxim Levitsky a écrit :

On Thu, 2011-04-28 at 01:58 +0200, Martin Peres wrote:

Hi everyone,

I would like everyone to test this set of patch as we'll need them quite soon 
for timing management on nv50.

Please report success/failure by answering to this email.

Thanks in advance,
Martin

I tested this.
Patch seems to work except following problems:

Sometimes reclocking fails like this:

root@maxim-laptop:/home/maxim# echo 2  
/sys/class/drm/card0/device/performance_level
bash: echo: write error: Resource temporarily unavailable
This is expected. Unfortunately, I can't do anything better than this 
for the upcoming months. I need help from the people really into the 
command submission system.


[  630.371117] [drm] nouveau :01:00.0: setting performance level: 
performance_level_2
[  630.412048] [drm] nouveau :01:00.0: PFIFO DMA_PUSH never depleted 
(0xd06091)
I consider it not safe to reclock core if PFIFO DMA_PUSH isn't empty. 
Hence the reason why I abort there.

Once it even  hang the GPU.
This shouldn't happen but I managed to hang it too once. Anyway, this 
isn't perfect but still way better than what is currently implemented.

Easy to reproduce while running compiz and its benchmark overlay.

Exactly, when playing open arena, the success ratio is very very low but 
I don't mind yet. I first want stability and then reliability.

Also, it seems not to restore perf level after resume from ram.
Good catch, I thought I had fixed that but it doesn't seem like. I'll 
fix this tonight and send an update. Thanks a lot.

Best regards
Maxim Levitsky

Thanks a lot for testing it Maxim.

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


Re: [Nouveau] [PATCH 0/2] reclocking stability improvements

2011-04-28 Thread Martin Peres

Le 28/04/2011 13:43, Maxim Levitsky a écrit :


Martin, one more thing, this is my observations regarding clocks I
finished today:


clock = (ref * N / M)  (P  0x7)

first line is blob, second nouveau

level0:
  P NNMM
 0x4008 - memory - 0018e200 2505   = 1   = 01.
   80016400 2505   = 37 / 5 / 2  = 03.7000

 0x4020 - shader - 8001 0b01   = 11 / 1 / 2  = 05.5000
   8002 1b02   = 27 / 2 / 4  = 03.3750

 0x4028 - core   - a012 1b04   = 27 / 4 / 4  = 01.6875
   a002 1b04   = 27 / 4 / 4  = 01.6875

 0x4030 - unk_05 - a012 0b02   = 11 / 2 / 4  = 01.3750
   8002 1b04   = 27 / 4 / 4  = 01.6875

level1:

 0x4008 - memory - 809ae400 2505   = 37 / 5 / 4  = 01.8500
   80026400 2505   = 37 / 5 / 4  = 01.8500

 0x4020 - shader - 8000 0b01   = 11 / 1 / 1  = 11.
   8001 0b01   = 11 / 1 / 2  = 05.5000

 0x4028 - core   - a009 0b02   = 11 / 2 / 1  = 05.5000
   a001 0b02   = 11 / 2 / 1  = 05.5000

 0x4030 - unk_05 - a012 0b02   = 11 / 2 / 4  = 01.3750
   8001 0b02   = 11 / 2 / 2  = 05.5000

level2:

 0x4008 - memory - 8059e400 2505   = 37 / 5 / 2  = 03.7000
   80016400 2505   = 37 / 5 / 2  = 03.7000

 0x4020 - shader - 8000 0b01   = 11 / 1 / 1  = 11.
   8000 1002   = 16 / 2 / 1  = 08.

 0x4028 - core   - a009 1002   = 16 / 2 / 2  = 04.
   a001 1002   = 16 / 2 / 2  = 04.

 0x4030 - unk_05 - a012 0b02   = 11 / 2 / 4  = 01.3750
   8001 1202   = 18 / 2 / 2  = 06.


Clocks are very different and we seems to overclock hard the unk_05 PLL
And shader PLL is underclocked always, so another way to boost performance?
(it didn't seem to affect perfomace much here, but yet...)

Good work Maxim!

Can you please tell us what card you use? For what range of card is this 
true? I can give you access to the vbios repo so as you can contact some 
people for further testing if you want to :)


Anyway, I hope you are interested in looking deeper into this. Xexaxo 
and darktama did all the work on this.
I have no time to put on this issue in the upcoming weeks as I'm already 
working on getting the PMS patches upstream, fan management and Fermi PM.


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


Re: [Nouveau] [PATCH 0/2] reclocking stability improvements

2011-04-28 Thread Martin Peres

Le 28/04/2011 14:32, Maxim Levitsky a écrit :

On Thu, 2011-04-28 at 14:11 +0200, Martin Peres wrote:

Good work Maxim!
Can you please tell us what card you use? For what range of card is this
true? I can give you access to the vbios repo so as you can contact some
people for further testing if you want to :)

I use NV86 Geforce 8400M GS card.
Don't have much time though.
Ok, cool. I got a 8600 GS from my father, I'll see if I can reproduce 
this issue.


Too bad for your time, I'll see what I can do though. This could very 
well explain some instability I've been encountering.


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


Re: [Nouveau] [PATCH 0/2] reclocking stability improvements

2011-04-28 Thread Martin Peres

Le 28/04/2011 18:58, Maxim Levitsky a écrit :

Interesting fact is that GPU temperatures rise to very high levels
(~75C) even while doing CPU only work (like compiling kernel for
example).
Let me guess, you're on a laptop? The temperature of the case goes up 
when the processor is working and so, it cools the GPU less ;)

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


[Nouveau] [PATCH 2/2] drm/nouveau/nv50: reclock memory using PMS on nv50

2011-04-28 Thread Martin Peres
From: Martin Peres martin.pe...@ensi-bourges.fr

v2: Reclock memory after reclocking the other engines

Signed-off-by: Martin Peres martin.pe...@ensi-bourges.fr
---
 drivers/gpu/drm/nouveau/nouveau_pm.c |   11 +--
 drivers/gpu/drm/nouveau/nv50_pm.c|  153 +++---
 2 files changed, 144 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c 
b/drivers/gpu/drm/nouveau/nouveau_pm.c
index 88f58b1..44d01bb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -45,10 +45,6 @@ nouveau_pm_clock_set(struct drm_device *dev, struct 
nouveau_pm_level *perflvl,
if (khz == 0)
return 0;
 
-   /* Do no reclock the memory if the frequencies didn't change */
-   if (id == PLL_MEMORY  pm-cur-memory == khz)
-   return 0;
-
pre_state = pm-clock_pre(dev, perflvl, id, khz);
if (IS_ERR(pre_state))
return PTR_ERR(pre_state);
@@ -100,7 +96,6 @@ nouveau_pm_perflvl_set(struct drm_device *dev, struct 
nouveau_pm_level *perflvl)
 
nouveau_pm_clock_set(dev, perflvl, PLL_CORE, perflvl-core);
nouveau_pm_clock_set(dev, perflvl, PLL_SHADER, perflvl-shader);
-   nouveau_pm_clock_set(dev, perflvl, PLL_MEMORY, perflvl-memory);
nouveau_pm_clock_set(dev, perflvl, PLL_UNK05, perflvl-unk05);
 
/* Decrease the voltage if needed*/
@@ -110,11 +105,13 @@ nouveau_pm_perflvl_set(struct drm_device *dev, struct 
nouveau_pm_level *perflvl)
/* Wait for PLLs to stabilize */
udelay(100);
 
+   pm-unpause(dev);
+
+   nouveau_pm_clock_set(dev, perflvl, PLL_MEMORY, perflvl-memory);
+
pm-cur = perflvl;
ret = 0;
 
-   pm-unpause(dev);
-
NV_DEBUG(dev, Reclocking took %lluns\n,
 (nv04_timer_read(dev) - start));
 
diff --git a/drivers/gpu/drm/nouveau/nv50_pm.c 
b/drivers/gpu/drm/nouveau/nv50_pm.c
index 4dd2d76..9b81f03 100644
--- a/drivers/gpu/drm/nouveau/nv50_pm.c
+++ b/drivers/gpu/drm/nouveau/nv50_pm.c
@@ -26,9 +26,11 @@
 #include nouveau_drv.h
 #include nouveau_bios.h
 #include nouveau_pm.h
+#include nouveau_pms.h
 
 struct nv50_pm_state {
struct nouveau_pm_level *perflvl;
+   struct pms_ucode ucode;
struct pll_lims pll;
enum pll_types type;
int N, M, P;
@@ -73,14 +75,20 @@ void *
 nv50_pm_clock_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl,
  u32 id, int khz)
 {
+   struct drm_nouveau_private *dev_priv = dev-dev_private;
struct nv50_pm_state *state;
-   int dummy, ret;
+   struct pms_ucode *pms;
+   u32 reg0_old, reg0_new;
+   u32 crtc_mask;
+   u32 reg_c040;
+   int ret, dummy, i;
 
state = kzalloc(sizeof(*state), GFP_KERNEL);
if (!state)
return ERR_PTR(-ENOMEM);
state-type = id;
state-perflvl = perflvl;
+   pms = state-ucode;
 
ret = get_pll_limits(dev, id, state-pll);
if (ret  0) {
@@ -95,20 +103,88 @@ nv50_pm_clock_pre(struct drm_device *dev, struct 
nouveau_pm_level *perflvl,
return ERR_PTR(ret);
}
 
+   reg0_old = nv_rd32(dev, state-pll.reg + 0);
+   reg0_new = 0x8000 | (state-P  16) | (reg0_old  0xfff8);
+
+   reg_c040 = nv_rd32(dev, 0xc040);
+
+   crtc_mask = 0;
+   for (i = 0; i  2; i++) {
+   if (nv_rd32(dev, NV50_PDISPLAY_CRTC_C(i, CLOCK)))
+   crtc_mask |= (1  i);
+   }
+
+   pms_init(pms);
+
+   switch (state-type) {
+   case PLL_MEMORY:
+   /* Wait for vblank on all the CRTCs */
+   if (crtc_mask) {
+   pms_op5f(pms, crtc_mask, 0x00);
+   pms_op5f(pms, crtc_mask, 0x01);
+   }
+
+   pms_wr32(pms, 0x002504, 0x0001);
+   pms_unkn(pms, 0x06); /* unknown */
+   pms_unkn(pms, 0xb0); /* Disable bus access */
+   pms_op5f(pms, 0x00, 0x01);
+
+   pms_wr32(pms, 0x1002d4, 0x0001);
+   pms_wr32(pms, 0x1002d0, 0x0001);
+
+   pms_wr32(pms, 0x100210, 0x);
+   pms_wr32(pms, 0x1002dc, 0x0001);
+   pms_wr32(pms, state-pll.reg + 0, reg0_old);
+   pms_wr32(pms, state-pll.reg + 4, (state-N  8) | state-M);
+
+   pms_wr32(pms, state-pll.reg + 0, reg0_new);
+   pms_wr32(pms, 0x1002dc, 0x);
+   pms_wr32(pms, 0x100210, 0x8000);
+   pms_unkn(pms, 0x07); /* unknown */
+
+   pms_unkn(pms, 0x0b);
+   pms_unkn(pms, 0xd0); /* Enable bus access again */
+   pms_op5f(pms, 0x00, 0x01);
+   pms_wr32(pms, 0x002504, 0x);
+   break;
+   default:
+   pms_unkn(pms, 0xb0); /* Disable bus access */
+
+   pms_wr32(pms, 0xc040,
+   (reg_c040  ~(1  5 | 1  4)) | (1

[Nouveau] [PATCH 0/2] safer reclocking take 2

2011-04-28 Thread Martin Peres
Hi everyone,

This new version of the previous patchset features some memory reclocking and 
voltage management improvements.

Memory: Reclock it after all the other engines so as we don't need to reclock 
it back again if pausing didn't work.
Voltage: Bump the voltage before reclocking or lower it after reclocking. It 
should increase the stability when downclocking.

If you didn't test the previous pathset, test this one. If the former worked 
for you, this one will too.

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


[Nouveau] [PATCH 1/2] drm/nouveau/pm: Add pm.(un)pause functions

2011-04-28 Thread Martin Peres
From: Martin Peres martin.pe...@ensi-bourges.fr

With this patch, cards without internal memory (IONs and other IGPs)
and cards with no memory reclock (a lot of nv40) should support
safe reclocking while gaming.

This should work on all hardware( nva3), report bugs if it doesn't.

v2: Fix missing symbol at compilation on x86_32 systems
v3: Better voltage management

Signed-off-by: Martin Peres martin.pe...@ensi-bourges.fr
---
 drivers/gpu/drm/nouveau/nouveau_drv.h   |9 ++
 drivers/gpu/drm/nouveau/nouveau_pm.c|   57 +--
 drivers/gpu/drm/nouveau/nouveau_pm.h|4 +
 drivers/gpu/drm/nouveau/nouveau_reg.h   |3 +
 drivers/gpu/drm/nouveau/nouveau_state.c |   13 ++-
 drivers/gpu/drm/nouveau/nv04_pm.c   |  126 ++
 drivers/gpu/drm/nouveau/nv50_pm.c   |  172 +++
 7 files changed, 374 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h 
b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 9c56331..01167fd 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -462,6 +462,10 @@ struct nouveau_pm_memtimings {
int nr_timing;
 };
 
+struct nouveau_pm_pause_card_state {
+   u32 reg_c040;
+};
+
 struct nouveau_pm_engine {
struct nouveau_pm_voltage voltage;
struct nouveau_pm_level perflvl[NOUVEAU_PM_MAX_LEVEL];
@@ -476,6 +480,11 @@ struct nouveau_pm_engine {
struct device *hwmon;
struct notifier_block acpi_nb;
 
+   struct nouveau_pm_pause_card_state pause_state;
+
+   int (*pause)(struct drm_device *);
+   void (*unpause)(struct drm_device *);
+
int (*clock_get)(struct drm_device *, u32 id);
void *(*clock_pre)(struct drm_device *, struct nouveau_pm_level *,
   u32 id, int khz);
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c 
b/drivers/gpu/drm/nouveau/nouveau_pm.c
index da8d994..88f58b1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -45,6 +45,10 @@ nouveau_pm_clock_set(struct drm_device *dev, struct 
nouveau_pm_level *perflvl,
if (khz == 0)
return 0;
 
+   /* Do no reclock the memory if the frequencies didn't change */
+   if (id == PLL_MEMORY  pm-cur-memory == khz)
+   return 0;
+
pre_state = pm-clock_pre(dev, perflvl, id, khz);
if (IS_ERR(pre_state))
return PTR_ERR(pre_state);
@@ -55,30 +59,66 @@ nouveau_pm_clock_set(struct drm_device *dev, struct 
nouveau_pm_level *perflvl,
 }
 
 static int
+nouveau_pm_voltage_set(struct drm_device *dev, u8 voltage)
+{
+   struct drm_nouveau_private *dev_priv = dev-dev_private;
+   struct nouveau_pm_engine *pm = dev_priv-engine.pm;
+   int ret;
+
+   if (pm-voltage.supported  pm-voltage_set  voltage) {
+   ret = pm-voltage_set(dev, voltage);
+   if (ret) {
+   NV_ERROR(dev, voltage_set %d failed: %d\n,
+voltage, ret);
+   }
+
+   return ret;
+   } else
+   return -EIO;
+}
+
+static int
 nouveau_pm_perflvl_set(struct drm_device *dev, struct nouveau_pm_level 
*perflvl)
 {
struct drm_nouveau_private *dev_priv = dev-dev_private;
struct nouveau_pm_engine *pm = dev_priv-engine.pm;
int ret;
+   uint64_t start = nv04_timer_read(dev);
 
if (perflvl == pm-cur)
return 0;
 
-   if (pm-voltage.supported  pm-voltage_set  perflvl-voltage) {
-   ret = pm-voltage_set(dev, perflvl-voltage);
-   if (ret) {
-   NV_ERROR(dev, voltage_set %d failed: %d\n,
-perflvl-voltage, ret);
-   }
-   }
+   NV_INFO(dev, setting performance level: %s\n, perflvl-name);
+
+   ret = pm-pause(dev);
+   if (ret)
+   return ret;
+
+   /* Increase the voltage now if needed */
+   if (perflvl-voltage  pm-cur-voltage)
+   nouveau_pm_voltage_set(dev, perflvl-voltage);
 
nouveau_pm_clock_set(dev, perflvl, PLL_CORE, perflvl-core);
nouveau_pm_clock_set(dev, perflvl, PLL_SHADER, perflvl-shader);
nouveau_pm_clock_set(dev, perflvl, PLL_MEMORY, perflvl-memory);
nouveau_pm_clock_set(dev, perflvl, PLL_UNK05, perflvl-unk05);
 
+   /* Decrease the voltage if needed*/
+   if (perflvl-voltage  pm-cur-voltage)
+   nouveau_pm_voltage_set(dev, perflvl-voltage);
+
+   /* Wait for PLLs to stabilize */
+   udelay(100);
+
pm-cur = perflvl;
-   return 0;
+   ret = 0;
+
+   pm-unpause(dev);
+
+   NV_DEBUG(dev, Reclocking took %lluns\n,
+(nv04_timer_read(dev) - start));
+
+   return ret;
 }
 
 static int
@@ -112,7 +152,6 @@ nouveau_pm_profile_set(struct drm_device *dev, const char 
*profile)
return -EINVAL;
}
 
-   NV_INFO(dev

Re: [Nouveau] [PATCH 0/2] reclocking stability improvements

2011-04-28 Thread Martin Peres

Le 28/04/2011 20:29, Maxim Levitsky a écrit :

On Thu, 2011-04-28 at 20:24 +0200, Martin Peres wrote:

Le 28/04/2011 18:58, Maxim Levitsky a écrit :

Interesting fact is that GPU temperatures rise to very high levels
(~75C) even while doing CPU only work (like compiling kernel for
example).

Let me guess, you're on a laptop? The temperature of the case goes up
when the processor is working and so, it cools the GPU less ;)

Yes, but that doesn't happen while using nvidia to this extent.
I think that GPU has many units running in endless loop doing nothing
but consuming power (~5W) difference!
I really need to have a look at this. I have a power meter now (acpi 
reports me funky power consumption figures because my battery is dead).


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


Re: [Nouveau] [PATCH 0/2] reclocking stability improvements

2011-04-29 Thread Martin Peres

Le 29/04/2011 02:56, Nigel Cunningham a écrit :

Hi.

On 29/04/11 04:35, Martin Peres wrote:

Le 28/04/2011 20:29, Maxim Levitsky a écrit :

On Thu, 2011-04-28 at 20:24 +0200, Martin Peres wrote:

Le 28/04/2011 18:58, Maxim Levitsky a écrit :

Interesting fact is that GPU temperatures rise to very high levels
(~75C) even while doing CPU only work (like compiling kernel for
example).

Let me guess, you're on a laptop? The temperature of the case goes up
when the processor is working and so, it cools the GPU less ;)

Yes, but that doesn't happen while using nvidia to this extent.
I think that GPU has many units running in endless loop doing nothing
but consuming power (~5W) difference!

I really need to have a look at this. I have a power meter now (acpi
reports me funky power consumption figures because my battery is dead).

Just been reading through your posts from last night, and wanted to let
you know I'm interested and willing to test patches too.

I have an 8600GTS based laptop, and have seen the same range of power
usage (ie have seen 14W in the page - presumably when I was using the
blob -, but can only get it down to 23W at the moment using Nouveau).

Regards,

Nigel
9W! Well, you can try downclocking the card, but this won't get you down 
to 14W. When fan management is done, I'll have a look at what the blob 
does and try to find some magic there.


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


[Nouveau] (no subject)

2011-04-29 Thread Martin Peres
Sorry, forgot to add nouveau_pms.h

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


[Nouveau] [PATCH 2/2] drm/nouveau/nv50: reclock memory using PMS on nv50

2011-04-29 Thread Martin Peres
From: Martin Peres martin.pe...@ensi-bourges.fr

v2: Reclock memory after reclocking the other engines

Signed-off-by: Martin Peres martin.pe...@ensi-bourges.fr
---
 drivers/gpu/drm/nouveau/nouveau_pm.c  |   11 +--
 drivers/gpu/drm/nouveau/nouveau_pms.h |   98 +
 drivers/gpu/drm/nouveau/nv50_pm.c |  153 ++---
 3 files changed, 242 insertions(+), 20 deletions(-)
 create mode 100644 drivers/gpu/drm/nouveau/nouveau_pms.h

diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c 
b/drivers/gpu/drm/nouveau/nouveau_pm.c
index 88f58b1..44d01bb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -45,10 +45,6 @@ nouveau_pm_clock_set(struct drm_device *dev, struct 
nouveau_pm_level *perflvl,
if (khz == 0)
return 0;
 
-   /* Do no reclock the memory if the frequencies didn't change */
-   if (id == PLL_MEMORY  pm-cur-memory == khz)
-   return 0;
-
pre_state = pm-clock_pre(dev, perflvl, id, khz);
if (IS_ERR(pre_state))
return PTR_ERR(pre_state);
@@ -100,7 +96,6 @@ nouveau_pm_perflvl_set(struct drm_device *dev, struct 
nouveau_pm_level *perflvl)
 
nouveau_pm_clock_set(dev, perflvl, PLL_CORE, perflvl-core);
nouveau_pm_clock_set(dev, perflvl, PLL_SHADER, perflvl-shader);
-   nouveau_pm_clock_set(dev, perflvl, PLL_MEMORY, perflvl-memory);
nouveau_pm_clock_set(dev, perflvl, PLL_UNK05, perflvl-unk05);
 
/* Decrease the voltage if needed*/
@@ -110,11 +105,13 @@ nouveau_pm_perflvl_set(struct drm_device *dev, struct 
nouveau_pm_level *perflvl)
/* Wait for PLLs to stabilize */
udelay(100);
 
+   pm-unpause(dev);
+
+   nouveau_pm_clock_set(dev, perflvl, PLL_MEMORY, perflvl-memory);
+
pm-cur = perflvl;
ret = 0;
 
-   pm-unpause(dev);
-
NV_DEBUG(dev, Reclocking took %lluns\n,
 (nv04_timer_read(dev) - start));
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_pms.h 
b/drivers/gpu/drm/nouveau/nouveau_pms.h
new file mode 100644
index 000..d7a445b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_pms.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2010 Red Hat Inc.
+ *
+ * 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: Ben Skeggs
+ */
+
+#ifndef __NOUVEAU_PMS_H__
+#define __NOUVEAU_PMS_H__
+
+struct pms_ucode {
+   u8 data[256];
+   union {
+   u8  *u08;
+   u16 *u16;
+   u32 *u32;
+   } ptr;
+   u16 len;
+
+   u32 reg;
+   u32 val;
+};
+
+static inline void
+pms_init(struct pms_ucode *pms)
+{
+   pms-ptr.u08 = pms-data;
+   pms-reg = 0x;
+   pms-val = 0x;
+}
+
+static inline void
+pms_fini(struct pms_ucode *pms)
+{
+   do {
+   *pms-ptr.u08++ = 0x7f;
+   pms-len = pms-ptr.u08 - pms-data;
+   } while (pms-len  3);
+   pms-ptr.u08 = pms-data;
+}
+
+static inline void
+pms_unkn(struct pms_ucode *pms, u8 v0)
+{
+   *pms-ptr.u08++ = v0;
+}
+
+static inline void
+pms_op5f(struct pms_ucode *pms, u8 v0, u8 v1)
+{
+   *pms-ptr.u08++ = 0x5f;
+   *pms-ptr.u08++ = v0;
+   *pms-ptr.u08++ = v1;
+}
+
+static inline void
+pms_wr32(struct pms_ucode *pms, u32 reg, u32 val)
+{
+   if (val != pms-val) {
+   if ((val  0x) == (pms-val  0x)) {
+   *pms-ptr.u08++ = 0x42;
+   *pms-ptr.u16++ = (val  0x);
+   } else {
+   *pms-ptr.u08++ = 0xe2;
+   *pms-ptr.u32++ = val;
+   }
+
+   pms-val = val;
+   }
+
+   if ((reg  0x) == (pms-reg  0x)) {
+   *pms-ptr.u08++ = 0x40;
+   *pms-ptr.u16++ = (reg  0x);
+   } else {
+   *pms-ptr.u08++ = 0xe0;
+   *pms-ptr.u32++ = reg;
+   }
+   pms-reg = reg

[Nouveau] [PATCH 1/2] drm/nouveau/pm: Add pm.(un)pause functions

2011-04-29 Thread Martin Peres
From: Martin Peres martin.pe...@ensi-bourges.fr

With this patch, cards without internal memory (IONs and other IGPs)
and cards with no memory reclock (a lot of nv40) should support
safe reclocking while gaming.

This should work on all hardware( nva3), report bugs if it doesn't.

v2: Fix missing symbol at compilation on x86_32 systems
v3: Better voltage management

Signed-off-by: Martin Peres martin.pe...@ensi-bourges.fr
---
 drivers/gpu/drm/nouveau/nouveau_drv.h   |9 ++
 drivers/gpu/drm/nouveau/nouveau_pm.c|   57 +--
 drivers/gpu/drm/nouveau/nouveau_pm.h|4 +
 drivers/gpu/drm/nouveau/nouveau_reg.h   |3 +
 drivers/gpu/drm/nouveau/nouveau_state.c |   13 ++-
 drivers/gpu/drm/nouveau/nv04_pm.c   |  126 ++
 drivers/gpu/drm/nouveau/nv50_pm.c   |  172 +++
 7 files changed, 374 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h 
b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 9c56331..01167fd 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -462,6 +462,10 @@ struct nouveau_pm_memtimings {
int nr_timing;
 };
 
+struct nouveau_pm_pause_card_state {
+   u32 reg_c040;
+};
+
 struct nouveau_pm_engine {
struct nouveau_pm_voltage voltage;
struct nouveau_pm_level perflvl[NOUVEAU_PM_MAX_LEVEL];
@@ -476,6 +480,11 @@ struct nouveau_pm_engine {
struct device *hwmon;
struct notifier_block acpi_nb;
 
+   struct nouveau_pm_pause_card_state pause_state;
+
+   int (*pause)(struct drm_device *);
+   void (*unpause)(struct drm_device *);
+
int (*clock_get)(struct drm_device *, u32 id);
void *(*clock_pre)(struct drm_device *, struct nouveau_pm_level *,
   u32 id, int khz);
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c 
b/drivers/gpu/drm/nouveau/nouveau_pm.c
index da8d994..88f58b1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -45,6 +45,10 @@ nouveau_pm_clock_set(struct drm_device *dev, struct 
nouveau_pm_level *perflvl,
if (khz == 0)
return 0;
 
+   /* Do no reclock the memory if the frequencies didn't change */
+   if (id == PLL_MEMORY  pm-cur-memory == khz)
+   return 0;
+
pre_state = pm-clock_pre(dev, perflvl, id, khz);
if (IS_ERR(pre_state))
return PTR_ERR(pre_state);
@@ -55,30 +59,66 @@ nouveau_pm_clock_set(struct drm_device *dev, struct 
nouveau_pm_level *perflvl,
 }
 
 static int
+nouveau_pm_voltage_set(struct drm_device *dev, u8 voltage)
+{
+   struct drm_nouveau_private *dev_priv = dev-dev_private;
+   struct nouveau_pm_engine *pm = dev_priv-engine.pm;
+   int ret;
+
+   if (pm-voltage.supported  pm-voltage_set  voltage) {
+   ret = pm-voltage_set(dev, voltage);
+   if (ret) {
+   NV_ERROR(dev, voltage_set %d failed: %d\n,
+voltage, ret);
+   }
+
+   return ret;
+   } else
+   return -EIO;
+}
+
+static int
 nouveau_pm_perflvl_set(struct drm_device *dev, struct nouveau_pm_level 
*perflvl)
 {
struct drm_nouveau_private *dev_priv = dev-dev_private;
struct nouveau_pm_engine *pm = dev_priv-engine.pm;
int ret;
+   uint64_t start = nv04_timer_read(dev);
 
if (perflvl == pm-cur)
return 0;
 
-   if (pm-voltage.supported  pm-voltage_set  perflvl-voltage) {
-   ret = pm-voltage_set(dev, perflvl-voltage);
-   if (ret) {
-   NV_ERROR(dev, voltage_set %d failed: %d\n,
-perflvl-voltage, ret);
-   }
-   }
+   NV_INFO(dev, setting performance level: %s\n, perflvl-name);
+
+   ret = pm-pause(dev);
+   if (ret)
+   return ret;
+
+   /* Increase the voltage now if needed */
+   if (perflvl-voltage  pm-cur-voltage)
+   nouveau_pm_voltage_set(dev, perflvl-voltage);
 
nouveau_pm_clock_set(dev, perflvl, PLL_CORE, perflvl-core);
nouveau_pm_clock_set(dev, perflvl, PLL_SHADER, perflvl-shader);
nouveau_pm_clock_set(dev, perflvl, PLL_MEMORY, perflvl-memory);
nouveau_pm_clock_set(dev, perflvl, PLL_UNK05, perflvl-unk05);
 
+   /* Decrease the voltage if needed*/
+   if (perflvl-voltage  pm-cur-voltage)
+   nouveau_pm_voltage_set(dev, perflvl-voltage);
+
+   /* Wait for PLLs to stabilize */
+   udelay(100);
+
pm-cur = perflvl;
-   return 0;
+   ret = 0;
+
+   pm-unpause(dev);
+
+   NV_DEBUG(dev, Reclocking took %lluns\n,
+(nv04_timer_read(dev) - start));
+
+   return ret;
 }
 
 static int
@@ -112,7 +152,6 @@ nouveau_pm_profile_set(struct drm_device *dev, const char 
*profile)
return -EINVAL;
}
 
-   NV_INFO(dev

Re: [Nouveau] [PATCH 2/2] drm/nouveau/nv50: reclock memory using PMS on nv50

2011-05-06 Thread Martin Peres

Le 07/05/2011 01:42, Emil Velikov a écrit :
On Sat, 30 Apr 2011 01:17:13 +0100, Martin Peres 
martin.pe...@free.fr wrote:



From: Martin Peres martin.pe...@ensi-bourges.fr

v2: Reclock memory after reclocking the other engines

Signed-off-by: Martin Peres martin.pe...@ensi-bourges.fr
---
 drivers/gpu/drm/nouveau/nouveau_pm.c  |   11 +--
 drivers/gpu/drm/nouveau/nouveau_pms.h |   98 +
 drivers/gpu/drm/nouveau/nv50_pm.c |  153 
++---

 3 files changed, 242 insertions(+), 20 deletions(-)
 create mode 100644 drivers/gpu/drm/nouveau/nouveau_pms.h

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

index 88f58b1..44d01bb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -45,10 +45,6 @@ nouveau_pm_clock_set(struct drm_device *dev, 
struct nouveau_pm_level *perflvl,

 if (khz == 0)
 return 0;
-/* Do no reclock the memory if the frequencies didn't change */
-if (id == PLL_MEMORY  pm-cur-memory == khz)
-return 0;
-
 pre_state = pm-clock_pre(dev, perflvl, id, khz);
 if (IS_ERR(pre_state))
 return PTR_ERR(pre_state);
@@ -100,7 +96,6 @@ nouveau_pm_perflvl_set(struct drm_device *dev, 
struct nouveau_pm_level *perflvl)

nouveau_pm_clock_set(dev, perflvl, PLL_CORE, perflvl-core);
 nouveau_pm_clock_set(dev, perflvl, PLL_SHADER, perflvl-shader);
-nouveau_pm_clock_set(dev, perflvl, PLL_MEMORY, perflvl-memory);
 nouveau_pm_clock_set(dev, perflvl, PLL_UNK05, perflvl-unk05);
/* Decrease the voltage if needed*/
@@ -110,11 +105,13 @@ nouveau_pm_perflvl_set(struct drm_device *dev, 
struct nouveau_pm_level *perflvl)

 /* Wait for PLLs to stabilize */
 udelay(100);
+pm-unpause(dev);
+
+nouveau_pm_clock_set(dev, perflvl, PLL_MEMORY, perflvl-memory);
+
 pm-cur = perflvl;
 ret = 0;
-pm-unpause(dev);
-
 NV_DEBUG(dev, Reclocking took %lluns\n,
  (nv04_timer_read(dev) - start));
diff --git a/drivers/gpu/drm/nouveau/nouveau_pms.h 
b/drivers/gpu/drm/nouveau/nouveau_pms.h

new file mode 100644
index 000..d7a445b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_pms.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2010 Red Hat Inc.
+ *
+ * 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: Ben Skeggs
+ */
+
+#ifndef __NOUVEAU_PMS_H__
+#define __NOUVEAU_PMS_H__
+
+struct pms_ucode {
+u8 data[256];
+union {
+u8  *u08;
+u16 *u16;
+u32 *u32;
+} ptr;
+u16 len;
+
+u32 reg;
+u32 val;
+};
+
+static inline void
+pms_init(struct pms_ucode *pms)
+{
+pms-ptr.u08 = pms-data;
+pms-reg = 0x;
+pms-val = 0x;
+}
+
+static inline void
+pms_fini(struct pms_ucode *pms)
+{
+do {
+*pms-ptr.u08++ = 0x7f;
+pms-len = pms-ptr.u08 - pms-data;
+} while (pms-len  3);
+pms-ptr.u08 = pms-data;
+}
+
+static inline void
+pms_unkn(struct pms_ucode *pms, u8 v0)
+{
+*pms-ptr.u08++ = v0;
+}
+
+static inline void
+pms_op5f(struct pms_ucode *pms, u8 v0, u8 v1)
+{
+*pms-ptr.u08++ = 0x5f;
+*pms-ptr.u08++ = v0;
+*pms-ptr.u08++ = v1;
+}
+
+static inline void
+pms_wr32(struct pms_ucode *pms, u32 reg, u32 val)
+{
+if (val != pms-val) {
+if ((val  0x) == (pms-val  0x)) {
+*pms-ptr.u08++ = 0x42;
+*pms-ptr.u16++ = (val  0x);
+} else {
+*pms-ptr.u08++ = 0xe2;
+*pms-ptr.u32++ = val;
+}
+
+pms-val = val;
+}
+
+if ((reg  0x) == (pms-reg  0x)) {
+*pms-ptr.u08++ = 0x40;
+*pms-ptr.u16++ = (reg  0x);
+} else {
+*pms-ptr.u08++ = 0xe0;
+*pms-ptr.u32++ = reg;
+}
+pms-reg = reg;
+}
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/nv50_pm.c 
b/drivers/gpu/drm/nouveau/nv50_pm.c

index 4dd2d76..9b81f03 100644
--- a/drivers/gpu

Re: [Nouveau] [PATCH] drm/nouveau/pm: Prevent overflow in nouveau_perf_init()

2011-06-11 Thread Martin Peres

Le 11/06/2011 14:30, Emil Velikov a écrit :

+   if (entries  NOUVEAU_PM_MAX_LEVEL) {
+   NV_DEBUG(dev, perf table has too many entries - buggy 
vbios?\n);
+   entries = NOUVEAU_PM_MAX_LEVEL;
+   }
+
I would suggest using NV_ERROR or INFO. How will we get buggy vbios if 
we don't warn the users of such cards?

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


Re: [Nouveau] [PATCH] drm/nouveau: set ptimer to count in ns on all chipset at the exception of nv40

2011-07-04 Thread Martin Peres

Le 04/07/2011 08:42, Ben Skeggs a écrit :

Apologies for top-posting.

Martin,

As per our convo on irc earlier, pushed code achieving this functionality.

Let me know if there's issues :)

Ben.


Ack, I'll test that tonight but as I said in our conversation, it looks 
good to me.


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


[Nouveau] [TESTING CALL] Fan management

2011-08-29 Thread Martin Peres

Hi Nouveau users,

Just saw the bitching on Phoronix about lack of fan management in 
nouveau (no offence Michael, it was justified ;) ).
Since it has been working flawlessly for more than a week on my desktop, 
I decided to let you guys know about it and ask for testing.


Here is the code: 
http://gitorious.org/linux-nouveau-pm/linux-nouveau-pm/commits/thermal
Please read the following paragraphs before pulling this branch and fry 
your GPU.


The hardware and current limitations
---

This branch introduces code to drive the most common fan type (and the 
most problematic one, I guess/hope). We call them PWM fan.
The other types are TOGGLE (can only be ON or OFF) and I2C (driven using 
an I2C chip).


The TOGGLE fans aren't supported because I think I lack the hw (to be 
confirmed).


The PWM fans are the most common ones. It supports a full range of speed 
(from 0% to 100%).


The I2C-accessible fans are usually limited to high-end cards. At the 
moment, the only thing we can do for them is to launch their hwmon driver.
This is due to a limitation in hwmon that doesn't let kernel drivers 
accessing the i2c chips' methods. We are working with the hwmon team and 
provided
a patch to support that: 
http://www.spinics.net/lists/lm-sensors/msg32906.html

If you have such a fan, you can manage it from the userspace.

The implemented fan management support
---

Current fan management should only work on what we call PWM fans.

This work should be usable up to (not including) nva3 chipset generation.
This is because nva3+ cards all have hw to drive the speed of the fan 
(pwm or i2c).


Reading the fan speed (power): cat /sys/class/drm/cardX/device/pwm0

Reading the fan speed (RPM): cat /sys/class/drm/cardX/device/fan0_input

Setting the fan management method: echo X  
/sys/class/drm/cardX/device/pwm0_enable

- X = 0: Fan management disabled, fan power set to 100%
- X = 1: Manual fan management (you can set the speed by writing 
[0-100] to /sys/class/drm/cardX/device/pwm0)
- X = 2: The default automatic fan management (equivalent to X = 3 for 
the moment)
- X = 3: Linear fan management. The fan speed is linearly correlated to 
the temperature.
- X = 4: Target temperature management. The fan is driven to keep the 
GPU to a certain temperature


The thermal zone implementation


Since I believe thermal zones are great but massively under-used. I used 
thermal zones to define some trip points.


Here are some noteworthy trip points:
- Default mode: Listen to the user commands
- Fan boost: Whenever the GPU reaches this temperature, the fan will 
blow at 100%
- Downclocking: Whenever the GPU reaches this temperature, your GPU will 
be downclocked to the lowest perflvl
- Critical: Whenever the GPU reaches this temperature, your computer 
will shut down to prevent damages.


BIG FAT WARNING
-

For those willing to try this, please watch your GPU temperature closely 
at any time using $ sensors and your fingers.
If you think sensors doesn't report the right temperature, please send 
us a mail with your vbios and show up on IRC (ask mupuf).


Check this before having fun with fan management, it is very important!

Installation
--

cd my_package_directory
git clone git://gitorious.org/linux-nouveau-pm/linux-nouveau-pm.git
git branch --track thermal origin/thermal

Then it is just a matter of compiling and testing your kernel. Please 
follow your distribution's guide.


Report


Please report your story on our IRC channel. Please also send your 
kernel logs along with your vbios to martin.peres at free(dot)fr.


Conclusion


Hope you like it. Keep us informed of how well it works ;)

Martin (AKA mupuf)

PS: Another testing call about power management should also follow but 
there is something I want to implement before people try it.
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [TESTING CALL] Fan management

2011-08-31 Thread Martin Peres

Le 31/08/2011 13:48, Mr Dash Four a écrit :



The implemented fan management support
---

Current fan management should only work on what we call PWM fans.

This work should be usable up to (not including) nva3 chipset 
generation.
This is because nva3+ cards all have hw to drive the speed of the fan 
(pwm or i2c).


Reading the fan speed (power): cat /sys/class/drm/cardX/device/pwm0

Reading the fan speed (RPM): cat /sys/class/drm/cardX/device/fan0_input

Setting the fan management method: echo X  
/sys/class/drm/cardX/device/pwm0_enable

- X = 0: Fan management disabled, fan power set to 100%
- X = 1: Manual fan management (you can set the speed by writing 
[0-100] to /sys/class/drm/cardX/device/pwm0)
- X = 2: The default automatic fan management (equivalent to X = 3 
for the moment)
- X = 3: Linear fan management. The fan speed is linearly correlated 
to the temperature.
- X = 4: Target temperature management. The fan is driven to keep the 
GPU to a certain temperature
I have 7800gs (NV49) card and tried to use the new driver yesterday 
after pulling the latest source, compiling and installing it. 
Unfortunately, pwm0_enable is not showing up, so I am unable to use 
the fan management at all. Previous attempts to write values to either 
/sys/class/drm/cardX/device/pwm0 or the port itself (using nvpoke) 
also failed - even though the value changes the fan speed stays the 
same. I was hoping that the latest additions will solve these problems 
and reduce the noise coming out of the fan (blasting at 100%), but 
that seems to be way off, at least for now.


What could be the problem? Could it be that my card is using i2c 
instead? Any ideas?

Could you provide your kernel logs and vbios please? I'll have a look at it.
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH] drm/nv50/pm: fix a typo in clock calculation

2011-11-01 Thread Martin Peres
Signed-off-by: Martin Peres martin.pe...@labri.fr
---
 drivers/gpu/drm/nouveau/nv50_pm.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nv50_pm.c 
b/drivers/gpu/drm/nouveau/nv50_pm.c
index e7ff5ac..e025cae 100644
--- a/drivers/gpu/drm/nouveau/nv50_pm.c
+++ b/drivers/gpu/drm/nouveau/nv50_pm.c
@@ -295,7 +295,7 @@ read_clk(struct drm_device *dev, enum clk_src src)
case 0x0800:
return read_clk(dev, clk_src_hclkm3d2)  P;
case 0x0c00:
-   return read_pll(dev, clk_src_mclk)  P;
+   return read_clk(dev, clk_src_mclk)  P;
}
break;
}
-- 
1.7.7.1

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


Re: [Nouveau] enable ctxprog xfer only when we need it to save power introduces big performance regression

2011-11-09 Thread Martin Peres

Le 09/11/2011 23:10, Marcin Slusarz a écrit :
For anyone who don't read IRC logs - it turns out it regressed only on 
my box, because I have page flipping disabled (due to page flipping 
being very buggy here, see 
https://bugs.freedesktop.org/show_bug.cgi?id=42398), which forces gpu 
context switch on every frame - even with (OpenGL) full screen apps. 
And this patch slows down context switches. So, can we disable xfers 
in ctxprog only when page flipping is enabled? Or is there any other 
option? Marcin 
Hmm, it isn't logical yet. To test for performance regression, I 
launched the well known context switch test that is glxgears and only 
found a performance decrease of 1%.


I'll test with pageflip disabled though and see for myself.

Anyway, we'll do something about it. I just hope that most cards don't 
have this problem. This is clearly an hw regression.


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


Re: [Nouveau] [PATCH] drm/nv50/pm: fix a typo in clock calculation

2011-11-10 Thread Martin Peres

Le 01/11/2011 11:41, Martin Peres a écrit :

Signed-off-by: Martin Peresmartin.pe...@labri.fr
---
  drivers/gpu/drm/nouveau/nv50_pm.c |2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nv50_pm.c 
b/drivers/gpu/drm/nouveau/nv50_pm.c
index e7ff5ac..e025cae 100644
--- a/drivers/gpu/drm/nouveau/nv50_pm.c
+++ b/drivers/gpu/drm/nouveau/nv50_pm.c
@@ -295,7 +295,7 @@ read_clk(struct drm_device *dev, enum clk_src src)
case 0x0800:
return read_clk(dev, clk_src_hclkm3d2)  P;
case 0x0c00:
-   return read_pll(dev, clk_src_mclk)  P;
+   return read_clk(dev, clk_src_mclk)  P;
}
break;
}

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


Re: [Nouveau] enable ctxprog xfer only when we need it to save power introduces big performance regression

2011-12-28 Thread Martin Peres

On 28/12/2011 22:39, Marcin Slusarz wrote:

Heh, with page flipping enabled, regression is still there, only smaller
(61-54, instead of 49 FPS).

I want my Nouveau performance back ;)

---
From: Marcin Slusarzmarcin.slus...@gmail.com
Subject: [PATCH] drm/nv50/gr: make xfers only in ctxprog optional

Commit fbba036a56fe0e5c5e8c91daf3fa211f88d94a03
drm/nv50/gr: enable ctxprog xfer only when we need it to save power
introduced performance regression.

So revert to previous behaviour and add module option (nv50_xfer_ctxprog=0/1)
to restore it back.

Signed-off-by: Marcin Slusarzmarcin.slus...@gmail.com


Hi,

I'm really sorry about not following up to your many emails you sent me 
in the past.


I now have time to work on this issue and I would like a little more 
information if you don't mind. Could you do a mmiotrace and look at what 
nvidia does in their ctxprog for your specific card ?


If nVidia does the same thing as we do, well, you'll have to wait for 
something I've been thinking for some times now.


What we want is to define power consumption profiles. A simple example 
is, when on battery, you don't want to save as much power as possible 
but when you are on sector, you may want to get the full performance out 
of your card (You may also don't mind the performance loss, but one 
thing at a time).


Ben (darktama) has recently talked about introducing a kind of automatic 
reclocking kind of like what radeon does. That is to say, having 
performance profiles that are switched according to the energy source 
(battery / sector). This automatic behaviour could then be overriden by 
the user, just like radeon.


We would then turn some nobs according to the current performance 
profile. One of these nobs could be xfer on some specific cards (yours).


Would that solution suit you? Clearly, introducing a new kernel 
parameter isn't an acceptable solution to the problem.


I hope we can find a way that would suit both performance and 
battery-life while being kernel-friendly.


Martin (mupuf)
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] enable ctxprog xfer only when we need it to save power introduces big performance regression

2012-01-13 Thread Martin Peres

Hi Marcin,

As promised, I started working on your performance problem.

Le 29/12/2011 02:38, Marcin Slusarz a écrit :
I tried to implement xfers runtime switching, but couldn't figure out 
how to change ctxprog behaviour without rebuilding and reuploading 
whole thing. Reading host-writable memory from ctxprog would be enough. 
Well, I did that for you (see the patch enclosed). The patch uses the 
4th ctxprog flag register's bit 0 to store the wanted behaviour.

Mwk suggested me to do so and it worked perfectly.

You have all the instructions in the commit message, please report on 
the actual results!


By the mean time, I'll plug it to a PM brain so as it would switch back 
and forth between the two modes according to the load or the perflvl.


Take care,

Martin
From 8e6667c87074b1b519fef0946083d46d01dfe8a0 Mon Sep 17 00:00:00 2001
From: Martin Peres martin.pe...@labri.fr
Date: Fri, 13 Jan 2012 22:05:28 +0100
Subject: [PATCH] drm/nv50/gr: make ctxprog decide at run time to disable or
 not xfer

This commit is a follow-up on drm/nv50/gr: enable ctxprog xfer only when we need it to save power.

The current situation is that some cards (nv92) have an hw regression that lower performance that
has been reported to about 15%.

This commit is the initial work to get the best of both world, that is to say:
- Performance when it is actually needed
- Power consumption when current performance is enough for the current needs

How-to:
- To go for performance  : nvapoke 400830 1
- To go for power consumption: nvapoke 400830 0

Then, force the card to do a context switch (switch to a TTY for instance).
Make sure it worked by peeking 400824. Bit 0x4000 is the XFER_ENABLE.

Reported-by: Marcin Slusarz marcin.slus...@gmail.com
Signed-off-by: Martin Peres martin.pe...@labri.fr
---
 drivers/gpu/drm/nouveau/nv50_grctx.c |   14 --
 1 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nv50_grctx.c b/drivers/gpu/drm/nouveau/nv50_grctx.c
index 4b46d69..b2fdb7d 100644
--- a/drivers/gpu/drm/nouveau/nv50_grctx.c
+++ b/drivers/gpu/drm/nouveau/nv50_grctx.c
@@ -74,6 +74,11 @@
 #define CP_FLAG_INTR_NOT_PENDING  0
 #define CP_FLAG_INTR_PENDING  1
 
+/* CTXCTL_FLAGS_3: should only be written by host ! */
+#define CP_FLAG_PM_XFER   ((3 * 32) + 0)
+#define CP_FLAG_PM_XFER_ENABLE0
+#define CP_FLAG_PM_XFER_DISABLE   1
+
 #define CP_CTX   0x0010
 #define CP_CTX_COUNT 0x000f
 #define CP_CTX_COUNT_SHIFT   16
@@ -163,6 +168,7 @@ enum cp_label {
 	cp_setup_save,
 	cp_swap_state,
 	cp_prepare_exit,
+	cp_xfer,
 	cp_exit,
 };
 
@@ -263,13 +269,17 @@ nv50_grctx_init(struct nouveau_grctx *ctx)
 	cp_set (ctx, UNK03, CLEAR);
 	cp_set (ctx, UNK1D, CLEAR);
 
-	cp_bra (ctx, USER_SAVE, PENDING, cp_exit);
+	cp_bra (ctx, USER_SAVE, PENDING, cp_xfer);
 	cp_out (ctx, CP_NEXT_TO_CURRENT);
 
+	/* disable xfer unless we are told otherwise by the host */
+	cp_name(ctx, cp_xfer);
+	cp_bra (ctx, PM_XFER, DISABLE, cp_exit);
+	cp_set (ctx, XFER_SWITCH, DISABLE);
+
 	cp_name(ctx, cp_exit);
 	cp_set (ctx, USER_SAVE, NOT_PENDING);
 	cp_set (ctx, USER_LOAD, NOT_PENDING);
-	cp_set (ctx, XFER_SWITCH, DISABLE);
 	cp_set (ctx, STATE, STOPPED);
 	cp_out (ctx, CP_END);
 	ctx-ctxvals_pos += 0x400; /* padding... no idea why you need it */
-- 
1.7.8.3

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


Re: [Nouveau] enable ctxprog xfer only when we need it to save power introduces big performance regression

2012-01-17 Thread Martin Peres

Le 17/01/2012 21:55, Lucas Stach a écrit :
Isn't it possible that the performance regression seen with xfer 
disabled by default is caused by slow memory clock speed? Martin, you 
saw only a 1% performance drop on your 8600 which is running with full 
speed by default. Marcins nv92 is likely running at a much lower clock 
speed. It would be nice to know if the perf regression is still as big 
when running with full speed. We could stop caring about this when the 
perf regression is not observable in the highest perf level.
Well, actually, the performance hit should be higher when running at a 
highest memory clock since we context switch more often (there is no 
logic here, just a personal experience).


Anyway, I tried again last week end at every possible speed and I 
haven't been able to spot any performance hit *at all*.

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


Re: [Nouveau] Nouveau: NV43 unknown ROM tables? + division by zero

2012-04-03 Thread Martin Peres

Le 03/04/2012 11:03, Meelis Roos a écrit :
This time, memory timing table is not unknown, but voltage tabele 
still is, and only 0 available performance levels instead of 8 empty 
ones. Also, monitor is not attached at the moment, used somewhere else. 


Looks better, indeed.

Could you send us your vbios please ?

Thanks by advance,

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


Re: [Nouveau] [RFC PATCH 5/5] drm/nouveau: gpu lockup recovery

2012-04-23 Thread Martin Peres

Le 23/04/2012 18:32, Marcin Slusarz a écrit :


Just run piglit. Even quick tests can cause ~5 lockups (it eventually messes
up DDX channel, but this patchset can't fix this case).
You can run fs-discard-exit-2 test first - for me it causes instant GPU lockup.

Marcin

Great, Thanks.

Did you have a look at 
https://bugs.freedesktop.org/show_bug.cgi?id=40886 and 
http://xorg.freedesktop.org/wiki/SummerOfCodeIdeas ?
The Ubuntu xorg devs were looking for something like this, but they also 
wanted a lockup report. Are you also interested on working on it ?


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


Re: [Nouveau] [PATCH 4/5] drm/nv50: let applications hanging on vm flush to be killed

2012-04-23 Thread Martin Peres

Le 23/04/2012 00:18, Marcin Slusarz a écrit :

Signed-off-by: Marcin Slusarzmarcin.slus...@gmail.com
---
  drivers/gpu/drm/nouveau/nv50_graph.c |5 +
  1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c 
b/drivers/gpu/drm/nouveau/nv50_graph.c
index 6899547..a61853f 100644
--- a/drivers/gpu/drm/nouveau/nv50_graph.c
+++ b/drivers/gpu/drm/nouveau/nv50_graph.c
@@ -435,6 +435,11 @@ nv84_graph_tlb_flush(struct drm_device *dev, int engine)
if ((tmp  7) == 1)
idle = false;
}
+
+   if (fatal_signal_pending(current)) {
+   ret = -ERESTARTSYS;
+   break;
+   }
} while (!idle  !(timeout = ptimer-read(dev) - start  20));

if (timeout) {

Good, but who should send the kill signal in the first place?

Shouldn't nouveau drm terminate the process(es) associated with the 
channel that generated the lockup ?


Can you provide more info on how the lockup recovery works?

Thanks in advance,
Martin
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] rendering problems with latest ddx driver (nv50)

2012-04-24 Thread Martin Peres

Le 24/04/2012 20:14, Maarten Maathuis a écrit :

Do you get rendering errors also when using a nv50 class gpu? I seem
to get them in firefox.

I also noticed a huge amount of failures when running rendercheck -t
gradients, which i find odd, because they are not supposed to be
accelerated.

Hi,

By any chance, are you using cairo 1.12? If so, try downgrading to cairo 
1.10.


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


Re: [Nouveau] rendering problems with latest ddx driver (nv50)

2012-04-24 Thread Martin Peres

Le 24/04/2012 20:49, Maarten Maathuis a écrit :

On Tue, Apr 24, 2012 at 8:36 PM, Martin Peresmartin.pe...@free.fr  wrote:

Le 24/04/2012 20:14, Maarten Maathuis a écrit :


Do you get rendering errors also when using a nv50 class gpu? I seem
to get them in firefox.

I also noticed a huge amount of failures when running rendercheck -t
gradients, which i find odd, because they are not supposed to be
accelerated.

Hi,

By any chance, are you using cairo 1.12? If so, try downgrading to cairo
1.10.

Martin

No, i'm using cairo 1.10.2. Also rendercheck isn't affected by cairo.
The last driver upgrade included at least the migration to the new
libdrm and everything that came after it. That's when the rendering
corruption started.


Right, I was under the asumption that both issues were un-related.

I guess you are using the latest ddx which does accelerate solid pictures.
Have you tried resetting to this commit ? 
http://cgit.freedesktop.org/nouveau/xf86-video-nouveau/commit/?id=ec019b3a50475b7ff1b5e0a5dbe14e5ef677bd9e


Please keep us posted
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH v2 4/4] drm/nouveau: gpu lockup recovery

2012-04-30 Thread Martin Peres

Le 28/04/2012 16:56, Marcin Slusarz a écrit :

On Wed, Apr 25, 2012 at 11:20:36PM +0200, Marcin Slusarz wrote:

Overall idea:
Detect lockups by watching for timeouts (vm flush / fence), return -EIOs,
handle them at ioctl level, reset the GPU and repeat last ioctl.

GPU reset is done by doing suspend / resume cycle with few tweaks:
- CPU-only bo eviction
- ignoring vm flush / fence timeouts
- shortening waits

Signed-off-by: Marcin Slusarzmarcin.slus...@gmail.com
---

Martin,

I'm wondering how below patch (which builds upon the above) affects
reclocking stability. I can't test it on my card, because it has only
one performance level. Can you test it on yours?

Hi Marcin,

I was away from my computers for a few days. I'll test this patch tonight.

Martin

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


Re: [Nouveau] [PATCH v2 4/4] drm/nouveau: gpu lockup recovery

2012-05-02 Thread Martin Peres

On 02/05/2012 13:28, Ben Skeggs wrote:

Right, again, I don't disagree :)  I think we can improve a lot on the
big-hammer-suspend-the-gpu solution though, and instead reset only the
faulting engine.  It's (in theory) almost possible for us to do now, but
I have a couple of reworks to areas related to this pending (basically,
making the various driver subsystems more independent), which should be
ready soon.  This'll go a long way to making it very easy to reset a
single engine, and likely result in *far* faster recovery from hangs.

Hey,

What about kicking a channel that put the card in a bad state? Wouldn't 
that be possible?


This way, we don't loose the context of other channels and only the 
application that hang the card will be exited.


I wonder how pfifo handles commands sent to a non-existing channel, but 
I'm sure it shouldn't hang or anything.


Anyway, if this is not possible to only kick one channel, then what 
about kicking all channels, rePOSTING the card and using KMS to output 
the lockup report (and send a notification of the report through udev 
and store the report in a sysfs file)?


Let's not try to be perfect, let us just be able to do better bug reports.

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


Re: [Nouveau] [PATCH v2 4/4] drm/nouveau: gpu lockup recovery

2012-05-02 Thread Martin Peres

On 02/05/2012 15:48, Ben Skeggs wrote:

On Wed, 2012-05-02 at 15:33 +0200, Martin Peres wrote:

On 02/05/2012 13:28, Ben Skeggs wrote:

Right, again, I don't disagree :)  I think we can improve a lot on the
big-hammer-suspend-the-gpu solution though, and instead reset only the
faulting engine.  It's (in theory) almost possible for us to do now, but
I have a couple of reworks to areas related to this pending (basically,
making the various driver subsystems more independent), which should be
ready soon.  This'll go a long way to making it very easy to reset a
single engine, and likely result in *far* faster recovery from hangs.

Hey,

What about kicking a channel that put the card in a bad state? Wouldn't
that be possible?

This way, we don't loose the context of other channels and only the
application that hang the card will be exited.

That's pretty much the idea.  The trouble comes in where PFIFO will hang
waiting for the stuck engine to report that it's done (eg. it will wait
for PGRAPH to go i've finished unloading my context now after it's
told PGRAPH to do so).

Hence why it's important to be able to (preferably) un-stick the stuck
engine (usually handling the appropriate interrupts properly will
achieve this), and failing that, reset it and lose the context for just
that channel.

The work I'm doing at the moment will, among other nice things, make
handling all of this a lot nicer.  And it should be nice and speedy in
comparison to the suspend/resume option, we won't have to evict all
buffers from vram without accel, which can take quite a while (not to
mention that it might not even be possible to get to the VRAM not mapped
into the FB BAR on earlier chipsets if accel dies).

I get it, that seems nice and good.



I wonder how pfifo handles commands sent to a non-existing channel, but
I'm sure it shouldn't hang or anything.

It can't happen anyway, if we destroyed the fifo context for a channel
we wouldn't be telling it to execute commands still :)
Right, but there may still be some commands left in the IB ring buffer, 
right?



Anyway, if this is not possible to only kick one channel, then what
about kicking all channels, rePOSTING the card and using KMS to output
the lockup report (and send a notification of the report through udev
and store the report in a sysfs file)?

Let's not try to be perfect, let us just be able to do better bug reports.

I'm still skeptical about how useful any kind of generic lockup report
can possibly be, beyond kernel logs..  However, as part of the work I'm
working on, there may be some additional information available via
debugfs..  I don't wan't to elaborate on this too much yet until I wrap
my head around what exactly I want to achieve, but I'll give you a
heads-up once I do :)
Well, a good report is important so as we can have an idea of what went 
wrong

and also, that would allow us to differenciate bug reports.

Basically, I'm now convinced that the nvaX random lockup is not actually 
one issue.

Having such an enhanced bug report could allow us to verify this theory.

PS: Speaking about nvaX lockups. I still get lockups (nva3/5) and I 
suspect that the
problem comes from the context switching micro code. Not loosing the 
email I'm writing

simply because kwin's channel crashed would be a big win to me.

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


Re: [Nouveau] [patch] Junior ToDo Warn if Modesetting Disabled

2012-08-26 Thread Martin Peres

On 26/08/2012 23:05, Mark Carey wrote:

v2 spaces to tabs as per RSpliets feedback on IRC

Hi Mark,

Thanks for the patch, it is indeed needed :)

However, I don't like the wording. Instead of telling that it isn't 
normal, we don't tell what should be done neither what it will impact.
I guess something like modesetting disabled, hw acceleration disabled 
would be more suitable.


Speaking about that, I wonder how Nouveau would work on a CRTC-less card :D

Martin

PS: I have tested booting Arch with nomodeset and x-server loads VESA. 
Exactly the behaviour we are looking for :)

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


Re: [Nouveau] How to install nouveau manually?

2012-10-19 Thread Martin Peres

On 10/17/12 22:11, Nilton Teixeira wrote:
Please, I tried to install xserver-xorg-video-nouveau and Xterm (Linux 
Ubuntu) returned this information: /xserver-xorg-video-nouveau 
configurado para instalar manualmente/ (xserver-xorg-video-nouveau 
set to install manually. How should I proceed?


Thanks,
Nilton Teixeira
Santo André-SP

Please follow this http://nouveau.freedesktop.org/wiki/InstallNouveau

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


[Nouveau] [PATCH] drm/nouveau/therm: force a minimum hysteresis on temperature alarm thresholds

2012-12-08 Thread martin . peres
From: Martin Peres martin.pe...@labri.fr

This should avoid the situation where a user gets its kernel logs flooded when
temperature oscillates around a threshold with 0°C hysteresis.

This patch is just meant to fix broken vbios (as reported on a nv4e on
sysfs hwmon interface.

Signed-off-by: Martin Peres martin.pe...@labri.fr
---
 drivers/gpu/drm/nouveau/core/subdev/therm/temp.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c 
b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c
index 76621cc..50e17f0 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c
@@ -60,11 +60,18 @@ static void
 nouveau_therm_temp_safety_checks(struct nouveau_therm *therm)
 {
struct nouveau_therm_priv *priv = (void *)therm;
+   struct nvbios_therm_sensor *s = priv-bios_sensor;
 
if (!priv-bios_sensor.slope_div)
priv-bios_sensor.slope_div = 1;
if (!priv-bios_sensor.offset_den)
priv-bios_sensor.offset_den = 1;
+
+   /* enforce a minimum hysteresis on thresholds */
+   s-thrs_fan_boost.hysteresis = max_t(u8, s-thrs_fan_boost.hysteresis, 
2);
+   s-thrs_down_clock.hysteresis = max_t(u8, 
s-thrs_down_clock.hysteresis, 2);
+   s-thrs_critical.hysteresis = max_t(u8, s-thrs_critical.hysteresis, 2);
+   s-thrs_shutdown.hysteresis = max_t(u8, s-thrs_shutdown.hysteresis, 2);
 }
 
 /* must be called with alarm_program_lock taken ! */
-- 
1.8.0.1

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


[Nouveau] Request for nv40-c0 testing thermal/fan management

2012-12-16 Thread Martin Peres

Hi Nouveau enthusiasts,

One week ago was merged the thermal/fan management code for most nvidia 
cards.


So far, no major issue arose but we would like to have more testing as 
soon as possible to deliver a nice and solid support when Linux 3.8 is 
released.


Thermal management is split into two parts:

- Temperature monitoring: Making sure your card doesn't overheat
- Fan management: Driving the fan speed according to the temperature

Thermal monitoring should be working on all chipsets that support it 
(nv43+). However, some cards use an external (i2c) monitoring chip. 
Because of the limitations of the hwmon interface, we cannot access this 
information and thus, cannot monitor the temperature of your card 
ourselves. However, we should be able to load the right kernel module so 
as you can monitor it for us.


As for fan management, the situation is the same as thermal mangement 
with the additional limitation that nvc0+ (Fermi+) chipsets are not 
supported for fan management. The reason is that nvc0+ chipset use an 
internal engine (PDAEMON) that is already set up by the vbios to do fan 
management and we didn't feel like getting rid of it just yet even 
though some experimental code for its replacement is already available.


What we are trying to avoid is:

VERY IMPORTANT:
- No temperature at all while the blob reports one!
- Inaccurate temperature (we already have a bug report for that on nv4x)

IMPORTANT:
- The fan/card makes a strange noise while driving the fan
- You manage to stop the fan without fiddling with pwm_min
- Non-linear fan speed with PWM value

Please report if one of these issues occur. If you experience something 
strange that isn't on the list, please inform us too :)


Complete documentation for thermal management is available at 
/Documentation/thermal/nouveau_thermal 
(http://cgit.freedesktop.org/nouveau/linux-2.6/tree/Documentation/thermal/nouveau_thermal).


Looking forward to your feedback!

Cheers,

Martin (AKA mupuf)
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH] drm/nouveau/fan: handle the cases where we are outside of the linear zone

2012-12-19 Thread martin . peres
From: Martin Peres martin.pe...@labri.fr

This fixes a bug where, when temperature is outside of the linear range, fan
pwm would be outside of the allowed range ([0, 100]) and could get negative in
some cases.

It seems like a regression that happened when we re-worked the fan management
logic before merging.

Tested-by: Ozan Çağlayan ozan...@gmail.com
Signed-off-by: Martin Peres martin.pe...@labri.fr
---
 drivers/gpu/drm/nouveau/core/subdev/therm/base.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c 
b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c
index b35b4a2..25b7f6a 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c
@@ -71,6 +71,13 @@ nouveau_therm_update_linear(struct nouveau_therm *therm)
u8  temp = therm-temp_get(therm);
u16 duty;
 
+   /* handle the non-linear part first */
+   if (temp  linear_min_temp)
+   return priv-fan-bios.min_duty;
+   else if (temp  linear_max_temp)
+   return priv-fan-bios.max_duty;
+
+   /* we are in the linear zone */
duty  = (temp - linear_min_temp);
duty *= (priv-fan-bios.max_duty - priv-fan-bios.min_duty);
duty /= (linear_max_temp - linear_min_temp);
-- 
1.8.0.2

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


Re: [Nouveau] [PATCH 1/3] drm/nouveau/therm: turn on a fan only when crossing threshold in positive direction

2013-02-08 Thread Martin Peres

On 03/02/2013 21:07, Marcin Slusarz wrote:

+ the same for shutdown threshold - seems impossible, but shutdown can fail.

Signed-off-by: Marcin Slusarz marcin.slus...@gmail.com

Looks good. Please add my signed-off-by

Signed-off-by: Martin Peres martin.pe...@labri.fr

---
  drivers/gpu/drm/nouveau/core/subdev/therm/temp.c | 11 +++
  1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c 
b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c
index bf9b3ce..8f27b44 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c
@@ -105,7 +105,7 @@ void nouveau_therm_sensor_event(struct nouveau_therm *therm,
return;
  
  	if (dir == NOUVEAU_THERM_THRS_FALLING)

-   nv_info(therm, temperature (%u C) went bellow the '%s' 
threshold\n,
+   nv_info(therm, temperature (%u C) went below the '%s' 
threshold\n,
temperature, thresolds[thrs]);
else
nv_info(therm, temperature (%u C) hit the '%s' threshold\n,
@@ -114,8 +114,10 @@ void nouveau_therm_sensor_event(struct nouveau_therm 
*therm,
active = (dir == NOUVEAU_THERM_THRS_RISING);
switch (thrs) {
case NOUVEAU_THERM_THRS_FANBOOST:
-   nouveau_therm_fan_set(therm, true, 100);
-   nouveau_therm_mode(therm, NOUVEAU_THERM_CTRL_AUTO);
+   if (active) {
+   nouveau_therm_fan_set(therm, true, 100);
+   nouveau_therm_mode(therm, NOUVEAU_THERM_CTRL_AUTO);
+   }
break;
case NOUVEAU_THERM_THRS_DOWNCLOCK:
if (priv-emergency.downclock)
@@ -126,7 +128,8 @@ void nouveau_therm_sensor_event(struct nouveau_therm *therm,
priv-emergency.pause(therm, active);
break;
case NOUVEAU_THERM_THRS_SHUTDOWN:
-   orderly_poweroff(true);
+   if (active)
+   orderly_poweroff(true);
break;
case NOUVEAU_THERM_THRS_NR:
break;


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


Re: [Nouveau] [PATCH 2/3] drm/nv40/therm: reset temperature sensor on init

2013-02-08 Thread Martin Peres

On 03/02/2013 21:07, Marcin Slusarz wrote:

Current uninitialized sensor detection does not work for me on nv4b and
sensor returns crazy values (190°C). It stabilises later, but it's too
late - therm code shutdowns the machine...

Let's just reset it on init.

Signed-off-by: Marcin Slusarz marcin.slus...@gmail.com
Hmm, so it means the bios initializes your sensor at POST. This was not 
the case on mine and we used to rely on the fact that nv4x's sensor was 
not initialized.


Anyway, forcing a reset is not a bad idea. Please add my signed-off-by.

Thanks for your ptherm patchset :)
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH 3/3] drm/nouveau/therm: use workqueue to shutdown the machine

2013-02-08 Thread Martin Peres

On 03/02/2013 21:07, Marcin Slusarz wrote:

orderly_poweroff cannot be called from atomic context.

Signed-off-by: Marcin Slusarz marcin.slus...@gmail.com

Oops, my bad. Please add my signed-off-by.

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


Re: [Nouveau] [PATCH] drm/nouveau: do not move buffers when not needed

2013-08-24 Thread Martin Peres

On 15/07/2013 10:39, Maarten Lankhorst wrote:

Op 15-07-13 08:05, Ben Skeggs schreef:

On Fri, Jul 12, 2013 at 10:45 PM, Maarten Lankhorst
maarten.lankho...@canonical.com wrote:

I have no idea what this bogus restriction on placement is, but it breaks 
decoding 1080p
VDPAU at boot speed. With this patch applied I only need to bump the vdec clock 
to
get real-time 1080p decoding. It prevents a lot of VRAM - VRAM buffer moves.

It's not bogus, and is required for pre-GF8 boards with VRAM  BAR size.

What configuration does the buffer that's getting moved here have
exactly?  The placement restriction isn't necessary on GF8, the rest
of the restrictions may currently be required still however.

= vdpau on NVC0 with tiling. I upload the raw bitstream to a tiling bo. This is 
ok because

the vm hides all the tiling translations, and the engines will read the raw 
bitstream correctly.
8---
This prevents buffer moves from being done on NV50+, where remapping is not 
needed because
the bar has its own VM, instead of only having the first BAR1-size chunk of 
VRAM accessible.
nouveau_bo_tile_layout is always 0 on  NV_50.

Signed-off-by: Maarten Lankhorst maarten.lankho...@canonical.com
There are still some rendering issues on my nvc4, but the framerate is 
much smoother than it was before this patch.


Tested-by: Martin Peres martin.pe...@labri.fr

---
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c 
b/drivers/gpu/drm/nouveau/nouveau_bo.c
index d506da5..762bfcd 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -1346,14 +1361,13 @@ nouveau_ttm_fault_reserve_notify(struct 
ttm_buffer_object *bo)
struct nouveau_device *device = nv_device(drm-device);
u32 mappable = pci_resource_len(device-pdev, 1)  PAGE_SHIFT;
  
-	/* as long as the bo isn't in vram, and isn't tiled, we've got

-* nothing to do here.
+   /*
+* if the bo is not in vram, or remapping can be done (nv50+)
+* do not worry about placement, any location is valid
 */
-   if (bo-mem.mem_type != TTM_PL_VRAM) {
-   if (nv_device(drm-device)-card_type  NV_50 ||
-   !nouveau_bo_tile_layout(nvbo))
-   return 0;
-   }
+   if (nv_device(drm-device)-card_type = NV_50 ||
+   bo-mem.mem_type != TTM_PL_VRAM)
+   return 0;
  
  	/* make sure bo is in mappable vram */

if (bo-mem.start + bo-mem.num_pages  mappable)

___
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] [PATCH 1/2] drm/nouveau/bios/therm: handle vbioses with duplicate entries (mostly nva5)

2013-08-30 Thread Martin Peres
From: Martin Peres martin.pe...@labri.fr

Some vbioses have extra useless entries after the end of the table. This is
problematic since all of the vbios I found with this issue redefine the
pwm freq divider to insane levels (52750 Hz instead of 2500), thus breaking
fan management.

The first solution to solve this mess would be to change the length of the
table. The solution I choose was simply to avoid setting the pwm freq twice
as the other redefinitions are harmless with our current parser.

Signed-off-by: Martin Peres martin.pe...@labbri.fr
Reported-by: Mariusz Bialonczyk ma...@skyboo.net
Tested-by: Mariusz Bialonczyk ma...@skyboo.net
---
 drivers/gpu/drm/nouveau/core/subdev/bios/therm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/therm.c 
b/drivers/gpu/drm/nouveau/core/subdev/bios/therm.c
index 22a2057..22ac6db 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/therm.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/therm.c
@@ -184,7 +184,8 @@ nvbios_therm_fan_parse(struct nouveau_bios *bios,
cur_trip-fan_duty = value;
break;
case 0x26:
-   fan-pwm_freq = value;
+   if (!fan-pwm_freq)
+   fan-pwm_freq = value;
break;
case 0x3b:
fan-bump_period = value;
-- 
1.8.4

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


[Nouveau] [PATCH 2/2] drm/nv84/therm: ack any pending IRQ at init

2013-08-30 Thread Martin Peres
From: Martin Peres martin.pe...@labri.fr

This is safe because ptherm hasn't been configured yet and will be a
little further down the initialization path. Ptherm should be safe
regarding to runtime reconfiguration.

Signed-off-by: Martin Peres martin.pe...@labri.fr
---
 drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c | 19 ++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c 
b/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c
index 42ba633..8615d62 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c
@@ -209,13 +209,30 @@ nv84_therm_ctor(struct nouveau_object *parent,
return nouveau_therm_preinit(priv-base.base);
 }
 
+static int
+nv84_therm_init(struct nouveau_object *object)
+{
+   struct nv84_therm_priv *priv = (void *)object;
+   int ret;
+
+   ret = nouveau_therm_init(priv-base.base);
+   if (ret)
+   return ret;
+
+   /* ACK ptherm IRQs */
+   nv_wr32(object, 0x20100, 0x);
+   nv_wr32(object, 0x1100, 0x1); /* PBUS */
+
+   return 0;
+}
+
 struct nouveau_oclass
 nv84_therm_oclass = {
.handle = NV_SUBDEV(THERM, 0x84),
.ofuncs = (struct nouveau_ofuncs) {
.ctor = nv84_therm_ctor,
.dtor = _nouveau_therm_dtor,
-   .init = _nouveau_therm_init,
+   .init = nv84_therm_init,
.fini = _nouveau_therm_fini,
},
 };
-- 
1.8.4

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


[Nouveau] [PATCH] drm/nouveau/therm: ack any pending IRQ at init v2

2013-08-30 Thread Martin Peres
From: Martin Peres martin.pe...@labri.fr

This is safe because ptherm hasn't been configured yet and will be a
little further down the initialization path. Ptherm should be safe
regarding to runtime reconfiguration.

v2:
- do not limit this patch to nv84-a3 and make it nv84+

Signed-off-by: Martin Peres martin.pe...@labri.fr
---
 drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c | 19 ++-
 drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c |  4 
 drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c |  4 
 3 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c 
b/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c
index 42ba633..8615d62 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c
@@ -209,13 +209,30 @@ nv84_therm_ctor(struct nouveau_object *parent,
return nouveau_therm_preinit(priv-base.base);
 }
 
+static int
+nv84_therm_init(struct nouveau_object *object)
+{
+   struct nv84_therm_priv *priv = (void *)object;
+   int ret;
+
+   ret = nouveau_therm_init(priv-base.base);
+   if (ret)
+   return ret;
+
+   /* ACK ptherm IRQs */
+   nv_wr32(object, 0x20100, 0x);
+   nv_wr32(object, 0x1100, 0x1); /* PBUS */
+
+   return 0;
+}
+
 struct nouveau_oclass
 nv84_therm_oclass = {
.handle = NV_SUBDEV(THERM, 0x84),
.ofuncs = (struct nouveau_ofuncs) {
.ctor = nv84_therm_ctor,
.dtor = _nouveau_therm_dtor,
-   .init = _nouveau_therm_init,
+   .init = nv84_therm_init,
.fini = _nouveau_therm_fini,
},
 };
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c 
b/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c
index d11a7c4..f740eeb 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c
@@ -60,6 +60,10 @@ nva3_therm_init(struct nouveau_object *object)
}
nv_mask(priv, 0x00e720, 0x0002, 0x);
 
+   /* ACK ptherm IRQs */
+   nv_wr32(object, 0x20100, 0x);
+   nv_wr32(object, 0x1100, 0x1); /* PBUS */
+
return 0;
 }
 
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c 
b/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c
index 54c28bd..d9b5103 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c
@@ -114,6 +114,10 @@ nvd0_therm_init(struct nouveau_object *object)
}
nv_mask(priv, 0x00e720, 0x0002, 0x);
 
+   /* ACK ptherm IRQs */
+   nv_wr32(object, 0x20100, 0x);
+   nv_wr32(object, 0x1100, 0x1); /* PBUS */
+
return 0;
 }
 
-- 
1.8.4

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


[Nouveau] [PATCH 2/2] drm/nouveau/therm: enable fan management by default

2013-09-08 Thread Martin Peres
From: Martin Peres martin.pe...@labri.fr

This should enable automatic fan management for all cards by default, at
boot time. However, this commit actually affects only nv40-c0 as nvc0+
cards already have vbios's PDAEMON fw already taking care of fan management.

Signed-off-by: Martin Peres martin.pe...@labri.fr
---
 drivers/gpu/drm/nouveau/core/subdev/therm/base.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c 
b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c
index f1de7a9..aaf8285 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c
@@ -335,7 +335,7 @@ nouveau_therm_preinit(struct nouveau_therm *therm)
nouveau_therm_ic_ctor(therm);
nouveau_therm_fan_ctor(therm);
 
-   nouveau_therm_fan_mode(therm, NOUVEAU_THERM_CTRL_NONE);
+   nouveau_therm_fan_mode(therm, NOUVEAU_THERM_CTRL_AUTO);
nouveau_therm_sensor_preinit(therm);
return 0;
 }
-- 
1.8.4

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


[Nouveau] [PATCH 1/2] drm/nouveau/therm: ack any pending IRQ at init

2013-09-08 Thread Martin Peres
From: Martin Peres martin.pe...@labri.fr

This is safe because ptherm hasn't been configured yet and will be a
little further down the initialization path. Ptherm should be safe
regarding to runtime reconfiguration.

v2:
  - do not limit this patch to nv84-a3 and make it nv84+

v3:
  - move the ack to fini()
  - disable IRQs on fini()
  - silently ignore un-requested IRQs

Signed-off-by: Martin Peres martin.pe...@labri.fr
---
 drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c | 17 +++--
 drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c |  2 +-
 drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c |  2 +-
 drivers/gpu/drm/nouveau/core/subdev/therm/priv.h |  1 +
 4 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c 
b/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c
index 42ba633..1d15c52 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c
@@ -126,7 +126,7 @@ nv84_therm_intr(struct nouveau_subdev *subdev)
 
spin_lock_irqsave(priv-sensor.alarm_program_lock, flags);
 
-   intr = nv_rd32(therm, 0x20100);
+   intr = nv_rd32(therm, 0x20100)  0x3ff;
 
/* THRS_4: downclock */
if (intr  0x002) {
@@ -209,6 +209,19 @@ nv84_therm_ctor(struct nouveau_object *parent,
return nouveau_therm_preinit(priv-base.base);
 }
 
+int
+nv84_therm_fini(struct nouveau_object *object, bool suspend)
+{
+   /* Disable PTherm IRQs */
+   nv_wr32(object, 0x2, 0x);
+
+   /* ACK all PTherm IRQs */
+   nv_wr32(object, 0x20100, 0x);
+   nv_wr32(object, 0x1100, 0x1); /* PBUS */
+
+   return _nouveau_therm_fini(object, suspend);
+}
+
 struct nouveau_oclass
 nv84_therm_oclass = {
.handle = NV_SUBDEV(THERM, 0x84),
@@ -216,6 +229,6 @@ nv84_therm_oclass = {
.ctor = nv84_therm_ctor,
.dtor = _nouveau_therm_dtor,
.init = _nouveau_therm_init,
-   .fini = _nouveau_therm_fini,
+   .fini = nv84_therm_fini,
},
 };
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c 
b/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c
index d11a7c4..3b2c458 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c
@@ -94,6 +94,6 @@ nva3_therm_oclass = {
.ctor = nva3_therm_ctor,
.dtor = _nouveau_therm_dtor,
.init = nva3_therm_init,
-   .fini = _nouveau_therm_fini,
+   .fini = nv84_therm_fini,
},
 };
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c 
b/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c
index 54c28bd..4dd4f81 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c
@@ -148,6 +148,6 @@ nvd0_therm_oclass = {
.ctor = nvd0_therm_ctor,
.dtor = _nouveau_therm_dtor,
.init = nvd0_therm_init,
-   .fini = _nouveau_therm_fini,
+   .fini = nv84_therm_fini,
},
 };
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h 
b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h
index dd38529..508b1ec 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h
@@ -144,6 +144,7 @@ int nv50_fan_pwm_get(struct nouveau_therm *, int, u32 *, 
u32 *);
 int nv50_fan_pwm_set(struct nouveau_therm *, int, u32, u32);
 int nv50_fan_pwm_clock(struct nouveau_therm *);
 int nv84_temp_get(struct nouveau_therm *therm);
+int nv84_therm_fini(struct nouveau_object *object, bool suspend);
 
 int nva3_therm_fan_sense(struct nouveau_therm *);
 
-- 
1.8.4

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


Re: [Nouveau] [PATCH] drm/nouveau/therm: ack any pending IRQ at init v2

2013-09-08 Thread Martin Peres

On 04/09/2013 03:52, Ben Skeggs wrote:

On Sat, Aug 31, 2013 at 10:06 AM, Martin Peres martin.pe...@free.fr wrote:

From: Martin Peres martin.pe...@labri.fr

This is safe because ptherm hasn't been configured yet and will be a
little further down the initialization path. Ptherm should be safe
regarding to runtime reconfiguration.

Any objections to instead sticking the ACK in a single fini() hook
(along with additional code to disable all therm interrupts), and
having the IRQ handle silently ignore any non-requested IRQs (see what
the copy engine irq handler does, for example)?

Ben.


Hi Ben,

Sorry for the late answer. This all perfectly make sense. Please have a 
look at the patches I've just sent.


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


Re: [Nouveau] [PATCH 1/2] drm/nouveau/bios/therm: handle vbioses with duplicate entries (mostly nva5)

2013-09-08 Thread Martin Peres

On 04/09/2013 03:55, Ben Skeggs wrote:

On Sat, Aug 31, 2013 at 9:58 AM, Martin Peres martin.pe...@free.fr wrote:

From: Martin Peres martin.pe...@labri.fr

Some vbioses have extra useless entries after the end of the table. This is
problematic since all of the vbios I found with this issue redefine the
pwm freq divider to insane levels (52750 Hz instead of 2500), thus breaking
fan management.

The first solution to solve this mess would be to change the length of the
table. The solution I choose was simply to avoid setting the pwm freq twice
as the other redefinitions are harmless with our current parser.

I'm still *really* not convinced we're using the thermal table correctly

However, this makes sense for our current handling, so, merged.

Thanks,
Ben.


Well, I do agree that the first versions of the vbios table really felt 
like a script but this isn't the case anymore (not sure how I tested 
this though as it was more than a year ago).


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


Re: [Nouveau] Nouveau Hardware donation proposal Fermi

2013-09-24 Thread Martin Peres

On 23/09/2013 17:42, Moritz Meiser wrote:

Hi,

I would like to donate my GT630 card (which is actually Fermi/NVC0 family
based) to support Nouveau's further development for this hardware generation.
It's this model: http://www.inno3d.com/product/gt630_4gb_dual.html

Anyone interested?

Regards,

Moritz Meiser

Hi Moritz,

Thank you for your proposition :) Do you know exactly what chipset is it?

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


[Nouveau] [PATCH] nv50: enable MPEG-4 for NVA3+ (VP4.0)

2013-12-07 Thread Martin Peres
From: Martin Peres martin.pe...@labri.fr

This patch is a follow-up from Ilia Mirkin's enable H.264 patch which
solves the problem that prevented MPEG-4 videos to play correctly.

Tested on an nva3.

Signed-off-by: Martin Peres martin.pe...@labri.fr
Tested-by: Martin Peres martin.pe...@labri.fr
Cc: 10.0 mesa-sta...@lists.freedesktop.org
---
 src/gallium/drivers/nouveau/nouveau_vp3_video.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/src/gallium/drivers/nouveau/nouveau_vp3_video.c 
b/src/gallium/drivers/nouveau/nouveau_vp3_video.c
index 2f4196c..0843b78 100644
--- a/src/gallium/drivers/nouveau/nouveau_vp3_video.c
+++ b/src/gallium/drivers/nouveau/nouveau_vp3_video.c
@@ -362,11 +362,6 @@ nouveau_vp3_screen_get_video_param(struct pipe_screen 
*pscreen,
enum pipe_video_format codec = u_reduce_video_profile(profile);
switch (param) {
case PIPE_VIDEO_CAP_SUPPORTED:
-  /* For now, mpeg4 doesn't work on pre-nvc0. */
-  if (chipset  0xc0)
- return codec == PIPE_VIDEO_FORMAT_MPEG12 ||
-codec == PIPE_VIDEO_FORMAT_VC1 ||
-codec == PIPE_VIDEO_FORMAT_MPEG4_AVC;
   /* In the general case, this should work, once the pre-nvc0 problems are
* resolved. */
   return profile = PIPE_VIDEO_PROFILE_MPEG1  (
-- 
1.8.4.2

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


Re: [Nouveau] [PATCH] nv50: enable MPEG-4 for NVA3+ (VP4.0)

2013-12-07 Thread Martin Peres

On 07/12/2013 17:09, Ilia Mirkin wrote:

On Sat, Dec 7, 2013 at 8:11 AM, Martin Peres martin.pe...@free.fr wrote:

From: Martin Peres martin.pe...@labri.fr

This patch is a follow-up from Ilia Mirkin's enable H.264 patch which
solves the problem that prevented MPEG-4 videos to play correctly.

Tested on an nva3.


I might reword this as


VP3/VP4 now work on all the codecs they are supposed to, remove old restriction.

Tested on NVA3


Or something like that...


Yeah, that would make more sense. Feel free to reword it before committing.

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


Re: [Nouveau] Is binary firmware still necessary for GTX660 card (NVE0 family) in order to use DRM and/or VDPAU video acceleration?

2013-12-11 Thread Martin Peres

On 12/12/2013 08:32, Matthias Nagel wrote:

Hello,

I run the Gentoo Linux distribution and use a self-compiled Linux 
3.10.17 kernel. According to


[1] http://nouveau.freedesktop.org/wiki/InstallDRM/
[2] http://nouveau.freedesktop.org/wiki/VideoAcceleration/

I need the original firmware from the binary driver in order to 
sucessully use DRM and to use VDPAU video acceleration. I used the 
python script from [2] and I had a look at the ebuild from


[3] https://bugs.gentoo.org/show_bug.cgi?id=480832

to extract the firmware and to place it at /lib/firmware/nouveau. But 
I do not see any dmesg output about loading the firmware. I do not see 
any dmesg output about nouveau failing to do so either. I neither do 
no see any nouveau pci id: firmware: requesting nouveau/ in my 
kernel output.


Anyway VDPAU seems to work. If I call mplayer with -vo vdpau -vc 
ffmpeg12vdpau,..., I don't get any error message and my CPU load 
drops from 30% to 7% for a recent mpeg transport stream 1080p video.


In conclusion, do I still need the firmware? Do the information given 
at [1], [2] still apply or are they outdated?


Thanks for your first hand investigation. To be honest, I can't remember 
which kernel provides a working-enough open source pgraph fw.


As you figured out, it works for you, but you should update your kernel, 
there is no point in staying on old Linux releases, at least 
Nouveau-wise. If there was a regression, let us know instead of staying 
on an old kernel.


Cheers,
Martin Peres
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] Is binary firmware still necessary for GTX660 card (NVE0 family) in order to use DRM and/or VDPAU video acceleration?

2013-12-12 Thread Martin Peres

Le 12/12/2013 08:58, Matthias Nagel a écrit :

Hi Martin,
if you refer to my kernel version. 3.10.17 is the latest, stable 
version in the official gentoo repository for the amd64 architeture. 
See here

...

[4] https://packages.gentoo.org/package/sys-kernel/gentoo-sources?full_cat

As long as I do not miss any features, I stay with the stable version.
Indeed, you are doing the right thing, I guess. But if you encounter any 
sort of crash, I really advise you to go against gentoo on this and 
update your kernel to the latest official release (3.12.x at the 
moment). FYI, the 3.12 brings performance improvements to Nouveau too.


Hence, if I understand you correctly, there are kernel version (newer 
than some unknown point in time) that already include the firmware? If 
this is the case, someone who knows the exact kernel version should 
mention that point on


[1] http://nouveau.freedesktop.org/wiki/InstallDRM/
[2] http://nouveau.freedesktop.org/wiki/VideoAcceleration/
[3] https://bugs.gentoo.org/show_bug.cgi?id=480832

and update the information.


What I wanted to say is that adding good fw support usually spans across 
multiple kernels. Even 3.13 has kepler fw fixes IIRC and 3.14 will 
receive some more updates to support new chipsets. It isn't a binary 
thing so this is hard to tell we support a feature...


I guess we could tell when is the first free implementation (with the 
possible fallback of using the blob's firmware[1]) and then when we 
added support for all chipsets of the family and it has been 
fairly-extensively tested and bug-free. Some cards would never pass the 
test though :s


[1] NvGrUseFw, http://nouveau.freedesktop.org/wiki/KernelModuleParameters/

Cheers,
Martin
http://nouveau.freedesktop.org/wiki/KernelModuleParameters/
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [GSoC2014] Call for projects ideas and mentors

2014-02-05 Thread Martin Peres

Hi, fellow graphics stack developers,

Now that FOSDEM is over, it is time to think about the
Google Summer of Code 2014!

If you would like to propose a project for the GSoC 2014, please
write your proposals at [1], before the 14th of February, in order
to increase our chances of being an accepted organization.

If you simply would potentially be interested in being a mentor,
please also contact me as Google wants to have an estimate of
the number of potential mentors we would have.

If you have any questions regarding the GSoC or need any additional
information, please answer in this thread.

Cheers,
Martin

[1] http://xorg.freedesktop.org/wiki/SummerOfCodeIdeas/
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] nouveau_fan_update: possible circular locking dependency detected

2014-03-13 Thread Martin Peres

Le 13/03/2014 14:38, Ilia Mirkin a écrit :

On Sun, Mar 9, 2014 at 10:51 AM, Marcin Slusarz
marcin.slus...@gmail.com wrote:

[  326.168487] ==
[  326.168491] [ INFO: possible circular locking dependency detected ]
[  326.168496] 3.13.6 #1270 Not tainted
[  326.168500] ---
[  326.168504] ldconfig/22297 is trying to acquire lock:
[  326.168507]  ((priv-fan-lock)-rlock){-.-...}, at: [a00d5363] 
nouveau_fan_update+0xeb/0x252 [nouveau]
[  326.168551]
but task is already holding lock:
[  326.168555]  ((priv-sensor.alarm_program_lock)-rlock){-.-...}, at: 
[a00d6a8a] alarm_timer_callback+0xf1/0x179 [nouveau]
[  326.168587]
which lock already depends on the new lock.

[  326.168592]
the existing dependency chain (in reverse order) is:
[  326.168596]
- #1 ((priv-sensor.alarm_program_lock)-rlock){-.-...}:
[  326.168606][900a5656] lock_acquire+0xce/0x117
[  326.168615][905a367e] _raw_spin_lock_irqsave+0x3f/0x51
[  326.168623][a00d6a8a] alarm_timer_callback+0xf1/0x179 
[nouveau]
[  326.168651][a00da895] nv04_timer_alarm_trigger+0x1b1/0x1cb 
[nouveau]
[  326.168679][a00daaa0] nv04_timer_alarm+0xb5/0xbe [nouveau]
[  326.168708][a00d54ac] nouveau_fan_update+0x234/0x252 
[nouveau]
[  326.168735][a00d54df] nouveau_fan_alarm+0x15/0x17 [nouveau]
[  326.168763][a00da895] nv04_timer_alarm_trigger+0x1b1/0x1cb 
[nouveau]
[  326.168790][a00da90a] nv04_timer_intr+0x5b/0x13c [nouveau]
[  326.168817][a00d0e9b] nouveau_mc_intr+0x2e2/0x3b1 [nouveau]
[  326.168838][900ad359] handle_irq_event_percpu+0x5c/0x1dc
[  326.168846][900ad515] handle_irq_event+0x3c/0x5c
[  326.168852][900afa5e] handle_edge_irq+0xc4/0xeb
[  326.168860][9003a828] handle_irq+0x120/0x12d
[  326.168868][9003a2f8] do_IRQ+0x48/0xaf
[  326.168873][905a41ef] ret_from_intr+0x0/0x13
[  326.168881][90040ea2] arch_cpu_idle+0x13/0x1d
[  326.168887][900acb2e] cpu_startup_entry+0x140/0x218
[  326.168895][9005b0a0] start_secondary+0x1bf/0x1c4
[  326.168902]
- #0 ((priv-fan-lock)-rlock){-.-...}:
[  326.168913][900a49cc] __lock_acquire+0x10be/0x182b
[  326.168920][900a5656] lock_acquire+0xce/0x117
[  326.168924][905a367e] _raw_spin_lock_irqsave+0x3f/0x51
[  326.168931][a00d5363] nouveau_fan_update+0xeb/0x252 
[nouveau]
[  326.168958][a00d5508] nouveau_therm_fan_set+0x14/0x16 
[nouveau]
[  326.168984][a00d4c6b] nouveau_therm_update+0x303/0x312 
[nouveau]
[  326.169011][a00d4c8d] nouveau_therm_alarm+0x13/0x15 
[nouveau]
[  326.169038][a00da895] nv04_timer_alarm_trigger+0x1b1/0x1cb 
[nouveau]
[  326.169059][a00daaa0] nv04_timer_alarm+0xb5/0xbe [nouveau]
[  326.169079][a00d6af7] alarm_timer_callback+0x15e/0x179 
[nouveau]
[  326.169101][a00da895] nv04_timer_alarm_trigger+0x1b1/0x1cb 
[nouveau]
[  326.169121][a00da90a] nv04_timer_intr+0x5b/0x13c [nouveau]
[  326.169142][a00d0e9b] nouveau_mc_intr+0x2e2/0x3b1 [nouveau]
[  326.169160][900ad359] handle_irq_event_percpu+0x5c/0x1dc
[  326.169165][900ad515] handle_irq_event+0x3c/0x5c
[  326.169170][900afa5e] handle_edge_irq+0xc4/0xeb
[  326.169175][9003a828] handle_irq+0x120/0x12d
[  326.169179][9003a2f8] do_IRQ+0x48/0xaf
[  326.169183][905a41ef] ret_from_intr+0x0/0x13
[  326.169189]
other info that might help us debug this:

[  326.169193]  Possible unsafe locking scenario:

[  326.169195]CPU0CPU1
[  326.169197]
[  326.169199]   lock((priv-sensor.alarm_program_lock)-rlock);
[  326.169205]lock((priv-fan-lock)-rlock);
[  326.169211]
lock((priv-sensor.alarm_program_lock)-rlock);
[  326.169216]   lock((priv-fan-lock)-rlock);
[  326.169221]
  *** DEADLOCK ***

  [  326.169225] 1 lock held by ldconfig/22297:
  [  326.169229]  #0:  ((priv-sensor.alarm_program_lock)-rlock){-.-...}, at: 
[a00d6a8a] alarm_timer_callback+0xf1/0x179 [nouveau]
  [  326.169253]
  stack backtrace:
  [  326.169258] CPU: 7 PID: 22297 Comm: ldconfig Not tainted 3.13.6 #1270
  [  326.169260] Hardware name: System manufacturer System Product Name/P6T SE, 
BIOS 060309/02/2009
  [  326.169264]  90fb6360 8801bfdc3a38 9059e369 
0006
  [  326.169273]  90fb61b0 8801bfdc3a88 905998cf 
0002
  [  326.169282]  8800b148dbe0 0001 8800b148e1e0 

[Nouveau] [PATCH] pm/fan: drop the fan lock in fan_update() before rescheduling

2014-03-13 Thread Martin Peres
From: Martin Peres martin.pe...@labri.fr

This should fix a deadlock that has been reported to us where fan_update()
would hold the fan lock and try to grab the alarm_program_lock to reschedule
an update. On an other CPU, the alarm_program_lock would have been taken
before calling fan_update(), leading to a deadlock.

Reported-by: Marcin Slusarz marcin.slus...@gmail.com
Signed-off-by: Martin Peres martin.pe...@free.fr
---
 nvkm/subdev/therm/fan.c | 19 +--
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/nvkm/subdev/therm/fan.c b/nvkm/subdev/therm/fan.c
index 95f6129..29d4c41 100644
--- a/nvkm/subdev/therm/fan.c
+++ b/nvkm/subdev/therm/fan.c
@@ -54,8 +54,10 @@ nouveau_fan_update(struct nouveau_fan *fan, bool immediate, 
int target)
 
/* check that we're not already at the target duty cycle */
duty = fan-get(therm);
-   if (duty == target)
-   goto done;
+   if (duty == target) {
+   spin_unlock_irqrestore(fan-lock, flags);
+   return 0;
+   }
 
/* smooth out the fanspeed increase/decrease */
if (!immediate  duty = 0) {
@@ -73,8 +75,15 @@ nouveau_fan_update(struct nouveau_fan *fan, bool immediate, 
int target)
 
nv_debug(therm, FAN update: %d\n, duty);
ret = fan-set(therm, duty);
-   if (ret)
-   goto done;
+   if (ret) {
+   spin_unlock_irqrestore(fan-lock, flags);
+   return ret;
+   }
+
+   /* fan speed updated, drop the fan lock before grabbing the
+* alarm-scheduling lock and risking a deadlock
+*/
+   spin_unlock_irqrestore(fan-lock, flags);
 
/* schedule next fan update, if not at target speed already */
if (list_empty(fan-alarm.head)  target != duty) {
@@ -92,8 +101,6 @@ nouveau_fan_update(struct nouveau_fan *fan, bool immediate, 
int target)
ptimer-alarm(ptimer, delay * 1000 * 1000, fan-alarm);
}
 
-done:
-   spin_unlock_irqrestore(fan-lock, flags);
return ret;
 }
 
-- 
1.9.0

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


  1   2   3   4   >