Re: [Nouveau] [TEST REQUEST] NV50/NV8x/NV9x/NVAx ctxprog and ctxvals generator
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
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
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
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
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
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.
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.
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.
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
--- 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
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
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
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?
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
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
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
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
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
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
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
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
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
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
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)
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
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
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
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()
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
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
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
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
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
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
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
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
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
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
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
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
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)
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)
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
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
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
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
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?
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
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
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
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
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
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
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
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)
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
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
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
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
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
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)
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
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)
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)
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?
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?
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
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
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
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