[05/15] volt/gm20b: add support for vmin parameter

Submitted by Alexandre Courbot on June 1, 2016, 8:39 a.m.

Details

Message ID 20160601083929.8555-6-acourbot@nvidia.com
State New
Headers show
Series "clk/tegra: improve code and add DFS support" ( rev: 1 ) in Nouveau

Not browsing as part of any series.

Commit Message

Alexandre Courbot June 1, 2016, 8:39 a.m.
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>
---
 drm/nouveau/nvkm/subdev/volt/gk20a.c | 10 +++++-----
 drm/nouveau/nvkm/subdev/volt/gk20a.h |  2 +-
 drm/nouveau/nvkm/subdev/volt/gm20b.c | 17 ++++++++++++++++-
 3 files changed, 22 insertions(+), 7 deletions(-)

Patch hide | download patch | download mbox

diff --git a/drm/nouveau/nvkm/subdev/volt/gk20a.c b/drm/nouveau/nvkm/subdev/volt/gk20a.c
index a4e9a5027a4c..ce5d83cdc7cf 100644
--- a/drm/nouveau/nvkm/subdev/volt/gk20a.c
+++ b/drm/nouveau/nvkm/subdev/volt/gk20a.c
@@ -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);
 }
diff --git a/drm/nouveau/nvkm/subdev/volt/gk20a.h b/drm/nouveau/nvkm/subdev/volt/gk20a.h
index 1ccca950c41a..6a6c97f9684e 100644
--- a/drm/nouveau/nvkm/subdev/volt/gk20a.h
+++ b/drm/nouveau/nvkm/subdev/volt/gk20a.h
@@ -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
diff --git a/drm/nouveau/nvkm/subdev/volt/gm20b.c b/drm/nouveau/nvkm/subdev/volt/gm20b.c
index 753074035cb1..d2d39ab74b8e 100644
--- a/drm/nouveau/nvkm/subdev/volt/gm20b.c
+++ b/drm/nouveau/nvkm/subdev/volt/gm20b.c
@@ -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);
 }