Re: [Nouveau] [igt-dev] [PATCH i-g-t] tests/kms_plane: Don't unset primary_fb when testing other planes

2021-03-22 Thread Martin Peres

On 21/03/2021 22:02, Juha-Pekka Heikkila wrote:

On 18.3.2021 8.41, Martin Peres wrote:

On 18/03/2021 00:44, Lyude wrote:

From: Lyude Paul 

Currently, nouveau doesn't support having a CRTC without a primary FB 
set. We
won't reject such configurations, but the behavior is undefined which 
will cause
CRCs to become undefined. So, avoid clearing the primary FB while 
we're testing

non-primary planes.


Looks good to me:

Reviewed-by: Martin Peres 



This doesn't look good at all. Code changes were never run on ci, see this:
https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5614/shards-all.html?testfilter=kms_plane@pixel-format 



This happen because of:
igt-gpu-tools$ git blame tests/intel-ci/blacklist-pre-merge.txt -L 173,+1
3e686098d9 (Martin Peres 2020-02-21 11:00:47 +0200 173) 
igt@kms_plane@pixel-format-pipe-[a-d]-planes(-source-clamping)?


Killed by my own creation, isn't it quaint? Thanks a lot for 
investigating the regression, and I'll be wearing my brown bag today :s




You'll need to include something like this to test and review what did 
change on pixel format tests:

https://patchwork.freedesktop.org/patch/404706/?series=84370=1

but as this patch seems to be already merged as untested we now have 
pixel format tests failing reliably ever since:
https://intel-gfx-ci.01.org/tree/drm-tip/index.html?testfilter=kms_plane@pixel-format=tgl%7Cicl 



I have only intel icl at hand so I have no suggestions for fix. Though, 
looking at those failures Stan (CCd) may have some interest on them.


I would indeed like to hear if this sounds like a kernel bug, a 
violation of the KMS spec, or the spec is not clear-enough on this.


If I don't hear back on this today, I'll send a revert while the 
situation is investigated.


Martin



/Juha-Pekka



Signed-off-by: Lyude Paul 
Cc: Martin Peres 
Cc: Ben Skeggs 
Cc: Jeremy Cline 
---
  tests/kms_plane.c | 9 +
  1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/tests/kms_plane.c b/tests/kms_plane.c
index 298a9375..c87983a4 100644
--- a/tests/kms_plane.c
+++ b/tests/kms_plane.c
@@ -817,9 +817,10 @@ enum crc_set { PACKED_CRC_SET,
 MAX_CRC_SET };
  static bool test_format_plane(data_t *data, enum pipe pipe,
-  igt_output_t *output, igt_plane_t *plane)
+  igt_output_t *output, igt_plane_t *plane, igt_fb_t 
*primary_fb)

  {
  struct igt_fb fb = {};
+    struct igt_fb *clear_fb = plane->type == DRM_PLANE_TYPE_PRIMARY 
? primary_fb : NULL;

  drmModeModeInfo *mode;
  uint32_t format, ref_format;
  uint64_t modifier, ref_modifier;
@@ -879,7 +880,7 @@ static bool test_format_plane(data_t *data, enum 
pipe pipe,

  height = test_fb.height;
  }
-    igt_plane_set_fb(plane, NULL);
+    igt_plane_set_fb(plane, clear_fb);
  igt_remove_fb(data->drm_fd, _fb);
  }
@@ -937,7 +938,7 @@ static bool test_format_plane(data_t *data, enum 
pipe pipe,

  igt_pipe_crc_stop(data->pipe_crc);
-    igt_plane_set_fb(plane, NULL);
+    igt_plane_set_fb(plane, clear_fb);
  igt_remove_fb(data->drm_fd, );
  return result;
@@ -1010,7 +1011,7 @@ test_pixel_formats(data_t *data, enum pipe pipe)
  for_each_plane_on_pipe(>display, pipe, plane) {
  if (skip_plane(data, plane))
  continue;
-    result &= test_format_plane(data, pipe, output, plane);
+    result &= test_format_plane(data, pipe, output, plane, 
_fb);

  }
  test_fini(data);


___
igt-dev mailing list
igt-...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev



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


Re: [Nouveau] [igt-dev] [PATCH i-g-t v2 1/2] tests/kms_cursor_crc: Probe kernel for cursor size support

2021-03-19 Thread Martin Peres

On 19/03/2021 00:21, Lyude wrote:

From: Lyude Paul 

Currently we just assume that every cursor size up to data->cursor_max_w/h will
be supported by the driver, and check for support of nonsquare cursors by
checking if we're running on u815 and if so, which variant of intel hardware
we're running on. This isn't really ideal as we're about to enable 32x32 cursor
size tests for nouveau, and Intel hardware doesn't support cursor sizes that
small.

So, fix this by removing has_nonsquare_cursors() and replacing it with a more
generic require_cursor_size() function which checks whether or not the driver
we're using supports a given cursor size by attempting a test-only atomic
commit.


Looks clean to me, and results in no new failures in Intel's results 
(https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5625/shards-all.html?testfilter=kms_cursor_crc), 
and no changes in the results for any other test.


Not sure I can comment on the implementation details of 
require_cursor_size(), but everything else, and the series is:


Reviewed-by: Martin Peres 



Signed-off-by: Lyude Paul 
Cc: Martin Peres 
Cc: Ben Skeggs 
Cc: Jeremy Cline 
---
  tests/kms_cursor_crc.c | 131 -
  1 file changed, 76 insertions(+), 55 deletions(-)

diff --git a/tests/kms_cursor_crc.c b/tests/kms_cursor_crc.c
index 3541ea06..b9c05472 100644
--- a/tests/kms_cursor_crc.c
+++ b/tests/kms_cursor_crc.c
@@ -523,26 +523,43 @@ static void create_cursor_fb(data_t *data, int cur_w, int 
cur_h)
igt_put_cairo_ctx(cr);
  }
  
-static bool has_nonsquare_cursors(data_t *data)

+static void require_cursor_size(data_t *data, int w, int h)
  {
-   uint32_t devid;
+   igt_fb_t primary_fb;
+   drmModeModeInfo *mode;
+   igt_display_t *display = >display;
+   igt_output_t *output = data->output;
+   igt_plane_t *primary, *cursor;
+   int ret;
  
-	if (!is_i915_device(data->drm_fd))

-   return false;
+   igt_output_set_pipe(output, data->pipe);
  
-	devid = intel_get_drm_devid(data->drm_fd);

+   mode = igt_output_get_mode(output);
+   primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
+   cursor = igt_output_get_plane_type(output, DRM_PLANE_TYPE_CURSOR);
  
-	/*

-* Test non-square cursors a bit on the platforms
-* that support such things.
-*/
-   if (devid == PCI_CHIP_845_G || devid == PCI_CHIP_I865_G)
-   return true;
+   /* Create temporary primary fb for testing */
+   igt_assert(igt_create_fb(data->drm_fd, mode->hdisplay, mode->vdisplay, 
DRM_FORMAT_XRGB,
+LOCAL_DRM_FORMAT_MOD_NONE, _fb));
  
-	if (IS_VALLEYVIEW(devid) || IS_CHERRYVIEW(devid))

-   return false;
+   igt_plane_set_fb(primary, _fb);
+   igt_plane_set_fb(cursor, >fb);
+   igt_plane_set_size(cursor, w, h);
+   igt_fb_set_size(>fb, cursor, w, h);
+
+   /* Test if the kernel supports the given cursor size or not */
+   ret = igt_display_try_commit_atomic(display,
+   DRM_MODE_ATOMIC_TEST_ONLY |
+   DRM_MODE_ATOMIC_ALLOW_MODESET,
+   NULL);
+
+   igt_plane_set_fb(primary, NULL);
+   igt_plane_set_fb(cursor, NULL);
+
+   igt_remove_fb(data->drm_fd, _fb);
+   igt_output_set_pipe(output, PIPE_NONE);
  
-	return intel_gen(devid) >= 7;

+   igt_skip_on_f(ret, "Cursor size %dx%d not supported by driver\n", w, h);
  }
  
  static void test_cursor_size(data_t *data)

@@ -697,27 +714,33 @@ static void run_tests_on_pipe(data_t *data, enum pipe 
pipe)
create_cursor_fb(data, w, h);
}
  
-		/* Using created cursor FBs to test cursor support */

-   igt_describe("Check if a given-size cursor is well-positioned inside 
the screen.");
-   igt_subtest_f("pipe-%s-cursor-%dx%d-onscreen", 
kmstest_pipe_name(pipe), w, h)
-   run_test(data, test_crc_onscreen, w, h);
-
-   igt_describe("Check if a given-size cursor is well-positioned 
outside the screen.");
-   igt_subtest_f("pipe-%s-cursor-%dx%d-offscreen", 
kmstest_pipe_name(pipe), w, h)
-   run_test(data, test_crc_offscreen, w, h);
-
-   igt_describe("Check the smooth and pixel-by-pixel given-size cursor 
movements on"
-"horizontal, vertical and diagonal.");
-   igt_subtest_f("pipe-%s-cursor-%dx%d-sliding", 
kmstest_pipe_name(pipe), w, h)
-   run_test(data, test_crc_sliding, w, h);
-
-   igt_describe("Check random placement of a cursor with given 
size.");
-   igt_subtest_f("pipe-%s-cursor-%dx%d-random", 
kmstest_pipe_name(pipe), w, h)

Re: [Nouveau] [igt-dev] [PATCH i-g-t 0/3] tests/kms_color: Fixup for nouveau

2021-03-18 Thread Martin Peres

On 18/03/2021 00:42, Lyude wrote:

From: Lyude Paul 

This patch series just introduces a small drive-by cleanup for
kms_color, and fixes the kms_color test so that it works correctly on
nouveau. Note that the invalid LUT/gamma tests will likely currently
fail, but I'm going to be submitting some kernel patches to fix these in
nouveau very shortly.


The series is:

Reviewed-by: Martin Peres 



Cc: Martin Peres 
Cc: Ben Skeggs 
Cc: Jeremy Cline 

Lyude Paul (3):
   tests/kms_color: Don't opencode igt_check_crc_equal()
   tests/kms_color: Allow tests to run on any driver
   tests/kms_color: Stop leaking fbs

  tests/kms_color.c| 15 +--
  tests/kms_color_helper.c |  6 --
  2 files changed, 13 insertions(+), 8 deletions(-)


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


Re: [Nouveau] [igt-dev] [PATCH i-g-t] tests/kms_plane: Don't unset primary_fb when testing other planes

2021-03-18 Thread Martin Peres

On 18/03/2021 00:44, Lyude wrote:

From: Lyude Paul 

Currently, nouveau doesn't support having a CRTC without a primary FB set. We
won't reject such configurations, but the behavior is undefined which will cause
CRCs to become undefined. So, avoid clearing the primary FB while we're testing
non-primary planes.


Looks good to me:

Reviewed-by: Martin Peres 



Signed-off-by: Lyude Paul 
Cc: Martin Peres 
Cc: Ben Skeggs 
Cc: Jeremy Cline 
---
  tests/kms_plane.c | 9 +
  1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/tests/kms_plane.c b/tests/kms_plane.c
index 298a9375..c87983a4 100644
--- a/tests/kms_plane.c
+++ b/tests/kms_plane.c
@@ -817,9 +817,10 @@ enum crc_set { PACKED_CRC_SET,
   MAX_CRC_SET };
  
  static bool test_format_plane(data_t *data, enum pipe pipe,

- igt_output_t *output, igt_plane_t *plane)
+ igt_output_t *output, igt_plane_t *plane, 
igt_fb_t *primary_fb)
  {
struct igt_fb fb = {};
+   struct igt_fb *clear_fb = plane->type == DRM_PLANE_TYPE_PRIMARY ? 
primary_fb : NULL;
drmModeModeInfo *mode;
uint32_t format, ref_format;
uint64_t modifier, ref_modifier;
@@ -879,7 +880,7 @@ static bool test_format_plane(data_t *data, enum pipe pipe,
height = test_fb.height;
}
  
-		igt_plane_set_fb(plane, NULL);

+   igt_plane_set_fb(plane, clear_fb);
  
  		igt_remove_fb(data->drm_fd, _fb);

}
@@ -937,7 +938,7 @@ static bool test_format_plane(data_t *data, enum pipe pipe,
  
  	igt_pipe_crc_stop(data->pipe_crc);
  
-	igt_plane_set_fb(plane, NULL);

+   igt_plane_set_fb(plane, clear_fb);
igt_remove_fb(data->drm_fd, );
  
  	return result;

@@ -1010,7 +1011,7 @@ test_pixel_formats(data_t *data, enum pipe pipe)
for_each_plane_on_pipe(>display, pipe, plane) {
if (skip_plane(data, plane))
continue;
-   result &= test_format_plane(data, pipe, output, plane);
+   result &= test_format_plane(data, pipe, output, plane, 
_fb);
}
  
  	test_fini(data);



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


Re: [Nouveau] [igt-dev] [PATCH i-g-t 0/7] lib: Miscellaneous cleanups from nouveau work

2021-03-18 Thread Martin Peres

On 18/03/2021 00:49, Lyude wrote:

From: Lyude Paul 

These are just a couple of small fixes that didn't seem important
enough to stick in their own patch series, but were various issues with
igt that I found along the way during my recent nouveau igt work.

Cc: Martin Peres 
Cc: Jeremy Cline 


This series looks sensible to me, and do not seem to have affected 
Intel's results.


I'll refrain from giving a full R-b because I lack the historical 
context for some of these changes, but it seems safe to me:


Acked-by: Martin Peres 



Lyude Paul (7):
   lib/drmtest: Use igt_assert_eq() for do_or_die()
   lib/drmtest: And use do_or_die() in do_ioctl()
   lib/drmtest: Remove i915 refs in do_ioctl*() docs
   lib/igt_fb: Remove domain from igt_fb
   lib/debugfs: Fix igt_crc_t docs to mention has_valid_frame
   lib/igt_aux: Print name of debug var in igt_debug_wait_for_keypress()
   lib/debugfs: Fix function name in igt_pipe_crc_get_for_frame() docs

  lib/drmtest.h | 8 
  lib/igt_aux.c | 2 +-
  lib/igt_debugfs.c | 2 +-
  lib/igt_debugfs.h | 3 ++-
  lib/igt_fb.c  | 3 ---
  lib/igt_fb.h  | 2 --
  6 files changed, 8 insertions(+), 12 deletions(-)


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


Re: [Nouveau] [igt-dev] [PATCH i-g-t] lib: Introduce the igt_nouveau library

2021-03-18 Thread Martin Peres

On 18/03/2021 00:38, Lyude wrote:

From: Lyude Paul 

This introduces the igt_nouveau library, which enables support for tiling
formats on nouveau, along with accelerated clears for allocated bos in VRAM
using the dma-copy engine present on Nvidia hardware since Tesla. Typically
the latter would be handled by the kernel automatically, which is the
long-term plan for nouveau, but since the kernel doesn't yet support that
we implement this in igt in order to fulfill the expectation that most of
igt has in which newly allocated fbs are expected to be zero-filled by
default.


Good to hear this is coming!



The dma-copy engine is capable of fast blitting, and is also able to
perform tiling/untiling at the same time. This is worth mentioning because
unlike many of the other drivers supported in igt, we go out of our way to
avoid using mmap() in order to perform CPU rendering wherever possible.
Instead of mmap()ing an fb that we want to draw to on the CPU (whether it
be for converting formats, or just normal rendering), we instead use
dma-copy to blit linear/tiled fbs over to linear system memory which we
mmap() instead. This is primarily because while mmap() is typically
painfully slow for vram, it's even slower on nouveau due to the current
lack of dynamic reclocking in our driver. Furthermore, using the dma-copy
engine for copying things over to system ram is also dramatically faster
than using igt's memcpy wc helpers even when no tiling is involved. Such
speed improvements are both quite nice, but also very necessary for certain
tests like kms_plane that are rather sensitive when it comes to slow
rendering with drivers.


Very interesting, I would not have expected there would have been a 
performance difference, unless pixels would be read/written more than once.




This doesn't mean we won't want to provide a way of using mmap() for
rendering in the future however, as at least basic testing of mmap() is
certainly something we eventually want for nouveau. However, I think the
best way for us to do this in the future will be to adapt the igt_draw API
to work with nouveau so we can explicitly request using mmap() in tests
which need it.


Yeah, one thing at a time :)



Finally, this code also adds a hard dependency on libdrm support for
nouveau tests. The main reason for this is currently there are no real
applications that use nouveau's ioctls directly (mesa for instance, uses
libdrm as well) and also that nouveau's ioctls are currently a bit
complicated to use by hand. This will likely be temporary however, as Ben
Skeggs is planning on revamping a lot of nouveau's APIs to simplify them
and make libdrm support for nouveau obsolete in the future. Note that we
take care to make sure that users can still disable libdrm support for
nouveau if needed, with the only caveat being that any tests using
igt_nouveau will be disabled, along with any tiling support for
nvidia-specific tiling formats.


Seems reasonable to me.



This should enable igt tests which test tiling formats to run on nouveau,
and fix some seemingly random test failures as a result of not having
zero-filled buffers in a few other tests like kms_cursor_crc.


\o/

More comments inline :)



Signed-off-by: Lyude Paul 
Cc: Martin Peres 
Cc: Ben Skeggs 
Cc: Jeremy Cline 
---
  .gitlab-ci.yml  |   7 +
  include/drm-uapi/drm_fourcc.h   |   2 +-
  lib/drmtest.c   |   5 +
  lib/igt_fb.c|  98 +++--
  lib/igt_fb.h|   2 +
  lib/igt_nouveau.c   | 281 ++
  lib/igt_nouveau.h   |  65 ++
  lib/meson.build |   8 +
  lib/nouveau/cea0b5.c| 252 +++
  lib/nouveau/nvhw/class/cl906f.h | 103 ++
  lib/nouveau/nvhw/class/cla0b5.h | 250 +++
  lib/nouveau/nvhw/drf.h  | 209 +++
  lib/nouveau/nvif/push.h | 345 
  lib/nouveau/nvif/push906f.h |  70 +++
  lib/nouveau/priv.h  |  57 ++
  meson.build |   3 +
  tests/meson.build   |   2 +-
  17 files changed, 1745 insertions(+), 14 deletions(-)
  create mode 100644 lib/igt_nouveau.c
  create mode 100644 lib/igt_nouveau.h
  create mode 100644 lib/nouveau/cea0b5.c
  create mode 100644 lib/nouveau/nvhw/class/cl906f.h
  create mode 100644 lib/nouveau/nvhw/class/cla0b5.h
  create mode 100644 lib/nouveau/nvhw/drf.h
  create mode 100644 lib/nouveau/nvif/push.h
  create mode 100644 lib/nouveau/nvif/push906f.h
  create mode 100644 lib/nouveau/priv.h

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index e226d9d7..8d275be7 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -89,6 +89,13 @@ build:tests-fedora-oldest-meson:
  - ninja -C build || ninja -C build -j 1
  - ninja -C build igt-gpu-tools-doc
  
+# ensure igt_nouveau stubs build when nouveau support for libdrm is disabled

+build:tests-fedora-no-libdrm

Re: [Nouveau] [igt-dev] [PATCH i-g-t] tests/kms_cursor_crc: Test 32x32 cursors

2021-03-18 Thread Martin Peres

On 18/03/2021 00:45, Lyude wrote:

From: Lyude Paul 

Since pre-nve4 only has two cursor sizes (32x32 and 64x64), we should at
least test both of them.


This adds 36 subtests, which take about 1s in average. So the runtime is 
not significantly increased on the Intel side.


It also seems that Intel should add skips or fix the kernel to support 
these 32xXX format.


@Petri, could you get someone to investigate this?

In the mean time, here is my:

Reviewed-by: Martin Peres 

Martin


Signed-off-by: Lyude Paul 
Cc: Martin Peres 
Cc: Ben Skeggs 
Cc: Jeremy Cline 
---
  tests/kms_cursor_crc.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/kms_cursor_crc.c b/tests/kms_cursor_crc.c
index 0be8f7f8..c70c4a8f 100644
--- a/tests/kms_cursor_crc.c
+++ b/tests/kms_cursor_crc.c
@@ -683,7 +683,7 @@ static void run_tests_on_pipe(data_t *data, enum pipe pipe)
igt_fixture
igt_remove_fb(data->drm_fd, >fb);
  
-	for (cursor_size = 64; cursor_size <= 512; cursor_size *= 2) {

+   for (cursor_size = 32; cursor_size <= 512; cursor_size *= 2) {
int w = cursor_size;
int h = cursor_size;
  


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


Re: [Nouveau] [PATCH] drm/nouveau: Don't disable polling in fallback mode

2018-09-14 Thread Martin Peres
On 14/09/2018 10:28, Ben Skeggs wrote:
> On Wed, 12 Sep 2018 at 20:59, Takashi Iwai  wrote:
>>
>> When a fan is controlled via linear fallback without cstate, we
>> shouldn't stop polling.  Otherwise it won't be adjusted again and
>> keeps running at an initial crazy pace.
> Martin,
> 
> Any thoughts on this?
> 
> Ben.

Wow, blast from the past!

Anyway, the analysis is pretty spot on here. When using the cstate-based
fan speed (change the speed of the fan based on what frequency is used),
then polling is unnecessary and this function should only be called when
changing the pstate.

However, in the absence of ANY information, we fallback to a
temperature-based management which requires constant polling, so the
patch is accurate and poll = false should only be set if we have a cstate.

So, the patch is Reviewed-by: Martin Peres 

> 
>>
>> Fixes: 800efb4c2857 ("drm/nouveau/drm/therm/fan: add a fallback if no fan 
>> control is specified in the vbios")
>> Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=1103356
>> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=107447

I see that Thomas has been having issues with the noise level anyway. I
suggest he should bump the value of temp1_auto_point1_temp (see
https://www.kernel.org/doc/Documentation/thermal/nouveau_thermal).

The default value is set to 90°C which is quite safe on these old GPUs
(NVIDIA G71 / nv49). I would say that it is safe to go up to 110°C.
Which should reduce the noise level.

Another technique may be to reduce the minimum fan speed to something
lower than 30°C. It should increase the slope but reduce the noise level
at a given temperature.

One reason why these GPUs run so hot on nouveau is the lack of power and
clock gating. I am sorry that I never finished to reverse engineer these...

Anyway, thanks a lot for the patch!

>> Reported-by: Thomas Blume 
>> Signed-off-by: Takashi Iwai 
>>
>> ---
>>  drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c | 7 ---
>>  1 file changed, 4 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c 
>> b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
>> index 3695cde669f8..07914e36939e 100644
>> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
>> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
>> @@ -132,11 +132,12 @@ nvkm_therm_update(struct nvkm_therm *therm, int mode)
>> duty = nvkm_therm_update_linear(therm);
>> break;
>> case NVBIOS_THERM_FAN_OTHER:
>> -   if (therm->cstate)
>> +   if (therm->cstate) {
>> duty = therm->cstate;
>> -   else
>> +   poll = false;
>> +   } else {
>> duty = 
>> nvkm_therm_update_linear_fallback(therm);
>> -   poll = false;
>> +   }
>> break;
>> }
>> immd = false;
>> --
>> 2.18.0
>>
>> ___
>> Nouveau mailing list
>> Nouveau@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/nouveau

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


Re: [Nouveau] Aspirant for GSOC 2018 for Nouveau Vulkan driver

2018-03-07 Thread Martin Peres
Hi Anusha,

Sorry, I was under the expectation that userspace developers would
answer you after your first message, and I missed your second one! My
sincere apologies.

Generally, the process is that the student should research the topic by
first asking questions to developers about the effort, then they would
make their own plan. Then you would present this plan while looking for
a mentor.

Of course, you can expect help from the community in order to better
understand what needs to be done, but don't expect to be given a
detailed plan, just pointers.

Sorry again for my lack of feedback,
Martin

On 07/03/18 05:53, Anusha Srivastava wrote:
> Hi,
> 
> I am not been able to contact with mentor of this project.
> Can someone else from the community help me with this ?
> 
> 
> Regards,
> Anusha Srivastava
> 
> 
> On 3 March 2018 at 11:16, Anusha Srivastava  wrote:
>> Hi Martin,
>>
>> Any update on this ?
>> Regards,
>> Anusha Srivastava
>>
>>
>> On 28 February 2018 at 23:37, Anusha Srivastava  
>> wrote:
>>> Hi,
>>>
>>> I would like to participate in  GSOC 2018 with Xorg to contribute to
>>> project "Initial Nouveau Vulkan driver'
>>> I would need some help in how to get started with the same.
>>>
>>> Regards,
>>> Anusha Srivastava

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


[Nouveau] Google Summer of Code 2018

2018-02-26 Thread Martin Peres
Hi everyone,

Just a quick word to remind you that the X.Org Foundation got accepted
to the Google Summer of Code 2018!

As a potential mentor, if you have a project falling under the
foundation's (large) umbrella that you would like to kick start or get
help finishing, please add it to the list on the ideas page[1] as soon
as possible. Students will start applying on the 12th of March, see the
full timeline[2].

As a student, check out the projects our ideas' page[1]. If you find one
that interests you, check out our application guidelines[3] and, if you
are eligible, contact your potential mentor and start discussing right
away with him/her. We welcome any student who finds the prospect of
working on our Open Source Graphics stack exciting!

I will be once again the primary contact for the X.Org Foundation, so
please ask me anything by email or on IRC (mupuf on freenode). Other
administrators are Alex Deucher and Taylor Campbell (both Cc:ed).

Looking forward to interacting with old and new contributors, and maybe
welcome previous GSoC/EVoC students as mentors now that they grew to
become core contributors and/or have full-time jobs in the Graphics
stack (*wink wink nudge nudge*)!

Martin, on behalf of the X.Org Foundation

[1] https://www.x.org/wiki/SummerOfCodeIdeas/
[2] https://developers.google.com/open-source/gsoc/timeline
[3] https://www.x.org/wiki/GSoCApplication/
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] Addressing the problem of noisy GPUs under Nouveau

2018-02-14 Thread Martin Peres
On 07/02/18 05:31, John Hubbard wrote:
> On 01/28/2018 04:05 PM, Martin Peres wrote:
>> On 29/01/18 01:24, Martin Peres wrote:
>>> On 28/11/17 07:32, John Hubbard wrote:
>>>> On 11/23/2017 02:48 PM, Martin Peres wrote:
>>>>> On 23/11/17 10:06, John Hubbard wrote:
>>>>>> On 11/22/2017 05:07 PM, Martin Peres wrote:
>>>>>>> Hey,
>>>>>>>
>>>>>>> Thanks for your answer, Andy!
>>>>>>>
>>>>>>> On 22/11/17 04:06, Ilia Mirkin wrote:
>>>>>>>> On Tue, Nov 21, 2017 at 8:29 PM, Andy Ritger <arit...@nvidia.com> 
>>>>>>>> wrote:
>>>>>>>> Martin's question was very long, but it boils down to this:
>>>>>>>>
>>>>>>>> How do we compute the correct values to write into the e114/e118 pwm
>>>>>>>> registers based on the VBIOS contents and current state of the board
>>>>>>>> (like temperature).
>>>>>>>
>>>>>>> Unfortunately, it can also be the e11c/e120 couple, or 0x200d8/dc on
>>>>>>> GF119+, or 0x200cd/d0 on Kepler+.
>>>>>>>
>>>>>>> At least, it looks like we know which PWM controler we need to drive, so
>>>>>>> I did not want to muddy the water even more by giving register
>>>>>>> addresses, rather concentrating on the problem at hand: How to compute
>>>>>>> the duty value for the PWM controler.
>>>>>>>
>>>>>>>>
>>>>>>>> We generally do this right, but appear to get it extra-wrong for 
>>>>>>>> certain GPUs.
>>>>>>>
>>>>>>> Yes... So far, we are always safe, but users tend to mind when their
>>>>>>> computer sound like a jumbo jet at take off... Who would have thought? 
>>>>>>> :D
>>>>>>>
>>>>>>> Anyway, looking forward to your answer!
>>>>>>>
>>>>>>> Cheers,
>>>>>>> Martin
>>>>>>
> [...]
> 
> Hi Martin,
> 
> I strongly suspect you are seeing a special behavior, which is: on
> some GF108 boards we use only a very limited range of PWM,
> 0.4 to 2.5%, due to the particular type of DC power conversion
> circuit on those boards. However, it could also just be difficulties
> in interpreting the fixed-point variables in the tables. In either
> case, the answer is to explain those formats, so I'll do that now.
> 
> I am attaching the fan cooler table, in HTML format. We have also
> published the BIT (BIOS Information Table) format, separately:
> 
> 
> http://download.nvidia.com/open-gpu-doc/BIOS-Information-Table/1/BIOS-Information-Table.html
> 
> , but I don't think it has any surprises for you, in this regard. You
> can check it, to be sure you're looking at the right subtable, though,
> just in case.
> 
> The interesting parts of that table are:
> 
> PWM Scale Slope (16 bits):
> 
>   Slope to scale effective PWM to actual PWM (1/4096, F4.12, signed).
>   For backwards compatibility, a value of 0.0 (0x) is interpreted as 1.0 
> (0x1000).
>   This value is used to scale the effective PWM duty cycle, a conceptual 
> fraction
>   of full speed (0% to 100%), to the actual electrical PWM duty cycle.
>   PWM(actual) = Slope × PWM(effective) + Offset
> 
> PWM Scale Offset (16 bits):
> 
>   Offset to scale effective PWM to actual PWM (1/4096, F4.12, signed).
>   This value is used to scale the effective PWM duty cycle, a conceptual 
> fraction
>   of full speed (0% to 100%), to the actual electrical PWM duty cycle.
>   PWM(actual) = Slope × PWM(effective) + Offset
> 
> 
> However, the calculations are hard to get right, and the table stores
> values in fixed-point format, so I'm showing a few simplified code excerpts
> that use these. The various fixed point macro definitions are found as part of
> our normal driver package, in nvmisc.h and nvtypes.h. Any other definitions
> that you need are included right here (I ran a quick compiler check to be 
> sure.)

Wow John, thanks a lot! Sorry for the delay, I was on vacation when you
posted this, but this definitely is what I was looking for!

Thanks a lot for the code example, I will try to make use of it soon and
come back to you if I still have issues!

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


Re: [Nouveau] Addressing the problem of noisy GPUs under Nouveau

2018-01-29 Thread Martin Peres
On 29/01/18 09:51, John Hubbard wrote:
> On 01/28/2018 04:05 PM, Martin Peres wrote:
>> On 29/01/18 01:24, Martin Peres wrote:
>>> On 28/11/17 07:32, John Hubbard wrote:
>>>> On 11/23/2017 02:48 PM, Martin Peres wrote:
>>>>> On 23/11/17 10:06, John Hubbard wrote:
>>>>>> On 11/22/2017 05:07 PM, Martin Peres wrote:
>>>>>>> Hey,
>>>>>>>
>>>>>>> Thanks for your answer, Andy!
>>>>>>>
>>>>>>> On 22/11/17 04:06, Ilia Mirkin wrote:
>>>>>>>> On Tue, Nov 21, 2017 at 8:29 PM, Andy Ritger <arit...@nvidia.com> 
>>>>>>>> wrote:
>>>>>>>> Martin's question was very long, but it boils down to this:
>>>>>>>>
>>>>>>>> How do we compute the correct values to write into the e114/e118 pwm
>>>>>>>> registers based on the VBIOS contents and current state of the board
>>>>>>>> (like temperature).
>>>>>>>
>>>>>>> Unfortunately, it can also be the e11c/e120 couple, or 0x200d8/dc on
>>>>>>> GF119+, or 0x200cd/d0 on Kepler+.
>>>>>>>
>>>>>>> At least, it looks like we know which PWM controler we need to drive, so
>>>>>>> I did not want to muddy the water even more by giving register
>>>>>>> addresses, rather concentrating on the problem at hand: How to compute
>>>>>>> the duty value for the PWM controler.
>>>>>>>
>>>>>>>>
>>>>>>>> We generally do this right, but appear to get it extra-wrong for 
>>>>>>>> certain GPUs.
>>>>>>>
>>>>>>> Yes... So far, we are always safe, but users tend to mind when their
>>>>>>> computer sound like a jumbo jet at take off... Who would have thought? 
>>>>>>> :D
>>>>>>>
>>>>>>> Anyway, looking forward to your answer!
>>>>>>>
>>>>>>> Cheers,
>>>>>>> Martin
>>>>>>
>>>>>>
>>>>>> Hi Martin,
>>>>>>
>>>>>> One of our firmware engineers thinks that this looks a lot like PWM 
>>>>>> inversion.
>>>>>> For some SKUs, the interpretation of the PWM duty cycle is inverted. 
>>>>>> That 
>>>>>> would probably make it *very* difficult to find a sensible algorithm 
>>>>>> that 
>>>>>> covered all the SKUs, given that some are inverted and others are not.
>>>>>>
>>>>>> For the noisy GPUs, a very useful experiment would be to try inverting 
>>>>>> it, 
>>>>>> like this:
>>>>>>
>>>>>>  pwmDutyCycle = pwmPeriod - pwmDutyCycle;
>>>>>>
>>>>>> ...and then see if fan control starts behaving closer to how you've 
>>>>>> actually 
>>>>>> programmed it.
>>>>>>
>>>>>> Would that be easy enough to try out? It should help narrow down the
>>>>>> problem at least.
>>>>>>
>>>>>
>>>>> Hey John,
>>>>>
>>>>> Unfortunately, we know about PWM inversion, and one can know which mode
>>>>> to use based on the GPIO entry associated to the fan (inverted). We have
>>>>> had support for this in Nouveau for a long time. At the very least, this
>>>>> is not the problem on my GF108.
>>>>>
>>>>> I am certain that the problem I am seeing is related to this vbios table
>>>>> I wrote about (BIT P, offset 0x18). It is used to compute what PWM duty
>>>>> I should use for both 0 and 100% of the fan speed.
>>>>>
>>>>> Computing the value for 0% fan speed is difficult because of
>>>>> non-continuous nature of some of the functions[1], but I can always
>>>>> over-approximate. However, I failed to accurately compute the duty I
>>>>> need to write to get the 100% fan speed (I have cases where I greatly
>>>>> over-estimate it...).
>>>>>
>>>>> Could you please check out the vbios table I am pointing at? I am quite
>>>>> sure that your documentation will be clearer than my babbling :D
>>>>
>>>> Yes. We will check on this. There has been some productive discussion 
>>>> internally, but it will take some more investigation.
>>>>
>>>> thanks,
>>>> John Hubbard
>>>
>>> Have the productive discussions panned out?
> 
> Yes, we concluded our discussions, and decided that I should study the 
> situation 
> and write some documentation.  I just finished my research and writeup late 
> last Friday, 
> though, so my colleagues haven't had a chance to review it. Not to put undue
> pressure on them, but I'm hoping that will go quickly now. The long pole is
> done. :)
> 
> I was going to wait until the review was done, to respond, but I wanted to 
> ACK 
> this and to let you know that I do realize that the tables below are not 
> directly 
> answering your question.
> 
> (What happened here is: the new tables below are not actually what I've 
> personally been working on; they just happen to be a very good set of 
> supporting 
> documentation in the exact same area. One of our teammates was already 
> working 
> on these independently, and managed to get them released.)

Thanks for the information and your work, it is greatly appreciated.

No need to hurry, I will be away from home for 2 weeks.

Thanks,
Martin
> 
> thanks,
> 

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


Re: [Nouveau] Addressing the problem of noisy GPUs under Nouveau

2018-01-28 Thread Martin Peres
On 28/11/17 07:32, John Hubbard wrote:
> On 11/23/2017 02:48 PM, Martin Peres wrote:
>> On 23/11/17 10:06, John Hubbard wrote:
>>> On 11/22/2017 05:07 PM, Martin Peres wrote:
>>>> Hey,
>>>>
>>>> Thanks for your answer, Andy!
>>>>
>>>> On 22/11/17 04:06, Ilia Mirkin wrote:
>>>>> On Tue, Nov 21, 2017 at 8:29 PM, Andy Ritger <arit...@nvidia.com> wrote:
>>>>> Martin's question was very long, but it boils down to this:
>>>>>
>>>>> How do we compute the correct values to write into the e114/e118 pwm
>>>>> registers based on the VBIOS contents and current state of the board
>>>>> (like temperature).
>>>>
>>>> Unfortunately, it can also be the e11c/e120 couple, or 0x200d8/dc on
>>>> GF119+, or 0x200cd/d0 on Kepler+.
>>>>
>>>> At least, it looks like we know which PWM controler we need to drive, so
>>>> I did not want to muddy the water even more by giving register
>>>> addresses, rather concentrating on the problem at hand: How to compute
>>>> the duty value for the PWM controler.
>>>>
>>>>>
>>>>> We generally do this right, but appear to get it extra-wrong for certain 
>>>>> GPUs.
>>>>
>>>> Yes... So far, we are always safe, but users tend to mind when their
>>>> computer sound like a jumbo jet at take off... Who would have thought? :D
>>>>
>>>> Anyway, looking forward to your answer!
>>>>
>>>> Cheers,
>>>> Martin
>>>
>>>
>>> Hi Martin,
>>>
>>> One of our firmware engineers thinks that this looks a lot like PWM 
>>> inversion.
>>> For some SKUs, the interpretation of the PWM duty cycle is inverted. That 
>>> would probably make it *very* difficult to find a sensible algorithm that 
>>> covered all the SKUs, given that some are inverted and others are not.
>>>
>>> For the noisy GPUs, a very useful experiment would be to try inverting it, 
>>> like this:
>>>
>>> pwmDutyCycle = pwmPeriod - pwmDutyCycle;
>>>
>>> ...and then see if fan control starts behaving closer to how you've 
>>> actually 
>>> programmed it.
>>>
>>> Would that be easy enough to try out? It should help narrow down the
>>> problem at least.
>>>
>>
>> Hey John,
>>
>> Unfortunately, we know about PWM inversion, and one can know which mode
>> to use based on the GPIO entry associated to the fan (inverted). We have
>> had support for this in Nouveau for a long time. At the very least, this
>> is not the problem on my GF108.
>>
>> I am certain that the problem I am seeing is related to this vbios table
>> I wrote about (BIT P, offset 0x18). It is used to compute what PWM duty
>> I should use for both 0 and 100% of the fan speed.
>>
>> Computing the value for 0% fan speed is difficult because of
>> non-continuous nature of some of the functions[1], but I can always
>> over-approximate. However, I failed to accurately compute the duty I
>> need to write to get the 100% fan speed (I have cases where I greatly
>> over-estimate it...).
>>
>> Could you please check out the vbios table I am pointing at? I am quite
>> sure that your documentation will be clearer than my babbling :D
> 
> Yes. We will check on this. There has been some productive discussion 
> internally, but it will take some more investigation.
> 
> thanks,
> John Hubbard

Have the productive discussions panned out?

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


Re: [Nouveau] Addressing the problem of noisy GPUs under Nouveau

2018-01-28 Thread Martin Peres
On 29/01/18 01:24, Martin Peres wrote:
> On 28/11/17 07:32, John Hubbard wrote:
>> On 11/23/2017 02:48 PM, Martin Peres wrote:
>>> On 23/11/17 10:06, John Hubbard wrote:
>>>> On 11/22/2017 05:07 PM, Martin Peres wrote:
>>>>> Hey,
>>>>>
>>>>> Thanks for your answer, Andy!
>>>>>
>>>>> On 22/11/17 04:06, Ilia Mirkin wrote:
>>>>>> On Tue, Nov 21, 2017 at 8:29 PM, Andy Ritger <arit...@nvidia.com> wrote:
>>>>>> Martin's question was very long, but it boils down to this:
>>>>>>
>>>>>> How do we compute the correct values to write into the e114/e118 pwm
>>>>>> registers based on the VBIOS contents and current state of the board
>>>>>> (like temperature).
>>>>>
>>>>> Unfortunately, it can also be the e11c/e120 couple, or 0x200d8/dc on
>>>>> GF119+, or 0x200cd/d0 on Kepler+.
>>>>>
>>>>> At least, it looks like we know which PWM controler we need to drive, so
>>>>> I did not want to muddy the water even more by giving register
>>>>> addresses, rather concentrating on the problem at hand: How to compute
>>>>> the duty value for the PWM controler.
>>>>>
>>>>>>
>>>>>> We generally do this right, but appear to get it extra-wrong for certain 
>>>>>> GPUs.
>>>>>
>>>>> Yes... So far, we are always safe, but users tend to mind when their
>>>>> computer sound like a jumbo jet at take off... Who would have thought? :D
>>>>>
>>>>> Anyway, looking forward to your answer!
>>>>>
>>>>> Cheers,
>>>>> Martin
>>>>
>>>>
>>>> Hi Martin,
>>>>
>>>> One of our firmware engineers thinks that this looks a lot like PWM 
>>>> inversion.
>>>> For some SKUs, the interpretation of the PWM duty cycle is inverted. That 
>>>> would probably make it *very* difficult to find a sensible algorithm that 
>>>> covered all the SKUs, given that some are inverted and others are not.
>>>>
>>>> For the noisy GPUs, a very useful experiment would be to try inverting it, 
>>>> like this:
>>>>
>>>>pwmDutyCycle = pwmPeriod - pwmDutyCycle;
>>>>
>>>> ...and then see if fan control starts behaving closer to how you've 
>>>> actually 
>>>> programmed it.
>>>>
>>>> Would that be easy enough to try out? It should help narrow down the
>>>> problem at least.
>>>>
>>>
>>> Hey John,
>>>
>>> Unfortunately, we know about PWM inversion, and one can know which mode
>>> to use based on the GPIO entry associated to the fan (inverted). We have
>>> had support for this in Nouveau for a long time. At the very least, this
>>> is not the problem on my GF108.
>>>
>>> I am certain that the problem I am seeing is related to this vbios table
>>> I wrote about (BIT P, offset 0x18). It is used to compute what PWM duty
>>> I should use for both 0 and 100% of the fan speed.
>>>
>>> Computing the value for 0% fan speed is difficult because of
>>> non-continuous nature of some of the functions[1], but I can always
>>> over-approximate. However, I failed to accurately compute the duty I
>>> need to write to get the 100% fan speed (I have cases where I greatly
>>> over-estimate it...).
>>>
>>> Could you please check out the vbios table I am pointing at? I am quite
>>> sure that your documentation will be clearer than my babbling :D
>>
>> Yes. We will check on this. There has been some productive discussion 
>> internally, but it will take some more investigation.
>>
>> thanks,
>> John Hubbard
> 
> Have the productive discussions panned out?

Oh, I see you pushed new vbios documentation:
 1)
