diff options
Diffstat (limited to 'drm/nouveau/nvkm/subdev/volt/gm20b.c')
-rw-r--r-- | drm/nouveau/nvkm/subdev/volt/gm20b.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/drm/nouveau/nvkm/subdev/volt/gm20b.c b/drm/nouveau/nvkm/subdev/volt/gm20b.c new file mode 100644 index 000000000..298548bb2 --- /dev/null +++ b/drm/nouveau/nvkm/subdev/volt/gm20b.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved. + * + * 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 AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +#include "priv.h" +#include "gk20a.h" + +#include <core/tegra.h> + +const struct cvb_coef gm20b_na_cvb_coef[] = { + /* KHz, c0, c1, c2, c3, c4, c5 */ + /* 76800 */ { 814294, 8144, -940, 808, -21583, 226 }, + /* 153600 */ { 856185, 8144, -940, 808, -21583, 226 }, + /* 230400 */ { 898077, 8144, -940, 808, -21583, 226 }, + /* 307200 */ { 939968, 8144, -940, 808, -21583, 226 }, + /* 384000 */ { 981860, 8144, -940, 808, -21583, 226 }, + /* 460800 */ { 1023751, 8144, -940, 808, -21583, 226 }, + /* 537600 */ { 1065642, 8144, -940, 808, -21583, 226 }, + /* 614400 */ { 1107534, 8144, -940, 808, -21583, 226 }, + /* 691200 */ { 1149425, 8144, -940, 808, -21583, 226 }, + /* 768000 */ { 1191317, 8144, -940, 808, -21583, 226 }, + /* 844800 */ { 1233208, 8144, -940, 808, -21583, 226 }, + /* 921600 */ { 1275100, 8144, -940, 808, -21583, 226 }, + /* 998400 */ { 1316991, 8144, -940, 808, -21583, 226 }, +}; + +const struct cvb_coef gm20b_cvb_coef[] = { + /* KHz, c0, c1, c2 */ + /* 76800 */ { 1786666, -85625, 1632 }, + /* 153600 */ { 1846729, -87525, 1632 }, + /* 230400 */ { 1910480, -89425, 1632 }, + /* 307200 */ { 1977920, -91325, 1632 }, + /* 384000 */ { 2049049, -93215, 1632 }, + /* 460800 */ { 2122872, -95095, 1632 }, + /* 537600 */ { 2201331, -96985, 1632 }, + /* 614400 */ { 2283479, -98885, 1632 }, + /* 691200 */ { 2369315, -100785, 1632 }, + /* 768000 */ { 2458841, -102685, 1632 }, + /* 844800 */ { 2550821, -104555, 1632 }, + /* 921600 */ { 2647676, -106455, 1632 }, +}; + +static const struct nvkm_volt_func +gm20b_volt = { + .vid_get = gk20a_volt_vid_get, + .vid_set = gk20a_volt_vid_set, + .set_id = gk20a_volt_set_id, +}; + +#define MAX_SPEEDO 4 + +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; + const struct cvb_coef *coef_table; + int i, uv; + + if (!(volt = kzalloc(sizeof(*volt), GFP_KERNEL))) + return -ENOMEM; + + nvkm_volt_ctor(&gm20b_volt, device, index, &volt->base); + *pvolt = &volt->base; + + if (tdev->gpu_speedo_id > MAX_SPEEDO) { + nvkm_error(&volt->base.subdev, "Unsupported Speedo = %d\n", + tdev->gpu_speedo_id); + return -EINVAL; + } + + uv = regulator_get_voltage(tdev->vdd); + nvkm_info(&volt->base.subdev, "The default voltage is %duV\n", uv); + + volt->vdd = tdev->vdd; + + if (tdev->gpu_speedo_id >= 1) { + coef_table = gm20b_na_cvb_coef; + volt->base.vid_nr = ARRAY_SIZE(gm20b_na_cvb_coef); + } else { + coef_table = gm20b_cvb_coef; + volt->base.vid_nr = ARRAY_SIZE(gm20b_cvb_coef); + } + + nvkm_debug(&volt->base.subdev, "%s - vid_nr = %d\n", __func__, + volt->base.vid_nr); + + for (i = 0; i < volt->base.vid_nr; i++) { + volt->base.vid[i].vid = i; + volt->base.vid[i].uv = + gk20a_volt_calc_voltage(&coef_table[i], + tdev->gpu_speedo_value); + nvkm_debug(&volt->base.subdev, "%2d: vid=%d, uv=%d\n", i, + volt->base.vid[i].vid, volt->base.vid[i].uv); + } + + return 0; +} |