drm/nouveau/volt/gm20b: add support for vmin parameter
authorAlexandre Courbot <acourbot@nvidia.com>
Wed, 1 Jun 2016 08:39:19 +0000 (17:39 +0900)
committerBen Skeggs <bskeggs@redhat.com>
Thu, 14 Jul 2016 01:53:25 +0000 (11:53 +1000)
Chips may be characterized for a minimum voltage. Support this extra
parameter and select the appropriate minimum voltage for the detected
GPU speedo.

Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c
drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.h
drivers/gpu/drm/nouveau/nvkm/subdev/volt/gm20b.c

index a4e9a5027a4c7ea5e1eb7ff53a60d917dc32db34..ce5d83cdc7cf7900cf86060750b9398ef24063d9 100644 (file)
@@ -146,7 +146,7 @@ gk20a_volt = {
 int
 gk20a_volt_ctor(struct nvkm_device *device, int index,
                const struct cvb_coef *coefs, int nb_coefs,
-               struct gk20a_volt *volt)
+               int vmin, struct gk20a_volt *volt)
 {
        struct nvkm_device_tegra *tdev = device->func->tegra(device);
        int i, uv;
@@ -161,9 +161,9 @@ gk20a_volt_ctor(struct nvkm_device *device, int index,
        volt->base.vid_nr = nb_coefs;
        for (i = 0; i < volt->base.vid_nr; i++) {
                volt->base.vid[i].vid = i;
-               volt->base.vid[i].uv =
-                       gk20a_volt_calc_voltage(&coefs[i],
-                                               tdev->gpu_speedo);
+               volt->base.vid[i].uv = max(
+                       gk20a_volt_calc_voltage(&coefs[i], tdev->gpu_speedo),
+                       vmin);
                nvkm_debug(&volt->base.subdev, "%2d: vid=%d, uv=%d\n", i,
                           volt->base.vid[i].vid, volt->base.vid[i].uv);
        }
@@ -182,5 +182,5 @@ gk20a_volt_new(struct nvkm_device *device, int index, struct nvkm_volt **pvolt)
        *pvolt = &volt->base;
 
        return gk20a_volt_ctor(device, index, gk20a_cvb_coef,
-                              ARRAY_SIZE(gk20a_cvb_coef), volt);
+                              ARRAY_SIZE(gk20a_cvb_coef), 0, volt);
 }
index 1ccca950c41a92f1bdd28ef33588e991397f993a..6a6c97f9684e0c1e560d03209fbed77755ac4dac 100644 (file)
@@ -39,6 +39,6 @@ struct gk20a_volt {
 
 int gk20a_volt_ctor(struct nvkm_device *device, int index,
                    const struct cvb_coef *coefs, int nb_coefs,
-                   struct gk20a_volt *volt);
+                   int vmin, struct gk20a_volt *volt);
 
 #endif
index 753074035cb126e76e42dea8df50c767ee9f8485..d2d39ab74b8ee29b807e481b4ea504b9da40c765 100644 (file)
@@ -41,16 +41,31 @@ const struct cvb_coef gm20b_cvb_coef[] = {
        /* 921600 */ { 2647676, -106455, 1632 },
 };
 
+const u32 speedo_to_vmin[] = {
+       /*   0,      1,      2,      3,      4, */
+       950000, 840000, 818750, 840000, 810000,
+};
+
 int
 gm20b_volt_new(struct nvkm_device *device, int index, struct nvkm_volt **pvolt)
 {
+       struct nvkm_device_tegra *tdev = device->func->tegra(device);
        struct gk20a_volt *volt;
+       u32 vmin;
+
+       if (tdev->gpu_speedo_id >= ARRAY_SIZE(speedo_to_vmin)) {
+               nvdev_error(device, "unsupported speedo %d\n",
+                           tdev->gpu_speedo_id);
+               return -EINVAL;
+       }
 
        volt = kzalloc(sizeof(*volt), GFP_KERNEL);
        if (!volt)
                return -ENOMEM;
        *pvolt = &volt->base;
 
+       vmin = speedo_to_vmin[tdev->gpu_speedo_id];
+
        return gk20a_volt_ctor(device, index, gm20b_cvb_coef,
-                              ARRAY_SIZE(gm20b_cvb_coef), volt);
+                              ARRAY_SIZE(gm20b_cvb_coef), vmin, volt);
 }