http://download.nvidia.com/open-gpu-doc/BIOS-Information-Table/1/BIOS-Information-Table.html
 2)
http://download.nvidia.com/open-gpu-doc/MemoryClockTable/1/MemoryClockTable.html
 3)
http://download.nvidia.com/open-gpu-doc/MemoryTweakTable/1/MemoryTweakTable.html

Is there any chance to get the documentation of the "Thermal Coolers
Table", and the "Thermal Device Table" (the latter does not seem super
important though).

Anyway, thanks for the new documentation, reverse engineering of power
management will be greatly simplified as we have a better idea which
bits will control what. Too bad it won't help for the current issue
though...

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


Re: [Nouveau] [RFC v3 2/4] drm/nouveau: Add support for BLCG on Kepler1

2018-01-27 Thread Martin Peres
On 26/01/18 22:59, Lyude Paul wrote:
> This enables BLCG optimization for kepler1. When using clockgating,
> nvidia's firmware has a set of registers which are initially programmed
> by the vbios with various engine delays and other mysterious settings
> that are safe enough to bring up the GPU. However, the values used by
> the vbios are more power hungry then they need to be, so the nvidia driver

then -> than.

With the comment about not exposing clock gating until patch 2, 3, and 4
have landed addressed, the series is:

Reviewed-by: Martin Peres <martin.pe...@free.fr>

Thanks a lot! I really like how this turned out :)

> writes it's own more optimized set of BLCG settings before enabling
> CG_CTRL. This adds support for programming the optimized BLCG values
> during engine/subdev init, which enables rather significant power
> savings.
> 
> This introduces the nvkm_therm_clkgate_init() helper, which we use to
> program the optimized BLCG settings before enabling clockgating with
> nvkm_therm_clkgate_enable.
> 
> As well, this commit shares a lot more code with Fermi since BLCG is
> mostly the same there as far as we can tell. In the future, it's likely
> we'll reformat the clkgate_packs for kepler1 so that they share a list
> of mmio packs with Fermi.
> 
> Signed-off-by: Lyude Paul <ly...@redhat.com>
> ---
>  .../gpu/drm/nouveau/include/nvkm/subdev/therm.h|  12 ++
>  drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h |   1 +
>  drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c | 207 
> +
>  drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.h |  55 ++
>  drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c |   6 +
>  drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c |  47 +
>  drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.h |  35 
>  drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h  |   2 +
>  drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild   |   1 +
>  drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c   |  10 +
>  drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf100.c  |  75 
>  drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.c  |   1 +
>  drivers/gpu/drm/nouveau/nvkm/subdev/therm/gt215.c  |   2 +-
>  drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h   |   8 +
>  14 files changed, 461 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.h
>  create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.h
>  create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf100.c
> 
> diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h 
> b/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h
> index 240b19bb4667..9398d9f09339 100644
> --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h
> +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h
> @@ -46,6 +46,16 @@ enum nvkm_therm_attr_type {
>   NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST = 17,
>  };
>  
> +struct nvkm_therm_clkgate_init {
> + u32 addr;
> + u8  count;
> + u32 data;
> +};
> +
> +struct nvkm_therm_clkgate_pack {
> + const struct nvkm_therm_clkgate_init *init;
> +};
> +
>  struct nvkm_therm {
>   const struct nvkm_therm_func *func;
>   struct nvkm_subdev subdev;
> @@ -92,6 +102,8 @@ struct nvkm_therm {
>  int nvkm_therm_temp_get(struct nvkm_therm *);
>  int nvkm_therm_fan_sense(struct nvkm_therm *);
>  int nvkm_therm_cstate(struct nvkm_therm *, int, int);
> +void nvkm_therm_clkgate_init(struct nvkm_therm *,
> +  const struct nvkm_therm_clkgate_pack *);
>  void nvkm_therm_clkgate_enable(struct nvkm_therm *);
>  void nvkm_therm_clkgate_fini(struct nvkm_therm *, bool);
>  
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h 
> b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h
> index d7c2adb9b543..c8ec3fd97155 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h
> @@ -137,6 +137,7 @@ struct gf100_gr_func {
>   int (*rops)(struct gf100_gr *);
>   int ppc_nr;
>   const struct gf100_grctx_func *grctx;
> + const struct nvkm_therm_clkgate_pack *clkgate_pack;
>   struct nvkm_sclass sclass[];
>  };
>  
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c 
> b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c
> index 5e82f94c2245..17cea9c70f7f 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c
> @@ -22,6 +22,7 @@
>   * Authors: Ben Skeggs <bske...@redhat.com>
>   */
>  #include "gf100.h"
> +#include "gk104.h"
>  #include "ctxgf100.h"
>  
>  #include 
> @@ -173,6 +174,208 @@ gk104_gr_pack_mmio[] = {

Re: [Nouveau] [RFC v3 1/4] drm/nouveau: Add support for basic clockgating on Kepler1

2018-01-27 Thread Martin Peres
 @@ -1760,7 +1761,7 @@ nve7_chipset = {
>   .mxm = nv50_mxm_new,
>   .pci = gk104_pci_new,
>   .pmu = gk104_pmu_new,
> - .therm = gf119_therm_new,
> + .therm = gk104_therm_new,
>   .timer = nv41_timer_new,
>   .top = gk104_top_new,
>   .volt = gk104_volt_new,
> @@ -1824,7 +1825,7 @@ nvf0_chipset = {
>   .mxm = nv50_mxm_new,
>   .pci = gk104_pci_new,
>   .pmu = gk110_pmu_new,
> - .therm = gf119_therm_new,
> + .therm = gk104_therm_new,
>   .timer = nv41_timer_new,
>   .top = gk104_top_new,
>   .volt = gk104_volt_new,
> @@ -1862,7 +1863,7 @@ nvf1_chipset = {
>   .mxm = nv50_mxm_new,
>   .pci = gk104_pci_new,
>   .pmu = gk110_pmu_new,
> - .therm = gf119_therm_new,
> + .therm = gk104_therm_new,
>   .timer = nv41_timer_new,
>   .top = gk104_top_new,
>   .volt = gk104_volt_new,
> @@ -1900,7 +1901,7 @@ nv106_chipset = {
>   .mxm = nv50_mxm_new,
>   .pci = gk104_pci_new,
>   .pmu = gk208_pmu_new,
> - .therm = gf119_therm_new,
> + .therm = gk104_therm_new,
>   .timer = nv41_timer_new,
>   .top = gk104_top_new,
>   .volt = gk104_volt_new,
> @@ -1938,7 +1939,7 @@ nv108_chipset = {
>   .mxm = nv50_mxm_new,
>   .pci = gk104_pci_new,
>   .pmu = gk208_pmu_new,
> - .therm = gf119_therm_new,
> + .therm = gk104_therm_new,
>   .timer = nv41_timer_new,
>   .top = gk104_top_new,
>   .volt = gk104_volt_new,
> @@ -2508,6 +2509,7 @@ nvkm_device_fini(struct nvkm_device *device, bool 
> suspend)
>   }
>   }
>  
> + nvkm_therm_clkgate_fini(device->therm, suspend);
>  
>   if (device->func->fini)
>   device->func->fini(device, suspend);
> @@ -2597,6 +2599,7 @@ nvkm_device_init(struct nvkm_device *device)
>   }
>  
>   nvkm_acpi_init(device);
> + nvkm_therm_clkgate_enable(device->therm);
>  
>   time = ktime_to_us(ktime_get()) - time;
>   nvdev_trace(device, "init completed in %lldus\n", time);
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild 
> b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild
> index 7ba56b12badd..4bac4772d8ed 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild
> @@ -10,6 +10,7 @@ nvkm-y += nvkm/subdev/therm/nv50.o
>  nvkm-y += nvkm/subdev/therm/g84.o
>  nvkm-y += nvkm/subdev/therm/gt215.o
>  nvkm-y += nvkm/subdev/therm/gf119.o
> +nvkm-y += nvkm/subdev/therm/gk104.o
>  nvkm-y += nvkm/subdev/therm/gm107.o
>  nvkm-y += nvkm/subdev/therm/gm200.o
>  nvkm-y += nvkm/subdev/therm/gp100.o
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c 
> b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
> index f27fc6d0d4c6..e4c96e46db8f 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
> @@ -21,6 +21,7 @@
>   *
>   * Authors: Martin Peres
>   */
> +#include 
>  #include "priv.h"
>  
>  int
> @@ -297,6 +298,38 @@ nvkm_therm_attr_set(struct nvkm_therm *therm,
>   return -EINVAL;
>  }
>  
> +void
> +nvkm_therm_clkgate_enable(struct nvkm_therm *therm)
> +{
> + if (!therm->func->clkgate_enable || !therm->clkgating_enabled)
> + return;
> +
> + nvkm_debug(>subdev,
> +"Enabling clockgating\n");
> + therm->func->clkgate_enable(therm);
> +}
> +
> +void
> +nvkm_therm_clkgate_fini(struct nvkm_therm *therm, bool suspend)
> +{
> + if (!therm->func->clkgate_fini || !therm->clkgating_enabled)
> + return;
> +
> + nvkm_debug(>subdev,
> +"Preparing clockgating for %s\n",
> +suspend ? "suspend" : "fini");
> + therm->func->clkgate_fini(therm, suspend);
> +}
> +
> +static void
> +nvkm_therm_clkgate_oneinit(struct nvkm_therm *therm)
> +{
> + if (!therm->func->clkgate_enable || !therm->clkgating_enabled)
> + return;
> +
> + nvkm_info(>subdev, "Clockgating enabled\n");

Thanks for adding this!

> +}
> +
>  static void
>  nvkm_therm_intr(struct nvkm_subdev *subdev)
>  {
> @@ -333,6 +366,7 @@ nvkm_therm_oneinit(struct nvkm_subdev *subdev)
>   nvkm_therm_fan_ctor(therm);
>   nvkm_therm_fan_mode(therm, NVKM_THERM_CTRL_AUTO);
>   nvkm_therm_sensor_preinit(therm);
> + nvkm_therm_clkgate_oneinit(therm);
>   return 0;
>  }
>  
> @@ -374,15 +408,10 @@ nvkm_therm = {
>   .intr = nvkm_therm_intr,
>  };
&

Re: [Nouveau] [RFC 1/4] drm/nouveau: Add support for basic clockgating on Kepler1

2018-01-21 Thread Martin Peres
gm200_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
>  int gp100_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c 
> b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
> index 00eeaaffeae5..6c5f966c66ad 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
> @@ -28,6 +28,7 @@
>  #include 
>  
>  #include 
> +#include 
>  
>  static DEFINE_MUTEX(nv_devices_mutex);
>  static LIST_HEAD(nv_devices);
> @@ -1682,7 +1683,7 @@ nve4_chipset = {
>   .mxm = nv50_mxm_new,
>   .pci = gk104_pci_new,
>   .pmu = gk104_pmu_new,
> - .therm = gf119_therm_new,
> + .therm = gk104_therm_new,
>   .timer = nv41_timer_new,
>   .top = gk104_top_new,
>   .volt = gk104_volt_new,
> @@ -1721,7 +1722,7 @@ nve6_chipset = {
>   .mxm = nv50_mxm_new,
>   .pci = gk104_pci_new,
>   .pmu = gk104_pmu_new,
> - .therm = gf119_therm_new,
> + .therm = gk104_therm_new,
>   .timer = nv41_timer_new,
>   .top = gk104_top_new,
>   .volt = gk104_volt_new,
> @@ -1760,7 +1761,7 @@ nve7_chipset = {
>   .mxm = nv50_mxm_new,
>   .pci = gk104_pci_new,
>   .pmu = gk104_pmu_new,
> - .therm = gf119_therm_new,
> + .therm = gk104_therm_new,
>   .timer = nv41_timer_new,
>   .top = gk104_top_new,
>   .volt = gk104_volt_new,
> @@ -1824,7 +1825,7 @@ nvf0_chipset = {
>   .mxm = nv50_mxm_new,
>   .pci = gk104_pci_new,
>   .pmu = gk110_pmu_new,
> - .therm = gf119_therm_new,
> + .therm = gk104_therm_new,
>   .timer = nv41_timer_new,
>   .top = gk104_top_new,
>   .volt = gk104_volt_new,
> @@ -1862,7 +1863,7 @@ nvf1_chipset = {
>   .mxm = nv50_mxm_new,
>   .pci = gk104_pci_new,
>   .pmu = gk110_pmu_new,
> - .therm = gf119_therm_new,
> + .therm = gk104_therm_new,
>   .timer = nv41_timer_new,
>   .top = gk104_top_new,
>   .volt = gk104_volt_new,
> @@ -1900,7 +1901,7 @@ nv106_chipset = {
>   .mxm = nv50_mxm_new,
>   .pci = gk104_pci_new,
>   .pmu = gk208_pmu_new,
> - .therm = gf119_therm_new,
> + .therm = gk104_therm_new,
>   .timer = nv41_timer_new,
>   .top = gk104_top_new,
>   .volt = gk104_volt_new,
> @@ -1938,7 +1939,7 @@ nv108_chipset = {
>   .mxm = nv50_mxm_new,
>   .pci = gk104_pci_new,
>   .pmu = gk208_pmu_new,
> - .therm = gf119_therm_new,
> + .therm = gk104_therm_new,
>   .timer = nv41_timer_new,
>   .top = gk104_top_new,
>   .volt = gk104_volt_new,
> @@ -2508,6 +2509,7 @@ nvkm_device_fini(struct nvkm_device *device, bool 
> suspend)
>   }
>   }
>  
> + nvkm_therm_clkgate_fini(device->therm, suspend);
>  
>   if (device->func->fini)
>   device->func->fini(device, suspend);
> @@ -2597,6 +2599,7 @@ nvkm_device_init(struct nvkm_device *device)
>   }
>  
>   nvkm_acpi_init(device);
> + nvkm_therm_clkgate_enable(device->therm);
>  
>   time = ktime_to_us(ktime_get()) - time;
>   nvdev_trace(device, "init completed in %lldus\n", time);
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild 
> b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild
> index 7ba56b12badd..4bac4772d8ed 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild
> @@ -10,6 +10,7 @@ nvkm-y += nvkm/subdev/therm/nv50.o
>  nvkm-y += nvkm/subdev/therm/g84.o
>  nvkm-y += nvkm/subdev/therm/gt215.o
>  nvkm-y += nvkm/subdev/therm/gf119.o
> +nvkm-y += nvkm/subdev/therm/gk104.o
>  nvkm-y += nvkm/subdev/therm/gm107.o
>  nvkm-y += nvkm/subdev/therm/gm200.o
>  nvkm-y += nvkm/subdev/therm/gp100.o
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c 
> b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
> index f27fc6d0d4c6..ba1a3aabb559 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
> @@ -21,6 +21,7 @@
>   *
>   * Authors: Martin Peres
>   */
> +#include 
>  #include "priv.h"
>  
>  int
> @@ -297,6 +298,47 @@ nvkm_therm_attr_set(struct nvkm_therm *therm,
>   return -EINVAL;
>  }
>  
> +void
> +nvkm_therm_clkgate_enable(struct nvkm_therm *therm)
> +{
> + if (!therm->func->clkgate_enable || !therm->clkgate_level)
> + return;
> +
> + nvkm_debug(>subdev,
> +"Enabling clock/powergating\n");
> + therm->func->clkgate_enable(therm);
> +}
> +

Re: [Nouveau] Addressing the problem of noisy GPUs under Nouveau

2017-11-23 Thread Martin Peres
On 23/11/17 10:06, John Hubbard wrote:
> On 11/22/2017 05:07 PM, Martin Peres wrote:
>> Hey,
>>
>> Thanks for your answer, Andy!
>>
>> On 22/11/17 04:06, Ilia Mirkin wrote:
>>> On Tue, Nov 21, 2017 at 8:29 PM, Andy Ritger <arit...@nvidia.com> wrote:
>>> Martin's question was very long, but it boils down to this:
>>>
>>> How do we compute the correct values to write into the e114/e118 pwm
>>> registers based on the VBIOS contents and current state of the board
>>> (like temperature).
>>
>> Unfortunately, it can also be the e11c/e120 couple, or 0x200d8/dc on
>> GF119+, or 0x200cd/d0 on Kepler+.
>>
>> At least, it looks like we know which PWM controler we need to drive, so
>> I did not want to muddy the water even more by giving register
>> addresses, rather concentrating on the problem at hand: How to compute
>> the duty value for the PWM controler.
>>
>>>
>>> We generally do this right, but appear to get it extra-wrong for certain 
>>> GPUs.
>>
>> Yes... So far, we are always safe, but users tend to mind when their
>> computer sound like a jumbo jet at take off... Who would have thought? :D
>>
>> Anyway, looking forward to your answer!
>>
>> Cheers,
>> Martin
> 
> 
> Hi Martin,
> 
> One of our firmware engineers thinks that this looks a lot like PWM inversion.
> For some SKUs, the interpretation of the PWM duty cycle is inverted. That 
> would probably make it *very* difficult to find a sensible algorithm that 
> covered all the SKUs, given that some are inverted and others are not.
> 
> For the noisy GPUs, a very useful experiment would be to try inverting it, 
> like this:
> 
>   pwmDutyCycle = pwmPeriod - pwmDutyCycle;
> 
> ...and then see if fan control starts behaving closer to how you've actually 
> programmed it.
> 
> Would that be easy enough to try out? It should help narrow down the
> problem at least.
>

Hey John,

Unfortunately, we know about PWM inversion, and one can know which mode
to use based on the GPIO entry associated to the fan (inverted). We have
had support for this in Nouveau for a long time. At the very least, this
is not the problem on my GF108.

I am certain that the problem I am seeing is related to this vbios table
I wrote about (BIT P, offset 0x18). It is used to compute what PWM duty
I should use for both 0 and 100% of the fan speed.

Computing the value for 0% fan speed is difficult because of
non-continuous nature of some of the functions[1], but I can always
over-approximate. However, I failed to accurately compute the duty I
need to write to get the 100% fan speed (I have cases where I greatly
over-estimate it...).

Could you please check out the vbios table I am pointing at? I am quite
sure that your documentation will be clearer than my babbling :D

Thanks,
Martin

[1] http://fs.mupuf.org/nvidia/fan_calib/pwm_offset.png
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] Addressing the problem of noisy GPUs under Nouveau

2017-11-22 Thread Martin Peres
Hey,

Thanks for your answer, Andy!

On 22/11/17 04:06, Ilia Mirkin wrote:
> On Tue, Nov 21, 2017 at 8:29 PM, Andy Ritger  wrote:
>> Hi Martin,
> 
> Martin should have complete answers,
> 
>>
>> I was asked to clarify a few things:
>>
>> (1) Are all the user reports of loud fans on Fermi-era GPUs?
> 
> Yes. Although I believe some GK208 users are also having trouble,
> including yours truly. (It's been quite a while since I've checked
> though... my memory is weak in that regard.)

We did not hear back from a lot of users about these issues, but I can
see that most GF108 vbios in our vbios repo are problematic, and some
GK106/GT215/GT216/GT218 might be too.

> 
>>
>> (2) When the VBIOS POSTs the card, it loads initial ucode onto the Falcon
>> processor (PMU), which will do basic fan management on its own.  We call this
>> init ucode "IFR" (Init From ROM).  nvidia.ko will restore the IFR ucode when
>> unloaded.  I assume the loud fan symptom occurs after Nouveau is loaded and
>> running, correct?  I.e., this is a problem in Nouveau's fan control
>> programming, rather than a problem in IFR.
> 
> Correct.

Indeed.

> 
>>
>> (3) IFR will run until something else is loaded on the Falcon processor 
>> (PMU).
>> On Fermi, I assume the Nouveau kernel driver is uploading the Nouveau-written
>> ucode from here:
>>
>> drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc
>>
>> correct?  I only ask to rule out the possibility that IFR and Nouveau are 
>> both
>> attempting to program fans simultaneously.  The symptoms you describe don't
>> sound like that, but just double checking...
> 
> Correct.

Indeed.

> 
>>
>> (4) Given the PMU ucode debacle, I'm embarrassed to ask, but at least on 
>> Fermi,
>> how much does Nouveau strictly depend on Nouveau's PMU ucode?  Would it be an
>> option to just let IFR continue to manage fans?
> 
> Reclocking is still on our horizon, which clearly won't happen without
> nouveau PMU code loaded. Not sure what it's used for until reclocking
> becomes a thing on Fermi.

Yeah, this would hinder our reclocking efforts :s

The best idea I can come up with is to fake the temperature (register
0x20408) to 1°C (minimum the hardware allows us) and read the PWM duty,
then we can get the maximum duty by setting the temperature to the
fan_boost threshold.

Not sure we have a sure-way of computing the fan_boost threshold though,
maybe we can just use of the thermal throttling threshold for this (more
on this later in the email).

In any case, all of these solutions are workarounds. Given that the code
to compute these values is already found in vbioses, why is it a problem
to share the meaning of all the values in the fan calibration table,
and/or the algorithm?

> 
>>
>> (5) Lastly, I was asked how Nouveau determines what fan speed to (attempt
>> to) program.

Oh, thanks for giving me an idea about what the other values in this
table may be about :D

Anyways, the current code uses the entry id 0x46 of the thermal table
(bit P, offset 0x10) to find out what are the thermal points for
$fan_min and $fan_max. The $fan_min and $fan_max values are found in the
entry id 0x22 of the same table.

If the 0x46 entry is not present in the thermal table (which seems to be
the norm for Fermi), we revert to default values: 40 -> 85°C.

With these 4 values, we get 2 trip points (temp_min, fan_min)
and(temp_max, fan_max), and we merely do linear interpolation between them.

> 
> I'll let Martin answer this, but as you're probably aware, there's 2
> different ways this can be done - there might be a PWM, we might have
> to toggle it manually. Maybe something else still.

The manual toggle fans are only present on pre-tesla GPUs, let's ignore
them here, because we know what to do there.

All recent (2006+) GPUs use PWM, and anything after the GT215 use this
fan calibration table which took me a while to find, and that is still
mostly a mystery to me :s

> 
> Have a look at drm/nouveau/nvkm/subdev/therm/fan.c and the various
> bits it ends up calling (pre-GF119 fermi's end up with the nv50
> fan_set, I believe).
> 
> The bios stuff is parsed in nvkm/subdev/bios/fan.c and therm.c,
> although I believe Martin's latest analysis is more advanced than
> what's in that code.

Absolutely :) I have not updated Nouveau yet, in fear of setting a value
lower than what the proprietary driver does...

> 
> Martin's question was very long, but it boils down to this:
> 
> How do we compute the correct values to write into the e114/e118 pwm
> registers based on the VBIOS contents and current state of the board
> (like temperature).

Unfortunately, it can also be the e11c/e120 couple, or 0x200d8/dc on
GF119+, or 0x200cd/d0 on Kepler+.

At least, it looks like we know which PWM controler we need to drive, so
I did not want to muddy the water even more by giving register
addresses, rather concentrating on the problem at hand: How to compute
the duty value for the PWM controler.

> 
> We generally do this right, but 

Re: [Nouveau] [PATCH 03/32] therm: Split return code and value in nvkm_get_temp

2017-11-22 Thread Martin Peres
On 22/11/17 03:42, Karol Herbst wrote:
> On Wed, Nov 22, 2017 at 1:32 AM, Martin Peres <martin.pe...@free.fr> wrote:
>> On 17/11/17 02:04, Karol Herbst wrote:
>>> The current hwmon code doesn't check if the returned value was actually an
>>> error.
>>>
>>> Since Kepler temperature sensors are able to report negative values. Those
>>> negative values are not for error reporting, but rather when you buried
>>> your GPU in snow somewhere in Antarctica and still want a valid
>>> temperature to be reported (unverified).
>>>
>>> Since Pascal (and maybe earlier) we have sensors with improved precision.
>>>
>>> Adjust the nvkm_get_temp method to be able to deal with those changes
>>> and let hwmon return an error properly.
>>
>> Where did you get this information? And if it is the case, then we will
>> royally screw up the value because we don't even know on how many bits
>> 0x20400 uses...
>>
>> If you are indeed right, I would like to see g84.c's temp_get().
>>
> 
> Nvidia uses 0x020460 on Pascal and I thought we had that in envytools already?

Nothing in nvbios.

> 
> [0] 228.412618 MMIO32 R 0x020460 0x20002f20 PTHERM.I2C_SLAVE+0x60 => 
> 0x20002f20
> [0] 229.413039 MMIO32 R 0x020460 0x20002f10 PTHERM.I2C_SLAVE+0x60 => 
> 0x20002f10
> [0] 230.416976 MMIO32 R 0x020460 0x20002f68 PTHERM.I2C_SLAVE+0x60 => 
> 0x20002f68
> [0] 231.417407 MMIO32 R 0x020460 0x20002fe8 PTHERM.I2C_SLAVE+0x60 => 
> 0x20002fe8
> [0] 232.417742 MMIO32 R 0x020460 0x20002ff0 PTHERM.I2C_SLAVE+0x60 => 
> 0x20002ff0
> [0] 233.417742 MMIO32 R 0x020460 0x20003020 PTHERM.I2C_SLAVE+0x60 => 
> 0x20003020
> 
> or nvapeek 0x20400 && nvapeek 0x020460;
> 00020400: 002c
> 00020460: 20002c60

Cool that they increased the accuracy, but where do you get that the
value can be negative? And if it is, how many bits are used? 16 or more?
What are those high bits?

> 
>>>
>>> Signed-off-by: Karol Herbst <karolher...@gmail.com>
>>> ---
>>>  drm/nouveau/include/nvkm/subdev/clk.h   |  4 ++--
>>>  drm/nouveau/include/nvkm/subdev/therm.h |  2 +-
>>>  drm/nouveau/nouveau_hwmon.c | 15 +--
>>>  drm/nouveau/nvkm/subdev/clk/base.c  |  2 +-
>>>  drm/nouveau/nvkm/subdev/therm/base.c| 19 ++-
>>>  drm/nouveau/nvkm/subdev/therm/g84.c | 13 -
>>>  drm/nouveau/nvkm/subdev/therm/gp100.c   |  9 +
>>>  drm/nouveau/nvkm/subdev/therm/nv40.c|  9 +++--
>>>  drm/nouveau/nvkm/subdev/therm/nv50.c|  9 +++--
>>>  drm/nouveau/nvkm/subdev/therm/priv.h|  4 ++--
>>>  drm/nouveau/nvkm/subdev/therm/temp.c| 16 
>>>  11 files changed, 60 insertions(+), 42 deletions(-)
>>>
>>> diff --git a/drm/nouveau/include/nvkm/subdev/clk.h 
>>> b/drm/nouveau/include/nvkm/subdev/clk.h
>>> index e5275f74..506f8cc6 100644
>>> --- a/drm/nouveau/include/nvkm/subdev/clk.h
>>> +++ b/drm/nouveau/include/nvkm/subdev/clk.h
>>> @@ -100,7 +100,7 @@ struct nvkm_clk {
>>>   int ustate_dc; /* user-requested (-1 disabled, -2 perfmon) */
>>>   int astate; /* perfmon adjustment (base) */
>>>   int dstate; /* display adjustment (min+) */
>>> - u8  temp;
>>> + int temp;
>>>
>>>   bool allow_reclock;
>>>  #define NVKM_CLK_BOOST_NONE 0x0
>>> @@ -122,7 +122,7 @@ int nvkm_clk_read(struct nvkm_clk *, enum nv_clk_src);
>>>  int nvkm_clk_ustate(struct nvkm_clk *, int req, int pwr);
>>>  int nvkm_clk_astate(struct nvkm_clk *, int req, int rel, bool wait);
>>>  int nvkm_clk_dstate(struct nvkm_clk *, int req, int rel);
>>> -int nvkm_clk_tstate(struct nvkm_clk *, u8 temperature);
>>> +int nvkm_clk_tstate(struct nvkm_clk *, int temperature);
>>>
>>>  int nv04_clk_new(struct nvkm_device *, int, struct nvkm_clk **);
>>>  int nv40_clk_new(struct nvkm_device *, int, struct nvkm_clk **);
>>> diff --git a/drm/nouveau/include/nvkm/subdev/therm.h 
>>> b/drm/nouveau/include/nvkm/subdev/therm.h
>>> index 9841f076..8c84017f 100644
>>> --- a/drm/nouveau/include/nvkm/subdev/therm.h
>>> +++ b/drm/nouveau/include/nvkm/subdev/therm.h
>>> @@ -86,7 +86,7 @@ struct nvkm_therm {
>>>   int (*attr_set)(struct nvkm_therm *, enum nvkm_therm_attr_type, int);
>>>  };
>>>
>>> -int nvkm_therm_temp_get(struct nvkm_therm *);
>>> +int nvkm_therm_temp_get(struct nvkm_therm *, int *);
>>>  int nvkm_therm_fan_sense(struct nvkm_the

Re: [Nouveau] [PATCH 03/32] therm: Split return code and value in nvkm_get_temp

2017-11-21 Thread Martin Peres
On 17/11/17 02:04, Karol Herbst wrote:
> The current hwmon code doesn't check if the returned value was actually an
> error.
> 
> Since Kepler temperature sensors are able to report negative values. Those
> negative values are not for error reporting, but rather when you buried
> your GPU in snow somewhere in Antarctica and still want a valid
> temperature to be reported (unverified).
> 
> Since Pascal (and maybe earlier) we have sensors with improved precision.
> 
> Adjust the nvkm_get_temp method to be able to deal with those changes
> and let hwmon return an error properly.

Where did you get this information? And if it is the case, then we will
royally screw up the value because we don't even know on how many bits
0x20400 uses...

If you are indeed right, I would like to see g84.c's temp_get().

> 
> Signed-off-by: Karol Herbst 
> ---
>  drm/nouveau/include/nvkm/subdev/clk.h   |  4 ++--
>  drm/nouveau/include/nvkm/subdev/therm.h |  2 +-
>  drm/nouveau/nouveau_hwmon.c | 15 +--
>  drm/nouveau/nvkm/subdev/clk/base.c  |  2 +-
>  drm/nouveau/nvkm/subdev/therm/base.c| 19 ++-
>  drm/nouveau/nvkm/subdev/therm/g84.c | 13 -
>  drm/nouveau/nvkm/subdev/therm/gp100.c   |  9 +
>  drm/nouveau/nvkm/subdev/therm/nv40.c|  9 +++--
>  drm/nouveau/nvkm/subdev/therm/nv50.c|  9 +++--
>  drm/nouveau/nvkm/subdev/therm/priv.h|  4 ++--
>  drm/nouveau/nvkm/subdev/therm/temp.c| 16 
>  11 files changed, 60 insertions(+), 42 deletions(-)
> 
> diff --git a/drm/nouveau/include/nvkm/subdev/clk.h 
> b/drm/nouveau/include/nvkm/subdev/clk.h
> index e5275f74..506f8cc6 100644
> --- a/drm/nouveau/include/nvkm/subdev/clk.h
> +++ b/drm/nouveau/include/nvkm/subdev/clk.h
> @@ -100,7 +100,7 @@ struct nvkm_clk {
>   int ustate_dc; /* user-requested (-1 disabled, -2 perfmon) */
>   int astate; /* perfmon adjustment (base) */
>   int dstate; /* display adjustment (min+) */
> - u8  temp;
> + int temp;
>  
>   bool allow_reclock;
>  #define NVKM_CLK_BOOST_NONE 0x0
> @@ -122,7 +122,7 @@ int nvkm_clk_read(struct nvkm_clk *, enum nv_clk_src);
>  int nvkm_clk_ustate(struct nvkm_clk *, int req, int pwr);
>  int nvkm_clk_astate(struct nvkm_clk *, int req, int rel, bool wait);
>  int nvkm_clk_dstate(struct nvkm_clk *, int req, int rel);
> -int nvkm_clk_tstate(struct nvkm_clk *, u8 temperature);
> +int nvkm_clk_tstate(struct nvkm_clk *, int temperature);
>  
>  int nv04_clk_new(struct nvkm_device *, int, struct nvkm_clk **);
>  int nv40_clk_new(struct nvkm_device *, int, struct nvkm_clk **);
> diff --git a/drm/nouveau/include/nvkm/subdev/therm.h 
> b/drm/nouveau/include/nvkm/subdev/therm.h
> index 9841f076..8c84017f 100644
> --- a/drm/nouveau/include/nvkm/subdev/therm.h
> +++ b/drm/nouveau/include/nvkm/subdev/therm.h
> @@ -86,7 +86,7 @@ struct nvkm_therm {
>   int (*attr_set)(struct nvkm_therm *, enum nvkm_therm_attr_type, int);
>  };
>  
> -int nvkm_therm_temp_get(struct nvkm_therm *);
> +int nvkm_therm_temp_get(struct nvkm_therm *, int *);
>  int nvkm_therm_fan_sense(struct nvkm_therm *);
>  int nvkm_therm_cstate(struct nvkm_therm *, int, int);
>  
> diff --git a/drm/nouveau/nouveau_hwmon.c b/drm/nouveau/nouveau_hwmon.c
> index 7c965648..7486e4af 100644
> --- a/drm/nouveau/nouveau_hwmon.c
> +++ b/drm/nouveau/nouveau_hwmon.c
> @@ -326,8 +326,9 @@ nouveau_temp_is_visible(const void *data, u32 attr, int 
> channel)
>  {
>   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
>   struct nvkm_therm *therm = nvxx_therm(>client.device);
> + int val;
>  
> - if (therm && therm->attr_get && nvkm_therm_temp_get(therm) < 0)
> + if (therm && therm->attr_get && nvkm_therm_temp_get(therm, ))
>   return 0;
>  
>   switch (attr) {
> @@ -421,15 +422,16 @@ nouveau_temp_read(struct device *dev, u32 attr, int 
> channel, long *val)
>   struct drm_device *drm_dev = dev_get_drvdata(dev);
>   struct nouveau_drm *drm = nouveau_drm(drm_dev);
>   struct nvkm_therm *therm = nvxx_therm(>client.device);
> - int ret;
> + int ret = 0;
> + int temp;
>  
>   if (!therm || !therm->attr_get)
>   return -EOPNOTSUPP;
>  
>   switch (attr) {
>   case hwmon_temp_input:
> - ret = nvkm_therm_temp_get(therm);
> - *val = ret < 0 ? ret : (ret * 1000);
> + ret = nvkm_therm_temp_get(therm, );
> + *val = temp * 1000;
>   break;
>   case hwmon_temp_max:
>   *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK)
> @@ -459,7 +461,7 @@ nouveau_temp_read(struct device *dev, u32 attr, int 
> channel, long *val)
>   return -EOPNOTSUPP;
>   }
>  
> - return 0;
> + return ret;
>  }
>  
>  static int
> @@ -713,6 +715,7 @@ nouveau_hwmon_init(struct drm_device *dev)
>   struct device *hwmon_dev;
>   int ret = 0;
>   int i = 0;
> + int 

Re: [Nouveau] [PATCH 02/32] debugfs: Wake up GPU before doing any reclocking

2017-11-21 Thread Martin Peres
On 17/11/17 02:04, Karol Herbst wrote:
> Fixes various reclocking related issues on prime systems.

Is that the only place that was not covered? Could you check if other
places would need this code too?

In any case, this patch is (assuming you are calling the right functions
to prevent the GPU from sleeping):
Signed-off-by: Martin Peres <martin.pe...@free.fr>
> 
> Signed-off-by: Karol Herbst <karolher...@gmail.com>
> ---
>  drm/nouveau/nouveau_debugfs.c | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drm/nouveau/nouveau_debugfs.c b/drm/nouveau/nouveau_debugfs.c
> index 963a4dba..9109b69c 100644
> --- a/drm/nouveau/nouveau_debugfs.c
> +++ b/drm/nouveau/nouveau_debugfs.c
> @@ -160,7 +160,11 @@ nouveau_debugfs_pstate_set(struct file *file, const char 
> __user *ubuf,
>   args.ustate = value;
>   }
>  
> + ret = pm_runtime_get_sync(drm->dev);
> + if (IS_ERR_VALUE(ret) && ret != -EACCES)
> + return ret;
>   ret = nvif_mthd(ctrl, NVIF_CONTROL_PSTATE_USER, , sizeof(args));
> + pm_runtime_put_autosuspend(drm->dev);
>   if (ret < 0)
>   return ret;
>  
> 

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


Re: [Nouveau] [PATCH 01/32] bios/vpstate: There are some fermi vbios with no boost or tdp entry

2017-11-21 Thread Martin Peres
On 17/11/17 02:04, Karol Herbst wrote:

Please add here something like this:

If the entry size is too small, default to invalid values for both
boost_id and tdp_id, so as to default to the base clock in both cases.

> Signed-off-by: Karol Herbst <karolher...@gmail.com>

With the better commit message, this patch is:
Signed-off-by: Martin Peres <martin.pe...@free.fr>

> ---
>  drm/nouveau/nvkm/subdev/bios/vpstate.c | 10 --
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/drm/nouveau/nvkm/subdev/bios/vpstate.c 
> b/drm/nouveau/nvkm/subdev/bios/vpstate.c
> index 20b6fc82..71524548 100644
> --- a/drm/nouveau/nvkm/subdev/bios/vpstate.c
> +++ b/drm/nouveau/nvkm/subdev/bios/vpstate.c
> @@ -58,8 +58,14 @@ nvbios_vpstate_parse(struct nvkm_bios *b, struct 
> nvbios_vpstate_header *h)
>   h->ecount   = nvbios_rd08(b, h->offset + 0x5);
>  
>   h->base_id  = nvbios_rd08(b, h->offset + 0x0f);
> - h->boost_id = nvbios_rd08(b, h->offset + 0x10);
> - h->tdp_id   = nvbios_rd08(b, h->offset + 0x11);
> + if (h->hlen > 0x10)
> + h->boost_id = nvbios_rd08(b, h->offset + 0x10);
> + else
> + h->boost_id = 0xff;
> + if (h->hlen > 0x11)
> + h->tdp_id = nvbios_rd08(b, h->offset + 0x11);
> + else
> + h->tdp_id = 0xff;
>   return 0;
>   default:
>   return -EINVAL;
> 

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


Re: [Nouveau] Addressing the problem of noisy GPUs under Nouveau

2017-11-13 Thread Martin Peres
Hello,

On 13/11/17 09:15, John Hubbard wrote:
> On 11/12/2017 06:29 PM, Martin Peres wrote:
>> Hello,
>>
>> Some users have been complaining for years about their GPU sounding like
>> a jet engine at take off. Last year, I finally laid my hand on one of
>> these GPUs and have been trying to fix this issue on and off since then.
> 
> Some early feedback: can you tell us the exact SKUs you have? And are these
> production boards with production VBIOSes?  
> 
> Normally, it's just our bringup boards that we'd expect to be noisy like 
> this, so we're looking for a few more details.

Thanks for the quick feedback.

We only have access to production hardware with production vbioses, as
far as I know. In any case, I made all my experiments on the following
GPU (with a stock vbios, albeit modified to perform the experiment):

NVIDIA Corporation GF108 [GeForce GT 620] (rev a1) (prog-if 00 [VGA
controller])
Subsystem: eVga.com. Corp. Device 2625

I pushed my vbios to http://fs.mupuf.org/nvidia/fan_calib/ if this is
interesting to you (I doubt it, but if that can save us a round trip,
then let's do this :)).

Thanks,
Martin

> 
> thanks,
> John Hubbard
> NVIDIA
> 
>>
>> After failing to find anything in the HW, I figured out that the duty
>> cycle set by nvidia's proprietary driver would be way under the expected
>> value. By randomly changing values in the unknown tables of the vbios, I
>> found out that there is a fan calibration table at the offset 0x18 in
>> the BIT P table (version 2).
>>
>> In this table, I identified 2 major 16 bits parameters at offset 0xa and
>> 0xc[2]. The first one, I named pwm_max, while naming the latter
>> pwm_offset. As expected, these parameters look like a mapping function
>> of the form aX + b. However, after gathering more samples, I found out
>> that the output was not continuous when linearly increasing pwm_offset
>> [1]. Even more funnily, the period of this square function is linear
>> with the frequency used for the fan's PWN.
>>
>> I tried reverse engineering the formula to describe this function, but
>> failed to find a version that would work perfectly for all PWM
>> frequency. This is the closest I have got to[3], and I basically stopped
>> there about a year ago because I could not figure it out and got
>> frustrated :s.
>>
>> I started again on this project 2 weeks ago, with the intent of finding
>> a good-enough solution for nouveau, and modelling the rest of the
>> equation that that would allow me to compute what duty I should set for
>> every wanted fan speed (%). I again mostly succeeded... but it would
>> seem that the interpretation of the table depends on the generation of
>> chipset (Tesla behaves one way, Fermi+ behaves another way). Also, the
>> proprietary is not consistent for rules such as what to do when the
>> computed duty value is going to be lower than 0 or not (sometimes we
>> clamp it to 0, some times we set it to the same value as the divider,
>> some times we set it to a slightly lower value than the divider).
>>
>> I have been trying to cover all edge cases by generating a randomized
>> set of values for the PWM frequency, pwm_max, and pwm_offset values,
>> flashed the vbios, and iterate from 0% to 100% fan speed while dumping
>> the values set by your driver. Using half a million sample points (which
>> took a week to acquire), my model computes 97% of the values correctly
>> (ignoring off by ones), while the remaining 3% are worryingly off (by up
>> to 100%)... It is clear that the code is not trivial and is full of
>> branching, which makes clean-room reverse engineering a chore.
>>
>> As a final attempt to make a somewhat complete solution, I tried this
>> weekend to make a "safe" model that would still make the GPUs quiet. I
>> managed to improve the pass rate from 97 to 99.6%, but the remaining
>> failures conflict with my previous findings, which are also way more
>> prevalent. In the end, the only completely-safe way of driving the fan
>> is the current behaviour of nouveau...
>>
>> At this point, I am ready to throw in the towel and hardcode parameters
>> in nouveau to address the problem of the loudest GPUs, but this is of
>> course suboptimal. This is why I am asking for your help. Would you have
>> some documentation about this fan calibration table that could help me
>> here? Code would be even more appreciated.
>>
>> Thanks a lot in advance,
>> Martin
>>
>> PS: here is most of the code you may want to see:
>> http://fs.mupuf.org/nvidia/fan_calib/
>>
>> [1] http://fs.mupuf.org/nvidia/fan_calib/pwm_offset.png
>> [2] https://github.com/envytools/envytools/blob/master/nvbios/power.c#L333
>> [3] https://github.com/envytools/envytools/blob/master/nvbios/power.c#L298
>>

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


[Nouveau] Addressing the problem of noisy GPUs under Nouveau

2017-11-12 Thread Martin Peres
Hello,

Some users have been complaining for years about their GPU sounding like
a jet engine at take off. Last year, I finally laid my hand on one of
these GPUs and have been trying to fix this issue on and off since then.

After failing to find anything in the HW, I figured out that the duty
cycle set by nvidia's proprietary driver would be way under the expected
value. By randomly changing values in the unknown tables of the vbios, I
found out that there is a fan calibration table at the offset 0x18 in
the BIT P table (version 2).

In this table, I identified 2 major 16 bits parameters at offset 0xa and
0xc[2]. The first one, I named pwm_max, while naming the latter
pwm_offset. As expected, these parameters look like a mapping function
of the form aX + b. However, after gathering more samples, I found out
that the output was not continuous when linearly increasing pwm_offset
[1]. Even more funnily, the period of this square function is linear
with the frequency used for the fan's PWN.

I tried reverse engineering the formula to describe this function, but
failed to find a version that would work perfectly for all PWM
frequency. This is the closest I have got to[3], and I basically stopped
there about a year ago because I could not figure it out and got
frustrated :s.

I started again on this project 2 weeks ago, with the intent of finding
a good-enough solution for nouveau, and modelling the rest of the
equation that that would allow me to compute what duty I should set for
every wanted fan speed (%). I again mostly succeeded... but it would
seem that the interpretation of the table depends on the generation of
chipset (Tesla behaves one way, Fermi+ behaves another way). Also, the
proprietary is not consistent for rules such as what to do when the
computed duty value is going to be lower than 0 or not (sometimes we
clamp it to 0, some times we set it to the same value as the divider,
some times we set it to a slightly lower value than the divider).

I have been trying to cover all edge cases by generating a randomized
set of values for the PWM frequency, pwm_max, and pwm_offset values,
flashed the vbios, and iterate from 0% to 100% fan speed while dumping
the values set by your driver. Using half a million sample points (which
took a week to acquire), my model computes 97% of the values correctly
(ignoring off by ones), while the remaining 3% are worryingly off (by up
to 100%)... It is clear that the code is not trivial and is full of
branching, which makes clean-room reverse engineering a chore.

As a final attempt to make a somewhat complete solution, I tried this
weekend to make a "safe" model that would still make the GPUs quiet. I
managed to improve the pass rate from 97 to 99.6%, but the remaining
failures conflict with my previous findings, which are also way more
prevalent. In the end, the only completely-safe way of driving the fan
is the current behaviour of nouveau...

At this point, I am ready to throw in the towel and hardcode parameters
in nouveau to address the problem of the loudest GPUs, but this is of
course suboptimal. This is why I am asking for your help. Would you have
some documentation about this fan calibration table that could help me
here? Code would be even more appreciated.

Thanks a lot in advance,
Martin

PS: here is most of the code you may want to see:
http://fs.mupuf.org/nvidia/fan_calib/

[1] http://fs.mupuf.org/nvidia/fan_calib/pwm_offset.png
[2] https://github.com/envytools/envytools/blob/master/nvbios/power.c#L333
[3] https://github.com/envytools/envytools/blob/master/nvbios/power.c#L298

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


Re: [Nouveau] Project ideas for GSoC/EVoC

2017-10-15 Thread Martin Peres
On 15/10/17 22:13, Karol Herbst wrote:
> Hi everybody,
> 
> currently on the Xorg Wiki page [1] there are only three projects
> ideas, two being quite similiar:
> 1. Instruction scheduling
> 2. Maxwell Video Accel Decoding
> 3. Kepler Video Accel Encoding
> and also the reference to our Trello board.
> 
> Because I don't expect any student interested in a GSoC/EVoC project
> to read our wiki or trello, I am sure to attract more students, we
> should give more project examples, best if those are all in different
> areas of the driver.
> 
> I am fine with writing and adding new ideas on the wiki, but it would
> be nice if you come up with interesting projects as well, so that I
> can work on those and add them to the wiki.
> 
> My spontaneous ideas are:
> 
> * Better handling of OOM situations:
> ** more swapping to system memory
> ** memory usage reporting to userspace

That sounds way over the scope of a GSoC.
> 
> * Performance analysis:
> ** what are Noveaus most hit bottlenecks
> ** how easy is it to figure those out
> ** improve/write tools and nouveaus support for those to figure those
> out (maybe more counters needed, something else?)

Yes, this is definitely more doable! Being able to run frameretracer on
nouveau would be ideal, as it is an impressive tool to debug performance
issue on Intel platforms (and it may already somewhat work).

> 
> * initial Vulkan driver
> 
> * OpenCL
> ** finishing up what we already have
> ** pass the CTS

Well, I know you are optimistic, but that sounds impossible to someone
who is not already a contributor!

> 
> * experimental nir support (why not if somebody wants to spend time on this?)

Yes, that could be a good one. This is a pretty self-contained project.
Not sure this is what we want to be working towards, but anything we can
do to reduce our workload is appreciated :)

> 
> * some super difficult compiler optimizations
> ** which ones indeed?

I would rather go for implementing a lot of simple ones, and hope that
the student will stay long enough to get to the useful ones ;)

> 
> * random reclocking stuff
> ** big enough for an entire GSoC/EVoC project?
> ** Roy, Ben: Status on Fermi/Tesla

Big enough? It is big-enough for a decade apparently given how slow we
have been :s

> 
> And because I don't just go ahead and add those things, I also would
> like to get your feedback on the ideas I mentioned here. In the end I
> would like to get 10 or more ideas written down somewhere, maybe even
> on the Xorg wiki page, but then it would be like 50% Nouveau, but this
> shouldn't be our problem.

Thanks for doing this, we need to get more contributors, and this is the
first step!

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


Re: [Nouveau] [PATCH] drm/nouveau: Document nouveau support for Tegra in DRIVER_DESC

2017-10-01 Thread Martin Peres
On 11/08/17 13:56, Rhys Kidd wrote:
> nouveau supports the Tegra K1 and higher after the SoC-based GPUs converged
> with the main GeForce GPU families.
> 
> Signed-off-by: Rhys Kidd <rhysk...@gmail.com>
> ---
>  drivers/gpu/drm/nouveau/nouveau_drv.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h 
> b/drivers/gpu/drm/nouveau/nouveau_drv.h
> index 822fe1d4d35e..fbe42ec0a5f1 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_drv.h
> +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
> @@ -5,7 +5,7 @@
>  #define DRIVER_EMAIL "nouveau@lists.freedesktop.org"
>  
>  #define DRIVER_NAME  "nouveau"
> -#define DRIVER_DESC  "nVidia Riva/TNT/GeForce/Quadro/Tesla"
> +#define DRIVER_DESC  "nVidia Riva/TNT/GeForce/Quadro/Tesla/Tegra"

The problem is that we do not support all Tegras. How about Tegra TK1+?

I really do not care much about this string, but I guess I probably
should a bit.

With the TK1 added, this is:

Reviewed-by" Martin Peres <martin.pe...@free.fr>

>  #define DRIVER_DATE  "20120801"
>  
>  #define DRIVER_MAJOR 1
> 

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


[Nouveau] XDC 2017 : Call for paper

2017-06-06 Thread Martin Peres
Hello,

I have the pleasure to announce that the X.org Developer Conference 2017
will be held in Mountain View, California from September 20th to
September 22nd. The venue is located at the Googleplex.

The official page for the event is http://www.x.org/wiki/Events/XDC2017
while the call for paper is at http://www.x.org/wiki/Other/Press/CFP2017/

As usual, we are open to talks across the layers of the graphics stack,
from the kernel to desktop environments / graphical applications and
about how to make things better for the developers who build them.
Given that the conference is located at Google, we would welcome topics
related to Android and Chromebooks. We would also like to hear about
Virtual Reality and end-to-end buffer format negociation. If you're not
sure if something might fit, mail me or add it to the ideas list found
in the program page.

The conference is free of charge and open to the general public. If
you plan on coming, please add yourself to the attendees list. We'll
use this list to make badges and plan for the catering, so if you are
attending please add your name as early as possible.

I am looking forward to seeing you there. If you have any
inquiries/questions, please send them to Stéphane Marchesin (please also
CC: board at foundation.x.org).

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


Re: [Nouveau] [PATCH v5 5/5] nouveau_hwmon: Change permissions to numeric

2017-05-01 Thread Martin Peres
On 26/04/17 19:46, Oscar Salvador wrote:
> This patch replaces the symbolic permissions with the numeric ones,
> and adds me to the authors too.
> 
> Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>


> ---
>  drivers/gpu/drm/nouveau/nouveau_hwmon.c | 14 +++---
>  1 file changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
> b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
> index 9142779..45b5c85 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
> @@ -1,5 +1,6 @@
>  /*
> - * Copyright 2010 Red Hat Inc.
> + * Copyright 2010 Red Hat Inc. (Ben Skeggs)

Please drop this change.

> + * Copyright 2017 Oscar Salvador
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining a
>   * copy of this software and associated documentation files (the "Software"),
> @@ -19,7 +20,6 @@
>   * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>   * OTHER DEALINGS IN THE SOFTWARE.
>   *
> - * Authors: Ben Skeggs

You can't remove people as being the author of something. Just add
yourself if you care about this (I did not care to add my name when I
wrote in this file, because the git history makes more sense nowadays.

Otherwise, I have no strong opinions on this patch. I guess the numeric
representation is easier to read, so I will give you my R-b for this and
let others decide what to do:

Reviewed-by: Martin Peres <martin.pe...@free.fr>

>   */
>  
>  #ifdef CONFIG_ACPI
> @@ -56,7 +56,7 @@ nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d,
>  {
>   return snprintf(buf, PAGE_SIZE, "%d\n", 100);
>  }
> -static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, S_IRUGO,
> +static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, 0444,
> nouveau_hwmon_show_temp1_auto_point1_pwm, NULL, 0);
>  
>  static ssize_t
> @@ -88,7 +88,7 @@ nouveau_hwmon_set_temp1_auto_point1_temp(struct device *d,
>  
>   return count;
>  }
> -static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, S_IRUGO | S_IWUSR,
> +static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, 0644,
> nouveau_hwmon_temp1_auto_point1_temp,
> nouveau_hwmon_set_temp1_auto_point1_temp, 0);
>  
> @@ -121,7 +121,7 @@ nouveau_hwmon_set_temp1_auto_point1_temp_hyst(struct 
> device *d,
>  
>   return count;
>  }
> -static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
> +static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, 0644,
> nouveau_hwmon_temp1_auto_point1_temp_hyst,
> nouveau_hwmon_set_temp1_auto_point1_temp_hyst, 0);
>  
> @@ -255,7 +255,7 @@ nouveau_hwmon_set_pwm1_min(struct device *d, struct 
> device_attribute *a,
>   return count;
>  }
>  
> -static SENSOR_DEVICE_ATTR(pwm1_min, S_IRUGO | S_IWUSR,
> +static SENSOR_DEVICE_ATTR(pwm1_min, 0644,
> nouveau_hwmon_get_pwm1_min,
> nouveau_hwmon_set_pwm1_min, 0);
>  
> @@ -295,7 +295,7 @@ nouveau_hwmon_set_pwm1_max(struct device *d, struct 
> device_attribute *a,
>   return count;
>  }
>  
> -static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO | S_IWUSR,
> +static SENSOR_DEVICE_ATTR(pwm1_max, 0644,
> nouveau_hwmon_get_pwm1_max,
> nouveau_hwmon_set_pwm1_max, 0);
>  
> 

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


Re: [Nouveau] [PATCH v5 4/5] nouveau_hwmon: Add support for auto_point attributes

2017-05-01 Thread Martin Peres
The name of the patch is misleading since you also add support for
pwm1_min/max.

Could you add change the title to "nouveau/hwmon: expose the auto_point
and pwm_min/max attrs"? And while you are at it, please change every
commit title to nouveau/hwmon instead of nouveau_hwmon.

On 26/04/17 19:46, Oscar Salvador wrote:
> This patch creates a special group attributes for attrs like "*auto_point*".
> We check if we have support for them, and if we do, we gather them all in
> an attribute_group's structure which is the parameter regarding special groups
> of hwmon_device_register_with_info.
> 
> Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
> ---
>  drivers/gpu/drm/nouveau/nouveau_hwmon.c | 29 -
>  1 file changed, 28 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
> b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
> index 4db65fb..9142779 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
> @@ -358,6 +358,23 @@ nouveau_hwmon_get_power1_crit(struct nouveau_drm *drm)
>   return iccsense->power_w_crit;
>  }
>  
> +static struct attribute *pwm_fan_sensor_attrs[] = {
> + _dev_attr_pwm1_min.dev_attr.attr,
> + _dev_attr_pwm1_max.dev_attr.attr,
> + NULL
> +};
> +ATTRIBUTE_GROUPS(pwm_fan_sensor);
> +
> +static struct attribute *temp1_auto_point_sensor_attrs[] = {
> + _dev_attr_temp1_auto_point1_pwm.dev_attr.attr,
> + _dev_attr_temp1_auto_point1_temp.dev_attr.attr,
> + _dev_attr_temp1_auto_point1_temp_hyst.dev_attr.attr,
> + NULL
> +};
> +ATTRIBUTE_GROUPS(temp1_auto_point_sensor);
> +
> +#define N_ATTR_GROUPS   3
> +
>  static const u32 nouveau_config_chip[] = {
>   HWMON_C_UPDATE_INTERVAL,
>   0
> @@ -792,17 +809,27 @@ nouveau_hwmon_init(struct drm_device *dev)
>  #if defined(CONFIG_HWMON) || (defined(MODULE) && 
> defined(CONFIG_HWMON_MODULE))
>   struct nouveau_drm *drm = nouveau_drm(dev);
>   struct nvkm_therm *therm = nvxx_therm(>client.device);
> + const struct attribute_group *special_groups[N_ATTR_GROUPS];
>   struct nouveau_hwmon *hwmon;
>   struct device *hwmon_dev;
>   int ret = 0;
> + int i = 0;
>  
>   hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL);
>   if (!hwmon)
>   return -ENOMEM;
>   hwmon->dev = dev;
>  
> + if (therm && therm->attr_get && therm->attr_set) {
> + if (nvkm_therm_temp_get(therm) >= 0)
> + special_groups[i++] = _auto_point_sensor_group;
> + if (therm->fan_get && therm->fan_get(therm) >= 0)
> + special_groups[i++] = _fan_sensor_group;
> + }
> +
> + special_groups[i] = 0;
>   hwmon_dev = hwmon_device_register_with_info(dev->dev, "nouveau", dev,
> - _chip_info, NULL);
> + _chip_info, special_groups);

Please align _chip_info with dev->dev and split special_groups
on the following line.

>   if (IS_ERR(hwmon_dev)) {
>   ret = PTR_ERR(hwmon_dev);
>   NV_ERROR(drm, "Unable to register hwmon device: %d\n", ret);
> 

This commit breaks bisectability, so Ben may have to squash it in the
previous one. Otherwise, this looks good to me:

Reviewed-by: Martin Peres <martin.pe...@free.fr>
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH v5 3/5] nouveau_hwmon: Remove old code, add .write/.read operations

2017-05-01 Thread Martin Peres
read_string(struct device *dev, enum 
> hwmon_sensor_types type, u32 attr,
>   return -EOPNOTSUPP;
>  }
>  
> +static int
> +nouveau_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
> + int channel, long *val)
> +{
> + switch (type) {
> + case hwmon_chip:
> + return nouveau_chip_read(dev, attr, channel, val);
> + case hwmon_temp:
> + return nouveau_temp_read(dev, attr, channel, val);
> + case hwmon_fan:
> + return nouveau_fan_read(dev, attr, channel, val);
> + case hwmon_in:
> + return nouveau_in_read(dev, attr, channel, val);
> + case hwmon_pwm:
> + return nouveau_pwm_read(dev, attr, channel, val);
> + case hwmon_power:
> + return nouveau_power_read(dev, attr, channel, val);
> + default:
> + return -EOPNOTSUPP;
> + }
> +}
> +
> +static int
> +nouveau_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
> + int channel, long val)
> +{
> + switch (type) {
> + case hwmon_pwm:
> + return nouveau_pwm_write(dev, attr, channel, val);

Where did all the temperature-related writes go?

Some vbios have fucked up thermal values set by default, this is why we
allow users to override them through hwmon.

Could you expose _max, _max_hyst, _crit and _crit_hyst?

> + default:
> + return -EOPNOTSUPP;
> + }
> +}
> +
>  static const struct hwmon_ops nouveau_hwmon_ops = {
>   .is_visible = nouveau_is_visible,
> - .read = NULL,
> + .read = nouveau_read,
>   .read_string = nouveau_read_string,
> - .write = NULL,
> + .write = nouveau_write,
>  };
>  
>  static const struct hwmon_chip_info nouveau_chip_info = {
> @@ -942,8 +792,6 @@ nouveau_hwmon_init(struct drm_device *dev)
>  #if defined(CONFIG_HWMON) || (defined(MODULE) && 
> defined(CONFIG_HWMON_MODULE))
>   struct nouveau_drm *drm = nouveau_drm(dev);
>   struct nvkm_therm *therm = nvxx_therm(>client.device);
> - struct nvkm_volt *volt = nvxx_volt(>client.device);
> - struct nvkm_iccsense *iccsense = nvxx_iccsense(>client.device);
>   struct nouveau_hwmon *hwmon;
>   struct device *hwmon_dev;
>   int ret = 0;
> @@ -953,79 +801,16 @@ nouveau_hwmon_init(struct drm_device *dev)
>   return -ENOMEM;
>   hwmon->dev = dev;
>  
> - hwmon_dev = hwmon_device_register(dev->dev);
> + hwmon_dev = hwmon_device_register_with_info(dev->dev, "nouveau", dev,
> + _chip_info, NULL);
>   if (IS_ERR(hwmon_dev)) {
>   ret = PTR_ERR(hwmon_dev);
>   NV_ERROR(drm, "Unable to register hwmon device: %d\n", ret);
>   return ret;
>   }
> - dev_set_drvdata(hwmon_dev, dev);
> -
> - /* set the default attributes */
> - ret = sysfs_create_group(_dev->kobj, _default_attrgroup);
> - if (ret)
> - goto error;
> -
> - if (therm && therm->attr_get && therm->attr_set) {
> - /* if the card has a working thermal sensor */
> - if (nvkm_therm_temp_get(therm) >= 0) {
> - ret = sysfs_create_group(_dev->kobj, 
> _temp_attrgroup);
> - if (ret)
> -     goto error;
> - }
> -
> - /* if the card has a pwm fan */
> - /*XXX: incorrect, need better detection for this, some boards 
> have
> -  * the gpio entries for pwm fan control even when there's no
> -  * actual fan connected to it... therm table? */
> - if (therm->fan_get && therm->fan_get(therm) >= 0) {
> - ret = sysfs_create_group(_dev->kobj,
> -  _pwm_fan_attrgroup);
> - if (ret)
> - goto error;
> - }
> - }
> -
> - /* if the card can read the fan rpm */
> - if (therm && nvkm_therm_fan_sense(therm) >= 0) {
> - ret = sysfs_create_group(_dev->kobj,
> -  _fan_rpm_attrgroup);
> - if (ret)
> - goto error;
> - }
> -
> - if (volt && nvkm_volt_get(volt) >= 0) {
> - ret = sysfs_create_group(_dev->kobj,
> -  _in0_attrgroup);
> -
> - if (ret)
> - goto error;
> - }
> -
> - if (iccsense && iccsense->data_valid && !list_empty(>rails)) {
> - ret = sysfs_create_group(_dev->kobj,
> -  _power_attrgroup);
> -
> - if (ret)
> - goto error;
> -
> - if (iccsense->power_w_max && iccsense->power_w_crit) {
> - ret = sysfs_create_group(_dev->kobj,
> -  _power_caps_attrgroup);
> - if (ret)
> - goto error;
> - }
> - }
>  
>   hwmon->hwmon = hwmon_dev;
> -
>   return 0;
> -
> -error:
> - NV_ERROR(drm, "Unable to create some hwmon sysfs files: %d\n", ret);
> - hwmon_device_unregister(hwmon_dev);
> - hwmon->hwmon = NULL;
> - return ret;
>  #else
>   return 0;
>  #endif
> @@ -1037,17 +822,8 @@ nouveau_hwmon_fini(struct drm_device *dev)
>  #if defined(CONFIG_HWMON) || (defined(MODULE) && 
> defined(CONFIG_HWMON_MODULE))
>   struct nouveau_hwmon *hwmon = nouveau_hwmon(dev);
>  
> - if (hwmon->hwmon) {
> - sysfs_remove_group(>hwmon->kobj, 
> _default_attrgroup);
> - sysfs_remove_group(>hwmon->kobj, _temp_attrgroup);
> - sysfs_remove_group(>hwmon->kobj, 
> _pwm_fan_attrgroup);
> - sysfs_remove_group(>hwmon->kobj, 
> _fan_rpm_attrgroup);
> - sysfs_remove_group(>hwmon->kobj, _in0_attrgroup);
> - sysfs_remove_group(>hwmon->kobj, _power_attrgroup);
> - sysfs_remove_group(>hwmon->kobj, 
> _power_caps_attrgroup);
> -
> + if (hwmon->hwmon)
>   hwmon_device_unregister(hwmon->hwmon);
> - }
>  
>   nouveau_drm(dev)->hwmon = NULL;
>   kfree(hwmon);
> 

Thanks a lot, this patch makes a huge improvement in readability! With
the comments addressed, this patch is:

Reviewed-by: Martin Peres <martin.pe...@free.fr>
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH v5 2/5] nouveau_hwmon: Add nouveau_hwmon_ops structure with .is_visible/.read_string

2017-05-01 Thread Martin Peres
gt; +
> + if (!therm || !therm->attr_get || nvkm_therm_fan_sense(therm) < 0)
> + return 0;
> +
> + switch (attr) {
> + case hwmon_fan_input:
> + return 0444;
> + default:
> + return 0;
> + }
> +}
> +
> +static umode_t
> +nouveau_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr,
> + int channel)

Could you align 'int channel' with 'const void *data'?

> +{
> + switch (type) {
> + case hwmon_chip:
> + return nouveau_chip_is_visible(data, attr, channel);
> + case hwmon_temp:
> + return nouveau_temp_is_visible(data, attr, channel);
> + case hwmon_fan:
> + return nouveau_fan_is_visible(data, attr, channel);
> + case hwmon_in:
> + return nouveau_input_is_visible(data, attr, channel);
> + case hwmon_pwm:
> + return nouveau_pwm_is_visible(data, attr, channel);
> + case hwmon_power:
> + return nouveau_power_is_visible(data, attr, channel);
> + default:
> + return 0;
> + }
> +}
> +
> +static const char input_label[] = "GPU core";
> +
> +static int
> +nouveau_read_string(struct device *dev, enum hwmon_sensor_types type, u32 
> attr,
> + int channel, char **buf)

Same as above.

> +{
> + if (type == hwmon_in && attr == hwmon_in_label) {
> + *buf = input_label;
> + return 0;
> + }
> +
> + return -EOPNOTSUPP;
> +}
> +
> +static const struct hwmon_ops nouveau_hwmon_ops = {
> + .is_visible = nouveau_is_visible,
> + .read = NULL,
> + .read_string = nouveau_read_string,
> + .write = NULL,
> +};
> +
> +static const struct hwmon_chip_info nouveau_chip_info = {
> + .ops = _hwmon_ops,
> + .info = nouveau_info,
> +};
>  #endif
>  
>  int
>

With the power-related conditions and all the alignments fixed, patches
1-2 are:

Reviewed-by: Martin Peres <martin.pe...@free.fr>
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


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

2017-04-22 Thread Martin Peres

deteaction -> detection

On 22/04/17 15:22, Karol Herbst wrote:

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

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

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

diff --git a/drm/nouveau/nvkm/subdev/volt/base.c 
b/drm/nouveau/nvkm/subdev/volt/base.c
index e344901c..61b29c7a 100644
--- a/drm/nouveau/nvkm/subdev/volt/base.c
+++ b/drm/nouveau/nvkm/subdev/volt/base.c
@@ -195,14 +195,16 @@ nvkm_volt_parse_bios(struct nvkm_bios *bios, struct 
nvkm_volt *volt)
data = nvbios_volt_parse(bios, , , , , );
if (data && info.vidmask && info.base && info.step && info.ranged) {
nvkm_debug(subdev, "found ranged based VIDs\n");
-   volt->min_uv = info.min;
-   volt->max_uv = info.max;
+   volt->min_uv = 0x;
+   volt->max_uv = 0;
for (i = 0; i < info.vidmask + 1; i++) {
if (info.base >= info.min &&
info.base <= info.max) {
volt->vid[volt->vid_nr].uv = info.base;
volt->vid[volt->vid_nr].vid = i;
volt->vid_nr++;
+   volt->min_uv = min(volt->min_uv, info.base);
+   volt->max_uv = max(volt->max_uv, info.base);
    }
info.base += info.step;
}



Reviewed-by: Martin Peres <martin.pe...@free.fr>
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] A request for Virtual GPU based on Nouveau

2017-03-07 Thread Martin Peres

On 25/02/17 05:39, Zhengjie (PARC) wrote:

Hi,

I’m a developer from Huawei Technologies Co.,Ltd. China. I’m working on
GPU Virtualization.

I found some academic papers on google which describe how to virtualize
GPU on Cloud based on Nouveau, Such as < TimeGraph: GPU Scheduling for
Real-Time Multi-Tasking Environments >   written by Ph.D Shinpei Kato.

I know the nouveau project aims to build high-quality, free/libre
software drivers for nVidia cards
. Maybe
the nouveau project developers can do something to help GPU
Virtualization. So I’d like to ask whether there is the possibility of
cooperation on GPU Virtualization between Huawei and the nouveau project.

Maybe there is another way for cooperation. But I don’t know how. Or you
can give some advices to us on GPU Virtualization based on nouveau. That
will be grateful. I’m looking forward to you reply.



Nouveau's design is meant for allowing virtualization, so you should not 
have too much trouble getting something to work, provided you can make 
hypercalls. Check out NVIF in the nouveau's source.


Martin

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


Re: [Nouveau] [PATCH 9/9] clk: Check pm_runtime status before reclocking

2017-03-06 Thread Martin Peres

On 05/03/17 18:35, Karol Herbst wrote:

We don't want to change anything on the GPU if it's suspended. Also we
need to increase the refcount on the pm_runtime counter so that the GPU
won't be suspended while reclocking.

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

diff --git a/drm/nouveau/nvkm/subdev/clk/base.c 
b/drm/nouveau/nvkm/subdev/clk/base.c
index bc65906e..143ce0ea 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -320,6 +320,7 @@ nvkm_clk_update_work(struct work_struct *work)
 {
struct nvkm_clk *clk = container_of(work, typeof(*clk), work);
struct nvkm_subdev *subdev = >subdev;
+   struct device *dev = subdev->device->dev;
int pstate;

if (!atomic_xchg(>waiting, 0))
@@ -345,7 +346,14 @@ nvkm_clk_update_work(struct work_struct *work)
pstate = NVKM_CLK_PSTATE_DEFAULT;
}

-   clk->func->update(clk, pstate);
+   // only call into the code if the GPU is powered on
+   if (!pm_runtime_suspended(dev)) {
+   // it would be a shame if the GPU goes into suspend
+   // while doing the reclock
+   pm_runtime_get_sync(dev);
+   clk->func->update(clk, pstate);
+   pm_runtime_put(dev);
+   }


Good catch! But Java has corrupted your mind :D Please use /* */ for 
comments.




wake_up_all(>wait);
nvkm_notify_get(>pwrsrc_ntfy);


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


Re: [Nouveau] [PATCH 8/9] clk: Set clocks to pre suspend state after suspend

2017-03-06 Thread Martin Peres

On 05/03/17 18:35, Karol Herbst wrote:

The idea is to clear out the saved state, because after a resume we can't
know what the GPU is clocked to. The reclock is triggered by the call to
nvkm_clk_update later in nvkm_clk_init.

Signed-off-by: Karol Herbst <karolher...@gmail.com>
Reviewed-by: Martin Peres <martin.pe...@free.fr>
---
 drm/nouveau/nvkm/subdev/clk/base.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drm/nouveau/nvkm/subdev/clk/base.c 
b/drm/nouveau/nvkm/subdev/clk/base.c
index 54a4b7fa..bc65906e 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -627,11 +627,9 @@ nvkm_clk_init(struct nvkm_subdev *subdev)
if (clk->func->init)
return clk->func->init(clk);

-   clk->astate = NVKM_CLK_PSTATE_DEFAULT;
+   // after a resume we have no idea what clocks are set, reset the state


No c++ comments, please use /* */


clk->pstate = NULL;
-   clk->exp_cstateid = NVKM_CLK_CSTATE_DEFAULT;
clk->cstate = NULL;
-   clk->temp = 90; /* reasonable default value */
nvkm_clk_update(clk, true);
return 0;
 }
@@ -685,8 +683,13 @@ nvkm_clk_ctor(const struct nvkm_clk_func *func, struct 
nvkm_device *device,
clk->func = func;
INIT_LIST_HEAD(>states);
clk->domains = func->domains;
+
+   clk->astate = NVKM_CLK_PSTATE_DEFAULT;
clk->ustate_ac = -1;
clk->ustate_dc = -1;
+   clk->exp_cstateid = NVKM_CLK_CSTATE_DEFAULT;
+   clk->temp = 90; /* reasonable default value */
+
clk->allow_reclock = allow_reclock;

INIT_WORK(>work, nvkm_clk_update_work);


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


Re: [Nouveau] [PATCH 5/9] clk: We should pass the pstate id around not the index in the list

2017-03-06 Thread Martin Peres

On 05/03/17 18:35, Karol Herbst wrote:

This makes the code easier, because we can compare the id with
pstate->pstate and safe us the trouble iterating over the entire pstate


saves us from the trouble of iterating over the pstates.


list to match the index.

Signed-off-by: Karol Herbst <karolher...@gmail.com>
Reviewed-by: Martin Peres <martin.pe...@free.fr>
---
 drm/nouveau/nouveau_debugfs.c  |  6 +--
 drm/nouveau/nvkm/subdev/clk/base.c | 78 +++---
 2 files changed, 41 insertions(+), 43 deletions(-)

diff --git a/drm/nouveau/nouveau_debugfs.c b/drm/nouveau/nouveau_debugfs.c
index fd64dfdc..b114a429 100644
--- a/drm/nouveau/nouveau_debugfs.c
+++ b/drm/nouveau/nouveau_debugfs.c
@@ -96,11 +96,11 @@ nouveau_debugfs_pstate_get(struct seq_file *m, void *data)
} while (attr.index);

if (state >= 0) {
-   if (info.ustate_ac == state)
+   if (info.ustate_ac == attr.state)
seq_printf(m, " AC");
-   if (info.ustate_dc == state)
+   if (info.ustate_dc == attr.state)
seq_printf(m, " DC");
-   if (info.pstate == state)
+   if (info.pstate == attr.state)
seq_printf(m, " *");
} else {
if (info.ustate_ac < -1)
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c 
b/drm/nouveau/nvkm/subdev/clk/base.c
index d37c13b7..1d71bf09 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -272,23 +272,26 @@ nvkm_cstate_new(struct nvkm_clk *clk, int idx, struct 
nvkm_pstate *pstate)
  * P-States
  */
 static int
-nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)
+nvkm_pstate_prog(struct nvkm_clk *clk, int pstateid)
 {
struct nvkm_subdev *subdev = >subdev;
struct nvkm_fb *fb = subdev->device->fb;
struct nvkm_pci *pci = subdev->device->pci;
struct nvkm_pstate *pstate;
-   int ret, idx = 0;
+   int ret;

-   if (pstatei == NVKM_CLK_PSTATE_DEFAULT)
+   if (pstateid == NVKM_CLK_PSTATE_DEFAULT)
return 0;

list_for_each_entry(pstate, >states, head) {
-   if (idx++ == pstatei)
+   if (pstate->pstate == pstateid)
break;
}

-   nvkm_debug(subdev, "setting performance state %d\n", pstatei);
+   if (!pstate)
+   return -EINVAL;
+
+   nvkm_debug(subdev, "setting performance state %x\n", pstateid);
clk->pstate = pstate;

nvkm_pcie_set_link(pci, pstate->pcie_speed, pstate->pcie_width);
@@ -329,7 +332,6 @@ nvkm_clk_update_work(struct work_struct *work)
pstate = clk->pwrsrc ? clk->ustate_ac : clk->ustate_dc;
if (clk->state_nr && pstate != -1) {
pstate = (pstate < 0) ? clk->astate : pstate;
-   pstate = min(pstate, clk->state_nr - 1);
} else {
pstate = NVKM_CLK_PSTATE_DEFAULT;
}
@@ -491,32 +493,9 @@ nvkm_pstate_new(struct nvkm_clk *clk, int idx)
  * Adjustment triggers
  */
 static int
-nvkm_clk_ustate_update(struct nvkm_clk *clk, int req)
-{
-   struct nvkm_pstate *pstate;
-   int i = 0;
-
-   if (!clk->allow_reclock)
-   return -ENOSYS;
-
-   if (req != -1 && req != -2) {
-   list_for_each_entry(pstate, >states, head) {
-   if (pstate->pstate == req)
-   break;
-   i++;
-   }
-
-   if (pstate->pstate != req)
-   return -EINVAL;
-   req = i;
-   }
-
-   return req + 2;
-}
-
-static int
 nvkm_clk_nstate(struct nvkm_clk *clk, const char *mode, int arglen)
 {
+   struct nvkm_pstate *pstate;
int ret = 1;

if (clk->allow_reclock && !strncasecmpz(mode, "auto", arglen))
@@ -528,27 +507,46 @@ nvkm_clk_nstate(struct nvkm_clk *clk, const char *mode, 
int arglen)

((char *)mode)[arglen] = '\0';
if (!kstrtol(mode, 0, )) {
-   ret = nvkm_clk_ustate_update(clk, v);
+   ret = v;
if (ret < 0)
ret = 1;
}
((char *)mode)[arglen] = save;
}

-   return ret - 2;
+   if (ret < 0)
+   return ret;
+
+   list_for_each_entry(pstate, >states, head) {
+   if (pstate->pstate == ret)
+   return ret;
+   }
+   return -EINVAL;
 }

 int
 nvkm_cl

Re: [Nouveau] [PATCH 3/9] clk: Make pstate a pointer to nvkm_pstate

2017-03-06 Thread Martin Peres

On 05/03/17 18:35, Karol Herbst wrote:

We will access the current set cstate at least every second and this safes


Either "the current ctstate" or "the currently-set cstate", but not a 
mix of both :D I prefer the first.


safes -> saves.


us some CPU cycles looking them up every second.

Signed-off-by: Karol Herbst <karolher...@gmail.com>
Reviewed-by: Martin Peres <martin.pe...@free.fr>
---
 drm/nouveau/include/nvkm/subdev/clk.h |  4 +++-
 drm/nouveau/nvkm/engine/device/ctrl.c |  5 -
 drm/nouveau/nvkm/subdev/clk/base.c| 17 -
 drm/nouveau/nvkm/subdev/pmu/gk20a.c   | 18 +++---
 4 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h 
b/drm/nouveau/include/nvkm/subdev/clk.h
index 69942b14..37263b7f 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -10,6 +10,8 @@ struct nvkm_pll_vals;
 #define NVKM_CLK_CSTATE_BASE-2 /* pstate base */
 #define NVKM_CLK_CSTATE_HIGHEST -3 /* highest possible */

+#define NVKM_CLK_PSTATE_DEFAULT -1
+
 enum nv_clk_src {
nv_clk_src_crystal,
nv_clk_src_href,
@@ -95,7 +97,7 @@ struct nvkm_clk {

struct nvkm_notify pwrsrc_ntfy;
int pwrsrc;
-   int pstate; /* current */
+   struct nvkm_pstate *pstate; /* current */
int ustate_ac; /* user-requested (-1 disabled, -2 perfmon) */
int ustate_dc; /* user-requested (-1 disabled, -2 perfmon) */
int astate; /* perfmon adjustment (base) */
diff --git a/drm/nouveau/nvkm/engine/device/ctrl.c 
b/drm/nouveau/nvkm/engine/device/ctrl.c
index b0ece71a..da70626c 100644
--- a/drm/nouveau/nvkm/engine/device/ctrl.c
+++ b/drm/nouveau/nvkm/engine/device/ctrl.c
@@ -52,7 +52,10 @@ nvkm_control_mthd_pstate_info(struct nvkm_control *ctrl, 
void *data, u32 size)
args->v0.ustate_ac = clk->ustate_ac;
args->v0.ustate_dc = clk->ustate_dc;
args->v0.pwrsrc = clk->pwrsrc;
-   args->v0.pstate = clk->pstate;
+   if (clk->pstate)
+   args->v0.pstate = clk->pstate->pstate;
+   else
+   args->v0.pstate = NVKM_CLK_PSTATE_DEFAULT;
} else {
args->v0.count = 0;
args->v0.ustate_ac = NVIF_CONTROL_PSTATE_INFO_V0_USTATE_DISABLE;
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c 
b/drm/nouveau/nvkm/subdev/clk/base.c
index 07d530ed..0d4d9fdf 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -271,13 +271,16 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)
struct nvkm_pstate *pstate;
int ret, idx = 0;

+   if (pstatei == NVKM_CLK_PSTATE_DEFAULT)
+   return 0;
+
list_for_each_entry(pstate, >states, head) {
if (idx++ == pstatei)
break;
}

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

nvkm_pcie_set_link(pci, pstate->pcie_speed, pstate->pcie_width);

@@ -306,8 +309,12 @@ nvkm_clk_update_work(struct work_struct *work)
return;
clk->pwrsrc = power_supply_is_system_supplied();

+   if (clk->pstate)
+   pstate = clk->pstate->pstate;
+   else
+   pstate = NVKM_CLK_PSTATE_DEFAULT;
nvkm_trace(subdev, "P %d PWR %d U(AC) %d U(DC) %d A %d T %d°C\n",
-  clk->pstate, clk->pwrsrc, clk->ustate_ac, clk->ustate_dc,
+  pstate, clk->pwrsrc, clk->ustate_ac, clk->ustate_dc,
   clk->astate, clk->temp);

pstate = clk->pwrsrc ? clk->ustate_ac : clk->ustate_dc;
@@ -315,11 +322,11 @@ nvkm_clk_update_work(struct work_struct *work)
pstate = (pstate < 0) ? clk->astate : pstate;
pstate = min(pstate, clk->state_nr - 1);
} else {
-   pstate = clk->pstate = -1;
+   pstate = NVKM_CLK_PSTATE_DEFAULT;
}

nvkm_trace(subdev, "-> %d\n", pstate);
-   if (pstate != clk->pstate) {
+   if (!clk->pstate || pstate != clk->pstate->pstate) {
int ret = nvkm_pstate_prog(clk, pstate);
if (ret) {
nvkm_error(subdev, "error setting pstate %d: %d\n",
@@ -610,7 +617,7 @@ nvkm_clk_init(struct nvkm_subdev *subdev)
return clk->func->init(clk);

clk->astate = clk->state_nr - 1;
-   clk->pstate = -1;
+   clk->pstate = NULL;
clk->temp = 90; /* reasonable default value */
nvkm_clk_update(clk, true);
return 0;
diff --git a/drm/nouveau/nvkm/subdev/pmu/gk20a.c 
b/drm/nouveau/nvkm/subdev/pmu/gk20a.c
index 9ca0db79..43a9a74a 100

Re: [Nouveau] [PATCH 1/9] clk: Rename nvkm_pstate_calc to nvkm_clk_update and export it

2017-03-06 Thread Martin Peres

On 05/03/17 18:34, Karol Herbst wrote:

This function will be used to update the current clock state.

This will happen for various reasons:
  * Temperature changes
  * User changes clocking state
  * Load changes

Signed-off-by: Karol Herbst 
---
 drm/nouveau/include/nvkm/subdev/clk.h |  1 +
 drm/nouveau/nvkm/subdev/clk/base.c| 26 --
 2 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h 
b/drm/nouveau/include/nvkm/subdev/clk.h
index e5275f74..b2c94cd5 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -123,6 +123,7 @@ int nvkm_clk_ustate(struct nvkm_clk *, int req, int pwr);
 int nvkm_clk_astate(struct nvkm_clk *, int req, int rel, bool wait);
 int nvkm_clk_dstate(struct nvkm_clk *, int req, int rel);
 int nvkm_clk_tstate(struct nvkm_clk *, u8 temperature);
+int nvkm_clk_update(struct nvkm_clk *clk, bool wait);


To keep in line with the rest, please get rid of 'clk'.

Otherwise, looks good to me!



 int nv04_clk_new(struct nvkm_device *, int, struct nvkm_clk **);
 int nv40_clk_new(struct nvkm_device *, int, struct nvkm_clk **);
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c 
b/drm/nouveau/nvkm/subdev/clk/base.c
index e4c8d310..ecff3ff3 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -296,7 +296,7 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)
 }

 static void
-nvkm_pstate_work(struct work_struct *work)
+nvkm_clk_update_work(struct work_struct *work)
 {
struct nvkm_clk *clk = container_of(work, typeof(*clk), work);
struct nvkm_subdev *subdev = >subdev;
@@ -332,9 +332,15 @@ nvkm_pstate_work(struct work_struct *work)
nvkm_notify_get(>pwrsrc_ntfy);
 }

-static int
-nvkm_pstate_calc(struct nvkm_clk *clk, bool wait)
+int
+nvkm_clk_update(struct nvkm_clk *clk, bool wait)
 {
+   if (!clk)
+   return -EINVAL;
+
+   if (!clk->allow_reclock)
+   return -ENODEV;
+
atomic_set(>waiting, 1);
schedule_work(>work);
if (wait)
@@ -524,7 +530,7 @@ nvkm_clk_ustate(struct nvkm_clk *clk, int req, int pwr)
if (ret >= 0) {
if (ret -= 2, pwr) clk->ustate_ac = ret;
else   clk->ustate_dc = ret;
-   return nvkm_pstate_calc(clk, true);
+   return nvkm_clk_update(clk, true);
}
return ret;
 }
@@ -536,7 +542,7 @@ nvkm_clk_astate(struct nvkm_clk *clk, int req, int rel, 
bool wait)
if ( rel) clk->astate += rel;
clk->astate = min(clk->astate, clk->state_nr - 1);
clk->astate = max(clk->astate, 0);
-   return nvkm_pstate_calc(clk, wait);
+   return nvkm_clk_update(clk, wait);
 }

 int
@@ -545,7 +551,7 @@ nvkm_clk_tstate(struct nvkm_clk *clk, u8 temp)
if (clk->temp == temp)
return 0;
clk->temp = temp;
-   return nvkm_pstate_calc(clk, false);
+   return nvkm_clk_update(clk, false);
 }

 int
@@ -555,7 +561,7 @@ nvkm_clk_dstate(struct nvkm_clk *clk, int req, int rel)
if ( rel) clk->dstate += rel;
clk->dstate = min(clk->dstate, clk->state_nr - 1);
clk->dstate = max(clk->dstate, 0);
-   return nvkm_pstate_calc(clk, true);
+   return nvkm_clk_update(clk, true);
 }

 static int
@@ -563,7 +569,7 @@ nvkm_clk_pwrsrc(struct nvkm_notify *notify)
 {
struct nvkm_clk *clk =
container_of(notify, typeof(*clk), pwrsrc_ntfy);
-   nvkm_pstate_calc(clk, false);
+   nvkm_clk_update(clk, false);
return NVKM_NOTIFY_DROP;
 }

@@ -618,7 +624,7 @@ nvkm_clk_init(struct nvkm_subdev *subdev)
clk->dstate = 0;
clk->pstate = -1;
clk->temp = 90; /* reasonable default value */
-   nvkm_pstate_calc(clk, true);
+   nvkm_clk_update(clk, true);
return 0;
 }

@@ -675,7 +681,7 @@ nvkm_clk_ctor(const struct nvkm_clk_func *func, struct 
nvkm_device *device,
clk->ustate_dc = -1;
clk->allow_reclock = allow_reclock;

-   INIT_WORK(>work, nvkm_pstate_work);
+   INIT_WORK(>work, nvkm_clk_update_work);
init_waitqueue_head(>wait);
atomic_set(>waiting, 0);



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


[Nouveau] [PATCH] drm/nouveau/led: prevent a possible use-after-free

2017-01-18 Thread Martin Peres
If the led class registration fails, we free drm->led but do not reset
it to NULL, which means that the suspend/resume/fini function will act
as if everything went well in init() and will likely crash the kernel.

This patch adds the missing drm->led = NULL.

Reported-by: Emmanuel Pescosta <emmanuelpescosta...@gmail.com>
Signed-off-by: Martin Peres <martin.pe...@free.fr>
---

Ben, I do not have a 4.10 kernel available to at least test-compile the
patch. Could you make sure it works before applying it? After all the
trouble we got from the LED before, I don't want to add another one!

 drm/nouveau/nouveau_led.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drm/nouveau/nouveau_led.c b/drm/nouveau/nouveau_led.c
index 72456b16..2c5e0628 100644
--- a/drm/nouveau/nouveau_led.c
+++ b/drm/nouveau/nouveau_led.c
@@ -102,6 +102,7 @@ nouveau_led_init(struct drm_device *dev)
ret = led_classdev_register(dev->dev, >led->led);
if (ret) {
kfree(drm->led);
+   drm->led = NULL;
return ret;
}
 
-- 
2.11.0

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


Re: [Nouveau] nouveau_drm.c: undefined reference to `nouveau_led_init'

2017-01-12 Thread Martin Peres

On 12/01/17 09:55, George Spelvin wrote:

If CONFIG_DRM_NOUVEAU=y and CONFIG_LEDS_CLASS=m, then nouveau_led.o is
neither stubbed out nor compiled in and the compile fails with undefined
symbols in nouveau_drm.c.

I'm guessing it's commit 8d021d71b324.  (Thanks for the cool hack, BTW,
even if I don't have such a card and am complaining about the patch.)

Worked around by setting CONFIG_NEW_LEDS=n (it had been forced on by
CONFIG_HID_WACOM=m, but I don't have a Wacom tablet) and recompiling.


Hey!

Yes, this is known. The fix is waiting in Ben's tree for it to land in 
4.10-rcX. Hopefully, we can all forget about this bug soon :)


Sorry for the annoyance,

Martin

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


[Nouveau] [PATCH] nouveau/led: prevent compiling the led-code if nouveau=y and leds=m

2016-12-06 Thread Martin Peres
The proper fix would have been to select LEDS_CLASS but this can lead
to a circular dependency, as found out by Arnd.

This patch implements Arnd's suggestion instead, at the cost of some
auto-magic for a fringe feature.

Cc: <sta...@vger.kernel.org> # 4.9.x-
Reported-by: Arnd Bergmann <a...@arndb.de>
Reported-by: Intel's 0-DAY
Fixes: 8d021d71b324 ("drm/nouveau/drm/nouveau: add a LED driver for the NVIDIA 
logo")
Signed-off-by: Martin Peres <martin.pe...@free.fr>
---
 drivers/gpu/drm/nouveau/nouveau_led.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_led.h 
b/drivers/gpu/drm/nouveau/nouveau_led.h
index 187ecdb..21a5775 100644
--- a/drivers/gpu/drm/nouveau/nouveau_led.h
+++ b/drivers/gpu/drm/nouveau/nouveau_led.h
@@ -42,7 +42,7 @@ nouveau_led(struct drm_device *dev)
 }
 
 /* nouveau_led.c */
-#if IS_ENABLED(CONFIG_LEDS_CLASS)
+#if IS_REACHABLE(CONFIG_LEDS_CLASS)
 int  nouveau_led_init(struct drm_device *dev);
 void nouveau_led_suspend(struct drm_device *dev);
 void nouveau_led_resume(struct drm_device *dev);
-- 
2.10.2

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


Re: [Nouveau] [PATCH] nouveau/led: introduce CONFIG_DRM_NOUVEAU_LEDS

2016-12-06 Thread Martin Peres

On 07/12/16 05:32, Martin Peres wrote:

This fixes the auto-magic detection of LEDS_CLASS by fixing the case
where nouveau would be built-in and the LEDS_CLASS would be built as
as module.

Cc: <sta...@vger.kernel.org> # 4.9.x-
Reported-by: Intel's 0-DAY
Signed-off-by: Martin Peres <martin.pe...@free.fr>
---
  drivers/gpu/drm/nouveau/Kbuild  | 2 +-
  drivers/gpu/drm/nouveau/Kconfig | 9 +
  2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/Kbuild b/drivers/gpu/drm/nouveau/Kbuild
index fde6e36..0935396 100644
--- a/drivers/gpu/drm/nouveau/Kbuild
+++ b/drivers/gpu/drm/nouveau/Kbuild
@@ -22,7 +22,7 @@ nouveau-$(CONFIG_DEBUG_FS) += nouveau_debugfs.o
  nouveau-y += nouveau_drm.o
  nouveau-y += nouveau_hwmon.o
  nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
-nouveau-$(CONFIG_LEDS_CLASS) += nouveau_led.o
+nouveau-$(CONFIG_DRM_NOUVEAU_LEDS) += nouveau_led.o
  nouveau-y += nouveau_nvif.o
  nouveau-$(CONFIG_NOUVEAU_PLATFORM_DRIVER) += nouveau_platform.o
  nouveau-y += nouveau_usif.o # userspace <-> nvif
diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig
index 2922a82..9dbb816 100644
--- a/drivers/gpu/drm/nouveau/Kconfig
+++ b/drivers/gpu/drm/nouveau/Kconfig
@@ -16,6 +16,7 @@ config DRM_NOUVEAU
select INPUT if ACPI && X86
select THERMAL if ACPI && X86
select ACPI_VIDEO if ACPI && X86
+   select LEDS_CLASS if DRM_NOUVEAU_LEDS
help
  Choose this option for open-source NVIDIA support.
  
@@ -62,3 +63,11 @@ config DRM_NOUVEAU_BACKLIGHT

help
  Say Y here if you want to control the backlight of your display
  (e.g. a laptop panel).
+
+config DRM_NOUVEAU_LEDS
+   bool "Support for high-end GPUs' NVIDIA-logo LED control"
+   depends on DRM_NOUVEAU
+   default y
+   help
+ Say Y here if you want to control the LED behind the NVIDIA logo on
+ high-end GPUs.


Cancel this,the thread "[PATCH] drm/nouveau: fix LEDS_CLASS=m 
configuration" on

DRI-devel explained why it was a bad idea (circular dependencies).

Will implement his proposal of using IS_REACHABLE instead of IS_DEFINED.

Martin

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


[Nouveau] [PATCH] nouveau/led: introduce CONFIG_DRM_NOUVEAU_LEDS

2016-12-06 Thread Martin Peres
This fixes the auto-magic detection of LEDS_CLASS by fixing the case
where nouveau would be built-in and the LEDS_CLASS would be built as
as module.

Cc: <sta...@vger.kernel.org> # 4.9.x-
Reported-by: Intel's 0-DAY
Signed-off-by: Martin Peres <martin.pe...@free.fr>
---
 drivers/gpu/drm/nouveau/Kbuild  | 2 +-
 drivers/gpu/drm/nouveau/Kconfig | 9 +
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/Kbuild b/drivers/gpu/drm/nouveau/Kbuild
index fde6e36..0935396 100644
--- a/drivers/gpu/drm/nouveau/Kbuild
+++ b/drivers/gpu/drm/nouveau/Kbuild
@@ -22,7 +22,7 @@ nouveau-$(CONFIG_DEBUG_FS) += nouveau_debugfs.o
 nouveau-y += nouveau_drm.o
 nouveau-y += nouveau_hwmon.o
 nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
-nouveau-$(CONFIG_LEDS_CLASS) += nouveau_led.o
+nouveau-$(CONFIG_DRM_NOUVEAU_LEDS) += nouveau_led.o
 nouveau-y += nouveau_nvif.o
 nouveau-$(CONFIG_NOUVEAU_PLATFORM_DRIVER) += nouveau_platform.o
 nouveau-y += nouveau_usif.o # userspace <-> nvif
diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig
index 2922a82..9dbb816 100644
--- a/drivers/gpu/drm/nouveau/Kconfig
+++ b/drivers/gpu/drm/nouveau/Kconfig
@@ -16,6 +16,7 @@ config DRM_NOUVEAU
select INPUT if ACPI && X86
select THERMAL if ACPI && X86
select ACPI_VIDEO if ACPI && X86
+   select LEDS_CLASS if DRM_NOUVEAU_LEDS
help
  Choose this option for open-source NVIDIA support.
 
@@ -62,3 +63,11 @@ config DRM_NOUVEAU_BACKLIGHT
help
  Say Y here if you want to control the backlight of your display
  (e.g. a laptop panel).
+
+config DRM_NOUVEAU_LEDS
+   bool "Support for high-end GPUs' NVIDIA-logo LED control"
+   depends on DRM_NOUVEAU
+   default y
+   help
+ Say Y here if you want to control the LED behind the NVIDIA logo on
+ high-end GPUs.
-- 
2.10.2

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


Re: [Nouveau] [PATCH] drm/nouveau: fix LEDS_CLASS=m configuration

2016-11-08 Thread Martin Peres

On 08/11/16 15:56, Arnd Bergmann wrote:

The newly introduced LED handling for nouveau fails to link when the
driver is built-in but the LED subsystem is a loadable module:

drivers/gpu/drm/nouveau/nouveau.o: In function `nouveau_do_suspend':
tvnv17.c:(.text.nouveau_do_suspend+0x10): undefined reference to 
`nouveau_led_suspend'
drivers/gpu/drm/nouveau/nouveau.o: In function `nouveau_do_resume':
tvnv17.c:(.text.nouveau_do_resume+0xf0): undefined reference to 
`nouveau_led_resume'
drivers/gpu/drm/nouveau/nouveau.o: In function `nouveau_drm_unload':
tvnv17.c:(.text.nouveau_drm_unload+0x34): undefined reference to 
`nouveau_led_fini'
drivers/gpu/drm/nouveau/nouveau.o: In function `nouveau_drm_load':
tvnv17.c:(.text.nouveau_drm_load+0x7d0): undefined reference to 
`nouveau_led_init'

This adds a separate Kconfig symbol for the LED support that
correctly tracks the dependencies.

Fixes: 8d021d71b324 ("drm/nouveau/drm/nouveau: add a LED driver for the NVIDIA 
logo")
Signed-off-by: Arnd Bergmann 
---
  drivers/gpu/drm/nouveau/Kbuild| 2 +-
  drivers/gpu/drm/nouveau/Kconfig   | 8 
  drivers/gpu/drm/nouveau/nouveau_led.h | 2 +-
  3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/Kbuild b/drivers/gpu/drm/nouveau/Kbuild
index fde6e3656636..5e00e911daa6 100644
--- a/drivers/gpu/drm/nouveau/Kbuild
+++ b/drivers/gpu/drm/nouveau/Kbuild
@@ -22,7 +22,7 @@ nouveau-$(CONFIG_DEBUG_FS) += nouveau_debugfs.o
  nouveau-y += nouveau_drm.o
  nouveau-y += nouveau_hwmon.o
  nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
-nouveau-$(CONFIG_LEDS_CLASS) += nouveau_led.o
+nouveau-$(CONFIG_DRM_NOUVEAU_LED) += nouveau_led.o
  nouveau-y += nouveau_nvif.o
  nouveau-$(CONFIG_NOUVEAU_PLATFORM_DRIVER) += nouveau_platform.o
  nouveau-y += nouveau_usif.o # userspace <-> nvif
diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig
index 78631fb61adf..715cd6f4dc31 100644
--- a/drivers/gpu/drm/nouveau/Kconfig
+++ b/drivers/gpu/drm/nouveau/Kconfig
@@ -46,6 +46,14 @@ config NOUVEAU_DEBUG
  The paranoia and spam levels will add a lot of extra checks which
  may potentially slow down driver operation.
  
+config DRM_NOUVEAU_LED

+   bool "Support for logo LED"
+   depends on DRM_NOUVEAU && LEDS_CLASS
+   depends on !(DRM_NOUVEAU=y && LEDS_CLASS=m)
+   help
+ Say Y here to enabling controlling the brightness of the
+ LED behind NVIDIA logo on certain Titan cards.


Titan is a little too specific and inaccurate. How about high-end cards?

As for the patch itself... I was going for the auto-magic approach but
apparently failed at it :s Sorry... I guess what I wanted to do was to
only enable the LED support if LEDS_CLASS=y.

Anyway, your approach is cleaner because it makes it easy for the user
to say if he/she wants to enable.

I will have a closer look at it later. Thanks anyway for reporting the 
issue!


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


Re: [Nouveau] [PATCH 3/3] hwmon: expose power_max and power_crit

2016-10-24 Thread Martin Peres

On 25/10/16 00:11, Karol Herbst wrote:

Signed-off-by: Karol Herbst 
---
 drm/nouveau/nouveau_hwmon.c | 44 
 1 file changed, 44 insertions(+)

diff --git a/drm/nouveau/nouveau_hwmon.c b/drm/nouveau/nouveau_hwmon.c
index 71f764b..3d4672a 100644
--- a/drm/nouveau/nouveau_hwmon.c
+++ b/drm/nouveau/nouveau_hwmon.c
@@ -596,6 +596,32 @@ nouveau_hwmon_get_power1_input(struct device *d, struct 
device_attribute *a,
 static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO,
  nouveau_hwmon_get_power1_input, NULL, 0);

+static ssize_t
+nouveau_hwmon_get_power1_max(struct device *d, struct device_attribute *a,
+char *buf)
+{
+   struct drm_device *dev = dev_get_drvdata(d);
+   struct nouveau_drm *drm = nouveau_drm(dev);
+   struct nvkm_iccsense *iccsense = nvxx_iccsense(>device);
+   return sprintf(buf, "%i\n", iccsense->power_w_max);
+}
+
+static SENSOR_DEVICE_ATTR(power1_max, S_IRUGO,
+ nouveau_hwmon_get_power1_max, NULL, 0);
+
+static ssize_t
+nouveau_hwmon_get_power1_crit(struct device *d, struct device_attribute *a,
+ char *buf)
+{
+   struct drm_device *dev = dev_get_drvdata(d);
+   struct nouveau_drm *drm = nouveau_drm(dev);
+   struct nvkm_iccsense *iccsense = nvxx_iccsense(>device);
+   return sprintf(buf, "%i\n", iccsense->power_w_crit);
+}
+
+static SENSOR_DEVICE_ATTR(power1_crit, S_IRUGO,
+ nouveau_hwmon_get_power1_crit, NULL, 0);
+
 static struct attribute *hwmon_default_attributes[] = {
_dev_attr_name.dev_attr.attr,
_dev_attr_update_rate.dev_attr.attr,
@@ -639,6 +665,12 @@ static struct attribute *hwmon_power_attributes[] = {
NULL
 };

+static struct attribute *hwmon_power_caps_attributes[] = {
+   _dev_attr_power1_max.dev_attr.attr,
+   _dev_attr_power1_crit.dev_attr.attr,
+   NULL
+};
+
 static const struct attribute_group hwmon_default_attrgroup = {
.attrs = hwmon_default_attributes,
 };
@@ -657,6 +689,9 @@ static const struct attribute_group hwmon_in0_attrgroup = {
 static const struct attribute_group hwmon_power_attrgroup = {
.attrs = hwmon_power_attributes,
 };
+static const struct attribute_group hwmon_power_caps_attrgroup = {
+   .attrs = hwmon_power_caps_attributes,
+};
 #endif

 int
@@ -728,8 +763,16 @@ nouveau_hwmon_init(struct drm_device *dev)
if (iccsense && iccsense->data_valid && !list_empty(>rails)) {
ret = sysfs_create_group(_dev->kobj,
 _power_attrgroup);
+
if (ret)
goto error;
+
+   if (iccsense->power_w_max && iccsense->power_w_crit) {
+   ret = sysfs_create_group(_dev->kobj,
+_power_caps_attrgroup);
+   if (ret)
+   goto error;
+   }
}

hwmon->hwmon = hwmon_dev;
@@ -759,6 +802,7 @@ nouveau_hwmon_fini(struct drm_device *dev)
sysfs_remove_group(>hwmon->kobj, 
_fan_rpm_attrgroup);
sysfs_remove_group(>hwmon->kobj, _in0_attrgroup);
sysfs_remove_group(>hwmon->kobj, _power_attrgroup);
+   sysfs_remove_group(>hwmon->kobj, 
_power_caps_attrgroup);

hwmon_device_unregister(hwmon->hwmon);
}



So, you wanted to make a cache because you felt you may want to let the 
user edit the values?


Not sure we should ever allow this :s At least, a RO file is a very good 
idea to help debugging and just letting the user know about such 
limitations.


So, in my opinion, I think we should just kill patch 2 and use directly 
the output of the bios table here. Maybe you can write a helper function 
in patch 1 to get the min, avg and max values and return -1 if it is not 
valid? This way, you can access this info very easily in multiple places 
without duplicating this 0xff check.



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


Re: [Nouveau] [PATCH 2/3] subdev/iccsense: Parse max and crit power level

2016-10-24 Thread Martin Peres

On 25/10/16 00:11, Karol Herbst wrote:

Signed-off-by: Karol Herbst 
---
 drm/nouveau/include/nvkm/subdev/iccsense.h |  3 +++
 drm/nouveau/nvkm/subdev/iccsense/base.c| 13 -
 2 files changed, 15 insertions(+), 1 deletion(-)


What is the point of duplicating values here? Just store the parsed bios 
table, like we do for fan management.


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


Re: [Nouveau] [PATCH 1/3] nvbios/power_budget: Add basic power budget parsing

2016-10-24 Thread Martin Peres

On 25/10/16 00:11, Karol Herbst wrote:

Signed-off-by: Karol Herbst 
---
 .../include/nvkm/subdev/bios/power_budget.h|  20 
 drm/nouveau/nvkm/subdev/bios/Kbuild|   1 +
 drm/nouveau/nvkm/subdev/bios/power_budget.c| 108 +
 3 files changed, 129 insertions(+)
 create mode 100644 drm/nouveau/include/nvkm/subdev/bios/power_budget.h
 create mode 100644 drm/nouveau/nvkm/subdev/bios/power_budget.c

diff --git a/drm/nouveau/include/nvkm/subdev/bios/power_budget.h 
b/drm/nouveau/include/nvkm/subdev/bios/power_budget.h
new file mode 100644
index 000..dd65c08
--- /dev/null
+++ b/drm/nouveau/include/nvkm/subdev/bios/power_budget.h
@@ -0,0 +1,20 @@
+#ifndef __NVBIOS_POWER_BUDGET_H__
+#define __NVBIOS_POWER_BUDGET_H__
+
+#include 
+
+struct nvbios_power_budget_entry {
+   u32 min_w;
+   u32 avg_w;
+   u32 max_w;
+};
+
+struct nvbios_power_budget {
+   u8  nr_entry;
+   u8  cap_entry;
+   struct nvbios_power_budget_entry *entries;
+};
+
+int nvbios_power_budget_parse(struct nvkm_bios *, struct nvbios_power_budget 
*);
+
+#endif
diff --git a/drm/nouveau/nvkm/subdev/bios/Kbuild 
b/drm/nouveau/nvkm/subdev/bios/Kbuild
index be57220..6b4f1e0 100644
--- a/drm/nouveau/nvkm/subdev/bios/Kbuild
+++ b/drm/nouveau/nvkm/subdev/bios/Kbuild
@@ -19,6 +19,7 @@ nvkm-y += nvkm/subdev/bios/pcir.o
 nvkm-y += nvkm/subdev/bios/perf.o
 nvkm-y += nvkm/subdev/bios/pll.o
 nvkm-y += nvkm/subdev/bios/pmu.o
+nvkm-y += nvkm/subdev/bios/power_budget.o
 nvkm-y += nvkm/subdev/bios/ramcfg.o
 nvkm-y += nvkm/subdev/bios/rammap.o
 nvkm-y += nvkm/subdev/bios/shadow.o
diff --git a/drm/nouveau/nvkm/subdev/bios/power_budget.c 
b/drm/nouveau/nvkm/subdev/bios/power_budget.c
new file mode 100644
index 000..538497b
--- /dev/null
+++ b/drm/nouveau/nvkm/subdev/bios/power_budget.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2015 Karol Herbst
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Karol Herbst
+ */
+#include 
+#include 
+#include 
+
+static u32
+nvbios_power_budget_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt,
+ u8 *len)
+{
+   struct bit_entry bit_P;
+   u32 power_budget;
+
+   if (bit_entry(bios, 'P', _P) || bit_P.version != 2 ||
+   bit_P.length < 0x2c)
+   return 0;
+
+   power_budget = nvbios_rd32(bios, bit_P.offset + 0x2c);
+   if (!power_budget)
+   return 0;
+
+   *ver = nvbios_rd08(bios, power_budget);
+   switch (*ver) {
+   case 0x10:
+   case 0x20:
+   case 0x30:
+   *hdr = nvbios_rd08(bios, power_budget + 0x1);
+   *len = nvbios_rd08(bios, power_budget + 0x2);
+   *cnt = nvbios_rd08(bios, power_budget + 0x3);
+   return power_budget;
+   default:
+   break;
+   }
+
+   return 0;
+}
+
+int
+nvbios_power_budget_parse(struct nvkm_bios *bios, struct nvbios_power_budget 
*budget)
+{
+   struct nvkm_subdev *subdev = >subdev;
+   u8 ver, hdr, cnt, len, i, cap_entry;
+   u32 header;
+
+   header = nvbios_power_budget_table(bios, , , , );
+   if (!header || !cnt)
+   return -ENODEV;
+
+   budget->entries = kmalloc_array(cnt, sizeof(*budget->entries), 
GFP_KERNEL);
+   if (!budget->entries)
+   return -ENOMEM;
+
+   budget->nr_entry = cnt;
+   switch (ver) {
+   case 0x20:
+   cap_entry = nvbios_rd08(bios, header + 0x9);
+   break;
+   default:
+   cap_entry = 0;


Are you sure about this? How about setting it to 0xff instead?


+   }
+
+   if (cap_entry < cnt)
+   budget->cap_entry = cap_entry;
+   else {
+   if (cap_entry != 0xff)
+   nvkm_warn(subdev,
+ "invalid cap_entry in power budget table 
found\n");
+   budget->cap_entry = 

Re: [Nouveau] RFC [PATCH 0/3] Expose power budget cap via hwmon

2016-10-24 Thread Martin Peres

On 25/10/16 00:11, Karol Herbst wrote:

There is an optinal header field in the power budget table we can use to
read out the power cap of the GPU.

Sadly it is optional and if that field isn't sad, things beome


oh why would it be sad? Poor little one :p


complicated.

Anyhow, this is good enough for most cards and we can use it later for
capping the power consumption of the GPUs, but first, just export those
values through hwmon.

First design, will change stuff, want comments. Thanks.


Thanks for doing this!



Karol Herbst (3):
  nvbios/power_budget: Add basic power budget parsing
  subdev/iccsense: Parse max and crit power level
  hwmon: expose power_max and power_crit

 .../include/nvkm/subdev/bios/power_budget.h|  20 
 drm/nouveau/include/nvkm/subdev/iccsense.h |   3 +
 drm/nouveau/nouveau_hwmon.c|  44 +
 drm/nouveau/nvkm/subdev/bios/Kbuild|   1 +
 drm/nouveau/nvkm/subdev/bios/power_budget.c| 108 +
 drm/nouveau/nvkm/subdev/iccsense/base.c|  13 ++-
 6 files changed, 188 insertions(+), 1 deletion(-)
 create mode 100644 drm/nouveau/include/nvkm/subdev/bios/power_budget.h
 create mode 100644 drm/nouveau/nvkm/subdev/bios/power_budget.c



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


Re: [Nouveau] [PATCH 5/5] recognize and accelerate GM20x

2016-10-19 Thread Martin Peres

On 18/10/16 12:19, Alexandre Courbot wrote:

On Mon, Oct 17, 2016 at 6:47 PM, Samuel Pitoiset
 wrote:

This requires at least a quick test. :-)

Acked-by: Samuel Pitoiset 


On 10/16/2016 09:14 PM, Ilia Mirkin wrote:

Signed-off-by: Ilia Mirkin 
---

Untested. I don't have the hardware.

Tested on GM206, working great so far!

The series:
Tested-by: Alexandre Courbot 

What about the glyph issues you reported? Fixed by a new version?

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


[Nouveau] [PATCH] drm/therm/fan: add a fallback if no fan control is specified in the vbios

2016-09-28 Thread Martin Peres
This seems to be absolutely necessary for a lot of NV40.

Reported-by: gsgf on IRC/freenode
Signed-off-by: Martin Peres <martin.pe...@free.fr>
---
 drm/nouveau/nvkm/subdev/therm/base.c | 22 +++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/drm/nouveau/nvkm/subdev/therm/base.c 
b/drm/nouveau/nvkm/subdev/therm/base.c
index 8894fee..df949fa 100644
--- a/drm/nouveau/nvkm/subdev/therm/base.c
+++ b/drm/nouveau/nvkm/subdev/therm/base.c
@@ -64,10 +64,9 @@ nvkm_therm_update_trip(struct nvkm_therm *therm)
 }
 
 static int
-nvkm_therm_update_linear(struct nvkm_therm *therm)
+nvkm_therm_compute_linear_duty(struct nvkm_therm *therm, u8 linear_min_temp,
+   u8 linear_max_temp)
 {
-   u8  linear_min_temp = therm->fan->bios.linear_min_temp;
-   u8  linear_max_temp = therm->fan->bios.linear_max_temp;
u8  temp = therm->func->temp_get(therm);
u16 duty;
 
@@ -85,6 +84,21 @@ nvkm_therm_update_linear(struct nvkm_therm *therm)
return duty;
 }
 
+static int
+nvkm_therm_update_linear(struct nvkm_therm *therm)
+{
+   u8  min = therm->fan->bios.linear_min_temp;
+   u8  max = therm->fan->bios.linear_max_temp;
+   return nvkm_therm_compute_linear_duty(therm, min, max);
+}
+
+static int
+nvkm_therm_update_linear_fallback(struct nvkm_therm *therm)
+{
+   u8 max = therm->bios_sensor.thrs_fan_boost.temp;
+   return nvkm_therm_compute_linear_duty(therm, 30, max);
+}
+
 static void
 nvkm_therm_update(struct nvkm_therm *therm, int mode)
 {
@@ -119,6 +133,8 @@ nvkm_therm_update(struct nvkm_therm *therm, int mode)
case NVBIOS_THERM_FAN_OTHER:
if (therm->cstate)
duty = therm->cstate;
+   else
+   duty = nvkm_therm_update_linear_fallback(therm);
poll = false;
break;
}
-- 
2.8.0

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


Re: [Nouveau] [PATCH 1/2] Revert "bus: remove cpu_coherent flag"

2016-09-19 Thread Martin Peres

On 19/09/16 06:50, Alexandre Courbot wrote:

On Mon, Sep 19, 2016 at 12:43 PM, Ilia Mirkin  wrote:

On Sun, Sep 18, 2016 at 11:39 PM, Alexandre Courbot  wrote:

On Sun, Sep 18, 2016 at 7:21 PM, Karol Herbst  wrote:

This reverts commit 01bbcb69f80e1058395b737ae399c6f4ef48691b.

I think you meant aff51175cdbf345740ec9203eff88e772af88059 - that's
the commit id that matters, not the one in Ben's non-linux repo.


The commit caused fence timeouts within nvc0_screen_destroy and most likely
other places as well.

The most obvious effect is, that userspace processes take minutes to actually
quit.

Acked-by: Alexandre Courbot 

If this doesn't make it into v4.8 (which is due to be released in a
week), it should get tagged for stable as well.

By the way, Alexandre, I believe Martin was reporting issues like this
on his TK1 before this change as well. Probably worth investigating -
sounds like there's a wider issue with TTM_PL_FLAG_UNCACHED and/or
force_coherent.

Yes, it may be indeed related. I need to sync with Martin to
understand his exact repro case.


Running piglit on the tk1 is enough for me, but I will try to update the 
kernel again to see if it helps.


The issue is that mesa is waiting on a fence that never gets synced on 
in the gbm destructor. The probably of having the timeout is about 
50/50, so it is easy-enough to reproduce in my case :s


Martin

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


[Nouveau] [PATCH] drm/nouveau/led: make all the stub functions static inline

2016-09-17 Thread Martin Peres
Suggested-by: Ilia Mirkin <imir...@alum.mit.edu>
Signed-off-by: Martin Peres <martin.pe...@free.fr>
---
 drm/nouveau/nouveau_led.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drm/nouveau/nouveau_led.h b/drm/nouveau/nouveau_led.h
index 750a0d9..187ecdb 100644
--- a/drm/nouveau/nouveau_led.h
+++ b/drm/nouveau/nouveau_led.h
@@ -49,9 +49,9 @@ void nouveau_led_resume(struct drm_device *dev);
 void nouveau_led_fini(struct drm_device *dev);
 #else
 static inline int  nouveau_led_init(struct drm_device *dev) { return 0; };
-void nouveau_led_suspend(struct drm_device *dev) { return; };
-void nouveau_led_resume(struct drm_device *dev) { return; };
-void nouveau_led_fini(struct drm_device *dev) { return; };
+static inline void nouveau_led_suspend(struct drm_device *dev) { };
+static inline void nouveau_led_resume(struct drm_device *dev) { };
+static inline void nouveau_led_fini(struct drm_device *dev) { };
 #endif
 
 #endif
-- 
2.8.0

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


Re: [Nouveau] [PATCH 2/3] drm/nouveau/led: guard against a division by 0

2016-09-16 Thread Martin Peres

On 16/09/16 10:42, Karol Herbst wrote:

Reviewed-by: Karol Herbst <karolher...@gmail.com>

2016-09-16 9:34 GMT+02:00 Martin Peres <martin.pe...@free.fr>:

Signed-off-by: Martin Peres <martin.pe...@free.fr>
---
  drm/nouveau/nouveau_led.c | 5 -
  1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drm/nouveau/nouveau_led.c b/drm/nouveau/nouveau_led.c
index 5e28b5f..1f731da 100644
--- a/drm/nouveau/nouveau_led.c
+++ b/drm/nouveau/nouveau_led.c
@@ -44,7 +44,10 @@ nouveau_led_get_brightness(struct led_classdev *led)
 div =  nvif_rd32(device, 0x61c880) & 0x00ff;
 duty = nvif_rd32(device, 0x61c884) & 0x00ff;

-   return duty * LED_FULL / div;
+   if (div > 0)
+   return duty * LED_FULL / div;
+   else
+   return 0;

minor nitpick: you can drop the else, I don't mind though. Maybe it
would be clearer to do it the other way around though.

Or to do:

if (unlikely(div <= 0)) return 0;
return duty * LED_FULL / div;


The unlikely is a good idea, not a fan of single lines if conditions 
though :s

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


[Nouveau] [PATCH 3/3] drm/nouveau/led: abort early if the device does not have GPIOs

2016-09-16 Thread Martin Peres
Signed-off-by: Martin Peres <martin.pe...@free.fr>
---
 drm/nouveau/nouveau_led.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drm/nouveau/nouveau_led.c b/drm/nouveau/nouveau_led.c
index 1f731da..3e2f1b6 100644
--- a/drm/nouveau/nouveau_led.c
+++ b/drm/nouveau/nouveau_led.c
@@ -82,6 +82,9 @@ nouveau_led_init(struct drm_device *dev)
struct dcb_gpio_func logo_led;
int ret;
 
+   if (!gpio)
+   return 0;
+
/* check that there is a GPIO controlling the logo LED */
if (nvkm_gpio_find(gpio, 0, DCB_GPIO_LOGO_LED_PWM, 0xff, _led))
return 0;
-- 
2.8.0

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


[Nouveau] [PATCH 1/3] drm/nouveau/led: don't access led subdev if it wasn't initialized

2016-09-16 Thread Martin Peres
From: Karol Herbst 

Fixes a kernel crash on suspend/resume.
---
 drm/nouveau/nouveau_led.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drm/nouveau/nouveau_led.c b/drm/nouveau/nouveau_led.c
index 9eed5a6..5e28b5f 100644
--- a/drm/nouveau/nouveau_led.c
+++ b/drm/nouveau/nouveau_led.c
@@ -107,7 +107,8 @@ nouveau_led_suspend(struct drm_device *dev)
 {
struct nouveau_drm *drm = nouveau_drm(dev);
 
-   led_classdev_suspend(>led->led);
+   if (drm->led)
+   led_classdev_suspend(>led->led);
 }
 
 void
@@ -115,8 +116,8 @@ nouveau_led_resume(struct drm_device *dev)
 {
struct nouveau_drm *drm = nouveau_drm(dev);
 
-   led_classdev_resume(>led->led);
-
+   if (drm->led)
+   led_classdev_resume(>led->led);
 }
 
 void
-- 
2.8.0

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


[Nouveau] [PATCH 2/3] drm/nouveau/led: guard against a division by 0

2016-09-16 Thread Martin Peres
Signed-off-by: Martin Peres <martin.pe...@free.fr>
---
 drm/nouveau/nouveau_led.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drm/nouveau/nouveau_led.c b/drm/nouveau/nouveau_led.c
index 5e28b5f..1f731da 100644
--- a/drm/nouveau/nouveau_led.c
+++ b/drm/nouveau/nouveau_led.c
@@ -44,7 +44,10 @@ nouveau_led_get_brightness(struct led_classdev *led)
div =  nvif_rd32(device, 0x61c880) & 0x00ff;
duty = nvif_rd32(device, 0x61c884) & 0x00ff;
 
-   return duty * LED_FULL / div;
+   if (div > 0)
+   return duty * LED_FULL / div;
+   else
+   return 0;
 }
 
 static void
-- 
2.8.0

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


[Nouveau] [PATCH v3 take 2] drm/nouveau: add a LED driver for the NVIDIA logo

2016-08-24 Thread Martin Peres
We received a donation of a Titan which has this useless feature
allowing users to control the brightness of the LED behind the
logo of NVIDIA. In the true spirit of open source, let's expose
that to the users of very expensive cards!

This patch hooks up this LED/PWM to the LED subsystem which allows
blinking it in sync with cpu/disk/network/whatever activity (heartbeat
is quite nice!). Users may also implement some breathing effect or
morse code support in the userspace if they feel like it.

v2:
 - surround the use of the LED framework with ifdef CONFIG_LEDS_CLASS

v3:
 - avoid using ifdefs everywhere, follow the recommendations of
   /doc/Documentation/CodingStyle. Suggested by Emil Velikov.

Signed-off-by: Martin Peres <martin.pe...@free.fr>
---

I again managed to send the wrong patch...

I guess porting patches between kernels and then scp'ing at 4am is not
something I should be doing. Sorry *again* for the noise!

This time, it looks sane though and actually follows what Emil
suggested!

 drm/nouveau/Kbuild  |   1 +
 drm/nouveau/include/nvkm/subdev/bios/gpio.h |   1 +
 drm/nouveau/nouveau_drm.c   |   7 ++
 drm/nouveau/nouveau_drv.h   |   3 +
 drm/nouveau/nouveau_led.c   | 132 
 drm/nouveau/nouveau_led.h   |  57 
 6 files changed, 201 insertions(+)
 create mode 100644 drm/nouveau/nouveau_led.c
 create mode 100644 drm/nouveau/nouveau_led.h

diff --git a/drm/nouveau/Kbuild b/drm/nouveau/Kbuild
index 2527bf4..fde6e36 100644
--- a/drm/nouveau/Kbuild
+++ b/drm/nouveau/Kbuild
@@ -22,6 +22,7 @@ nouveau-$(CONFIG_DEBUG_FS) += nouveau_debugfs.o
 nouveau-y += nouveau_drm.o
 nouveau-y += nouveau_hwmon.o
 nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
+nouveau-$(CONFIG_LEDS_CLASS) += nouveau_led.o
 nouveau-y += nouveau_nvif.o
 nouveau-$(CONFIG_NOUVEAU_PLATFORM_DRIVER) += nouveau_platform.o
 nouveau-y += nouveau_usif.o # userspace <-> nvif
diff --git a/drm/nouveau/include/nvkm/subdev/bios/gpio.h 
b/drm/nouveau/include/nvkm/subdev/bios/gpio.h
index a47d46d..b7a54e6 100644
--- a/drm/nouveau/include/nvkm/subdev/bios/gpio.h
+++ b/drm/nouveau/include/nvkm/subdev/bios/gpio.h
@@ -6,6 +6,7 @@ enum dcb_gpio_func_name {
DCB_GPIO_TVDAC1 = 0x2d,
DCB_GPIO_FAN = 0x09,
DCB_GPIO_FAN_SENSE = 0x3d,
+   DCB_GPIO_LOGO_LED_PWM = 0x84,
DCB_GPIO_UNUSED = 0xff,
DCB_GPIO_VID0 = 0x04,
DCB_GPIO_VID1 = 0x05,
diff --git a/drm/nouveau/nouveau_drm.c b/drm/nouveau/nouveau_drm.c
index 66c1280..0f16652 100644
--- a/drm/nouveau/nouveau_drm.c
+++ b/drm/nouveau/nouveau_drm.c
@@ -47,6 +47,7 @@
 #include "nouveau_ttm.h"
 #include "nouveau_gem.h"
 #include "nouveau_vga.h"
+#include "nouveau_led.h"
 #include "nouveau_hwmon.h"
 #include "nouveau_acpi.h"
 #include "nouveau_bios.h"
@@ -475,6 +476,7 @@ nouveau_drm_load(struct drm_device *dev, unsigned long 
flags)
nouveau_hwmon_init(dev);
nouveau_accel_init(drm);
nouveau_fbcon_init(dev);
+   nouveau_led_init(dev);
 
if (nouveau_runtime_pm != 0) {
pm_runtime_use_autosuspend(dev->dev);
@@ -510,6 +512,7 @@ nouveau_drm_unload(struct drm_device *dev)
pm_runtime_forbid(dev->dev);
}
 
+   nouveau_led_fini(dev);
nouveau_fbcon_fini(dev);
nouveau_accel_fini(drm);
nouveau_hwmon_fini(dev);
@@ -561,6 +564,8 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime)
struct nouveau_cli *cli;
int ret;
 
+   nouveau_led_suspend(dev);
+
if (dev->mode_config.num_crtc) {
NV_INFO(drm, "suspending console...\n");
nouveau_fbcon_set_suspend(dev, 1);
@@ -649,6 +654,8 @@ nouveau_do_resume(struct drm_device *dev, bool runtime)
nouveau_fbcon_set_suspend(dev, 0);
}
 
+   nouveau_led_resume(dev);
+
return 0;
 }
 
diff --git a/drm/nouveau/nouveau_drv.h b/drm/nouveau/nouveau_drv.h
index 822a021..c0e2b32 100644
--- a/drm/nouveau/nouveau_drv.h
+++ b/drm/nouveau/nouveau_drv.h
@@ -166,6 +166,9 @@ struct nouveau_drm {
struct nouveau_hwmon *hwmon;
struct nouveau_debugfs *debugfs;
 
+   /* led management */
+   struct nouveau_led *led;
+
/* display power reference */
bool have_disp_power_ref;
 
diff --git a/drm/nouveau/nouveau_led.c b/drm/nouveau/nouveau_led.c
new file mode 100644
index 000..9eed5a6
--- /dev/null
+++ b/drm/nouveau/nouveau_led.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2016 Martin Peres
+ *
+ * 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, an

[Nouveau] [PATCH v3] drm/nouveau: add a LED driver for the NVIDIA logo

2016-08-24 Thread Martin Peres
We received a donation of a Titan which has this useless feature
allowing users to control the brightness of the LED behind the
logo of NVIDIA. In the true spirit of open source, let's expose
that to the users of very expensive cards!

This patch hooks up this LED/PWM to the LED subsystem which allows
blinking it in sync with cpu/disk/network/whatever activity (heartbeat
is quite nice!). Users may also implement some breathing effect or
morse code support in the userspace if they feel like it.

v2:
 - surround the use of the LED framework with ifdef CONFIG_LEDS_CLASS

v3:
 - avoid using ifdefs everywhere, follow the recommendations of
   /doc/Documentation/CodingStyle. Suggested by Emil Velikov.

Reviewed-by: Karol Herbst <karolher...@gmail.com>
Signed-off-by: Martin Peres <martin.pe...@free.fr>
---
 drm/nouveau/Kbuild  |   1 +
 drm/nouveau/include/nvkm/subdev/bios/gpio.h |   1 +
 drm/nouveau/nouveau_drm.c   |   7 ++
 drm/nouveau/nouveau_drv.h   |   3 +
 drm/nouveau/nouveau_led.c   | 148 
 drm/nouveau/nouveau_led.h   |  50 ++
 6 files changed, 210 insertions(+)
 create mode 100644 drm/nouveau/nouveau_led.c
 create mode 100644 drm/nouveau/nouveau_led.h

diff --git a/drm/nouveau/Kbuild b/drm/nouveau/Kbuild
index 2527bf4..312bca9 100644
--- a/drm/nouveau/Kbuild
+++ b/drm/nouveau/Kbuild
@@ -22,6 +22,7 @@ nouveau-$(CONFIG_DEBUG_FS) += nouveau_debugfs.o
 nouveau-y += nouveau_drm.o
 nouveau-y += nouveau_hwmon.o
 nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
+nouveau-y += nouveau_led.o
 nouveau-y += nouveau_nvif.o
 nouveau-$(CONFIG_NOUVEAU_PLATFORM_DRIVER) += nouveau_platform.o
 nouveau-y += nouveau_usif.o # userspace <-> nvif
diff --git a/drm/nouveau/include/nvkm/subdev/bios/gpio.h 
b/drm/nouveau/include/nvkm/subdev/bios/gpio.h
index a47d46d..b7a54e6 100644
--- a/drm/nouveau/include/nvkm/subdev/bios/gpio.h
+++ b/drm/nouveau/include/nvkm/subdev/bios/gpio.h
@@ -6,6 +6,7 @@ enum dcb_gpio_func_name {
DCB_GPIO_TVDAC1 = 0x2d,
DCB_GPIO_FAN = 0x09,
DCB_GPIO_FAN_SENSE = 0x3d,
+   DCB_GPIO_LOGO_LED_PWM = 0x84,
DCB_GPIO_UNUSED = 0xff,
DCB_GPIO_VID0 = 0x04,
DCB_GPIO_VID1 = 0x05,
diff --git a/drm/nouveau/nouveau_drm.c b/drm/nouveau/nouveau_drm.c
index 66c1280..0f16652 100644
--- a/drm/nouveau/nouveau_drm.c
+++ b/drm/nouveau/nouveau_drm.c
@@ -47,6 +47,7 @@
 #include "nouveau_ttm.h"
 #include "nouveau_gem.h"
 #include "nouveau_vga.h"
+#include "nouveau_led.h"
 #include "nouveau_hwmon.h"
 #include "nouveau_acpi.h"
 #include "nouveau_bios.h"
@@ -475,6 +476,7 @@ nouveau_drm_load(struct drm_device *dev, unsigned long 
flags)
nouveau_hwmon_init(dev);
nouveau_accel_init(drm);
nouveau_fbcon_init(dev);
+   nouveau_led_init(dev);
 
if (nouveau_runtime_pm != 0) {
pm_runtime_use_autosuspend(dev->dev);
@@ -510,6 +512,7 @@ nouveau_drm_unload(struct drm_device *dev)
pm_runtime_forbid(dev->dev);
}
 
+   nouveau_led_fini(dev);
nouveau_fbcon_fini(dev);
nouveau_accel_fini(drm);
nouveau_hwmon_fini(dev);
@@ -561,6 +564,8 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime)
struct nouveau_cli *cli;
int ret;
 
+   nouveau_led_suspend(dev);
+
if (dev->mode_config.num_crtc) {
NV_INFO(drm, "suspending console...\n");
nouveau_fbcon_set_suspend(dev, 1);
@@ -649,6 +654,8 @@ nouveau_do_resume(struct drm_device *dev, bool runtime)
nouveau_fbcon_set_suspend(dev, 0);
}
 
+   nouveau_led_resume(dev);
+
return 0;
 }
 
diff --git a/drm/nouveau/nouveau_drv.h b/drm/nouveau/nouveau_drv.h
index 822a021..c0e2b32 100644
--- a/drm/nouveau/nouveau_drv.h
+++ b/drm/nouveau/nouveau_drv.h
@@ -166,6 +166,9 @@ struct nouveau_drm {
struct nouveau_hwmon *hwmon;
struct nouveau_debugfs *debugfs;
 
+   /* led management */
+   struct nouveau_led *led;
+
/* display power reference */
bool have_disp_power_ref;
 
diff --git a/drm/nouveau/nouveau_led.c b/drm/nouveau/nouveau_led.c
new file mode 100644
index 000..824a9c6
--- /dev/null
+++ b/drm/nouveau/nouveau_led.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2016 Martin Peres
+ *
+ * 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 

Re: [Nouveau] [PATCH v2] drm/nouveau: add a LED driver for the NVIDIA logo

2016-08-24 Thread Martin Peres

On 23/08/16 17:43, Emil Velikov wrote:

On 23 August 2016 at 00:42, Martin Peres <martin.pe...@free.fr> wrote:

v2:
  - guard LED framework calls with ifdef CONFIG_LEDS_CLASS


IIRC kernel has the tendency of using static inlines in the headers
when CONFIG_foo is not set. Worth using that and removing the ifdef
from the source file ?


Oh, you mean, re-defining the functions I use but make them do nothing.

However, I should do it in the source file and not in the header since I do
not want to export these symbols outside of the object.

Do you have an example to share? Anyway, this seems like a good
candidate to reduce the number of ifdefs. Thanks!

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


Re: [Nouveau] [PATCH v2] drm/nouveau: add a LED driver for the NVIDIA logo

2016-08-23 Thread Martin Peres

On 23/08/16 11:31, Karol Herbst wrote:

maybe it makes sense to expose the SLI LED, too.

Regardless of my comments this patch is reviewed-by me.


You reviewed the wrong patch, I should have named the re-send v3.

I accidentally sent the v1 patch as a v2 :s



2016-08-23 1:39 GMT+02:00 Martin Peres <martin.pe...@free.fr>:

We received a donation of a Titan which has this useless feature
allowing users to control the brightness of the LED behind the
logo of NVIDIA. In the true spirit of open source, let's expose
that to the users of very expensive cards!

This patch hooks up this LED/PWM to the LED subsystem which allows
blinking it in sync with cpu/disk/network/whatever activity (heartbeat
is quite nice!). Users may also implement some breathing effect or
morse code support in the userspace if they feel like it.

Signed-off-by: Martin Peres <martin.pe...@free.fr>
---
  drm/nouveau/Kbuild  |   1 +
  drm/nouveau/include/nvkm/subdev/bios/gpio.h |   1 +
  drm/nouveau/nouveau_drm.c   |   7 ++
  drm/nouveau/nouveau_drm.h   |   3 +
  drm/nouveau/nouveau_led.c   | 131 
  drm/nouveau/nouveau_led.h   |  48 ++
  6 files changed, 191 insertions(+)
  create mode 100644 drm/nouveau/nouveau_led.c
  create mode 100644 drm/nouveau/nouveau_led.h

diff --git a/drm/nouveau/Kbuild b/drm/nouveau/Kbuild
index 2527bf4..312bca9 100644
--- a/drm/nouveau/Kbuild
+++ b/drm/nouveau/Kbuild
@@ -22,6 +22,7 @@ nouveau-$(CONFIG_DEBUG_FS) += nouveau_debugfs.o
  nouveau-y += nouveau_drm.o
  nouveau-y += nouveau_hwmon.o
  nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
+nouveau-y += nouveau_led.o
  nouveau-y += nouveau_nvif.o
  nouveau-$(CONFIG_NOUVEAU_PLATFORM_DRIVER) += nouveau_platform.o
  nouveau-y += nouveau_usif.o # userspace <-> nvif
diff --git a/drm/nouveau/include/nvkm/subdev/bios/gpio.h 
b/drm/nouveau/include/nvkm/subdev/bios/gpio.h
index a47d46d..b7a54e6 100644
--- a/drm/nouveau/include/nvkm/subdev/bios/gpio.h
+++ b/drm/nouveau/include/nvkm/subdev/bios/gpio.h
@@ -6,6 +6,7 @@ enum dcb_gpio_func_name {
 DCB_GPIO_TVDAC1 = 0x2d,
 DCB_GPIO_FAN = 0x09,
 DCB_GPIO_FAN_SENSE = 0x3d,
+   DCB_GPIO_LOGO_LED_PWM = 0x84,
 DCB_GPIO_UNUSED = 0xff,
 DCB_GPIO_VID0 = 0x04,
 DCB_GPIO_VID1 = 0x05,
diff --git a/drm/nouveau/nouveau_drm.c b/drm/nouveau/nouveau_drm.c
index d06877d..dc97401 100644
--- a/drm/nouveau/nouveau_drm.c
+++ b/drm/nouveau/nouveau_drm.c
@@ -49,6 +49,7 @@
  #include "nouveau_ttm.h"
  #include "nouveau_gem.h"
  #include "nouveau_vga.h"
+#include "nouveau_led.h"
  #include "nouveau_hwmon.h"
  #include "nouveau_acpi.h"
  #include "nouveau_bios.h"
@@ -468,6 +469,7 @@ nouveau_drm_load(struct drm_device *dev, unsigned long 
flags)
 nouveau_hwmon_init(dev);
 nouveau_accel_init(drm);
 nouveau_fbcon_init(dev);
+   nouveau_led_init(dev);

 if (nouveau_runtime_pm != 0) {
 pm_runtime_use_autosuspend(dev->dev);
@@ -499,6 +501,7 @@ nouveau_drm_unload(struct drm_device *dev)
 struct nouveau_drm *drm = nouveau_drm(dev);

 pm_runtime_get_sync(dev->dev);
+   nouveau_led_fini(dev);
 nouveau_fbcon_fini(dev);
 nouveau_accel_fini(drm);
 nouveau_hwmon_fini(dev);
@@ -550,6 +553,8 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime)
 struct nouveau_cli *cli;
 int ret;

+   nouveau_led_suspend(dev);
+
 if (dev->mode_config.num_crtc) {
 NV_INFO(drm, "suspending console...\n");
 nouveau_fbcon_set_suspend(dev, 1);
@@ -638,6 +643,8 @@ nouveau_do_resume(struct drm_device *dev, bool runtime)
 nouveau_fbcon_set_suspend(dev, 0);
 }

+   nouveau_led_resume(dev);
+
 return 0;
  }

diff --git a/drm/nouveau/nouveau_drm.h b/drm/nouveau/nouveau_drm.h
index 5c363ed..b148dcb 100644
--- a/drm/nouveau/nouveau_drm.h
+++ b/drm/nouveau/nouveau_drm.h
@@ -166,6 +166,9 @@ struct nouveau_drm {
 struct nouveau_hwmon *hwmon;
 struct nouveau_debugfs *debugfs;

+   /* led management */
+   struct nouveau_led *led;
+
 /* display power reference */
 bool have_disp_power_ref;

diff --git a/drm/nouveau/nouveau_led.c b/drm/nouveau/nouveau_led.c
new file mode 100644
index 000..3f23ff6
--- /dev/null
+++ b/drm/nouveau/nouveau_led.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2016 Martin Peres
+ *
+ * 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

[Nouveau] [PATCH v2] drm/nouveau: add a LED driver for the NVIDIA logo

2016-08-23 Thread Martin Peres
v2:
 - guard LED framework calls with ifdef CONFIG_LEDS_CLASS

Signed-off-by: Martin Peres <martin.pe...@free.fr>
---

For real this time! Sorry for the noise

 drm/nouveau/Kbuild  |   1 +
 drm/nouveau/include/nvkm/subdev/bios/gpio.h |   1 +
 drm/nouveau/nouveau_drm.c   |   7 ++
 drm/nouveau/nouveau_drv.h   |   3 +
 drm/nouveau/nouveau_led.c   | 140 
 drm/nouveau/nouveau_led.h   |  48 ++
 6 files changed, 200 insertions(+)
 create mode 100644 drm/nouveau/nouveau_led.c
 create mode 100644 drm/nouveau/nouveau_led.h

diff --git a/drm/nouveau/Kbuild b/drm/nouveau/Kbuild
index 2527bf4..312bca9 100644
--- a/drm/nouveau/Kbuild
+++ b/drm/nouveau/Kbuild
@@ -22,6 +22,7 @@ nouveau-$(CONFIG_DEBUG_FS) += nouveau_debugfs.o
 nouveau-y += nouveau_drm.o
 nouveau-y += nouveau_hwmon.o
 nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
+nouveau-y += nouveau_led.o
 nouveau-y += nouveau_nvif.o
 nouveau-$(CONFIG_NOUVEAU_PLATFORM_DRIVER) += nouveau_platform.o
 nouveau-y += nouveau_usif.o # userspace <-> nvif
diff --git a/drm/nouveau/include/nvkm/subdev/bios/gpio.h 
b/drm/nouveau/include/nvkm/subdev/bios/gpio.h
index a47d46d..b7a54e6 100644
--- a/drm/nouveau/include/nvkm/subdev/bios/gpio.h
+++ b/drm/nouveau/include/nvkm/subdev/bios/gpio.h
@@ -6,6 +6,7 @@ enum dcb_gpio_func_name {
DCB_GPIO_TVDAC1 = 0x2d,
DCB_GPIO_FAN = 0x09,
DCB_GPIO_FAN_SENSE = 0x3d,
+   DCB_GPIO_LOGO_LED_PWM = 0x84,
DCB_GPIO_UNUSED = 0xff,
DCB_GPIO_VID0 = 0x04,
DCB_GPIO_VID1 = 0x05,
diff --git a/drm/nouveau/nouveau_drm.c b/drm/nouveau/nouveau_drm.c
index 66c1280..0f16652 100644
--- a/drm/nouveau/nouveau_drm.c
+++ b/drm/nouveau/nouveau_drm.c
@@ -47,6 +47,7 @@
 #include "nouveau_ttm.h"
 #include "nouveau_gem.h"
 #include "nouveau_vga.h"
+#include "nouveau_led.h"
 #include "nouveau_hwmon.h"
 #include "nouveau_acpi.h"
 #include "nouveau_bios.h"
@@ -475,6 +476,7 @@ nouveau_drm_load(struct drm_device *dev, unsigned long 
flags)
nouveau_hwmon_init(dev);
nouveau_accel_init(drm);
nouveau_fbcon_init(dev);
+   nouveau_led_init(dev);
 
if (nouveau_runtime_pm != 0) {
pm_runtime_use_autosuspend(dev->dev);
@@ -510,6 +512,7 @@ nouveau_drm_unload(struct drm_device *dev)
pm_runtime_forbid(dev->dev);
}
 
+   nouveau_led_fini(dev);
nouveau_fbcon_fini(dev);
nouveau_accel_fini(drm);
nouveau_hwmon_fini(dev);
@@ -561,6 +564,8 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime)
struct nouveau_cli *cli;
int ret;
 
+   nouveau_led_suspend(dev);
+
if (dev->mode_config.num_crtc) {
NV_INFO(drm, "suspending console...\n");
nouveau_fbcon_set_suspend(dev, 1);
@@ -649,6 +654,8 @@ nouveau_do_resume(struct drm_device *dev, bool runtime)
nouveau_fbcon_set_suspend(dev, 0);
}
 
+   nouveau_led_resume(dev);
+
return 0;
 }
 
diff --git a/drm/nouveau/nouveau_drv.h b/drm/nouveau/nouveau_drv.h
index 822a021..c0e2b32 100644
--- a/drm/nouveau/nouveau_drv.h
+++ b/drm/nouveau/nouveau_drv.h
@@ -166,6 +166,9 @@ struct nouveau_drm {
struct nouveau_hwmon *hwmon;
struct nouveau_debugfs *debugfs;
 
+   /* led management */
+   struct nouveau_led *led;
+
/* display power reference */
bool have_disp_power_ref;
 
diff --git a/drm/nouveau/nouveau_led.c b/drm/nouveau/nouveau_led.c
new file mode 100644
index 000..5c19efe
--- /dev/null
+++ b/drm/nouveau/nouveau_led.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2016 Martin Peres
+ *
+ * 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 (including the
+ * next paragraph) 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 OWNER(S) AND/OR ITS SUPPLIERS 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:
+ *  Martin Peres

Re: [Nouveau] [PATCH] drm/nouveau: add a LED driver for the NVIDIA logo

2016-05-08 Thread Martin Peres

On 07/05/16 23:44, karol herbst wrote:

looks good, just a minor thing: You need to check for
CONFIG_LEDS_CLASS, otherwise the compile throws out "warnings":

WARNING: "led_classdev_register"
[/home/karol/Dokumente/repos/nouveau/drm/nouveau/nouveau.ko]
undefined!
WARNING: "led_classdev_resume"
[/home/karol/Dokumente/repos/nouveau/drm/nouveau/nouveau.ko]
undefined!
WARNING: "led_classdev_unregister"
[/home/karol/Dokumente/repos/nouveau/drm/nouveau/nouveau.ko]
undefined!
WARNING: "led_classdev_suspend"
[/home/karol/Dokumente/repos/nouveau/drm/nouveau/nouveau.ko]
undefined!

And then we may want to thing about if we want to have a nouveau
config option for this to force enable LEDS_CLASS.
Or maybe this isn't needed at all and we just enable this code when
CONFIG_LEDS_CLASS is enabled in the kernel.

Good stuff though


Oops, I had sent the following to myself, not including the ML:

"It just occurred to me that I have not checked if I needed to
conditionally-compile this code or not whether the LED class is
available or not. I designed the code so as to be able to do it, but
failed to remember. I will check and send a v2 if needed."

Anyways, yeah, my plan is simply to not expose the LED if the config is 
not set. No need to force a dependency!


I will cook up another patch tomorrow.

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


Re: [Nouveau] [PATCH] drm/nouveau: add a LED driver for the NVIDIA logo

2016-05-03 Thread Martin Peres

On 04/05/16 02:57, Ilia Mirkin wrote:

On Tue, May 3, 2016 at 7:51 PM, Martin Peres <martin.pe...@free.fr> wrote:

We received a donation of a Titan which has this useless feature
allowing users to control the brightness of the LED behind the
logo of NVIDIA. In the true spirit of open source, let's expose
that to the users of very expensive cards!

This patch hooks up this LED/PWM to the LED subsystem which allows
blinking it in sync with cpu/disk/network/whatever activity (heartbeat
is quite nice!). Users may also implement some breathing effect or
morse code support in the userspace if they feel like it.

Signed-off-by: Martin Peres <martin.pe...@free.fr>
---
  drm/nouveau/Kbuild  |   1 +
  drm/nouveau/include/nvkm/subdev/bios/gpio.h |   1 +
  drm/nouveau/nouveau_drm.c   |   7 ++
  drm/nouveau/nouveau_drm.h   |   3 +
  drm/nouveau/nouveau_led.c   | 131 
  drm/nouveau/nouveau_led.h   |  48 ++
  6 files changed, 191 insertions(+)
  create mode 100644 drm/nouveau/nouveau_led.c
  create mode 100644 drm/nouveau/nouveau_led.h

diff --git a/drm/nouveau/Kbuild b/drm/nouveau/Kbuild
index 2527bf4..312bca9 100644
--- a/drm/nouveau/Kbuild
+++ b/drm/nouveau/Kbuild
@@ -22,6 +22,7 @@ nouveau-$(CONFIG_DEBUG_FS) += nouveau_debugfs.o
  nouveau-y += nouveau_drm.o
  nouveau-y += nouveau_hwmon.o
  nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
+nouveau-y += nouveau_led.o
  nouveau-y += nouveau_nvif.o
  nouveau-$(CONFIG_NOUVEAU_PLATFORM_DRIVER) += nouveau_platform.o
  nouveau-y += nouveau_usif.o # userspace <-> nvif
diff --git a/drm/nouveau/include/nvkm/subdev/bios/gpio.h 
b/drm/nouveau/include/nvkm/subdev/bios/gpio.h
index a47d46d..b7a54e6 100644
--- a/drm/nouveau/include/nvkm/subdev/bios/gpio.h
+++ b/drm/nouveau/include/nvkm/subdev/bios/gpio.h
@@ -6,6 +6,7 @@ enum dcb_gpio_func_name {
 DCB_GPIO_TVDAC1 = 0x2d,
 DCB_GPIO_FAN = 0x09,
 DCB_GPIO_FAN_SENSE = 0x3d,
+   DCB_GPIO_LOGO_LED_PWM = 0x84,
 DCB_GPIO_UNUSED = 0xff,
 DCB_GPIO_VID0 = 0x04,
 DCB_GPIO_VID1 = 0x05,
diff --git a/drm/nouveau/nouveau_drm.c b/drm/nouveau/nouveau_drm.c
index d06877d..dc97401 100644
--- a/drm/nouveau/nouveau_drm.c
+++ b/drm/nouveau/nouveau_drm.c
@@ -49,6 +49,7 @@
  #include "nouveau_ttm.h"
  #include "nouveau_gem.h"
  #include "nouveau_vga.h"
+#include "nouveau_led.h"
  #include "nouveau_hwmon.h"
  #include "nouveau_acpi.h"
  #include "nouveau_bios.h"
@@ -468,6 +469,7 @@ nouveau_drm_load(struct drm_device *dev, unsigned long 
flags)
 nouveau_hwmon_init(dev);
 nouveau_accel_init(drm);
 nouveau_fbcon_init(dev);
+   nouveau_led_init(dev);

 if (nouveau_runtime_pm != 0) {
 pm_runtime_use_autosuspend(dev->dev);
@@ -499,6 +501,7 @@ nouveau_drm_unload(struct drm_device *dev)
 struct nouveau_drm *drm = nouveau_drm(dev);

 pm_runtime_get_sync(dev->dev);
+   nouveau_led_fini(dev);
 nouveau_fbcon_fini(dev);
 nouveau_accel_fini(drm);
 nouveau_hwmon_fini(dev);
@@ -550,6 +553,8 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime)
 struct nouveau_cli *cli;
 int ret;

+   nouveau_led_suspend(dev);
+
 if (dev->mode_config.num_crtc) {
 NV_INFO(drm, "suspending console...\n");
 nouveau_fbcon_set_suspend(dev, 1);
@@ -638,6 +643,8 @@ nouveau_do_resume(struct drm_device *dev, bool runtime)
 nouveau_fbcon_set_suspend(dev, 0);
 }

+   nouveau_led_resume(dev);
+
 return 0;
  }

diff --git a/drm/nouveau/nouveau_drm.h b/drm/nouveau/nouveau_drm.h
index 5c363ed..b148dcb 100644
--- a/drm/nouveau/nouveau_drm.h
+++ b/drm/nouveau/nouveau_drm.h
@@ -166,6 +166,9 @@ struct nouveau_drm {
 struct nouveau_hwmon *hwmon;
 struct nouveau_debugfs *debugfs;

+   /* led management */
+   struct nouveau_led *led;
+
 /* display power reference */
 bool have_disp_power_ref;

diff --git a/drm/nouveau/nouveau_led.c b/drm/nouveau/nouveau_led.c
new file mode 100644
index 000..3f23ff6
--- /dev/null
+++ b/drm/nouveau/nouveau_led.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2016 Martin Peres
+ *
+ * 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 (including the
+ * next paragraph) shall be included in all copie

[Nouveau] [PATCH] drm/nouveau: add a LED driver for the NVIDIA logo

2016-05-03 Thread Martin Peres
We received a donation of a Titan which has this useless feature
allowing users to control the brightness of the LED behind the
logo of NVIDIA. In the true spirit of open source, let's expose
that to the users of very expensive cards!

This patch hooks up this LED/PWM to the LED subsystem which allows
blinking it in sync with cpu/disk/network/whatever activity (heartbeat
is quite nice!). Users may also implement some breathing effect or
morse code support in the userspace if they feel like it.

Signed-off-by: Martin Peres <martin.pe...@free.fr>
---
 drm/nouveau/Kbuild  |   1 +
 drm/nouveau/include/nvkm/subdev/bios/gpio.h |   1 +
 drm/nouveau/nouveau_drm.c   |   7 ++
 drm/nouveau/nouveau_drm.h   |   3 +
 drm/nouveau/nouveau_led.c   | 131 
 drm/nouveau/nouveau_led.h   |  48 ++
 6 files changed, 191 insertions(+)
 create mode 100644 drm/nouveau/nouveau_led.c
 create mode 100644 drm/nouveau/nouveau_led.h

diff --git a/drm/nouveau/Kbuild b/drm/nouveau/Kbuild
index 2527bf4..312bca9 100644
--- a/drm/nouveau/Kbuild
+++ b/drm/nouveau/Kbuild
@@ -22,6 +22,7 @@ nouveau-$(CONFIG_DEBUG_FS) += nouveau_debugfs.o
 nouveau-y += nouveau_drm.o
 nouveau-y += nouveau_hwmon.o
 nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
+nouveau-y += nouveau_led.o
 nouveau-y += nouveau_nvif.o
 nouveau-$(CONFIG_NOUVEAU_PLATFORM_DRIVER) += nouveau_platform.o
 nouveau-y += nouveau_usif.o # userspace <-> nvif
diff --git a/drm/nouveau/include/nvkm/subdev/bios/gpio.h 
b/drm/nouveau/include/nvkm/subdev/bios/gpio.h
index a47d46d..b7a54e6 100644
--- a/drm/nouveau/include/nvkm/subdev/bios/gpio.h
+++ b/drm/nouveau/include/nvkm/subdev/bios/gpio.h
@@ -6,6 +6,7 @@ enum dcb_gpio_func_name {
DCB_GPIO_TVDAC1 = 0x2d,
DCB_GPIO_FAN = 0x09,
DCB_GPIO_FAN_SENSE = 0x3d,
+   DCB_GPIO_LOGO_LED_PWM = 0x84,
DCB_GPIO_UNUSED = 0xff,
DCB_GPIO_VID0 = 0x04,
DCB_GPIO_VID1 = 0x05,
diff --git a/drm/nouveau/nouveau_drm.c b/drm/nouveau/nouveau_drm.c
index d06877d..dc97401 100644
--- a/drm/nouveau/nouveau_drm.c
+++ b/drm/nouveau/nouveau_drm.c
@@ -49,6 +49,7 @@
 #include "nouveau_ttm.h"
 #include "nouveau_gem.h"
 #include "nouveau_vga.h"
+#include "nouveau_led.h"
 #include "nouveau_hwmon.h"
 #include "nouveau_acpi.h"
 #include "nouveau_bios.h"
@@ -468,6 +469,7 @@ nouveau_drm_load(struct drm_device *dev, unsigned long 
flags)
nouveau_hwmon_init(dev);
nouveau_accel_init(drm);
nouveau_fbcon_init(dev);
+   nouveau_led_init(dev);
 
if (nouveau_runtime_pm != 0) {
pm_runtime_use_autosuspend(dev->dev);
@@ -499,6 +501,7 @@ nouveau_drm_unload(struct drm_device *dev)
struct nouveau_drm *drm = nouveau_drm(dev);
 
pm_runtime_get_sync(dev->dev);
+   nouveau_led_fini(dev);
nouveau_fbcon_fini(dev);
nouveau_accel_fini(drm);
nouveau_hwmon_fini(dev);
@@ -550,6 +553,8 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime)
struct nouveau_cli *cli;
int ret;
 
+   nouveau_led_suspend(dev);
+
if (dev->mode_config.num_crtc) {
NV_INFO(drm, "suspending console...\n");
nouveau_fbcon_set_suspend(dev, 1);
@@ -638,6 +643,8 @@ nouveau_do_resume(struct drm_device *dev, bool runtime)
nouveau_fbcon_set_suspend(dev, 0);
}
 
+   nouveau_led_resume(dev);
+
return 0;
 }
 
diff --git a/drm/nouveau/nouveau_drm.h b/drm/nouveau/nouveau_drm.h
index 5c363ed..b148dcb 100644
--- a/drm/nouveau/nouveau_drm.h
+++ b/drm/nouveau/nouveau_drm.h
@@ -166,6 +166,9 @@ struct nouveau_drm {
struct nouveau_hwmon *hwmon;
struct nouveau_debugfs *debugfs;
 
+   /* led management */
+   struct nouveau_led *led;
+
/* display power reference */
bool have_disp_power_ref;
 
diff --git a/drm/nouveau/nouveau_led.c b/drm/nouveau/nouveau_led.c
new file mode 100644
index 000..3f23ff6
--- /dev/null
+++ b/drm/nouveau/nouveau_led.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2016 Martin Peres
+ *
+ * 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 (including the
+ * next paragraph) 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 LIMI

Re: [Nouveau] [PATCH v4 27/37] clk: make pstate a pointer to nvkm_pstate

2016-04-20 Thread Martin Peres

On 21/04/16 00:46, karol herbst wrote:

2016-04-20 20:53 GMT+00:00 Martin Peres <martin.pe...@free.fr>:

On 18/04/16 22:14, Karol Herbst wrote:

we will access the current set cstate at least every second and this safes
us

saves

some CPU cycles looking them up every second.

Signed-off-by: Karol Herbst <nouv...@karolherbst.de>
---
   drm/nouveau/include/nvkm/subdev/clk.h |  2 +-
   drm/nouveau/nvkm/engine/device/ctrl.c |  5 -
   drm/nouveau/nvkm/subdev/clk/base.c| 12 
   drm/nouveau/nvkm/subdev/pmu/gk20a.c   | 23 +++
   4 files changed, 20 insertions(+), 22 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h
b/drm/nouveau/include/nvkm/subdev/clk.h
index db52e65..4fb2c1b 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -91,7 +91,7 @@ struct nvkm_clk {
 struct nvkm_notify pwrsrc_ntfy;
 int pwrsrc;
-   int pstate; /* current */
+   struct nvkm_pstate *pstate; /* current */
 int ustate_ac; /* user-requested (-1 disabled, -2 perfmon) */
 int ustate_dc; /* user-requested (-1 disabled, -2 perfmon) */
 int astate; /* perfmon adjustment (base) */
diff --git a/drm/nouveau/nvkm/engine/device/ctrl.c
b/drm/nouveau/nvkm/engine/device/ctrl.c
index 039e8a4..cb85266 100644
--- a/drm/nouveau/nvkm/engine/device/ctrl.c
+++ b/drm/nouveau/nvkm/engine/device/ctrl.c
@@ -52,7 +52,10 @@ nvkm_control_mthd_pstate_info(struct nvkm_control
*ctrl, void *data, u32 size)
 args->v0.ustate_ac = clk->ustate_ac;
 args->v0.ustate_dc = clk->ustate_dc;
 args->v0.pwrsrc = clk->pwrsrc;
-   args->v0.pstate = clk->pstate;
+   if (clk->pstate)
+   args->v0.pstate = clk->pstate->pstate;
+   else
+   args->v0.pstate = -1;
 } else {
 args->v0.count = 0;
 args->v0.ustate_ac =
NVIF_CONTROL_PSTATE_INFO_V0_USTATE_DISABLE;
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c
b/drm/nouveau/nvkm/subdev/clk/base.c
index 3867ab7..762dfe2 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -288,7 +288,7 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)
 }
 nvkm_debug(subdev, "setting performance state %d\n", pstatei);
-   clk->pstate = pstatei;
+   clk->pstate = pstate;
 nvkm_pcie_set_link(pci, pstate->pcie_speed, pstate->pcie_width);
   @@ -317,15 +317,19 @@ nvkm_clk_update_work(struct work_struct *work)
 return;
 clk->pwrsrc = power_supply_is_system_supplied();
   + if (clk->pstate)
+   pstate = clk->pstate->pstate;
+   else
+   pstate = -1;
 nvkm_trace(subdev, "P %d PWR %d U(AC) %d U(DC) %d A %d\n",
-  clk->pstate, clk->pwrsrc, clk->ustate_ac,
clk->ustate_dc,
+  pstate, clk->pwrsrc, clk->ustate_ac, clk->ustate_dc,
clk->astate);
 pstate = clk->pwrsrc ? clk->ustate_ac : clk->ustate_dc;
 if (clk->state_nr && pstate != -1) {
 pstate = (pstate < 0) ? clk->astate : pstate;
 } else {
-   pstate = clk->pstate = -1;
+   pstate = -1;


Isn't "clk->pstate = NULL;" missing here? Why did you change this code
otherwise?


clk->pstate will never be set as long as they are no states


I see. Then, the patch is:
Reviewed-by: Martin Peres <martin.pe...@free.fr>



 }
 nvkm_trace(subdev, "-> %d\n", pstate);
@@ -609,7 +613,7 @@ nvkm_clk_init(struct nvkm_subdev *subdev)
 return clk->func->init(clk);
 clk->astate = clk->state_nr - 1;
-   clk->pstate = -1;
+   clk->pstate = NULL;
 nvkm_clk_update(clk, true);
 return 0;
   }
diff --git a/drm/nouveau/nvkm/subdev/pmu/gk20a.c
b/drm/nouveau/nvkm/subdev/pmu/gk20a.c
index f996d90..6f0d290 100644
--- a/drm/nouveau/nvkm/subdev/pmu/gk20a.c
+++ b/drm/nouveau/nvkm/subdev/pmu/gk20a.c
@@ -57,24 +57,21 @@ gk20a_pmu_dvfs_target(struct gk20a_pmu *pmu, int
*state)
   }
 static int
-gk20a_pmu_dvfs_get_cur_state(struct gk20a_pmu *pmu, int *state)
-{
-   struct nvkm_clk *clk = pmu->base.subdev.device->clk;
-
-   *state = clk->pstate;
-   return 0;
-}
-
-static int
   gk20a_pmu_dvfs_get_target_state(struct gk20a_pmu *pmu,
 int *state, int load)
   {
 struct gk20a_pmu_dvfs_data *data = pmu->data;
 struct nvkm_clk *clk = pmu->base.subdev.device->clk;
+   struct nvkm_pstate *pstate = clk->pstate;
 int cur_level, level;
   + if (!pstate) {
+   *state = 0;
+   return 1;
+   }
+
 /* For GK20A, th

Re: [Nouveau] [PATCH v4 37/37] volt: add NvVoltOffsetmV option

2016-04-20 Thread Martin Peres

On 18/04/16 22:14, Karol Herbst wrote:

This option can be used to adjust the calculated voltage or the cstate voltage
calculation

Signed-off-by: Karol Herbst <nouv...@karolherbst.de>
---
  bin/nv_cmp_volt.c  |  2 +-
  drm/nouveau/include/nvkm/subdev/volt.h |  4 +++-
  drm/nouveau/nvkm/subdev/clk/base.c |  8 
  drm/nouveau/nvkm/subdev/volt/base.c| 25 -
  4 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/bin/nv_cmp_volt.c b/bin/nv_cmp_volt.c
index e61056c..d1a0402 100644
--- a/bin/nv_cmp_volt.c
+++ b/bin/nv_cmp_volt.c
@@ -117,7 +117,7 @@ main(int argc, char **argv)
  
  		new_voltage = nvkm_volt_get(volt);

new_temp = nvkm_rd32(device, 
0x20400);//nvkm_therm_temp_get(therm);
-   new_nouveau_voltage = max(nvkm_volt_map(volt, 
best_cstate->voltage, new_temp), nvkm_volt_map(volt, best_pstate->base.voltage, 
new_temp));
+   new_nouveau_voltage = max(nvkm_volt_map(volt, 
best_cstate->voltage, new_temp, true), nvkm_volt_map(volt, 
best_pstate->base.voltage, new_temp, false));
new_pstate = best_pstate->pstate;
new_cstate = best_cstate->cstate;
  
diff --git a/drm/nouveau/include/nvkm/subdev/volt.h b/drm/nouveau/include/nvkm/subdev/volt.h

index 25588c7..f34fd39 100644
--- a/drm/nouveau/include/nvkm/subdev/volt.h
+++ b/drm/nouveau/include/nvkm/subdev/volt.h
@@ -22,9 +22,11 @@ struct nvkm_volt {
u8 max2_id;
  
  	int speedo;

+
+   int volt_offset_mv;
  };
  
-int nvkm_volt_map(struct nvkm_volt *volt, u8 id, u8 temperature);

+int nvkm_volt_map(struct nvkm_volt *volt, u8 id, u8 temperature, bool 
enableOffset);
  int nvkm_volt_map_min(struct nvkm_volt *volt, u8 id);
  int nvkm_volt_get(struct nvkm_volt *);
  int nvkm_volt_set_id(struct nvkm_volt *, u8 id, u8 min_id, int condition);
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c 
b/drm/nouveau/nvkm/subdev/clk/base.c
index d5440a9..7937155 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -100,7 +100,7 @@ nvkm_cstate_valid(struct nvkm_clk *clk, struct nvkm_cstate 
*cstate, u32 max_volt
if (!volt)
return true;
  
-	voltage = nvkm_volt_map(volt, cstate->voltage, temp);

+   voltage = nvkm_volt_map(volt, cstate->voltage, temp, true);
if (voltage < 0)
return false;
return voltage <= min(max_volt, volt->max_uv) &&
@@ -131,13 +131,13 @@ nvkm_cstate_find_best(struct nvkm_clk *clk, struct 
nvkm_pstate *pstate,
max_volt = volt->max_uv;
if (volt->max0_id != 0xff)
max_volt = min(max_volt,
-  nvkm_volt_map(volt, volt->max0_id, temp));
+  nvkm_volt_map(volt, volt->max0_id, temp, false));
if (volt->max1_id != 0xff)
max_volt = min(max_volt,
-  nvkm_volt_map(volt, volt->max1_id, temp));
+  nvkm_volt_map(volt, volt->max1_id, temp, false));
if (volt->max2_id != 0xff)
max_volt = min(max_volt,
-  nvkm_volt_map(volt, volt->max2_id, temp));
+  nvkm_volt_map(volt, volt->max2_id, temp, false));


So, this ugly dance of having true or flase depending on whether we are 
looking for a
pstate or a cstate looks really ugly, but it does make some sense. Given 
how useful this
may be to debug voltage-related issues, I would say it is worth the 
extra complexity (that

we really did not need).

Anyway: Reviewed-by: Martin Peres <martin.pe...@free.fr>
  
  	for (cstate = start; >head != >list;

 cstate = list_entry(cstate->head.prev, typeof(*cstate), head)) {
diff --git a/drm/nouveau/nvkm/subdev/volt/base.c 
b/drm/nouveau/nvkm/subdev/volt/base.c
index 5e35d96..7d5e6c8 100644
--- a/drm/nouveau/nvkm/subdev/volt/base.c
+++ b/drm/nouveau/nvkm/subdev/volt/base.c
@@ -23,6 +23,8 @@
   */
  #include "priv.h"
  
+#include 

+
  #include 
  #include 
  #include 
@@ -100,8 +102,8 @@ nvkm_volt_map_min(struct nvkm_volt *volt, u8 id)
return id ? id * 1 : -ENODEV;
  }
  
-int

-nvkm_volt_map(struct nvkm_volt *volt, u8 id, u8 temp)
+static int
+nvkm_volt_map_impl(struct nvkm_volt *volt, u8 id, u8 temp)
  {
struct nvkm_bios *bios = volt->subdev.device->bios;
struct nvbios_vmap_entry info;
@@ -145,7 +147,7 @@ nvkm_volt_map(struct nvkm_volt *volt, u8 id, u8 temp)
result = min(max(result, (s64)info.min), (s64)info.max);
  
  		if (info.link != 0xff) {

-   int ret = nvkm_volt_map(volt, info.link, temp);
+   int ret = nvkm_volt_map_impl(volt, info.link, temp);
if (ret < 0)
return ret;
result += ret;
@@ -157,6 +159,15 @@ nvkm_volt_map(st

Re: [Nouveau] [PATCH v4 36/37] WIP volt/gk104: readout speedo

2016-04-20 Thread Martin Peres

On 18/04/16 22:14, Karol Herbst wrote:

this gk104 volt implementation has to be reworked a little, because the speedo
readout in maxwell doesn't need those strange 0 and 41 writes into 0x122634,
but it needs this PWM thing.

Maybe Maxwell is PWM only and we could just simplify it there, but without
proper knowledge there has some refactoring to be made.


This is not true, my GM206 is GPIO-based.



Signed-off-by: Karol Herbst <nouv...@karolherbst.de>
---
  drm/nouveau/nvkm/subdev/volt/gk104.c | 19 +++
  1 file changed, 19 insertions(+)

diff --git a/drm/nouveau/nvkm/subdev/volt/gk104.c 
b/drm/nouveau/nvkm/subdev/volt/gk104.c
index b735173..81788c2 100644
--- a/drm/nouveau/nvkm/subdev/volt/gk104.c
+++ b/drm/nouveau/nvkm/subdev/volt/gk104.c
@@ -27,6 +27,7 @@
  #include 
  #include 
  #include 
+#include 
  
  #define gk104_volt(p) container_of((p), struct gk104_volt, base)

  struct gk104_volt {
@@ -64,13 +65,31 @@ gk104_volt_set(struct nvkm_volt *base, u32 uv)
return 0;
  }
  
+static int

+gk104_volt_speedo_read(struct nvkm_volt *volt)
+{
+   struct nvkm_device *device = volt->subdev.device;
+   struct nvkm_fuse *fuse = device->fuse;
+   int ret;
+
+   if (!fuse)
+   return -EINVAL;
+
+   nvkm_wr32(device, 0x122634, 0x0);


I checked on a mmiotrace, and these writes are not only for this fuse. 
So they should be put in the gk104_fuse_read :)


After this,you can stop calling it a WIP patch and get rid of this 
confusing talk about the PWM voltage management, because I really do not 
get how it is relevant.


With this addressed:

Reviewed-by: Martin Peres <martin.pe...@free.fr>


+   ret = nvkm_fuse_read(fuse, 0x3a8);
+   nvkm_wr32(device, 0x122634, 0x41);
+   return ret;
+}
+
  static const struct nvkm_volt_func
  gk104_volt_pwm = {
.volt_get = gk104_volt_get,
.volt_set = gk104_volt_set,
+   .speedo_read = gk104_volt_speedo_read,
  }, gk104_volt_gpio = {
.vid_get = nvkm_voltgpio_get,
.vid_set = nvkm_voltgpio_set,
+   .speedo_read = gk104_volt_speedo_read,
  };
  
  int


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


Re: [Nouveau] [PATCH v4 35/37] clk: set clocks to pre suspend state after suspend

2016-04-20 Thread Martin Peres

On 18/04/16 22:14, Karol Herbst wrote:

Signed-off-by: Karol Herbst <nouv...@karolherbst.de>


Reviewed-by: Martin Peres <martin.pe...@free.fr>

---
  drm/nouveau/nvkm/subdev/clk/base.c  | 19 +++
  drm/nouveau/nvkm/subdev/clk/gf100.c |  4 ++--
  drm/nouveau/nvkm/subdev/clk/nv40.c  |  2 +-
  drm/nouveau/nvkm/subdev/clk/priv.h  |  6 +++---
  4 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/drm/nouveau/nvkm/subdev/clk/base.c 
b/drm/nouveau/nvkm/subdev/clk/base.c
index 2776d79..d5440a9 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -324,7 +324,7 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstateid)
  }
  
  static void

-nvkm_clk_update_impl(struct nvkm_clk *clk)
+nvkm_clk_update_impl(struct nvkm_clk *clk, bool force)
  {
struct nvkm_subdev *subdev = >subdev;
int pstate;
@@ -349,7 +349,7 @@ nvkm_clk_update_impl(struct nvkm_clk *clk)
pstate = -1;
}
  
-	clk->func->update(clk, pstate);

+   clk->func->update(clk, pstate, force);
  }
  
  static void

@@ -360,7 +360,7 @@ nvkm_clk_update_work(struct work_struct *work)
if (!atomic_xchg(>waiting, 0))
return;
  
-	nvkm_clk_update_impl(clk);

+   nvkm_clk_update_impl(clk, false);
  
  	wake_up_all(>wait);

nvkm_notify_get(>pwrsrc_ntfy);
@@ -613,11 +613,7 @@ nvkm_clk_init(struct nvkm_subdev *subdev)
if (clk->func->init)
return clk->func->init(clk);
  
-	clk->astate = -1;

-   clk->pstate = NULL;
-   clk->exp_cstate = NVKM_CLK_CSTATE_DEFAULT;
-   clk->set_cstate = NULL;
-   nvkm_clk_update(clk, true);
+   nvkm_clk_update_impl(clk, true);
return 0;
  }
  
@@ -672,8 +668,15 @@ nvkm_clk_ctor(const struct nvkm_clk_func *func, struct nvkm_device *device,

clk->func = func;
INIT_LIST_HEAD(>states);
clk->domains = func->domains;
+
+   clk->pstate = NULL;
+   clk->astate = -1;
clk->ustate_ac = -1;
clk->ustate_dc = -1;
+
+   clk->exp_cstate = NVKM_CLK_CSTATE_DEFAULT;
+   clk->set_cstate = NULL;
+
clk->allow_reclock = allow_reclock;
  
  	INIT_WORK(>work, nvkm_clk_update_work);

diff --git a/drm/nouveau/nvkm/subdev/clk/gf100.c 
b/drm/nouveau/nvkm/subdev/clk/gf100.c
index 5025dcc..5621daf 100644
--- a/drm/nouveau/nvkm/subdev/clk/gf100.c
+++ b/drm/nouveau/nvkm/subdev/clk/gf100.c
@@ -447,12 +447,12 @@ gf100_clk_update_volt(struct nvkm_clk *clk)
  }
  
  void

-gf100_clk_update(struct nvkm_clk *clk, int pstate)
+gf100_clk_update(struct nvkm_clk *clk, int pstate, bool force)
  {
struct nvkm_subdev *subdev = >subdev;
int ret;
  
-	if (!clk->pstate || clk->pstate->pstate != pstate) {

+   if (!clk->pstate || clk->pstate->pstate != pstate || force) {
nvkm_trace(subdev, "-> P %d\n", pstate);
ret = nvkm_pstate_prog(clk, pstate);
if (ret) {
diff --git a/drm/nouveau/nvkm/subdev/clk/nv40.c 
b/drm/nouveau/nvkm/subdev/clk/nv40.c
index 5b10ee2..055063a 100644
--- a/drm/nouveau/nvkm/subdev/clk/nv40.c
+++ b/drm/nouveau/nvkm/subdev/clk/nv40.c
@@ -202,7 +202,7 @@ nv40_clk_tidy(struct nvkm_clk *obj)
  }
  
  void

-nv40_clk_update(struct nvkm_clk *clk, int pstate)
+nv40_clk_update(struct nvkm_clk *clk, int pstate, bool force)
  {
struct nvkm_subdev *subdev = >subdev;
int ret;
diff --git a/drm/nouveau/nvkm/subdev/clk/priv.h 
b/drm/nouveau/nvkm/subdev/clk/priv.h
index e2f15c4..06a78a2 100644
--- a/drm/nouveau/nvkm/subdev/clk/priv.h
+++ b/drm/nouveau/nvkm/subdev/clk/priv.h
@@ -10,7 +10,7 @@ struct nvkm_clk_func {
int (*calc)(struct nvkm_clk *, struct nvkm_cstate *);
int (*prog)(struct nvkm_clk *);
void (*tidy)(struct nvkm_clk *);
-   void (*update)(struct nvkm_clk *, int pstate);
+   void (*update)(struct nvkm_clk *, int pstate, bool force);
struct nvkm_pstate *pstates;
int nr_pstates;
struct nvkm_domain domains[];
@@ -30,6 +30,6 @@ int nv04_clk_pll_calc(struct nvkm_clk *, struct nvbios_pll *, 
int clk,
  struct nvkm_pll_vals *);
  int nv04_clk_pll_prog(struct nvkm_clk *, u32 reg1, struct nvkm_pll_vals *);
  
-void nv40_clk_update(struct nvkm_clk *, int pstate);

-void gf100_clk_update(struct nvkm_clk *, int pstate);
+void nv40_clk_update(struct nvkm_clk *, int pstate, bool force);
+void gf100_clk_update(struct nvkm_clk *, int pstate, bool force);
  #endif


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


Re: [Nouveau] [PATCH v4 34/37] mc: fix NULL pointer access in libnouveau

2016-04-20 Thread Martin Peres

On 18/04/16 22:14, Karol Herbst wrote:

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

diff --git a/drm/nouveau/nvkm/subdev/mc/base.c 
b/drm/nouveau/nvkm/subdev/mc/base.c
index aa394af..88bc1cc 100644
--- a/drm/nouveau/nvkm/subdev/mc/base.c
+++ b/drm/nouveau/nvkm/subdev/mc/base.c
@@ -90,10 +90,15 @@ nvkm_mc_intr(struct nvkm_mc *mc, bool *handled)
  void
  nvkm_mc_reset(struct nvkm_mc *mc, enum nvkm_devidx devidx)
  {
-   struct nvkm_device *device = mc->subdev.device;
+   struct nvkm_device *device;
const struct nvkm_mc_map *map;
u64 pmc_enable;
  
+	if (!mc)

+   return;
Not sure what is the policy of Ben on this, fixing the caller or the 
callee. His call!

+
+   device = mc->subdev.device;
+
if (!(pmc_enable = nvkm_top_reset(device->top, devidx))) {
for (map = mc->func->reset; map && map->stat; map++) {
if (map->unit == devidx) {


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


Re: [Nouveau] [PATCH v4 33/37] therm: trigger reclock in temperature daemon

2016-04-20 Thread Martin Peres

On 18/04/16 22:14, Karol Herbst wrote:

depending on the temperature, cstates might become unreachable or the maped
voltage of a cstate changes. We want to adjust to that.


Yeah! That was a lot of plumbing to get to this, but it is here!

Reviewed-by: Martin Peres <martin.pe...@free.fr>


Signed-off-by: Karol Herbst <nouv...@karolherbst.de>
---
  drm/nouveau/nvkm/subdev/therm/base.c | 5 +
  1 file changed, 5 insertions(+)

diff --git a/drm/nouveau/nvkm/subdev/therm/base.c 
b/drm/nouveau/nvkm/subdev/therm/base.c
index 0c0feec..566fe5d 100644
--- a/drm/nouveau/nvkm/subdev/therm/base.c
+++ b/drm/nouveau/nvkm/subdev/therm/base.c
@@ -23,6 +23,8 @@
   */
  #include "priv.h"
  
+#include 

+
  int
  nvkm_therm_temp_get(struct nvkm_therm *therm)
  {
@@ -153,7 +155,10 @@ nvkm_therm_alarm(struct nvkm_alarm *alarm)
  {
struct nvkm_therm *therm =
   container_of(alarm, struct nvkm_therm, alarm);
+   struct nvkm_clk *clk = therm->subdev.device->clk;
nvkm_therm_update(therm, -1);
+   if (clk)
+   nvkm_clk_update(clk, false);
  }
  
  int


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


Re: [Nouveau] [PATCH v4 32/37] clk: only do partial reclocks as required

2016-04-20 Thread Martin Peres

On 18/04/16 22:14, Karol Herbst wrote:

we don't want to reclock to the same pstate or cstate over and over again, so
only do things we actually have to do.

v4: move into gf100


Reviewed-by: Martin Peres <martin.pe...@free.fr>



Signed-off-by: Karol Herbst <nouv...@karolherbst.de>
---
  drm/nouveau/nvkm/subdev/clk/base.c  | 11 +--
  drm/nouveau/nvkm/subdev/clk/gf100.c | 62 -
  drm/nouveau/nvkm/subdev/clk/gk104.c |  2 +-
  drm/nouveau/nvkm/subdev/clk/nv40.c  |  3 ++
  drm/nouveau/nvkm/subdev/clk/priv.h  |  4 +++
  5 files changed, 77 insertions(+), 5 deletions(-)

diff --git a/drm/nouveau/nvkm/subdev/clk/base.c 
b/drm/nouveau/nvkm/subdev/clk/base.c
index 3c40f67..2776d79 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -107,7 +107,7 @@ nvkm_cstate_valid(struct nvkm_clk *clk, struct nvkm_cstate 
*cstate, u32 max_volt
   voltage >= volt->min_uv;
  }
  
-static struct nvkm_cstate *

+struct nvkm_cstate *
  nvkm_cstate_find_best(struct nvkm_clk *clk, struct nvkm_pstate *pstate,
  struct nvkm_cstate *start)
  {
@@ -148,7 +148,7 @@ nvkm_cstate_find_best(struct nvkm_clk *clk, struct 
nvkm_pstate *pstate,
return cstate;
  }
  
-static struct nvkm_cstate *

+struct nvkm_cstate *
  nvkm_cstate_get(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
  {
struct nvkm_cstate *cstate;
@@ -168,7 +168,7 @@ nvkm_cstate_get(struct nvkm_clk *clk, struct nvkm_pstate 
*pstate, int cstatei)
return NULL;
  }
  
-static int

+int
  nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int 
cstatei)
  {
struct nvkm_subdev *subdev = >subdev;
@@ -188,6 +188,11 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate 
*pstate, int cstatei)
cstate = >base;
}
  
+	if (!cstate) {

+   nvkm_error(subdev, "failed to set cstate %d\n", cstatei);
+   return -EINVAL;
+   }
+
if (therm) {
ret = nvkm_therm_cstate(therm, pstate->fanspeed, +1);
if (ret && ret != -ENODEV) {
diff --git a/drm/nouveau/nvkm/subdev/clk/gf100.c 
b/drm/nouveau/nvkm/subdev/clk/gf100.c
index 808e1ed..5025dcc 100644
--- a/drm/nouveau/nvkm/subdev/clk/gf100.c
+++ b/drm/nouveau/nvkm/subdev/clk/gf100.c
@@ -28,6 +28,7 @@
  #include 
  #include 
  #include 
+#include 
  
  struct gf100_clk_info {

u32 freq;
@@ -431,13 +432,72 @@ gf100_clk_tidy(struct nvkm_clk *base)
memset(clk->eng, 0x00, sizeof(clk->eng));
  }
  
+static int

+gf100_clk_update_volt(struct nvkm_clk *clk)
+{
+   struct nvkm_subdev *subdev = >subdev;
+   struct nvkm_volt *volt = subdev->device->volt;
+   struct nvkm_therm *therm = subdev->device->therm;
+
+   if (!volt || !therm || !clk->pstate || !clk->set_cstate)
+   return -EINVAL;
+
+   return nvkm_volt_set_id(volt, clk->set_cstate->voltage,
+   clk->pstate->base.voltage, 0);
+}
+
+void
+gf100_clk_update(struct nvkm_clk *clk, int pstate)
+{
+   struct nvkm_subdev *subdev = >subdev;
+   int ret;
+
+   if (!clk->pstate || clk->pstate->pstate != pstate) {
+   nvkm_trace(subdev, "-> P %d\n", pstate);
+   ret = nvkm_pstate_prog(clk, pstate);
+   if (ret) {
+   nvkm_error(subdev, "error setting pstate %d: %d\n",
+  pstate, ret);
+   }
+   } else if (!clk->set_cstate ||
+  clk->set_cstate->cstate != clk->exp_cstate) {
+
+   struct nvkm_cstate *cstate = nvkm_cstate_get(clk, clk->pstate, 
clk->exp_cstate);
+   if (!cstate) {
+   nvkm_error(subdev, "can't find cstate %i\n",
+  clk->exp_cstate);
+   return;
+   }
+
+   cstate = nvkm_cstate_find_best(clk, clk->pstate, cstate);
+   if (!cstate) {
+   nvkm_error(subdev, "can't find best cstate for %i\n",
+  cstate->cstate);
+   return;
+   }
+
+   if (cstate != clk->set_cstate) {
+   nvkm_trace(subdev, "-> C %d\n", cstate->cstate);
+   ret = nvkm_cstate_prog(clk, clk->pstate, 
cstate->cstate);
+   if (ret) {
+   nvkm_error(subdev, "error setting cstate %d: 
%d\n",
+  cstate->cstate, ret);
+   }
+   } else {
+   gf100_clk_update_volt(clk);
+   }
+   } else {
+   gf100_clk_update_volt(clk);
+   }
+}
+
  static 

Re: [Nouveau] [PATCH v4 31/37] clk: split out update code to nv40

2016-04-20 Thread Martin Peres

On 18/04/16 22:14, Karol Herbst wrote:

this code will change for gf100 and newer


Reviewed-by: Martin Peres <martin.pe...@free.fr>


Signed-off-by: Karol Herbst <nouv...@karolherbst.de>
---
  drm/nouveau/nvkm/subdev/clk/base.c  | 14 ++
  drm/nouveau/nvkm/subdev/clk/g84.c   |  1 +
  drm/nouveau/nvkm/subdev/clk/gf100.c |  1 +
  drm/nouveau/nvkm/subdev/clk/gk104.c |  1 +
  drm/nouveau/nvkm/subdev/clk/gk20a.c |  1 +
  drm/nouveau/nvkm/subdev/clk/gm20b.c |  1 +
  drm/nouveau/nvkm/subdev/clk/gt215.c |  1 +
  drm/nouveau/nvkm/subdev/clk/mcp77.c |  1 +
  drm/nouveau/nvkm/subdev/clk/nv40.c  | 15 +++
  drm/nouveau/nvkm/subdev/clk/nv50.c  |  1 +
  drm/nouveau/nvkm/subdev/clk/priv.h  |  5 +
  11 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/drm/nouveau/nvkm/subdev/clk/base.c 
b/drm/nouveau/nvkm/subdev/clk/base.c
index d6f239f..3c40f67 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -279,7 +279,7 @@ nvkm_cstate_new(struct nvkm_clk *clk, int idx, struct 
nvkm_pstate *pstate)
  
/**
   * P-States
   
*/
-static int
+int
  nvkm_pstate_prog(struct nvkm_clk *clk, int pstateid)
  {
struct nvkm_subdev *subdev = >subdev;
@@ -322,7 +322,10 @@ static void
  nvkm_clk_update_impl(struct nvkm_clk *clk)
  {
struct nvkm_subdev *subdev = >subdev;
-   int pstate, ret;
+   int pstate;
+
+   if (!clk->func->update)
+   return;
  
  	clk->pwrsrc = power_supply_is_system_supplied();
  
@@ -341,12 +344,7 @@ nvkm_clk_update_impl(struct nvkm_clk *clk)

pstate = -1;
}
  
-	nvkm_trace(subdev, "-> %d\n", pstate);

-   ret = nvkm_pstate_prog(clk, pstate);
-   if (ret) {
-   nvkm_error(subdev, "error setting pstate %d: %d\n",
-  pstate, ret);
-   }
+   clk->func->update(clk, pstate);
  }
  
  static void

diff --git a/drm/nouveau/nvkm/subdev/clk/g84.c 
b/drm/nouveau/nvkm/subdev/clk/g84.c
index f97e3ec..7b9b30d 100644
--- a/drm/nouveau/nvkm/subdev/clk/g84.c
+++ b/drm/nouveau/nvkm/subdev/clk/g84.c
@@ -29,6 +29,7 @@ g84_clk = {
.calc = nv50_clk_calc,
.prog = nv50_clk_prog,
.tidy = nv50_clk_tidy,
+   .update = nv40_clk_update,
.domains = {
{ nv_clk_src_crystal, 0xff },
{ nv_clk_src_href   , 0xff },
diff --git a/drm/nouveau/nvkm/subdev/clk/gf100.c 
b/drm/nouveau/nvkm/subdev/clk/gf100.c
index 71b7c9f..808e1ed 100644
--- a/drm/nouveau/nvkm/subdev/clk/gf100.c
+++ b/drm/nouveau/nvkm/subdev/clk/gf100.c
@@ -437,6 +437,7 @@ gf100_clk = {
.calc = gf100_clk_calc,
.prog = gf100_clk_prog,
.tidy = gf100_clk_tidy,
+   .update = nv40_clk_update,
.domains = {
{ nv_clk_src_crystal, 0xff },
{ nv_clk_src_href   , 0xff },
diff --git a/drm/nouveau/nvkm/subdev/clk/gk104.c 
b/drm/nouveau/nvkm/subdev/clk/gk104.c
index 639234f..8448a88 100644
--- a/drm/nouveau/nvkm/subdev/clk/gk104.c
+++ b/drm/nouveau/nvkm/subdev/clk/gk104.c
@@ -482,6 +482,7 @@ gk104_clk = {
.calc = gk104_clk_calc,
.prog = gk104_clk_prog,
.tidy = gk104_clk_tidy,
+   .update = nv40_clk_update,
.domains = {
{ nv_clk_src_crystal, 0xff },
{ nv_clk_src_href   , 0xff },
diff --git a/drm/nouveau/nvkm/subdev/clk/gk20a.c 
b/drm/nouveau/nvkm/subdev/clk/gk20a.c
index 5f0ee24..8b64cc9 100644
--- a/drm/nouveau/nvkm/subdev/clk/gk20a.c
+++ b/drm/nouveau/nvkm/subdev/clk/gk20a.c
@@ -636,6 +636,7 @@ gk20a_clk = {
.calc = gk20a_clk_calc,
.prog = gk20a_clk_prog,
.tidy = gk20a_clk_tidy,
+   .update = nv40_clk_update,
.pstates = gk20a_pstates,
.nr_pstates = ARRAY_SIZE(gk20a_pstates),
.domains = {
diff --git a/drm/nouveau/nvkm/subdev/clk/gm20b.c 
b/drm/nouveau/nvkm/subdev/clk/gm20b.c
index 71b2bbb..8c8eb8c 100644
--- a/drm/nouveau/nvkm/subdev/clk/gm20b.c
+++ b/drm/nouveau/nvkm/subdev/clk/gm20b.c
@@ -168,6 +168,7 @@ gm20b_clk_speedo0 = {
.calc = gk20a_clk_calc,
.prog = gk20a_clk_prog,
.tidy = gk20a_clk_tidy,
+   .update = nv40_clk_update,
.pstates = gm20b_pstates,
.nr_pstates = ARRAY_SIZE(gm20b_pstates) - 1,
.domains = {
diff --git a/drm/nouveau/nvkm/subdev/clk/gt215.c 
b/drm/nouveau/nvkm/subdev/clk/gt215.c
index 056702e..8913afa 100644
--- a/drm/nouveau/nvkm/subdev/clk/gt215.c
+++ b/drm/nouveau/nvkm/subdev/clk/gt215.c
@@ -520,6 +520,7 @@ gt215_clk = {
.calc = gt215_clk_calc,
.prog = gt215_clk_prog,
.tidy = gt215_clk_tidy,
+   .update = nv40_clk_update,
.domains = {
{ nv_clk_src_crystal  , 0xff },
{ nv_clk_src_core , 0x00, 0, "core", 1000 

Re: [Nouveau] [PATCH v4 30/37] clk: seperate the locking from the implementation in nvkm_clk_update

2016-04-20 Thread Martin Peres

sepArate

On 18/04/16 22:14, Karol Herbst wrote:

Would be nice to say what for.

With a better commit message and the typo fixed:

Reviewed-by: Martin Peres <martin.pe...@free.fr>

Signed-off-by: Karol Herbst <nouv...@karolherbst.de>
---
  drm/nouveau/nvkm/subdev/clk/base.c | 16 
  1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drm/nouveau/nvkm/subdev/clk/base.c 
b/drm/nouveau/nvkm/subdev/clk/base.c
index 7f86e41..d6f239f 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -319,14 +319,11 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstateid)
  }
  
  static void

-nvkm_clk_update_work(struct work_struct *work)
+nvkm_clk_update_impl(struct nvkm_clk *clk)
  {
-   struct nvkm_clk *clk = container_of(work, typeof(*clk), work);
struct nvkm_subdev *subdev = >subdev;
int pstate, ret;
  
-	if (!atomic_xchg(>waiting, 0))

-   return;
clk->pwrsrc = power_supply_is_system_supplied();
  
  	if (clk->pstate)

@@ -350,6 +347,17 @@ nvkm_clk_update_work(struct work_struct *work)
nvkm_error(subdev, "error setting pstate %d: %d\n",
   pstate, ret);
}
+}
+
+static void
+nvkm_clk_update_work(struct work_struct *work)
+{
+   struct nvkm_clk *clk = container_of(work, typeof(*clk), work);
+
+   if (!atomic_xchg(>waiting, 0))
+   return;
+
+   nvkm_clk_update_impl(clk);
  
  	wake_up_all(>wait);

nvkm_notify_get(>pwrsrc_ntfy);


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


Re: [Nouveau] [PATCH v4 29/37] clk: we should pass the pstate id around not the index in the list

2016-04-20 Thread Martin Peres

On 18/04/16 22:14, Karol Herbst wrote:

this makes the code easier, because we can compare the id with pstate->pstate
and safe us the trouble iterating over the entire pstate list

save us.

Not the easiest patch to read, but it seems alright and it has been 
tested, so:


Reviewed-by: Martin Peres <martin.pe...@free.fr>


Signed-off-by: Karol Herbst <nouv...@karolherbst.de>
---
  drm/nouveau/nouveau_debugfs.c  |  6 ++---
  drm/nouveau/nvkm/subdev/clk/base.c | 49 +++---
  2 files changed, 17 insertions(+), 38 deletions(-)

diff --git a/drm/nouveau/nouveau_debugfs.c b/drm/nouveau/nouveau_debugfs.c
index 31b309f..334b472 100644
--- a/drm/nouveau/nouveau_debugfs.c
+++ b/drm/nouveau/nouveau_debugfs.c
@@ -96,11 +96,11 @@ nouveau_debugfs_pstate_get(struct seq_file *m, void *data)
} while (attr.index);
  
  		if (state >= 0) {

-   if (info.ustate_ac == state)
+   if (info.ustate_ac == attr.state)
seq_printf(m, " AC");
-   if (info.ustate_dc == state)
+   if (info.ustate_dc == attr.state)
seq_printf(m, " DC");
-   if (info.pstate == state)
+   if (info.pstate == attr.state)
seq_printf(m, " *");
} else {
if (info.ustate_ac < -1)
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c 
b/drm/nouveau/nvkm/subdev/clk/base.c
index 23f4cfe..7f86e41 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -280,23 +280,26 @@ nvkm_cstate_new(struct nvkm_clk *clk, int idx, struct 
nvkm_pstate *pstate)
   * P-States
   
*/
  static int
-nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)
+nvkm_pstate_prog(struct nvkm_clk *clk, int pstateid)
  {
struct nvkm_subdev *subdev = >subdev;
struct nvkm_fb *fb = subdev->device->fb;
struct nvkm_pci *pci = subdev->device->pci;
struct nvkm_pstate *pstate;
-   int ret, idx = 0;
+   int ret;
  
-	if (pstatei == -1)

+   if (pstateid == -1)
return 0;
  
  	list_for_each_entry(pstate, >states, head) {

-   if (idx++ == pstatei)
+   if (pstate->pstate == pstateid)
break;
}
  
-	nvkm_debug(subdev, "setting performance state %d\n", pstatei);

+   if (!pstate)
+   return -EINVAL;
+
+   nvkm_debug(subdev, "setting performance state %x\n", pstateid);
clk->pstate = pstate;
  
  	nvkm_pcie_set_link(pci, pstate->pcie_speed, pstate->pcie_width);

@@ -496,30 +499,6 @@ nvkm_pstate_new(struct nvkm_clk *clk, int idx)
   * Adjustment triggers
   
*/
  static int
-nvkm_clk_ustate_update(struct nvkm_clk *clk, int req)
-{
-   struct nvkm_pstate *pstate;
-   int i = 0;
-
-   if (!clk->allow_reclock)
-   return -ENOSYS;
-
-   if (req != -1 && req != -2) {
-   list_for_each_entry(pstate, >states, head) {
-   if (pstate->pstate == req)
-   break;
-   i++;
-   }
-
-   if (pstate->pstate != req)
-   return -EINVAL;
-   req = i;
-   }
-
-   return req + 2;
-}
-
-static int
  nvkm_clk_nstate(struct nvkm_clk *clk, const char *mode, int arglen)
  {
int ret = 1;
@@ -533,23 +512,23 @@ nvkm_clk_nstate(struct nvkm_clk *clk, const char *mode, 
int arglen)
  
  		((char *)mode)[arglen] = '\0';

if (!kstrtol(mode, 0, )) {
-   ret = nvkm_clk_ustate_update(clk, v);
+   ret = v;
if (ret < 0)
ret = 1;
}
((char *)mode)[arglen] = save;
}
  
-	return ret - 2;

+   return ret;
  }
  
  int

  nvkm_clk_ustate(struct nvkm_clk *clk, int req, int pwr)
  {
-   int ret = nvkm_clk_ustate_update(clk, req);
+   int ret = req;
if (ret >= 0) {
-   if (ret -= 2, pwr) clk->ustate_ac = ret;
-   else   clk->ustate_dc = ret;
+   if (pwr) clk->ustate_ac = ret;
+   else clk->ustate_dc = ret;
clk->exp_cstate = NVKM_CLK_CSTATE_HIGHEST;
return nvkm_clk_update(clk, true);
}
@@ -623,7 +602,7 @@ nvkm_clk_init(struct nvkm_subdev *subdev)
if (clk->func->init)
return clk->func->init(clk);
  
-	clk->astate = clk->state_nr - 1;

+   clk->astate = -1;
clk->pstate = NULL;
clk->exp_cst

Re: [Nouveau] [PATCH v4 28/37] clk: hold information about the current cstate status

2016-04-20 Thread Martin Peres

On 18/04/16 22:14, Karol Herbst wrote:

Signed-off-by: Karol Herbst <nouv...@karolherbst.de>
---
  drm/nouveau/include/nvkm/subdev/clk.h |  5 +
  drm/nouveau/nvkm/subdev/clk/base.c| 32 +---
  2 files changed, 30 insertions(+), 7 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h 
b/drm/nouveau/include/nvkm/subdev/clk.h
index 4fb2c1b..6deda96 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -95,6 +95,11 @@ struct nvkm_clk {
int ustate_ac; /* user-requested (-1 disabled, -2 perfmon) */
int ustate_dc; /* user-requested (-1 disabled, -2 perfmon) */
int astate; /* perfmon adjustment (base) */
+   struct nvkm_cstate *set_cstate;
+#define NVKM_CLK_CSTATE_DEFAULT -1
+#define NVKM_CLK_CSTATE_BASE-2
+#define NVKM_CLK_CSTATE_HIGHEST -3
+   int exp_cstate;
  
  	bool allow_reclock;

  #define NVKM_CLK_BOOST_NONE 0x0
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c 
b/drm/nouveau/nvkm/subdev/clk/base.c
index 762dfe2..23f4cfe 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -152,9 +152,14 @@ static struct nvkm_cstate *
  nvkm_cstate_get(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
  {
struct nvkm_cstate *cstate;
-   if (cstatei == -1)
+   switch (cstatei) {
+   case NVKM_CLK_CSTATE_HIGHEST:
return list_entry(pstate->list.prev, typeof(*cstate), head);
-   else {
+   case NVKM_CLK_CSTATE_BASE:
+   return >base;
+   case NVKM_CLK_CSTATE_DEFAULT:
+   return NULL;
+   default:
list_for_each_entry(cstate, >list, head) {
if (cstate->cstate == cstatei)
return cstate;
@@ -173,6 +178,9 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate 
*pstate, int cstatei)
struct nvkm_cstate *cstate;
int ret;
  
+	if (cstatei == NVKM_CLK_CSTATE_DEFAULT)

+   return 0;
+
if (!list_empty(>list)) {
cstate = nvkm_cstate_get(clk, pstate, cstatei);
cstate = nvkm_cstate_find_best(clk, pstate, cstate);
@@ -199,6 +207,7 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate 
*pstate, int cstatei)
  
  	ret = clk->func->calc(clk, cstate);

if (ret == 0) {
+   clk->set_cstate = cstate;
ret = clk->func->prog(clk);
clk->func->tidy(clk);
}
@@ -303,7 +312,7 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)
ram->func->tidy(ram);
}
  
-	return nvkm_cstate_prog(clk, pstate, -1);

+   return nvkm_cstate_prog(clk, pstate, clk->exp_cstate);
  }
  
  static void

@@ -321,9 +330,9 @@ nvkm_clk_update_work(struct work_struct *work)
pstate = clk->pstate->pstate;
else
pstate = -1;
-   nvkm_trace(subdev, "P %d PWR %d U(AC) %d U(DC) %d A %d\n",
+   nvkm_trace(subdev, "P %d PWR %d U(AC) %d U(DC) %d A %d C %d\n",
   pstate, clk->pwrsrc, clk->ustate_ac, clk->ustate_dc,
-  clk->astate);
+  clk->astate, clk->exp_cstate);
  
  	pstate = clk->pwrsrc ? clk->ustate_ac : clk->ustate_dc;

if (clk->state_nr && pstate != -1) {
@@ -541,6 +550,7 @@ nvkm_clk_ustate(struct nvkm_clk *clk, int req, int pwr)
if (ret >= 0) {
if (ret -= 2, pwr) clk->ustate_ac = ret;
else   clk->ustate_dc = ret;
+   clk->exp_cstate = NVKM_CLK_CSTATE_HIGHEST;


I am really not a fan of this astate. We will revisit this when we are 
done with manual reclocking!


In the mean time, this is:

Reviewed-by: Martin Peres <martin.pe...@free.fr>


return nvkm_clk_update(clk, true);
}
return ret;
@@ -553,6 +563,7 @@ nvkm_clk_astate(struct nvkm_clk *clk, int req, int rel, 
bool wait)
if ( rel) clk->astate += rel;
clk->astate = min(clk->astate, clk->state_nr - 1);
clk->astate = max(clk->astate, 0);
+   clk->exp_cstate = NVKM_CLK_CSTATE_BASE;
return nvkm_clk_update(clk, wait);
  }
  
@@ -614,6 +625,8 @@ nvkm_clk_init(struct nvkm_subdev *subdev)
  
  	clk->astate = clk->state_nr - 1;

clk->pstate = NULL;
+   clk->exp_cstate = NVKM_CLK_CSTATE_DEFAULT;
+   clk->set_cstate = NULL;
nvkm_clk_update(clk, true);
return 0;
  }
@@ -698,15 +711,20 @@ nvkm_clk_ctor(const struct nvkm_clk_func *func, struct 
nvkm_device *device,
if (mode) {
clk->ustate_ac = nvkm_clk_nstate(clk, mode, arglen);
clk->ustate_dc = nvkm_clk_nstate(clk, mode, arglen);
+   clk->exp_cstate = NVKM_CLK_CSTATE_HIGHEST;
}
  
  	mode = nvkm_st

Re: [Nouveau] [PATCH v4 27/37] clk: make pstate a pointer to nvkm_pstate

2016-04-20 Thread Martin Peres

On 18/04/16 22:14, Karol Herbst wrote:

we will access the current set cstate at least every second and this safes us

saves

some CPU cycles looking them up every second.

Signed-off-by: Karol Herbst 
---
  drm/nouveau/include/nvkm/subdev/clk.h |  2 +-
  drm/nouveau/nvkm/engine/device/ctrl.c |  5 -
  drm/nouveau/nvkm/subdev/clk/base.c| 12 
  drm/nouveau/nvkm/subdev/pmu/gk20a.c   | 23 +++
  4 files changed, 20 insertions(+), 22 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h 
b/drm/nouveau/include/nvkm/subdev/clk.h
index db52e65..4fb2c1b 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -91,7 +91,7 @@ struct nvkm_clk {
  
  	struct nvkm_notify pwrsrc_ntfy;

int pwrsrc;
-   int pstate; /* current */
+   struct nvkm_pstate *pstate; /* current */
int ustate_ac; /* user-requested (-1 disabled, -2 perfmon) */
int ustate_dc; /* user-requested (-1 disabled, -2 perfmon) */
int astate; /* perfmon adjustment (base) */
diff --git a/drm/nouveau/nvkm/engine/device/ctrl.c 
b/drm/nouveau/nvkm/engine/device/ctrl.c
index 039e8a4..cb85266 100644
--- a/drm/nouveau/nvkm/engine/device/ctrl.c
+++ b/drm/nouveau/nvkm/engine/device/ctrl.c
@@ -52,7 +52,10 @@ nvkm_control_mthd_pstate_info(struct nvkm_control *ctrl, 
void *data, u32 size)
args->v0.ustate_ac = clk->ustate_ac;
args->v0.ustate_dc = clk->ustate_dc;
args->v0.pwrsrc = clk->pwrsrc;
-   args->v0.pstate = clk->pstate;
+   if (clk->pstate)
+   args->v0.pstate = clk->pstate->pstate;
+   else
+   args->v0.pstate = -1;
} else {
args->v0.count = 0;
args->v0.ustate_ac = NVIF_CONTROL_PSTATE_INFO_V0_USTATE_DISABLE;
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c 
b/drm/nouveau/nvkm/subdev/clk/base.c
index 3867ab7..762dfe2 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -288,7 +288,7 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)
}
  
  	nvkm_debug(subdev, "setting performance state %d\n", pstatei);

-   clk->pstate = pstatei;
+   clk->pstate = pstate;
  
  	nvkm_pcie_set_link(pci, pstate->pcie_speed, pstate->pcie_width);
  
@@ -317,15 +317,19 @@ nvkm_clk_update_work(struct work_struct *work)

return;
clk->pwrsrc = power_supply_is_system_supplied();
  
+	if (clk->pstate)

+   pstate = clk->pstate->pstate;
+   else
+   pstate = -1;
nvkm_trace(subdev, "P %d PWR %d U(AC) %d U(DC) %d A %d\n",
-  clk->pstate, clk->pwrsrc, clk->ustate_ac, clk->ustate_dc,
+  pstate, clk->pwrsrc, clk->ustate_ac, clk->ustate_dc,
   clk->astate);
  
  	pstate = clk->pwrsrc ? clk->ustate_ac : clk->ustate_dc;

if (clk->state_nr && pstate != -1) {
pstate = (pstate < 0) ? clk->astate : pstate;
} else {
-   pstate = clk->pstate = -1;
+   pstate = -1;


Isn't "clk->pstate = NULL;" missing here? Why did you change this code 
otherwise?


}
  
  	nvkm_trace(subdev, "-> %d\n", pstate);

@@ -609,7 +613,7 @@ nvkm_clk_init(struct nvkm_subdev *subdev)
return clk->func->init(clk);
  
  	clk->astate = clk->state_nr - 1;

-   clk->pstate = -1;
+   clk->pstate = NULL;
nvkm_clk_update(clk, true);
return 0;
  }
diff --git a/drm/nouveau/nvkm/subdev/pmu/gk20a.c 
b/drm/nouveau/nvkm/subdev/pmu/gk20a.c
index f996d90..6f0d290 100644
--- a/drm/nouveau/nvkm/subdev/pmu/gk20a.c
+++ b/drm/nouveau/nvkm/subdev/pmu/gk20a.c
@@ -57,24 +57,21 @@ gk20a_pmu_dvfs_target(struct gk20a_pmu *pmu, int *state)
  }
  
  static int

-gk20a_pmu_dvfs_get_cur_state(struct gk20a_pmu *pmu, int *state)
-{
-   struct nvkm_clk *clk = pmu->base.subdev.device->clk;
-
-   *state = clk->pstate;
-   return 0;
-}
-
-static int
  gk20a_pmu_dvfs_get_target_state(struct gk20a_pmu *pmu,
int *state, int load)
  {
struct gk20a_pmu_dvfs_data *data = pmu->data;
struct nvkm_clk *clk = pmu->base.subdev.device->clk;
+   struct nvkm_pstate *pstate = clk->pstate;
int cur_level, level;
  
+	if (!pstate) {

+   *state = 0;
+   return 1;
+   }
+
/* For GK20A, the performance level is directly mapped to pstate */
-   level = cur_level = clk->pstate;
+   level = cur_level = clk->pstate->pstate;
  
  	if (load > data->p_load_max) {

level = min(clk->state_nr - 1, level + (clk->state_nr / 3));
@@ -150,12 +147,6 @@ gk20a_pmu_dvfs_work(struct nvkm_alarm *alarm)
nvkm_trace(subdev, "utilization = %d %%, avg_load = %d %%\n",
   utilization, data->avg_load);
  
-	ret = gk20a_pmu_dvfs_get_cur_state(pmu, );

-   if (ret) {
-   

Re: [Nouveau] [PATCH v4 26/37] therm: don't cancel the timer

2016-04-20 Thread Martin Peres

On 18/04/16 22:14, Karol Herbst wrote:

we will need a always running therm daemon to adjust the voltage/clocks on the
fly.

Signed-off-by: Karol Herbst <nouv...@karolherbst.de>


Reviewed-by: Martin Peres <martin.pe...@free.fr>

---
  drm/nouveau/nvkm/subdev/therm/base.c | 9 ++---
  1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drm/nouveau/nvkm/subdev/therm/base.c 
b/drm/nouveau/nvkm/subdev/therm/base.c
index 8894fee..0c0feec 100644
--- a/drm/nouveau/nvkm/subdev/therm/base.c
+++ b/drm/nouveau/nvkm/subdev/therm/base.c
@@ -92,7 +92,6 @@ nvkm_therm_update(struct nvkm_therm *therm, int mode)
struct nvkm_timer *tmr = subdev->device->timer;
unsigned long flags;
bool immd = true;
-   bool poll = true;
int duty = -1;
  
  	spin_lock_irqsave(>lock, flags);

@@ -102,11 +101,9 @@ nvkm_therm_update(struct nvkm_therm *therm, int mode)
  
  	switch (mode) {

case NVKM_THERM_CTRL_MANUAL:
-   nvkm_timer_alarm_cancel(tmr, >alarm);
duty = nvkm_therm_fan_get(therm);
if (duty < 0)
duty = 100;
-   poll = false;
break;
case NVKM_THERM_CTRL_AUTO:
switch(therm->fan->bios.fan_mode) {
@@ -119,18 +116,16 @@ nvkm_therm_update(struct nvkm_therm *therm, int mode)
case NVBIOS_THERM_FAN_OTHER:
if (therm->cstate)
duty = therm->cstate;
-   poll = false;
break;
}
immd = false;
break;
case NVKM_THERM_CTRL_NONE:
default:
-   nvkm_timer_alarm_cancel(tmr, >alarm);
-   poll = false;
+   break;
}
  
-	if (list_empty(>alarm.head) && poll)

+   if (list_empty(>alarm.head))
nvkm_timer_alarm(tmr, 10ULL, >alarm);
spin_unlock_irqrestore(>lock, flags);
  


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


Re: [Nouveau] [PATCH v4 25/37] clk: remove dstate and tstate

2016-04-20 Thread Martin Peres

On 20/04/16 23:45, Martin Peres wrote:

On 18/04/16 22:13, Karol Herbst wrote:

we won't need them, because we will adjust the clocks depending on engine loads
later on anyway. It also simplifies the clocking logic.

You can also say that the code was just mocked up anyway.


Forgot to give my R-b!

Reviewed-by: Martin Peres <martin.pe...@free.fr>
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH v4 25/37] clk: remove dstate and tstate

2016-04-20 Thread Martin Peres

On 18/04/16 22:13, Karol Herbst wrote:

we won't need them, because we will adjust the clocks depending on engine loads
later on anyway. It also simplifies the clocking logic.


You can also say that the code was just mocked up anyway.



Signed-off-by: Karol Herbst 
---
  drm/nouveau/include/nvkm/subdev/clk.h |  4 
  drm/nouveau/nvkm/subdev/clk/base.c| 28 ++--
  2 files changed, 2 insertions(+), 30 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h 
b/drm/nouveau/include/nvkm/subdev/clk.h
index 77d94c1..db52e65 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -95,8 +95,6 @@ struct nvkm_clk {
int ustate_ac; /* user-requested (-1 disabled, -2 perfmon) */
int ustate_dc; /* user-requested (-1 disabled, -2 perfmon) */
int astate; /* perfmon adjustment (base) */
-   int tstate; /* thermal adjustment (max-) */
-   int dstate; /* display adjustment (min+) */
  
  	bool allow_reclock;

  #define NVKM_CLK_BOOST_NONE 0x0
@@ -118,8 +116,6 @@ struct nvkm_clk {
  int nvkm_clk_read(struct nvkm_clk *, enum nv_clk_src);
  int nvkm_clk_ustate(struct nvkm_clk *, int req, int pwr);
  int nvkm_clk_astate(struct nvkm_clk *, int req, int rel, bool wait);
-int nvkm_clk_dstate(struct nvkm_clk *, int req, int rel);
-int nvkm_clk_tstate(struct nvkm_clk *, int req, int rel);
  int nvkm_clk_update(struct nvkm_clk *, bool wait);
  
  int nv04_clk_new(struct nvkm_device *, int, struct nvkm_clk **);

diff --git a/drm/nouveau/nvkm/subdev/clk/base.c 
b/drm/nouveau/nvkm/subdev/clk/base.c
index bfc6a49..3867ab7 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -317,15 +317,13 @@ nvkm_clk_update_work(struct work_struct *work)
return;
clk->pwrsrc = power_supply_is_system_supplied();
  
-	nvkm_trace(subdev, "P %d PWR %d U(AC) %d U(DC) %d A %d T %d D %d\n",

+   nvkm_trace(subdev, "P %d PWR %d U(AC) %d U(DC) %d A %d\n",
   clk->pstate, clk->pwrsrc, clk->ustate_ac, clk->ustate_dc,
-  clk->astate, clk->tstate, clk->dstate);
+  clk->astate);
  
  	pstate = clk->pwrsrc ? clk->ustate_ac : clk->ustate_dc;

if (clk->state_nr && pstate != -1) {
pstate = (pstate < 0) ? clk->astate : pstate;
-   pstate = min(pstate, clk->state_nr - 1 + clk->tstate);
-   pstate = max(pstate, clk->dstate);
} else {
pstate = clk->pstate = -1;
}
@@ -554,26 +552,6 @@ nvkm_clk_astate(struct nvkm_clk *clk, int req, int rel, 
bool wait)
return nvkm_clk_update(clk, wait);
  }
  
-int

-nvkm_clk_tstate(struct nvkm_clk *clk, int req, int rel)
-{
-   if (!rel) clk->tstate  = req;
-   if ( rel) clk->tstate += rel;
-   clk->tstate = min(clk->tstate, 0);
-   clk->tstate = max(clk->tstate, -(clk->state_nr - 1));
-   return nvkm_clk_update(clk, true);
-}
-
-int
-nvkm_clk_dstate(struct nvkm_clk *clk, int req, int rel)
-{
-   if (!rel) clk->dstate  = req;
-   if ( rel) clk->dstate += rel;
-   clk->dstate = min(clk->dstate, clk->state_nr - 1);
-   clk->dstate = max(clk->dstate, 0);
-   return nvkm_clk_update(clk, true);
-}
-
  static int
  nvkm_clk_pwrsrc(struct nvkm_notify *notify)
  {
@@ -631,8 +609,6 @@ nvkm_clk_init(struct nvkm_subdev *subdev)
return clk->func->init(clk);
  
  	clk->astate = clk->state_nr - 1;

-   clk->tstate = 0;
-   clk->dstate = 0;
clk->pstate = -1;
nvkm_clk_update(clk, true);
return 0;


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


Re: [Nouveau] [PATCH v4 22/37] clk: rename nvkm_pstate_calc to nvkm_clk_update

2016-04-20 Thread Martin Peres

On 18/04/16 22:13, Karol Herbst wrote:

this function will be used to update the current clock state.

This will happen for various reasons:
  * temperature changes (may change cstate and/or voltage)
  * user changes boost mode
  * load changes

v2: add wait parameter

Signed-off-by: Karol Herbst 
---
  drm/nouveau/include/nvkm/subdev/clk.h |  1 +
  drm/nouveau/nvkm/subdev/clk/base.c| 46 ---
  2 files changed, 28 insertions(+), 19 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h 
b/drm/nouveau/include/nvkm/subdev/clk.h
index 61d99fd..77d94c1 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -120,6 +120,7 @@ int nvkm_clk_ustate(struct nvkm_clk *, int req, int pwr);
  int nvkm_clk_astate(struct nvkm_clk *, int req, int rel, bool wait);
  int nvkm_clk_dstate(struct nvkm_clk *, int req, int rel);
  int nvkm_clk_tstate(struct nvkm_clk *, int req, int rel);
+int nvkm_clk_update(struct nvkm_clk *, bool wait);
  
  int nv04_clk_new(struct nvkm_device *, int, struct nvkm_clk **);

  int nv40_clk_new(struct nvkm_device *, int, struct nvkm_clk **);
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c 
b/drm/nouveau/nvkm/subdev/clk/base.c
index 1ca25dd..bfc6a49 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -274,11 +274,14 @@ static int
  nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)
  {
struct nvkm_subdev *subdev = >subdev;
-   struct nvkm_ram *ram = subdev->device->fb->ram;
+   struct nvkm_fb *fb = subdev->device->fb;
struct nvkm_pci *pci = subdev->device->pci;
struct nvkm_pstate *pstate;
int ret, idx = 0;
  
+	if (pstatei == -1)

+   return 0;
+
list_for_each_entry(pstate, >states, head) {
if (idx++ == pstatei)
break;
@@ -289,7 +292,8 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)
  
  	nvkm_pcie_set_link(pci, pstate->pcie_speed, pstate->pcie_width);
  
-	if (ram && ram->func->calc) {

+   if (fb && fb->ram && fb->ram->func->calc) {
+   struct nvkm_ram *ram = fb->ram;
int khz = pstate->base.domain[nv_clk_src_mem];
do {
ret = ram->func->calc(ram, khz);


All the changes to this file do not belong to this patch. What are you 
doing here anyway?

@@ -303,11 +307,11 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)
  }
  
  static void

-nvkm_pstate_work(struct work_struct *work)
+nvkm_clk_update_work(struct work_struct *work)
  {
struct nvkm_clk *clk = container_of(work, typeof(*clk), work);
struct nvkm_subdev *subdev = >subdev;
-   int pstate;
+   int pstate, ret;
  
  	if (!atomic_xchg(>waiting, 0))

return;
@@ -327,21 +331,25 @@ nvkm_pstate_work(struct work_struct *work)
}
  
  	nvkm_trace(subdev, "-> %d\n", pstate);

-   if (pstate != clk->pstate) {
-   int ret = nvkm_pstate_prog(clk, pstate);
-   if (ret) {
-   nvkm_error(subdev, "error setting pstate %d: %d\n",
-  pstate, ret);
-   }
+   ret = nvkm_pstate_prog(clk, pstate);
+   if (ret) {
+   nvkm_error(subdev, "error setting pstate %d: %d\n",
+  pstate, ret);
}

Why did you get rid of the if?

  
  	wake_up_all(>wait);

nvkm_notify_get(>pwrsrc_ntfy);
  }
  
-static int

-nvkm_pstate_calc(struct nvkm_clk *clk, bool wait)
+int
+nvkm_clk_update(struct nvkm_clk *clk, bool wait)
  {
+   if (!clk)
+   return -EINVAL;
+
+   if (!clk->allow_reclock)
+   return -ENODEV;


This is also not part of the rename. Why do you meed this suddenly?

+
atomic_set(>waiting, 1);
schedule_work(>work);
if (wait)
@@ -531,7 +539,7 @@ nvkm_clk_ustate(struct nvkm_clk *clk, int req, int pwr)
if (ret >= 0) {
if (ret -= 2, pwr) clk->ustate_ac = ret;
else   clk->ustate_dc = ret;
-   return nvkm_pstate_calc(clk, true);
+   return nvkm_clk_update(clk, true);
}
return ret;
  }
@@ -543,7 +551,7 @@ nvkm_clk_astate(struct nvkm_clk *clk, int req, int rel, 
bool wait)
if ( rel) clk->astate += rel;
clk->astate = min(clk->astate, clk->state_nr - 1);
clk->astate = max(clk->astate, 0);
-   return nvkm_pstate_calc(clk, wait);
+   return nvkm_clk_update(clk, wait);
  }
  
  int

@@ -553,7 +561,7 @@ nvkm_clk_tstate(struct nvkm_clk *clk, int req, int rel)
if ( rel) clk->tstate += rel;
clk->tstate = min(clk->tstate, 0);
clk->tstate = max(clk->tstate, -(clk->state_nr - 1));
-   return nvkm_pstate_calc(clk, true);
+   return nvkm_clk_update(clk, true);
  }
  
  int

@@ -563,7 +571,7 @@ nvkm_clk_dstate(struct nvkm_clk *clk, int req, int rel)
if ( 

Re: [Nouveau] [PATCH v4 21/37] clk: save the max clock we can set

2016-04-19 Thread Martin Peres

On 18/04/16 22:13, Karol Herbst wrote:

Signed-off-by: Karol Herbst <nouv...@karolherbst.de>


Reviewed-by: Martin Peres <martin.pe...@free.fr>

---
  drm/nouveau/include/nvkm/subdev/clk.h | 1 +
  drm/nouveau/nvkm/subdev/clk/base.c| 2 ++
  2 files changed, 3 insertions(+)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h 
b/drm/nouveau/include/nvkm/subdev/clk.h
index 99ee05c..61d99fd 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -105,6 +105,7 @@ struct nvkm_clk {
u8  boost_mode;
u32 base_khz;
u32 boost_khz;
+   u32 max_khz;
  
  	/*XXX: die, these are here *only* to support the completely

 * bat-shit insane what-was-nouveau_hw.c code
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c 
b/drm/nouveau/nvkm/subdev/clk/base.c
index a9a3666..1ca25dd 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -257,6 +257,8 @@ nvkm_cstate_new(struct nvkm_clk *clk, int idx, struct 
nvkm_pstate *pstate)
u32 freq = nvkm_clk_adjust(clk, true, pstate->pstate,
   domain->bios, cstepX.freq);
cstate->domain[domain->name] = freq;
+   if (domain->flags & NVKM_CLK_DOM_FLAG_BASECLK)
+   clk->max_khz = max(clk->max_khz, freq);
}
domain++;
}


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


Re: [Nouveau] [PATCH v4 20/37] volt: add coefficients

2016-04-19 Thread Martin Peres

On 20/04/16 00:54, Ilia Mirkin wrote:

On Tue, Apr 19, 2016 at 5:52 PM, Martin Peres <martin.pe...@free.fr> wrote:

+   result =  ((s64)info.arg[0] * 15625) >>
18;
+   result += ((s64)info.arg[1] * volt->speedo
* 15625) >> 18;
+   result += ((s64)info.arg[2] * temp *
15625) >> 10;
+   result += ((s64)info.arg[3] * volt->speedo
* temp * 15625) >> 18;
+   result += ((s64)info.arg[4] * volt->speedo
* volt->speedo * 15625) >> 30;
+   result += ((s64)info.arg[5] * temp * temp
* 15625) >> 18;
+   break;


Well, I can only say that these values got us really really close to what
nvidia does... On around 10 GPUs... So... until we know better, let's stick
to them.

Hopefully, we can figure out where this 15625 comes from. This patch is:

5^6. Really it's 10^6, but it's silly to multiply by 10^6 and then
divide by powers of 2. Instead that's factored out...


That makes sense. I must have missed this on the IRC discussion.

Major congrats to Karol and you for figuring out all of this!

@Ben: I really think this is the right thing to do, it really was solid 
work for Karol's part.

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


Re: [Nouveau] [PATCH v4 20/37] volt: add coefficients

2016-04-19 Thread Martin Peres

On 18/04/16 22:13, Karol Herbst wrote:

I am sure that those are a bit different, but while testing the biggest error
compared to nvidia was -1.5%.


Is this still true? I thought we were *much* closer now.



Without this change we are most of the time around 10% below nvidias voltage,
so this change causes no harm and improves the situation a lot already.


Yeah, this is definitely not up to date!



These coefficients were REed by modifing the voltage map entries and by
calculating the set voltage back until I was able to forecast which voltage
nvidia sets for a given voltage map entry.

v4: use better coefficients and speedo

Signed-off-by: Karol Herbst <nouv...@karolherbst.de>
---
  drm/nouveau/nvkm/subdev/volt/base.c | 38 +++--
  1 file changed, 36 insertions(+), 2 deletions(-)

diff --git a/drm/nouveau/nvkm/subdev/volt/base.c 
b/drm/nouveau/nvkm/subdev/volt/base.c
index cecfac6..5e35d96 100644
--- a/drm/nouveau/nvkm/subdev/volt/base.c
+++ b/drm/nouveau/nvkm/subdev/volt/base.c
@@ -110,13 +110,47 @@ nvkm_volt_map(struct nvkm_volt *volt, u8 id, u8 temp)
  
  	vmap = nvbios_vmap_entry_parse(bios, id, , , );

if (vmap) {
+   s64 result;
+
+   if (volt->speedo < 0)
+   return volt->speedo;


Hmm, so you will refuse reclocking if the speedo cannot be read... 
Fair-enough, but I would like to see a warning in the kernel logs.



+
+   if (ver == 0x10 || (ver == 0x20 && info.mode == 0)) {
+   result  =  (s64)info.arg[0] / 10;
+   result += ((s64)info.arg[1] * volt->speedo) / 10;
+   result += ((s64)info.arg[2] * volt->speedo * 
volt->speedo) / 10;
+   } else if (ver == 0x20) {
+   switch (info.mode) {
+   /* 0x0 handled above! */
+   case 0x1:
+   result =  ((s64)info.arg[0] * 15625) >> 18;
+   result += ((s64)info.arg[1] * volt->speedo * 15625) 
>> 18;
+   result += ((s64)info.arg[2] * temp * 15625) >> 
10;
+   result += ((s64)info.arg[3] * volt->speedo * temp * 
15625) >> 18;
+   result += ((s64)info.arg[4] * volt->speedo * 
volt->speedo * 15625) >> 30;
+   result += ((s64)info.arg[5] * temp * temp * 15625) 
>> 18;
+   break;


Well, I can only say that these values got us really really close to 
what nvidia does... On around 10 GPUs... So... until we know better, 
let's stick to them.


Hopefully, we can figure out where this 15625 comes from. This patch is:

Reviewed-by: Martin Peres <martin.pe...@free.fr>


+   case 0x3:
+   result = (info.min + info.max) / 2;
+   break;
+   case 0x2:
+   default:
+   result = info.min;
+   break;
+   }
+   } else {
+   return -ENODEV;
+   }
+
+   result = min(max(result, (s64)info.min), (s64)info.max);
+
if (info.link != 0xff) {
int ret = nvkm_volt_map(volt, info.link, temp);
if (ret < 0)
return ret;
-   info.min += ret;
+   result += ret;
}
-   return info.min;
+   return result;
}
  
  	return id ? id * 1 : -ENODEV;


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


Re: [Nouveau] [PATCH v4 19/37] volt: add gf100 subdev with speedo

2016-04-19 Thread Martin Peres
bute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Karol Herbst
+ */
+#include "priv.h"
+
+#include 
+
+static int
+gf100_volt_speedo_read(struct nvkm_volt *volt)
+{
+   struct nvkm_device *device = volt->subdev.device;
+   struct nvkm_fuse *fuse = device->fuse;
+
+   if (!fuse)
+   return -EINVAL;
+
+   return nvkm_fuse_read(fuse, 0x1cc);
+}
+
+static const struct nvkm_volt_func
+gf100_volt = {
+   .vid_get = nvkm_voltgpio_get,
+   .vid_set = nvkm_voltgpio_set,
+   .speedo_read = gf100_volt_speedo_read,
+};
+
+int
+gf100_volt_new(struct nvkm_device *device, int index, struct nvkm_volt **pvolt)
+{
+   struct nvkm_volt *volt;
+   int ret;
+
+   ret = nvkm_volt_new_(_volt, device, index, );
+   *pvolt = volt;
+   if (ret)
+   return ret;
+
+   return nvkm_voltgpio_init(volt);
+}


This is OK because fuse is initialized before volt 
(drm/nouveau/include/nvkm/core/device.h). This is:


Reviewed-by: Martin Peres <martin.pe...@free.fr>
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH v4 16/37] volt: don't require perfect fit

2016-04-19 Thread Martin Peres

On 18/04/16 22:13, Karol Herbst wrote:

if we calculate the voltage in the table right, we get all kinds of values,
which never fit the hardware steps, so we use the closest higher value the
hardware can do.

v3: simplify the implementation

Signed-off-by: Karol Herbst <nouv...@karolherbst.de>
---
  drm/nouveau/nvkm/subdev/volt/base.c | 22 +-
  1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/drm/nouveau/nvkm/subdev/volt/base.c 
b/drm/nouveau/nvkm/subdev/volt/base.c
index d72bd4a..028c6e2 100644
--- a/drm/nouveau/nvkm/subdev/volt/base.c
+++ b/drm/nouveau/nvkm/subdev/volt/base.c
@@ -51,18 +51,30 @@ static int
  nvkm_volt_set(struct nvkm_volt *volt, u32 uv)
  {
struct nvkm_subdev *subdev = >subdev;
-   int i, ret = -EINVAL;
+   int i, ret = -EINVAL, best_err = uv, best = -1;


"best_err = uv" is not a safe value. You may set best_err to the maximum 
voltage, anything under that may fail in theory.

With this fixed, this is:

Reviewed-by: Martin Peres <martin.pe...@free.fr>

  
  	if (volt->func->volt_set)

return volt->func->volt_set(volt, uv);
  
  	for (i = 0; i < volt->vid_nr; i++) {

-   if (volt->vid[i].uv == uv) {
-   ret = volt->func->vid_set(volt, volt->vid[i].vid);
-   nvkm_debug(subdev, "set %duv: %d\n", uv, ret);
+   int err = volt->vid[i].uv - uv;
+   if (err < 0 || err > best_err)
+   continue;
+
+   best_err = err;
+   best = i;
+   if (best_err == 0)
break;
-   }
}
+
+   if (best == -1) {
+   nvkm_error(subdev, "couldn't set %iuv\n", uv);
+   return ret;
+   }
+
+   ret = volt->func->vid_set(volt, volt->vid[best].vid);
+   nvkm_debug(subdev, "set req %duv to %duv: %d\n", uv,
+  volt->vid[best].uv, ret);
return ret;
  }
  


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


Re: [Nouveau] [PATCH v4 17/37] bios/vmap: unk0 field is the mode

2016-04-19 Thread Martin Peres

On 18/04/16 22:13, Karol Herbst wrote:

this selects which formula is used to calculate the voltage.

depending on the value, the entry maps to a different voltage and even enables
if the temperature has any effect or not. This is easy to observe with the
binary driver.

Signed-off-by: Karol Herbst <nouv...@karolherbst.de>


Reviewed-by: Martin Peres <martin.pe...@free.fr>

---
  drm/nouveau/include/nvkm/subdev/bios/vmap.h | 2 +-
  drm/nouveau/nvkm/subdev/bios/vmap.c | 2 +-
  2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/bios/vmap.h 
b/drm/nouveau/include/nvkm/subdev/bios/vmap.h
index ae2f27b..8fa1294 100644
--- a/drm/nouveau/include/nvkm/subdev/bios/vmap.h
+++ b/drm/nouveau/include/nvkm/subdev/bios/vmap.h
@@ -11,7 +11,7 @@ u16 nvbios_vmap_parse(struct nvkm_bios *, u8 *ver, u8 *hdr, 
u8 *cnt, u8 *len,
  struct nvbios_vmap *);
  
  struct nvbios_vmap_entry {

-   u8  unk0;
+   u8  mode;
u8  link;
u32 min;
u32 max;
diff --git a/drm/nouveau/nvkm/subdev/bios/vmap.c 
b/drm/nouveau/nvkm/subdev/bios/vmap.c
index f2295e1..32bd8b1 100644
--- a/drm/nouveau/nvkm/subdev/bios/vmap.c
+++ b/drm/nouveau/nvkm/subdev/bios/vmap.c
@@ -105,7 +105,7 @@ nvbios_vmap_entry_parse(struct nvkm_bios *bios, int idx, u8 
*ver, u8 *len,
info->arg[2] = nvbios_rd32(bios, vmap + 0x10);
break;
case 0x20:
-   info->unk0   = nvbios_rd08(bios, vmap + 0x00);
+   info->mode   = nvbios_rd08(bios, vmap + 0x00);
info->link   = nvbios_rd08(bios, vmap + 0x01);
info->min= nvbios_rd32(bios, vmap + 0x02);
info->max= nvbios_rd32(bios, vmap + 0x06);


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


Re: [Nouveau] [PATCH v4 18/37] volt: add speedo

2016-04-19 Thread Martin Peres

On 18/04/16 22:13, Karol Herbst wrote:

Signed-off-by: Karol Herbst <nouv...@karolherbst.de>
---
  bin/nv_cmp_volt.c  |  2 +-
  drm/nouveau/include/nvkm/subdev/volt.h |  2 ++
  drm/nouveau/nvkm/subdev/volt/base.c| 12 
  drm/nouveau/nvkm/subdev/volt/priv.h|  1 +
  4 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/bin/nv_cmp_volt.c b/bin/nv_cmp_volt.c
index 34147b9..e61056c 100644
--- a/bin/nv_cmp_volt.c
+++ b/bin/nv_cmp_volt.c
@@ -53,7 +53,7 @@ main(int argc, char **argv)
  
  	ret = u_device("lib", argv[0], "error", true, true,

 (1ULL << NVKM_SUBDEV_CLK) |
-//   (1ULL << NVKM_SUBDEV_FUSE) |
+   (1ULL << NVKM_SUBDEV_FUSE) |


This change comes a little early, as fuse would be an implementation 
detail (coming in the next patch) to read the speedo.


Either way, I do not really care, as this won't go in the kernel anyway 
and it does not hurt to enable this a little early.


Reviewed-by: Martin Peres <martin.pe...@free.fr>


 (1ULL << NVKM_SUBDEV_GPIO) |
  //   (1ULL << NVKM_SUBDEV_I2C) |
 (1ULL << NVKM_SUBDEV_PCI) |
diff --git a/drm/nouveau/include/nvkm/subdev/volt.h 
b/drm/nouveau/include/nvkm/subdev/volt.h
index f223577..4cb0292 100644
--- a/drm/nouveau/include/nvkm/subdev/volt.h
+++ b/drm/nouveau/include/nvkm/subdev/volt.h
@@ -20,6 +20,8 @@ struct nvkm_volt {
u8 max0_id;
u8 max1_id;
u8 max2_id;
+
+   int speedo;
  };
  
  int nvkm_volt_map(struct nvkm_volt *volt, u8 id, u8 temperature);

diff --git a/drm/nouveau/nvkm/subdev/volt/base.c 
b/drm/nouveau/nvkm/subdev/volt/base.c
index 028c6e2..cecfac6 100644
--- a/drm/nouveau/nvkm/subdev/volt/base.c
+++ b/drm/nouveau/nvkm/subdev/volt/base.c
@@ -201,6 +201,14 @@ nvkm_volt_parse_bios(struct nvkm_bios *bios, struct 
nvkm_volt *volt)
  }
  
  static int

+nvkm_volt_speedo_read(struct nvkm_volt *volt)
+{
+   if (volt->func->speedo_read)
+   return volt->func->speedo_read(volt);
+   return -EINVAL;
+}
+
+static int
  nvkm_volt_init(struct nvkm_subdev *subdev)
  {
struct nvkm_volt *volt = nvkm_volt(subdev);
@@ -262,6 +270,10 @@ nvkm_volt_ctor(const struct nvkm_volt_func *func, struct 
nvkm_device *device,
   volt->vid[i].vid, volt->vid[i].uv);
}
}
+
+   volt->speedo = nvkm_volt_speedo_read(volt);
+   if (volt->speedo > 0)
+   nvkm_debug(>subdev, "speedo %x\n", volt->speedo);
  }
  
  int

diff --git a/drm/nouveau/nvkm/subdev/volt/priv.h 
b/drm/nouveau/nvkm/subdev/volt/priv.h
index d5140d9..9b34e9f 100644
--- a/drm/nouveau/nvkm/subdev/volt/priv.h
+++ b/drm/nouveau/nvkm/subdev/volt/priv.h
@@ -14,6 +14,7 @@ struct nvkm_volt_func {
int (*vid_get)(struct nvkm_volt *);
int (*vid_set)(struct nvkm_volt *, u8 vid);
int (*set_id)(struct nvkm_volt *, u8 id, int condition);
+   int (*speedo_read)(struct nvkm_volt *);
  };
  
  int nvkm_voltgpio_init(struct nvkm_volt *);


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


Re: [Nouveau] [PATCH v4 15/37] clk: allow boosting only when NvBoost is set

2016-04-19 Thread Martin Peres

On 18/04/16 22:13, Karol Herbst wrote:

0: base clock from the vbios is max clock
1: boost only to boost clock from the vbios (default)


As commented upon on IRC, I would prefer us to play it super safe and 
stick to the base
clock until we have power monitoring working, at which point we may make 
1 the default.


Please change it to keep my R-b :)

2: boost to max clock available

v2: moved into nvkm_cstate_valid
v4: check the existence of the clocks before limiting

Signed-off-by: Karol Herbst <nouv...@karolherbst.de>
Reviewed-by: Martin Peres <martin.pe...@free.fr>
---
  drm/nouveau/include/nvkm/subdev/clk.h |  9 -
  drm/nouveau/nvkm/subdev/clk/base.c| 33 -
  drm/nouveau/nvkm/subdev/clk/gf100.c   |  2 +-
  drm/nouveau/nvkm/subdev/clk/gk104.c   |  2 +-
  4 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h 
b/drm/nouveau/include/nvkm/subdev/clk.h
index 6226f0d..99ee05c 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -68,7 +68,8 @@ struct nvkm_pstate {
  struct nvkm_domain {
enum nv_clk_src name;
u8 bios; /* 0xff for none */
-#define NVKM_CLK_DOM_FLAG_CORE 0x01
+#define NVKM_CLK_DOM_FLAG_CORE0x01
+#define NVKM_CLK_DOM_FLAG_BASECLK 0x02
u8 flags;
const char *mname;
int mdiv;
@@ -98,6 +99,12 @@ struct nvkm_clk {
int dstate; /* display adjustment (min+) */
  
  	bool allow_reclock;

+#define NVKM_CLK_BOOST_NONE 0x0
+#define NVKM_CLK_BOOST_AVG  0x1
+#define NVKM_CLK_BOOST_FULL 0x2
+   u8  boost_mode;
+   u32 base_khz;
+   u32 boost_khz;
  
  	/*XXX: die, these are here *only* to support the completely

 * bat-shit insane what-was-nouveau_hw.c code
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c 
b/drm/nouveau/nvkm/subdev/clk/base.c
index 21f6369..a9a3666 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -24,6 +24,7 @@
  #include "priv.h"
  
  #include 

+#include 
  #include 
  #include 
  #include 
@@ -77,9 +78,25 @@ nvkm_clk_adjust(struct nvkm_clk *clk, bool adjust,
  static bool
  nvkm_cstate_valid(struct nvkm_clk *clk, struct nvkm_cstate *cstate, u32 
max_volt, int temp)
  {
+   const struct nvkm_domain *domain = clk->domains;
struct nvkm_volt *volt = clk->subdev.device->volt;
int voltage;
  
+	while (domain && domain->name != nv_clk_src_max) {

+   if (domain->flags & NVKM_CLK_DOM_FLAG_BASECLK) {
+   u32 freq = cstate->domain[domain->name];
+   switch (clk->boost_mode) {
+   case NVKM_CLK_BOOST_NONE:
+   if (clk->base_khz && freq > clk->base_khz)
+   return false;
+   case NVKM_CLK_BOOST_AVG:
+   if (clk->boost_khz && freq > clk->boost_khz)
+   return false;
+   }
+   }
+   domain++;
+   }
+
if (!volt)
return true;
  
@@ -641,10 +658,24 @@ int

  nvkm_clk_ctor(const struct nvkm_clk_func *func, struct nvkm_device *device,
  int index, bool allow_reclock, struct nvkm_clk *clk)
  {
+   struct nvkm_subdev *subdev = >subdev;
+   struct nvkm_bios *bios = device->bios;
int ret, idx, arglen;
const char *mode;
+   struct nvbios_baseclk_header h;
+
+   nvkm_subdev_ctor(_clk, device, index, subdev);
+
+   clk->boost_mode = nvkm_longopt(device->cfgopt, "NvBoost",
+  NVKM_CLK_BOOST_AVG);
+   if (bios && !nvbios_baseclock_parse(bios, )) {
+   struct nvbios_baseclk_entry base, boost;
+   if (!nvbios_baseclock_entry(bios, , h.boost_id, ))
+   clk->boost_khz = boost.clock_mhz * 1000;
+   if (!nvbios_baseclock_entry(bios, , h.base_id, ))
+   clk->base_khz = base.clock_mhz * 1000;
+   }
  
-	nvkm_subdev_ctor(_clk, device, index, >subdev);

clk->func = func;
INIT_LIST_HEAD(>states);
clk->domains = func->domains;
diff --git a/drm/nouveau/nvkm/subdev/clk/gf100.c 
b/drm/nouveau/nvkm/subdev/clk/gf100.c
index 78c449b..71b7c9f 100644
--- a/drm/nouveau/nvkm/subdev/clk/gf100.c
+++ b/drm/nouveau/nvkm/subdev/clk/gf100.c
@@ -443,7 +443,7 @@ gf100_clk = {
{ nv_clk_src_hubk06 , 0x00 },
{ nv_clk_src_hubk01 , 0x01 },
{ nv_clk_src_copy   , 0x02 },
-   { nv_clk_src_gpc, 0x03, 0, "core", 2000 },
+   { nv_clk_src_gpc, 0x03, NVKM_CLK_DOM_FLAG_BASECLK, "core", 
2000 },
{ nv_clk_src_rop, 0x04 },
{ nv_clk_src_mem   

Re: [Nouveau] [PATCH v4 13/37] clk: respect voltage limits in nvkm_cstate_prog

2016-04-19 Thread Martin Peres

On 18/04/16 22:13, Karol Herbst wrote:

we should never allow to select a cstate which current voltage (depending on
the temperature) is higher than

1. the max volt entries in the voltage map table
2. what tha gpu actually can volt to.

this resolves all remaining volting errors on fermi and newer.

v3: use find_best for all cstates before actually trying
 add nvkm_cstate_get function to get cstate by index

Signed-off-by: Karol Herbst <nouv...@karolherbst.de>
---
  drm/nouveau/nvkm/subdev/clk/base.c | 83 +-
  1 file changed, 74 insertions(+), 9 deletions(-)

diff --git a/drm/nouveau/nvkm/subdev/clk/base.c 
b/drm/nouveau/nvkm/subdev/clk/base.c
index fecf58f..21f6369 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -74,6 +74,78 @@ nvkm_clk_adjust(struct nvkm_clk *clk, bool adjust,
  
/**
   * C-States
   
*/
+static bool
+nvkm_cstate_valid(struct nvkm_clk *clk, struct nvkm_cstate *cstate, u32 
max_volt, int temp)
+{
+   struct nvkm_volt *volt = clk->subdev.device->volt;
+   int voltage;
+
+   if (!volt)
+   return true;
+
+   voltage = nvkm_volt_map(volt, cstate->voltage, temp);
+   if (voltage < 0)
+   return false;
+   return voltage <= min(max_volt, volt->max_uv) &&
+  voltage >= volt->min_uv;
+}
+
+static struct nvkm_cstate *
+nvkm_cstate_find_best(struct nvkm_clk *clk, struct nvkm_pstate *pstate,
+ struct nvkm_cstate *start)
+{
+   struct nvkm_device *device = clk->subdev.device;
+   struct nvkm_therm *therm = device->therm;
+   struct nvkm_volt *volt = device->volt;
+   struct nvkm_cstate *cstate;
+   int max_volt, temp = 0;
+
+   if (!pstate || !start)
+   return NULL;
+
+   if (!volt)
+   return start;
+
+   if (therm) {
+   /* ignore error code */
+   temp = max(0, nvkm_therm_temp_get(therm));
+   }
+
+   max_volt = volt->max_uv;
+   if (volt->max0_id != 0xff)
+   max_volt = min(max_volt,
+  nvkm_volt_map(volt, volt->max0_id, temp));
+   if (volt->max1_id != 0xff)
+   max_volt = min(max_volt,
+  nvkm_volt_map(volt, volt->max1_id, temp));
+   if (volt->max2_id != 0xff)
+   max_volt = min(max_volt,
+  nvkm_volt_map(volt, volt->max2_id, temp));
+
+   for (cstate = start; >head != >list;
+cstate = list_entry(cstate->head.prev, typeof(*cstate), head)) {
+   if (nvkm_cstate_valid(clk, cstate, max_volt, temp))
+   break;
+   }
+
+   return cstate;
+}
+
+static struct nvkm_cstate *
+nvkm_cstate_get(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
+{
+   struct nvkm_cstate *cstate;
+   if (cstatei == -1)
+   return list_entry(pstate->list.prev, typeof(*cstate), head);
+   else {
+   list_for_each_entry(cstate, >list, head) {
+   if (cstate->cstate == cstatei)
+   return cstate;
+   }
+   }
+   return NULL;
+}
+
  static int
  nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int 
cstatei)
  {
@@ -85,15 +157,8 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate 
*pstate, int cstatei)
int ret;
  
  	if (!list_empty(>list)) {

-   if (cstatei == -1)
-   cstate = list_entry(pstate->list.prev, typeof(*cstate),
-   head);
-   else {
-   list_for_each_entry(cstate, >list, head) {
-   if (cstate->cstate == cstatei)
-   break;
-   }
-   }
+   cstate = nvkm_cstate_get(clk, pstate, cstatei);
+   cstate = nvkm_cstate_find_best(clk, pstate, cstate);
} else {
cstate = >base;
}


Reviewed-by: Martin Peres <martin.pe...@free.fr>
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH v4 10/37] add daemon to compare nouveau with blob voltage

2016-04-19 Thread Martin Peres
  if (abs(cstate->domain[nv_clk_src_gpc] - gpc_clock) <= 
gpc_err &&
+   abs(cstate->domain[nv_clk_src_mem] - 
mem_clock) <= mem_err) {
+   best_pstate = pstate;
+   best_cstate = cstate;
+   gpc_err = 
abs(cstate->domain[nv_clk_src_gpc] - gpc_clock);
+   mem_err = 
abs(cstate->domain[nv_clk_src_mem] - mem_clock);
+   }
+   }
+
+   if (!best_pstate) {
+   best_pstate = pstate;
+   mem_err = abs(cstate->domain[nv_clk_src_mem] - 
mem_clock);
+   continue;
+   } else if (!best_cstate && 
abs(pstate->base.domain[nv_clk_src_mem] - mem_clock) <= mem_err) {
+   best_pstate = pstate;
+   mem_err = abs(cstate->domain[nv_clk_src_mem] - 
mem_clock);
+   }
+   }
+
+   if (!best_cstate)
+   best_cstate = _pstate->base;
+
+   new_voltage = nvkm_volt_get(volt);
+   new_temp = nvkm_rd32(device, 
0x20400);//nvkm_therm_temp_get(therm);


Same here, get rid of the comment.


+   new_nouveau_voltage = max(nvkm_volt_map(volt, 
best_cstate->voltage), nvkm_volt_map(volt, best_pstate->base.voltage));
+   new_pstate = best_pstate->pstate;
+   new_cstate = best_cstate->cstate;
+
+   if (new_voltage != old_voltage || new_nouveau_voltage != 
old_nouveau_voltage || new_pstate != old_pstate || new_cstate != old_cstate || 
new_temp != old_temp) {
+   old_voltage = new_voltage;
+   old_nouveau_voltage = new_nouveau_voltage;
+   old_pstate = new_pstate;
+   old_cstate = new_cstate;
+   old_temp = new_temp;
+   printf("%i, %i, %i, %f, %i, %i, %i\n", new_voltage,
+  new_nouveau_voltage, new_nouveau_voltage - 
new_voltage,
+  100 * (double)new_nouveau_voltage / new_voltage,
+      new_pstate, new_cstate, new_temp);
+   }
+   usleep(10);
+   }
+
+   return 0;
+}


I am surprised by how short this tool is. This is great! With the 
nitpicks addressed, this is :


Reviewed-by: Martin Peres <martin.pe...@free.fr>
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH v4 11/37] volt: add temperature parameter to nvkm_volt_map

2016-04-19 Thread Martin Peres

On 18/04/16 22:13, Karol Herbst wrote:

the voltage entries actually may map to a different voltage depending on the
current temperature.

v2: only read the temperatue when actually needed

temperatue -> temperature


Signed-off-by: Karol Herbst <nouv...@karolherbst.de>
---
  bin/nv_cmp_volt.c  |  2 +-
  drm/nouveau/include/nvkm/subdev/volt.h |  2 +-
  drm/nouveau/nvkm/subdev/volt/base.c| 14 ++
  3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/bin/nv_cmp_volt.c b/bin/nv_cmp_volt.c
index c63d91b..34147b9 100644
--- a/bin/nv_cmp_volt.c
+++ b/bin/nv_cmp_volt.c
@@ -117,7 +117,7 @@ main(int argc, char **argv)
  
  		new_voltage = nvkm_volt_get(volt);

new_temp = nvkm_rd32(device, 
0x20400);//nvkm_therm_temp_get(therm);
-   new_nouveau_voltage = max(nvkm_volt_map(volt, 
best_cstate->voltage), nvkm_volt_map(volt, best_pstate->base.voltage));
+   new_nouveau_voltage = max(nvkm_volt_map(volt, 
best_cstate->voltage, new_temp), nvkm_volt_map(volt, best_pstate->base.voltage, 
new_temp));
new_pstate = best_pstate->pstate;
new_cstate = best_cstate->cstate;
  
diff --git a/drm/nouveau/include/nvkm/subdev/volt.h b/drm/nouveau/include/nvkm/subdev/volt.h

index 870d212..f223577 100644
--- a/drm/nouveau/include/nvkm/subdev/volt.h
+++ b/drm/nouveau/include/nvkm/subdev/volt.h
@@ -22,7 +22,7 @@ struct nvkm_volt {
u8 max2_id;
  };
  
-int nvkm_volt_map(struct nvkm_volt *volt, u8 id);

+int nvkm_volt_map(struct nvkm_volt *volt, u8 id, u8 temperature);
  int nvkm_volt_map_min(struct nvkm_volt *volt, u8 id);
  int nvkm_volt_get(struct nvkm_volt *);
  int nvkm_volt_set_id(struct nvkm_volt *, u8 id, u8 min_id, int condition);
diff --git a/drm/nouveau/nvkm/subdev/volt/base.c 
b/drm/nouveau/nvkm/subdev/volt/base.c
index 6fb9d2e..d72bd4a 100644
--- a/drm/nouveau/nvkm/subdev/volt/base.c
+++ b/drm/nouveau/nvkm/subdev/volt/base.c
@@ -26,6 +26,7 @@
  #include 
  #include 
  #include 
+#include 
  
  int

  nvkm_volt_get(struct nvkm_volt *volt)
@@ -88,7 +89,7 @@ nvkm_volt_map_min(struct nvkm_volt *volt, u8 id)
  }
  
  int

-nvkm_volt_map(struct nvkm_volt *volt, u8 id)
+nvkm_volt_map(struct nvkm_volt *volt, u8 id, u8 temp)
  {
struct nvkm_bios *bios = volt->subdev.device->bios;
struct nvbios_vmap_entry info;
@@ -98,7 +99,7 @@ nvkm_volt_map(struct nvkm_volt *volt, u8 id)
vmap = nvbios_vmap_entry_parse(bios, id, , , );
if (vmap) {
if (info.link != 0xff) {
-   int ret = nvkm_volt_map(volt, info.link);
+   int ret = nvkm_volt_map(volt, info.link, temp);
if (ret < 0)
return ret;
info.min += ret;
@@ -112,18 +113,23 @@ nvkm_volt_map(struct nvkm_volt *volt, u8 id)
  int
  nvkm_volt_set_id(struct nvkm_volt *volt, u8 id, u8 min_id, int condition)
  {
+   struct nvkm_therm *therm = volt->subdev.device->therm;
int ret;


/* Set the default temperature to 0°C as it always produces the
 * highest possible voltage which is the safest from a stability point of
 * view. This may be overridden later if the temperature can be read.
 */


+   int temp = 0;
  
  	if (volt->func->set_id)

return volt->func->set_id(volt, id, condition);
  
-	ret = nvkm_volt_map(volt, id);

+   if (therm)
+   temp = nvkm_therm_temp_get(therm);

temp = max(0, nvkm_therm_temp_get(therm));

+
+   ret = nvkm_volt_map(volt, id, max(temp, 0));

s/max(temp, 0)/temp/g

if (ret >= 0) {
int prev = nvkm_volt_get(volt);
if (!condition || prev < 0 ||
(condition < 0 && ret < prev) ||
(condition > 0 && ret > prev)) {
-   int min = nvkm_volt_map(volt, min_id);
+   int min = nvkm_volt_map(volt, min_id, max(temp, 0));

s/max(temp, 0)/temp/g

if (min >= 0)
ret = max(min, ret);
ret = nvkm_volt_set(volt, ret);


With the commit message and the max() duplication fixed, this is:

Reviewed-by: Martin Peres <martin.pe...@free.fr>
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH v4 08/37] clk: export nvkm_volt_map

2016-04-19 Thread Martin Peres

On 18/04/16 22:13, Karol Herbst wrote:

before clocking to a cstate, we have to check if the voltage is within the
allowed range.

Signed-off-by: Karol Herbst <nouv...@karolherbst.de>
---
  drm/nouveau/include/nvkm/subdev/volt.h | 1 +
  drm/nouveau/nvkm/subdev/volt/base.c| 2 +-
  2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drm/nouveau/include/nvkm/subdev/volt.h 
b/drm/nouveau/include/nvkm/subdev/volt.h
index ec9d87d..870d212 100644
--- a/drm/nouveau/include/nvkm/subdev/volt.h
+++ b/drm/nouveau/include/nvkm/subdev/volt.h
@@ -22,6 +22,7 @@ struct nvkm_volt {
u8 max2_id;
  };
  
+int nvkm_volt_map(struct nvkm_volt *volt, u8 id);

  int nvkm_volt_map_min(struct nvkm_volt *volt, u8 id);
  int nvkm_volt_get(struct nvkm_volt *);
  int nvkm_volt_set_id(struct nvkm_volt *, u8 id, u8 min_id, int condition);
diff --git a/drm/nouveau/nvkm/subdev/volt/base.c 
b/drm/nouveau/nvkm/subdev/volt/base.c
index 1690c1c..6fb9d2e 100644
--- a/drm/nouveau/nvkm/subdev/volt/base.c
+++ b/drm/nouveau/nvkm/subdev/volt/base.c
@@ -87,7 +87,7 @@ nvkm_volt_map_min(struct nvkm_volt *volt, u8 id)
return id ? id * 1 : -ENODEV;
  }
  
-static int

+int
  nvkm_volt_map(struct nvkm_volt *volt, u8 id)
  {
struct nvkm_bios *bios = volt->subdev.device->bios;


Reviewed-by: Martin Peres <martin.pe...@free.fr>
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH v4 06/37] volt: parse the max voltage map entries

2016-04-19 Thread Martin Peres

On 18/04/16 22:13, Karol Herbst wrote:

There are at least three "max" entries, which specify the max voltage. Because
they are actually normal voltage map entries, they can also be affected by the
temperature.

Nvidia respects those entries and if they get changed, nvidia uses the lower
voltage from both.

both ;) I guess it is time to update this to: from the three of them.


We shouldn't exceed those voltages at any given time.

v2: state what those entries do in the source
v3: add the third max entry

Signed-off-by: Karol Herbst <nouv...@karolherbst.de>
---
  drm/nouveau/include/nvkm/subdev/bios/vmap.h |  3 +++
  drm/nouveau/include/nvkm/subdev/volt.h  |  5 +
  drm/nouveau/nvkm/subdev/bios/vmap.c | 10 ++
  drm/nouveau/nvkm/subdev/volt/base.c | 13 +
  4 files changed, 31 insertions(+)

diff --git a/drm/nouveau/include/nvkm/subdev/bios/vmap.h 
b/drm/nouveau/include/nvkm/subdev/bios/vmap.h
index 6633c6d..ae2f27b 100644
--- a/drm/nouveau/include/nvkm/subdev/bios/vmap.h
+++ b/drm/nouveau/include/nvkm/subdev/bios/vmap.h
@@ -1,6 +1,9 @@
  #ifndef __NVBIOS_VMAP_H__
  #define __NVBIOS_VMAP_H__
  struct nvbios_vmap {
+   u8  max0;
+   u8  max1;
+   u8  max2;
  };
  
  u16 nvbios_vmap_table(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);

diff --git a/drm/nouveau/include/nvkm/subdev/volt.h 
b/drm/nouveau/include/nvkm/subdev/volt.h
index fc68825..285c6bf 100644
--- a/drm/nouveau/include/nvkm/subdev/volt.h
+++ b/drm/nouveau/include/nvkm/subdev/volt.h
@@ -15,6 +15,11 @@ struct nvkm_volt {
  
  	u32 max_uv;

u32 min_uv;
+
+   /* max voltage map entries, might be affected by temperature */


might be affected *differently* by temperature.


+   u8 max0_id;
+   u8 max1_id;
+   u8 max2_id;
  };
  
  int nvkm_volt_map_min(struct nvkm_volt *volt, u8 id);

diff --git a/drm/nouveau/nvkm/subdev/bios/vmap.c 
b/drm/nouveau/nvkm/subdev/bios/vmap.c
index 2f13db7..f2295e1 100644
--- a/drm/nouveau/nvkm/subdev/bios/vmap.c
+++ b/drm/nouveau/nvkm/subdev/bios/vmap.c
@@ -61,7 +61,17 @@ nvbios_vmap_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, 
u8 *cnt, u8 *len,
memset(info, 0x00, sizeof(*info));
switch (!!vmap * *ver) {
case 0x10:
+   info->max0 = 0xff;
+   info->max1 = 0xff;
+   info->max2 = 0xff;
+   break;
case 0x20:
+   info->max0 = nvbios_rd08(bios, vmap + 0x7);
+   info->max1 = nvbios_rd08(bios, vmap + 0x8);
+   if (*len >= 0xc)
+   info->max2 = nvbios_rd08(bios, vmap + 0xc);
+   else
+   info->max2 = 0xff;
break;
}
return vmap;
diff --git a/drm/nouveau/nvkm/subdev/volt/base.c 
b/drm/nouveau/nvkm/subdev/volt/base.c
index ecf4cb4..63fffb8 100644
--- a/drm/nouveau/nvkm/subdev/volt/base.c
+++ b/drm/nouveau/nvkm/subdev/volt/base.c
@@ -217,9 +217,22 @@ nvkm_volt_ctor(const struct nvkm_volt_func *func, struct 
nvkm_device *device,
  
  	/* Assuming the non-bios device should build the voltage table later */

if (bios) {
+   u8 ver, hdr, cnt, len;
+   struct nvbios_vmap vmap;
+
nvkm_volt_parse_bios(bios, volt);
nvkm_debug(>subdev, "min: %iuv max: %iuv\n",
   volt->min_uv, volt->max_uv);
+
+   if (nvbios_vmap_parse(bios, , , , , )) {
+   volt->max0_id = vmap.max0;
+   volt->max1_id = vmap.max1;
+   volt->max2_id = vmap.max2;
+   } else {
+   volt->max0_id = 0xff;
+   volt->max1_id = 0xff;
+   volt->max2_id = 0xff;
+   }
}
  
  	if (volt->vid_nr) {


With the comment and commit message fixed:

Reviewed-by: Martin Peres <martin.pe...@free.fr>
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH v2 16/22] volt: don't require perfect fit

2016-03-28 Thread Martin Peres

On 21/03/16 18:16, Karol Herbst wrote:

if we calculate the voltage in the table right, we get all kinds of values,
which never fit the hardware steps, so we use the closest higher value the
hardware can do


This is indeed the goal.



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

diff --git a/drm/nouveau/nvkm/subdev/volt/base.c 
b/drm/nouveau/nvkm/subdev/volt/base.c
index e741383..58738e3 100644
--- a/drm/nouveau/nvkm/subdev/volt/base.c
+++ b/drm/nouveau/nvkm/subdev/volt/base.c
@@ -51,18 +51,37 @@ static int
  nvkm_volt_set(struct nvkm_volt *volt, u32 uv)
  {
struct nvkm_subdev *subdev = >subdev;
-   int i, ret = -EINVAL;
+   int i, ret = -EINVAL, err, best = -1;
  
  	if (volt->func->volt_set)

return volt->func->volt_set(volt, uv);
  
  	for (i = 0; i < volt->vid_nr; i++) {

-   if (volt->vid[i].uv == uv) {
-   ret = volt->func->vid_set(volt, volt->vid[i].vid);
+   if (i == 0) {
+   best = 0;
+   err = volt->vid[i].uv - uv;
+   } else {
+   int new_err = volt->vid[i].uv - uv;
+   if (abs(new_err) < abs(err)
+   || (err < 0 && new_err >= 0)) {
+   best = i;
+   err = new_err;
+   }
+   }
+
+   if (err == 0) {
+   ret = volt->func->vid_set(volt, volt->vid[best].vid);
nvkm_debug(subdev, "set %duv: %d\n", uv, ret);
break;
}
}
+
+   if (best != -1) {
+   ret = volt->func->vid_set(volt, volt->vid[best].vid);
+   nvkm_debug(subdev, "set req %duv to %duv: %d\n", uv,
+  volt->vid[best].uv, ret);
+   }
+
return ret;
  }


The code is really weird though :o How about the following? It would 
make it much more readable and actually do what your commit message says.


int best = -1;
u32 best_abs_err = -1;
for (i = 0; i < volt->vid_nr; i++) {
int abs_err = abs(volt->vid[i].uv - uv);
if (volt->vid[i].uv >= uv && abs_err < best_abs_err) {
best = i;
best_abs_err = abs_err; 
if (abs_err == 0)
break;
 }
}

if (best >= 0) {
ret = volt->func->vid_set(volt, volt->vid[best].vid);
nvkm_debug(subdev, "set %duv: %d\n", uv, ret);
} else {
/* return an error to tell that we cannot use the wanted clock since we 
cannot select the needed voltage! */
}


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


Re: [Nouveau] [PATCH v2 18/22] volt: add coefficients I found on my gpu

2016-03-28 Thread Martin Peres

On 21/03/16 18:16, Karol Herbst wrote:

I am sure that those are a bit different on other GPUs, but while testing
the error range compared to nvidia was around 100%+-3%.

Without this change we are most of the time around 10% below nvidias voltage,
so this change causes no harm and improves the situation a lot already.

The remaining task for this is to figure out which of these constants are
chip specific and from where to get the chip specific factors

Signed-off-by: Karol Herbst 


Instead of landing these coefficients like that, I would really like if 
you could dump pfuse and check if you find these coefficients there. 
What could be done also is to re-do the work you did to find out those 
coefficients on a GPU where your coefficients are not really good and 
find out what values would have needed and then compare pfuse with the 
original card.


If this is to be considered a long task, then I am OK landing those 
coefficients, but I would really appreciate if you could at least have a 
quick look at pfuse :)

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


Re: [Nouveau] [PATCH v2 06/22] volt: parse the both max voltage entries

2016-03-28 Thread Martin Peres

On 28/03/16 23:49, Martin Peres wrote:

On 21/03/16 18:16, Karol Herbst wrote:

these entries specify a maximum voltage nvidia never exceeds, we shouldn't do
that, too.

Signed-off-by: Karol Herbst <nouv...@karolherbst.de>
---
   drm/nouveau/include/nvkm/subdev/bios/vmap.h |  2 ++
   drm/nouveau/include/nvkm/subdev/volt.h  |  2 ++
   drm/nouveau/nvkm/subdev/bios/vmap.c |  5 +
   drm/nouveau/nvkm/subdev/volt/base.c | 11 +++
   4 files changed, 20 insertions(+)

diff --git a/drm/nouveau/include/nvkm/subdev/bios/vmap.h 
b/drm/nouveau/include/nvkm/subdev/bios/vmap.h
index 6633c6d..48fe71d 100644
--- a/drm/nouveau/include/nvkm/subdev/bios/vmap.h
+++ b/drm/nouveau/include/nvkm/subdev/bios/vmap.h
@@ -1,6 +1,8 @@
   #ifndef __NVBIOS_VMAP_H__
   #define __NVBIOS_VMAP_H__
   struct nvbios_vmap {
+   u8  max0;
+   u8  max1;
   };
   
   u16 nvbios_vmap_table(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);

diff --git a/drm/nouveau/include/nvkm/subdev/volt.h 
b/drm/nouveau/include/nvkm/subdev/volt.h
index fc68825..3e0f8da 100644
--- a/drm/nouveau/include/nvkm/subdev/volt.h
+++ b/drm/nouveau/include/nvkm/subdev/volt.h
@@ -15,6 +15,8 @@ struct nvkm_volt {
   
   	u32 max_uv;

u32 min_uv;
+   u8 max0_vid;
+   u8 max1_vid;
   };
   
   int nvkm_volt_map_min(struct nvkm_volt *volt, u8 id);

diff --git a/drm/nouveau/nvkm/subdev/bios/vmap.c 
b/drm/nouveau/nvkm/subdev/bios/vmap.c
index 2f13db7..f5463b1 100644
--- a/drm/nouveau/nvkm/subdev/bios/vmap.c
+++ b/drm/nouveau/nvkm/subdev/bios/vmap.c
@@ -61,7 +61,12 @@ nvbios_vmap_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, 
u8 *cnt, u8 *len,
memset(info, 0x00, sizeof(*info));
switch (!!vmap * *ver) {
case 0x10:
+   info->max0 = 0xff;
+   info->max1 = 0xff;
+   break;
case 0x20:
+   info->max0 = nvbios_rd08(bios, vmap + 0x7);
+   info->max1 = nvbios_rd08(bios, vmap + 0x8);
break;
}
return vmap;
diff --git a/drm/nouveau/nvkm/subdev/volt/base.c 
b/drm/nouveau/nvkm/subdev/volt/base.c
index 71094a9..205dfcf 100644
--- a/drm/nouveau/nvkm/subdev/volt/base.c
+++ b/drm/nouveau/nvkm/subdev/volt/base.c
@@ -217,9 +217,20 @@ nvkm_volt_ctor(const struct nvkm_volt_func *func, struct 
nvkm_device *device,
   
   	/* Assuming the non-bios device should build the voltage table later */

if (bios) {
+   u8 ver, hdr, cnt, len;
+   struct nvbios_vmap vmap;
+
nvkm_volt_parse_bios(bios, volt);
nvkm_debug(>subdev, "min: %iuv max: %iuv\n",
   volt->min_uv, volt->max_uv);
+
+   if (nvbios_vmap_parse(bios, , , , , )) {
+   volt->max0_vid = vmap.max0;
+   volt->max1_vid = vmap.max1;
+   } else {
+   volt->max0_vid = 0xff;
+   volt->max1_vid = 0xff;
+   }
}
   
   	if (volt->vid_nr) {

This is really peculiar that NVIDIA would have 2 max_vid in the same
entry :s

How did you reverse that? Did you really see no differences? Maybe the
two max_vid are for different temperatures?
Ok, after discussions on IRC, I understand better. Max0/1 is actually 
not a vid but an entry in the voltage mapping table, which has different 
coefficient for the temperature. This allows OEMs to clamp the maximum 
voltage with not one but two different functions. I can see why it is OK.


Can you explain this a little more? Maybe as a comment in the code?

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


Re: [Nouveau] [PATCH v2 22/22] debugfs: add boost interface to change the boost_mode

2016-03-28 Thread Martin Peres

On 21/03/16 18:16, Karol Herbst wrote:

Signed-off-by: Karol Herbst <nouv...@karolherbst.de>


21-22 are:

Reviewed-by: Martin Peres <martin.pe...@free.fr>
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


Re: [Nouveau] [PATCH v2 07/22] volt: add min_id parameter to nvkm_volt_set_id

2016-03-28 Thread Martin Peres

On 28/03/16 23:52, Martin Peres wrote:

On 21/03/16 18:16, Karol Herbst wrote:

min_id indicates a volt map entry which acts as a floor value, this will be
used to set the lower voltage limit through pstates


Please state that this comes that this min_id is different for each 
pstate, hence why volt should not know about this and needs to take it 
as an input!




Signed-off-by: Karol Herbst <nouv...@karolherbst.de>

Do we really want to push reclocking logic to the volt subsystem?

To me, volt should just allow you to read back and set a voltage. All
the rest of the logic should be in clk.

Since this is my first NAK, here are my R-b for 3, 4 and 5:

Reviewed-by: Martin Peres <martin.pe...@free.fr>


With this fixed, this patch is Reviewed-by: Martin Peres 
<martin.pe...@free.fr>

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


Re: [Nouveau] [PATCH v2 07/22] volt: add min_id parameter to nvkm_volt_set_id

2016-03-28 Thread Martin Peres

On 21/03/16 18:16, Karol Herbst wrote:

min_id indicates a volt map entry which acts as a floor value, this will be
used to set the lower voltage limit through pstates

Signed-off-by: Karol Herbst <nouv...@karolherbst.de>


Do we really want to push reclocking logic to the volt subsystem?

To me, volt should just allow you to read back and set a voltage. All 
the rest of the logic should be in clk.


Since this is my first NAK, here are my R-b for 3, 4 and 5:

Reviewed-by: Martin Peres <martin.pe...@free.fr>
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau


  1   2   3   4   >