summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVaikundanathan S <vaikuns@nvidia.com>2018-04-03 05:41:58 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-05-04 09:09:47 -0400
commit65a362c01a1adc567fa176113dfeb1834777926d (patch)
tree74c85f3b2c2b0ec880bc6ecb5980caf9effde880
parent010439ba08891ce97c53c239b5bb8c4a2f5b5f01 (diff)
gpu: nvgpu: Update clk_vin interface as per chips_a
clk_vin data structures updated as new calibration type (v20) is added. GP106 header does not have vin calibration type. Assuming V10 if calibration type is not V20. Add fuse calibration for V20 type. Bug 200399373 Change-Id: I9449de1ecb0d0873f3bc16f46660f93fab5b9eac Signed-off-by: Vaikundanathan S <vaikuns@nvidia.com> Signed-off-by: Mahantesh Kumbar <mkumbar@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1687591 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r--drivers/gpu/nvgpu/clk/clk_vin.c407
-rw-r--r--drivers/gpu/nvgpu/clk/clk_vin.h20
-rw-r--r--drivers/gpu/nvgpu/common/pmu/pmu_fw.c4
-rw-r--r--drivers/gpu/nvgpu/ctrl/ctrlclk.h24
-rw-r--r--drivers/gpu/nvgpu/ctrl/ctrlclkavfs.h8
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h3
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/bios.h9
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifclk.h14
8 files changed, 418 insertions, 71 deletions
diff --git a/drivers/gpu/nvgpu/clk/clk_vin.c b/drivers/gpu/nvgpu/clk/clk_vin.c
index 6f47d2c8..74bcd247 100644
--- a/drivers/gpu/nvgpu/clk/clk_vin.c
+++ b/drivers/gpu/nvgpu/clk/clk_vin.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a 4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"), 5 * copy of this software and associated documentation files (the "Software"),
@@ -40,8 +40,23 @@
40static u32 devinit_get_vin_device_table(struct gk20a *g, 40static u32 devinit_get_vin_device_table(struct gk20a *g,
41 struct avfsvinobjs *pvinobjs); 41 struct avfsvinobjs *pvinobjs);
42 42
43static u32 vin_device_construct_v10(struct gk20a *g,
44 struct boardobj **ppboardobj,
45 u16 size, void *pargs);
46static u32 vin_device_construct_v20(struct gk20a *g,
47 struct boardobj **ppboardobj,
48 u16 size, void *pargs);
49static u32 vin_device_construct_super(struct gk20a *g,
50 struct boardobj **ppboardobj,
51 u16 size, void *pargs);
43static struct vin_device *construct_vin_device(struct gk20a *g, void *pargs); 52static struct vin_device *construct_vin_device(struct gk20a *g, void *pargs);
44 53
54static u32 vin_device_init_pmudata_v10(struct gk20a *g,
55 struct boardobj *board_obj_ptr,
56 struct nv_pmu_boardobj *ppmudata);
57static u32 vin_device_init_pmudata_v20(struct gk20a *g,
58 struct boardobj *board_obj_ptr,
59 struct nv_pmu_boardobj *ppmudata);
45static u32 vin_device_init_pmudata_super(struct gk20a *g, 60static u32 vin_device_init_pmudata_super(struct gk20a *g,
46 struct boardobj *board_obj_ptr, 61 struct boardobj *board_obj_ptr,
47 struct nv_pmu_boardobj *ppmudata); 62 struct nv_pmu_boardobj *ppmudata);
@@ -184,6 +199,120 @@ static u32 read_vin_cal_slope_intercept_fuse(struct gk20a *g,
184 return 0; 199 return 0;
185} 200}
186 201
202static u32 read_vin_cal_gain_offset_fuse(struct gk20a *g,
203 u32 vin_id, s8 *gain,
204 s8 *offset)
205{
206 u32 data = 0;
207
208 switch (vin_id) {
209 case CTRL_CLK_VIN_ID_GPC0:
210 data = gk20a_readl(g, fuse_vin_cal_gpc0_r());
211 break;
212
213 case CTRL_CLK_VIN_ID_GPC1:
214 data = gk20a_readl(g, fuse_vin_cal_gpc1_delta_r());
215 break;
216
217 case CTRL_CLK_VIN_ID_GPC2:
218 data = gk20a_readl(g, fuse_vin_cal_gpc2_delta_r());
219 break;
220
221 case CTRL_CLK_VIN_ID_GPC3:
222 data = gk20a_readl(g, fuse_vin_cal_gpc3_delta_r());
223 break;
224
225 case CTRL_CLK_VIN_ID_GPC4:
226 data = gk20a_readl(g, fuse_vin_cal_gpc4_delta_r());
227 break;
228
229 case CTRL_CLK_VIN_ID_GPC5:
230 data = gk20a_readl(g, fuse_vin_cal_gpc5_delta_r());
231 break;
232
233 case CTRL_CLK_VIN_ID_SYS:
234 case CTRL_CLK_VIN_ID_XBAR:
235 case CTRL_CLK_VIN_ID_LTC:
236 data = gk20a_readl(g, fuse_vin_cal_shared_delta_r());
237 break;
238
239 case CTRL_CLK_VIN_ID_SRAM:
240 data = gk20a_readl(g, fuse_vin_cal_sram_delta_r());
241 break;
242
243 default:
244 return -EINVAL;
245 }
246 if (data == 0xFFFFFFFF)
247 return -EINVAL;
248 *gain = (s8) (data >> 16) & 0x1f;
249 *offset = (s8) data & 0x7f;
250
251 return 0;
252}
253
254u32 clk_avfs_get_vin_cal_fuse_v10(struct gk20a *g,
255 struct avfsvinobjs *pvinobjs,
256 struct vin_device_v20 *pvindev)
257{
258 u32 status = 0;
259 u32 slope, intercept;
260 u8 i;
261
262 if (pvinobjs->calibration_rev_vbios == read_vin_cal_fuse_rev(g)) {
263 BOARDOBJGRP_FOR_EACH(&(pvinobjs->super.super),
264 struct vin_device_v20 *, pvindev, i) {
265 slope = 0;
266 intercept = 0;
267 pvindev = (struct vin_device_v20 *)CLK_GET_VIN_DEVICE(pvinobjs, i);
268 status = read_vin_cal_slope_intercept_fuse(g,
269 pvindev->super.id, &slope, &intercept);
270 if (status) {
271 nvgpu_err(g,
272 "err reading vin cal for id %x", pvindev->super.id);
273 return status;
274 }
275 if (slope != 0 && intercept != 0) {
276 pvindev->data.vin_cal.cal_v10.slope = slope;
277 pvindev->data.vin_cal.cal_v10.intercept = intercept;
278 }
279 }
280 }
281 return status;
282
283}
284
285u32 clk_avfs_get_vin_cal_fuse_v20(struct gk20a *g,
286 struct avfsvinobjs *pvinobjs,
287 struct vin_device_v20 *pvindev)
288{
289 u32 status = 0;
290 s8 gain, offset;
291 u8 i;
292
293 if (pvinobjs->calibration_rev_vbios == read_vin_cal_fuse_rev(g)) {
294 BOARDOBJGRP_FOR_EACH(&(pvinobjs->super.super),
295 struct vin_device_v20 *, pvindev, i) {
296 gain = 0;
297 offset = 0;
298 pvindev = (struct vin_device_v20 *)CLK_GET_VIN_DEVICE(pvinobjs, i);
299 status = read_vin_cal_gain_offset_fuse(g,
300 pvindev->super.id, &gain, &offset);
301 if (status) {
302 nvgpu_err(g,
303 "err reading vin cal for id %x", pvindev->super.id);
304 return status;
305 }
306 if (gain != 0 && offset != 0) {
307 pvindev->data.vin_cal.cal_v20.gain = gain;
308 pvindev->data.vin_cal.cal_v20.offset = offset;
309 }
310 }
311 }
312 return status;
313
314}
315
187static u32 _clk_vin_devgrp_pmudatainit_super(struct gk20a *g, 316static u32 _clk_vin_devgrp_pmudatainit_super(struct gk20a *g,
188 struct boardobjgrp *pboardobjgrp, 317 struct boardobjgrp *pboardobjgrp,
189 struct nv_pmu_boardobjgrp_super *pboardobjgrppmu) 318 struct nv_pmu_boardobjgrp_super *pboardobjgrppmu)
@@ -249,11 +378,8 @@ u32 clk_vin_sw_setup(struct gk20a *g)
249{ 378{
250 u32 status; 379 u32 status;
251 struct boardobjgrp *pboardobjgrp = NULL; 380 struct boardobjgrp *pboardobjgrp = NULL;
252 u32 slope; 381 struct vin_device_v20 *pvindev = NULL;
253 u32 intercept;
254 struct vin_device *pvindev;
255 struct avfsvinobjs *pvinobjs; 382 struct avfsvinobjs *pvinobjs;
256 u8 i;
257 383
258 gk20a_dbg_info(""); 384 gk20a_dbg_info("");
259 385
@@ -288,25 +414,8 @@ u32 clk_vin_sw_setup(struct gk20a *g)
288 goto done; 414 goto done;
289 415
290 /*update vin calibration to fuse */ 416 /*update vin calibration to fuse */
291 if (pvinobjs->calibration_rev_vbios == read_vin_cal_fuse_rev(g)) { 417 g->ops.pmu_ver.clk.clk_avfs_get_vin_cal_data(g, pvinobjs, pvindev);
292 BOARDOBJGRP_FOR_EACH(&(pvinobjs->super.super), 418
293 struct vin_device *, pvindev, i) {
294 slope = 0;
295 intercept = 0;
296 pvindev = CLK_GET_VIN_DEVICE(pvinobjs, i);
297 status = read_vin_cal_slope_intercept_fuse(g,
298 pvindev->id, &slope, &intercept);
299 if (status) {
300 nvgpu_err(g,
301 "err reading vin cal for id %x", pvindev->id);
302 goto done;
303 }
304 if (slope != 0 && intercept != 0) {
305 pvindev->slope = slope;
306 pvindev->intercept = intercept;
307 }
308 }
309 }
310 status = BOARDOBJGRP_PMU_CMD_GRP_GET_STATUS_CONSTRUCT(g, 419 status = BOARDOBJGRP_PMU_CMD_GRP_GET_STATUS_CONSTRUCT(g,
311 &g->clk_pmu.avfs_vinobjs.super.super, 420 &g->clk_pmu.avfs_vinobjs.super.super,
312 clk, CLK, clk_vin_device, CLK_VIN_DEVICE); 421 clk, CLK, clk_vin_device, CLK_VIN_DEVICE);
@@ -349,9 +458,17 @@ static u32 devinit_get_vin_device_table(struct gk20a *g,
349 struct vin_descriptor_entry_10 vin_desc_table_entry = { 0 }; 458 struct vin_descriptor_entry_10 vin_desc_table_entry = { 0 };
350 u8 *vin_tbl_entry_ptr = NULL; 459 u8 *vin_tbl_entry_ptr = NULL;
351 u32 index = 0; 460 u32 index = 0;
352 u32 slope, intercept; 461 u32 slope=0, intercept=0;
353 struct vin_device vin_dev_data; 462 s8 offset=0, gain=0;
354 struct vin_device *pvin_dev; 463 struct vin_device *pvin_dev;
464 u32 cal_type;
465
466 union {
467 struct boardobj boardobj;
468 struct vin_device vin_device;
469 struct vin_device_v10 vin_device_v10;
470 struct vin_device_v20 vin_device_v20;
471 } vin_device_data;
355 472
356 gk20a_dbg_info(""); 473 gk20a_dbg_info("");
357 474
@@ -371,19 +488,36 @@ static u32 devinit_get_vin_device_table(struct gk20a *g,
371 pvinobjs->vin_is_disable_allowed = 488 pvinobjs->vin_is_disable_allowed =
372 BIOS_GET_FIELD(vin_desc_table_header.flags0, 489 BIOS_GET_FIELD(vin_desc_table_header.flags0,
373 NV_VIN_DESC_FLAGS0_DISABLE_CONTROL); 490 NV_VIN_DESC_FLAGS0_DISABLE_CONTROL);
491 cal_type = BIOS_GET_FIELD(vin_desc_table_header.flags0,
492 NV_VIN_DESC_FLAGS0_VIN_CAL_TYPE);
493 if(!cal_type)
494 cal_type = CTRL_CLK_VIN_CAL_TYPE_V10;
495
496 switch (cal_type) {
497 case CTRL_CLK_VIN_CAL_TYPE_V10:
498 /* VIN calibration slope: XX.YYY mV/code => XXYYY uV/code*/
499 slope = ((BIOS_GET_FIELD(vin_desc_table_header.vin_cal,
500 NV_VIN_DESC_VIN_CAL_SLOPE_INTEGER) * 1000)) +
501 ((BIOS_GET_FIELD(vin_desc_table_header.vin_cal,
502 NV_VIN_DESC_VIN_CAL_SLOPE_FRACTION)));
503
504 /* VIN calibration intercept: ZZZ.W mV => ZZZW00 uV */
505 intercept = ((BIOS_GET_FIELD(vin_desc_table_header.vin_cal,
506 NV_VIN_DESC_VIN_CAL_INTERCEPT_INTEGER) * 1000)) +
507 ((BIOS_GET_FIELD(vin_desc_table_header.vin_cal,
508 NV_VIN_DESC_VIN_CAL_INTERCEPT_FRACTION) * 100));
374 509
375 /* VIN calibration slope: XX.YYY mV/code => XXYYY uV/code*/ 510 break;
376 slope = ((BIOS_GET_FIELD(vin_desc_table_header.vin_cal, 511 case CTRL_CLK_VIN_CAL_TYPE_V20:
377 NV_VIN_DESC_VIN_CAL_SLOPE_INTEGER) * 1000)) + 512 offset = BIOS_GET_FIELD(vin_desc_table_header.vin_cal,
378 ((BIOS_GET_FIELD(vin_desc_table_header.vin_cal, 513 NV_VIN_DESC_VIN_CAL_OFFSET);
379 NV_VIN_DESC_VIN_CAL_SLOPE_FRACTION))); 514 gain = BIOS_GET_FIELD(vin_desc_table_header.vin_cal,
380 515 NV_VIN_DESC_VIN_CAL_GAIN);
381 /* VIN calibration intercept: ZZZ.W mV => ZZZW00 uV */ 516 break;
382 intercept = ((BIOS_GET_FIELD(vin_desc_table_header.vin_cal, 517 default:
383 NV_VIN_DESC_VIN_CAL_INTERCEPT_INTEGER) * 1000)) + 518 status = -1;
384 ((BIOS_GET_FIELD(vin_desc_table_header.vin_cal, 519 goto done;
385 NV_VIN_DESC_VIN_CAL_INTERCEPT_FRACTION) * 100)); 520 }
386
387 /* Read table entries*/ 521 /* Read table entries*/
388 vin_tbl_entry_ptr = vin_table_ptr + vin_desc_table_header.header_sizee; 522 vin_tbl_entry_ptr = vin_table_ptr + vin_desc_table_header.header_sizee;
389 for (index = 0; index < vin_desc_table_header.entry_count; index++) { 523 for (index = 0; index < vin_desc_table_header.entry_count; index++) {
@@ -393,17 +527,28 @@ static u32 devinit_get_vin_device_table(struct gk20a *g,
393 if (vin_desc_table_entry.vin_device_type == CTRL_CLK_VIN_TYPE_DISABLED) 527 if (vin_desc_table_entry.vin_device_type == CTRL_CLK_VIN_TYPE_DISABLED)
394 continue; 528 continue;
395 529
396 vin_dev_data.super.type = 530 vin_device_data.boardobj.type =
397 (u8)vin_desc_table_entry.vin_device_type; 531 (u8)vin_desc_table_entry.vin_device_type;
398 vin_dev_data.id = (u8)vin_desc_table_entry.vin_device_id; 532 vin_device_data.vin_device.id = (u8)vin_desc_table_entry.vin_device_id;
399 vin_dev_data.volt_domain_vbios = 533 vin_device_data.vin_device.volt_domain_vbios =
400 (u8)vin_desc_table_entry.volt_domain_vbios; 534 (u8)vin_desc_table_entry.volt_domain_vbios;
401 vin_dev_data.slope = slope; 535 vin_device_data.vin_device.flls_shared_mask = 0;
402 vin_dev_data.intercept = intercept; 536
403 537 switch (vin_device_data.boardobj.type) {
404 vin_dev_data.flls_shared_mask = 0; 538 case CTRL_CLK_VIN_TYPE_V10:
405 539 vin_device_data.vin_device_v10.data.vin_cal.slope = slope;
406 pvin_dev = construct_vin_device(g, (void *)&vin_dev_data); 540 vin_device_data.vin_device_v10.data.vin_cal.intercept = intercept;
541 break;
542 case CTRL_CLK_VIN_TYPE_V20:
543 vin_device_data.vin_device_v20.data.vin_cal.cal_v20.offset = offset;
544 vin_device_data.vin_device_v20.data.vin_cal.cal_v20.gain = gain;
545 break;
546 default:
547 status = -1;
548 goto done;
549 };
550
551 pvin_dev = construct_vin_device(g, (void *)&vin_device_data);
407 552
408 status = boardobjgrp_objinsert(&pvinobjs->super.super, 553 status = boardobjgrp_objinsert(&pvinobjs->super.super,
409 (struct boardobj *)pvin_dev, index); 554 (struct boardobj *)pvin_dev, index);
@@ -416,36 +561,168 @@ done:
416 return status; 561 return status;
417} 562}
418 563
564static u32 vin_device_construct_v10(struct gk20a *g,
565 struct boardobj **ppboardobj,
566 u16 size, void *pargs)
567{
568 struct boardobj *ptmpobj = (struct boardobj *)pargs;
569 struct vin_device_v10 *pvin_device_v10;
570 struct vin_device_v10 *ptmpvin_device_v10 = (struct vin_device_v10 *)pargs;
571 u32 status = 0;
572
573 if (BOARDOBJ_GET_TYPE(pargs) != CTRL_CLK_VIN_TYPE_V10)
574 return -EINVAL;
575
576 ptmpobj->type_mask |= BIT(CTRL_CLK_VIN_TYPE_V10);
577 status = vin_device_construct_super(g, ppboardobj, size, pargs);
578 if (status)
579 return -EINVAL;
580
581 pvin_device_v10 = (struct vin_device_v10 *)*ppboardobj;
582
583 pvin_device_v10->super.super.pmudatainit =
584 vin_device_init_pmudata_v10;
585
586 pvin_device_v10->data.vin_cal.slope = ptmpvin_device_v10->data.vin_cal.slope;
587 pvin_device_v10->data.vin_cal.intercept = ptmpvin_device_v10->data.vin_cal.intercept;
588
589 return status;
590}
591
592static u32 vin_device_construct_v20(struct gk20a *g,
593 struct boardobj **ppboardobj,
594 u16 size, void *pargs)
595{
596 struct boardobj *ptmpobj = (struct boardobj *)pargs;
597 struct vin_device_v20 *pvin_device_v20;
598 struct vin_device_v20 *ptmpvin_device_v20 = (struct vin_device_v20 *)pargs;
599 u32 status = 0;
600
601 if (BOARDOBJ_GET_TYPE(pargs) != CTRL_CLK_VIN_TYPE_V20)
602 return -EINVAL;
603
604 ptmpobj->type_mask |= BIT(CTRL_CLK_VIN_TYPE_V20);
605 status = vin_device_construct_super(g, ppboardobj, size, pargs);
606 if (status)
607 return -EINVAL;
608
609 pvin_device_v20 = (struct vin_device_v20 *)*ppboardobj;
610
611 pvin_device_v20->super.super.pmudatainit =
612 vin_device_init_pmudata_v20;
613
614 pvin_device_v20->data.vin_cal.cal_v20.offset = ptmpvin_device_v20->data.vin_cal.cal_v20.offset;
615 pvin_device_v20->data.vin_cal.cal_v20.gain = ptmpvin_device_v20->data.vin_cal.cal_v20.gain;
616
617 return status;
618}
619static u32 vin_device_construct_super(struct gk20a *g,
620 struct boardobj **ppboardobj,
621 u16 size, void *pargs)
622{
623 struct vin_device *pvin_device;
624 struct vin_device *ptmpvin_device = (struct vin_device *)pargs;
625 u32 status = 0;
626 status = boardobj_construct_super(g, ppboardobj, size, pargs);
627
628 if (status)
629 return -EINVAL;
630
631 pvin_device = (struct vin_device *)*ppboardobj;
632
633 pvin_device->super.pmudatainit =
634 vin_device_init_pmudata_super;
635
636 pvin_device->id = ptmpvin_device->id;
637 pvin_device->volt_domain_vbios = ptmpvin_device->volt_domain_vbios;
638 pvin_device->flls_shared_mask = ptmpvin_device->flls_shared_mask;
639 pvin_device->volt_domain = CTRL_VOLT_DOMAIN_LOGIC;
640
641 return status;
642}
419static struct vin_device *construct_vin_device(struct gk20a *g, void *pargs) 643static struct vin_device *construct_vin_device(struct gk20a *g, void *pargs)
420{ 644{
421 struct boardobj *board_obj_ptr = NULL; 645 struct boardobj *board_obj_ptr = NULL;
422 struct vin_device *pvin_dev;
423 struct vin_device *board_obj_vin_ptr = NULL;
424 u32 status; 646 u32 status;
425 647
426 gk20a_dbg_info(""); 648 gk20a_dbg_info(" %d", BOARDOBJ_GET_TYPE(pargs));
427 status = boardobj_construct_super(g, &board_obj_ptr, 649 switch (BOARDOBJ_GET_TYPE(pargs)) {
428 sizeof(struct vin_device), pargs); 650 case CTRL_CLK_VIN_TYPE_V10:
429 if (status) 651 status = vin_device_construct_v10(g, &board_obj_ptr,
652 sizeof(struct vin_device_v10), pargs);
653 break;
654
655 case CTRL_CLK_VIN_TYPE_V20:
656 status = vin_device_construct_v20(g, &board_obj_ptr,
657 sizeof(struct vin_device_v20), pargs);
658 break;
659
660 default:
430 return NULL; 661 return NULL;
662 };
431 663
432 /*got vin board obj allocated now fill it into boardobj grp*/ 664 if (status)
433 pvin_dev = (struct vin_device *)pargs; 665 return NULL;
434 board_obj_vin_ptr = (struct vin_device *)board_obj_ptr;
435 /* override super class interface */
436 board_obj_ptr->pmudatainit = vin_device_init_pmudata_super;
437 board_obj_vin_ptr->id = pvin_dev->id;
438 board_obj_vin_ptr->volt_domain_vbios = pvin_dev->volt_domain_vbios;
439 board_obj_vin_ptr->slope = pvin_dev->slope;
440 board_obj_vin_ptr->intercept = pvin_dev->intercept;
441 board_obj_vin_ptr->flls_shared_mask = pvin_dev->flls_shared_mask;
442 board_obj_vin_ptr->volt_domain = CTRL_VOLT_DOMAIN_LOGIC;
443 666
444 gk20a_dbg_info(" Done"); 667 gk20a_dbg_info(" Done");
445 668
446 return (struct vin_device *)board_obj_ptr; 669 return (struct vin_device *)board_obj_ptr;
447} 670}
448 671
672
673
674static u32 vin_device_init_pmudata_v10(struct gk20a *g,
675 struct boardobj *board_obj_ptr,
676 struct nv_pmu_boardobj *ppmudata)
677{
678 u32 status = 0;
679 struct vin_device_v20 *pvin_dev_v20;
680 struct nv_pmu_clk_clk_vin_device_v10_boardobj_set *perf_pmu_data;
681
682 gk20a_dbg_info("");
683
684 status = vin_device_init_pmudata_super(g, board_obj_ptr, ppmudata);
685 if (status != 0)
686 return status;
687
688 pvin_dev_v20 = (struct vin_device_v20 *)board_obj_ptr;
689 perf_pmu_data = (struct nv_pmu_clk_clk_vin_device_v10_boardobj_set *)
690 ppmudata;
691
692 perf_pmu_data->data.vin_cal.intercept = pvin_dev_v20->data.vin_cal.cal_v10.intercept;
693 perf_pmu_data->data.vin_cal.slope = pvin_dev_v20->data.vin_cal.cal_v10.slope;
694
695 gk20a_dbg_info(" Done");
696
697 return status;
698}
699
700static u32 vin_device_init_pmudata_v20(struct gk20a *g,
701 struct boardobj *board_obj_ptr,
702 struct nv_pmu_boardobj *ppmudata)
703{
704 u32 status = 0;
705 struct vin_device_v20 *pvin_dev_v20;
706 struct nv_pmu_clk_clk_vin_device_v20_boardobj_set *perf_pmu_data;
707
708 gk20a_dbg_info("");
709
710 status = vin_device_init_pmudata_super(g, board_obj_ptr, ppmudata);
711 if (status != 0)
712 return status;
713
714 pvin_dev_v20 = (struct vin_device_v20 *)board_obj_ptr;
715 perf_pmu_data = (struct nv_pmu_clk_clk_vin_device_v20_boardobj_set *)
716 ppmudata;
717
718 perf_pmu_data->data.vin_cal.cal_v20.offset = pvin_dev_v20->data.vin_cal.cal_v20.offset;
719 perf_pmu_data->data.vin_cal.cal_v20.gain = pvin_dev_v20->data.vin_cal.cal_v20.gain;
720
721 gk20a_dbg_info(" Done");
722
723 return status;
724}
725
449static u32 vin_device_init_pmudata_super(struct gk20a *g, 726static u32 vin_device_init_pmudata_super(struct gk20a *g,
450 struct boardobj *board_obj_ptr, 727 struct boardobj *board_obj_ptr,
451 struct nv_pmu_boardobj *ppmudata) 728 struct nv_pmu_boardobj *ppmudata)
@@ -465,9 +742,7 @@ static u32 vin_device_init_pmudata_super(struct gk20a *g,
465 ppmudata; 742 ppmudata;
466 743
467 perf_pmu_data->id = pvin_dev->id; 744 perf_pmu_data->id = pvin_dev->id;
468 perf_pmu_data->intercept = pvin_dev->intercept;
469 perf_pmu_data->volt_domain = pvin_dev->volt_domain; 745 perf_pmu_data->volt_domain = pvin_dev->volt_domain;
470 perf_pmu_data->slope = pvin_dev->slope;
471 perf_pmu_data->flls_shared_mask = pvin_dev->flls_shared_mask; 746 perf_pmu_data->flls_shared_mask = pvin_dev->flls_shared_mask;
472 747
473 gk20a_dbg_info(" Done"); 748 gk20a_dbg_info(" Done");
diff --git a/drivers/gpu/nvgpu/clk/clk_vin.h b/drivers/gpu/nvgpu/clk/clk_vin.h
index 3ce26c8a..209e7055 100644
--- a/drivers/gpu/nvgpu/clk/clk_vin.h
+++ b/drivers/gpu/nvgpu/clk/clk_vin.h
@@ -1,5 +1,5 @@
1/* 1/*
2* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. 2* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved.
3* 3*
4 * Permission is hereby granted, free of charge, to any person obtaining a 4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"), 5 * copy of this software and associated documentation files (the "Software"),
@@ -44,13 +44,21 @@ struct vin_device {
44 u8 id; 44 u8 id;
45 u8 volt_domain; 45 u8 volt_domain;
46 u8 volt_domain_vbios; 46 u8 volt_domain_vbios;
47 u32 slope;
48 u32 intercept;
49 u32 flls_shared_mask; 47 u32 flls_shared_mask;
50 48
51 vin_device_state_load *state_load; 49 vin_device_state_load *state_load;
52}; 50};
53 51
52struct vin_device_v10 {
53 struct vin_device super;
54 struct ctrl_clk_vin_device_info_data_v10 data;
55};
56
57struct vin_device_v20 {
58 struct vin_device super;
59 struct ctrl_clk_vin_device_info_data_v20 data;
60};
61
54/* get vin device object from descriptor table index*/ 62/* get vin device object from descriptor table index*/
55#define CLK_GET_VIN_DEVICE(pvinobjs, dev_index) \ 63#define CLK_GET_VIN_DEVICE(pvinobjs, dev_index) \
56 ((struct vin_device *)BOARDOBJGRP_OBJ_GET_BY_IDX( \ 64 ((struct vin_device *)BOARDOBJGRP_OBJ_GET_BY_IDX( \
@@ -61,5 +69,11 @@ boardobj_pmudatainit vindeviceinit_pmudata_super;
61 69
62u32 clk_vin_sw_setup(struct gk20a *g); 70u32 clk_vin_sw_setup(struct gk20a *g);
63u32 clk_vin_pmu_setup(struct gk20a *g); 71u32 clk_vin_pmu_setup(struct gk20a *g);
72u32 clk_avfs_get_vin_cal_fuse_v10(struct gk20a *g,
73 struct avfsvinobjs *pvinobjs,
74 struct vin_device_v20 *pvindev);
75u32 clk_avfs_get_vin_cal_fuse_v20(struct gk20a *g,
76 struct avfsvinobjs *pvinobjs,
77 struct vin_device_v20 *pvindev);
64 78
65#endif 79#endif
diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_fw.c b/drivers/gpu/nvgpu/common/pmu/pmu_fw.c
index 4dd6a21e..c95f5880 100644
--- a/drivers/gpu/nvgpu/common/pmu/pmu_fw.c
+++ b/drivers/gpu/nvgpu/common/pmu/pmu_fw.c
@@ -1307,6 +1307,8 @@ static int nvgpu_init_pmu_fw_ver_ops(struct nvgpu_pmu *pmu)
1307 nvgpu_volt_send_load_cmd_to_pmu_gv10x; 1307 nvgpu_volt_send_load_cmd_to_pmu_gv10x;
1308 g->ops.pmu_ver.clk.get_vbios_clk_domain = 1308 g->ops.pmu_ver.clk.get_vbios_clk_domain =
1309 nvgpu_clk_get_vbios_clk_domain_gv10x; 1309 nvgpu_clk_get_vbios_clk_domain_gv10x;
1310 g->ops.pmu_ver.clk.clk_avfs_get_vin_cal_data =
1311 clk_avfs_get_vin_cal_fuse_v20;
1310 } else { 1312 } else {
1311 g->ops.pmu_ver.get_pmu_init_msg_pmu_queue_params = 1313 g->ops.pmu_ver.get_pmu_init_msg_pmu_queue_params =
1312 get_pmu_init_msg_pmu_queue_params_v4; 1314 get_pmu_init_msg_pmu_queue_params_v4;
@@ -1474,6 +1476,8 @@ static int nvgpu_init_pmu_fw_ver_ops(struct nvgpu_pmu *pmu)
1474 nvgpu_volt_send_load_cmd_to_pmu_gp10x; 1476 nvgpu_volt_send_load_cmd_to_pmu_gp10x;
1475 g->ops.pmu_ver.clk.get_vbios_clk_domain = 1477 g->ops.pmu_ver.clk.get_vbios_clk_domain =
1476 nvgpu_clk_get_vbios_clk_domain_gp10x; 1478 nvgpu_clk_get_vbios_clk_domain_gp10x;
1479 g->ops.pmu_ver.clk.clk_avfs_get_vin_cal_data =
1480 clk_avfs_get_vin_cal_fuse_v10;
1477 break; 1481 break;
1478 case APP_VERSION_GM20B: 1482 case APP_VERSION_GM20B:
1479 g->ops.pmu_ver.pg_cmd_eng_buf_load_size = 1483 g->ops.pmu_ver.pg_cmd_eng_buf_load_size =
diff --git a/drivers/gpu/nvgpu/ctrl/ctrlclk.h b/drivers/gpu/nvgpu/ctrl/ctrlclk.h
index 3a383c17..3d50f413 100644
--- a/drivers/gpu/nvgpu/ctrl/ctrlclk.h
+++ b/drivers/gpu/nvgpu/ctrl/ctrlclk.h
@@ -135,6 +135,30 @@ struct ctrl_clk_clk_delta {
135 int volt_deltauv[CTRL_CLK_CLK_DELTA_MAX_VOLT_RAILS]; 135 int volt_deltauv[CTRL_CLK_CLK_DELTA_MAX_VOLT_RAILS];
136}; 136};
137 137
138struct ctrl_clk_vin_v10 {
139 u32 slope;
140 u32 intercept;
141};
142
143struct ctrl_clk_vin_v20 {
144 s8 offset;
145 s8 gain;
146};
147
148union ctrl_clk_vin_data_v20 {
149 struct ctrl_clk_vin_v10 cal_v10;
150 struct ctrl_clk_vin_v20 cal_v20;
151};
152
153struct ctrl_clk_vin_device_info_data_v10 {
154 struct ctrl_clk_vin_v10 vin_cal;
155};
156
157struct ctrl_clk_vin_device_info_data_v20 {
158 u8 cal_type;
159 union ctrl_clk_vin_data_v20 vin_cal;
160};
161
138union ctrl_clk_clk_prog_1x_source_data { 162union ctrl_clk_clk_prog_1x_source_data {
139 struct ctrl_clk_clk_prog_1x_source_pll pll; 163 struct ctrl_clk_clk_prog_1x_source_pll pll;
140}; 164};
diff --git a/drivers/gpu/nvgpu/ctrl/ctrlclkavfs.h b/drivers/gpu/nvgpu/ctrl/ctrlclkavfs.h
index 59a542c8..7338fa3a 100644
--- a/drivers/gpu/nvgpu/ctrl/ctrlclkavfs.h
+++ b/drivers/gpu/nvgpu/ctrl/ctrlclkavfs.h
@@ -41,6 +41,14 @@
41#define CTRL_CLK_VIN_ID_UNDEFINED 0x000000FF 41#define CTRL_CLK_VIN_ID_UNDEFINED 0x000000FF
42 42
43#define CTRL_CLK_VIN_TYPE_DISABLED 0x00000000 43#define CTRL_CLK_VIN_TYPE_DISABLED 0x00000000
44#define CTRL_CLK_VIN_TYPE_V10 0x00000001
45#define CTRL_CLK_VIN_TYPE_V20 0x00000002
46
47/*!
48 * Various types of VIN calibration that the GPU can support
49 */
50#define CTRL_CLK_VIN_CAL_TYPE_V10 (0x00000000)
51#define CTRL_CLK_VIN_CAL_TYPE_V20 (0x00000001)
44 52
45/*! 53/*!
46 * Mask of all GPC VIN IDs supported by RM 54 * Mask of all GPC VIN IDs supported by RM
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index 2d47f41e..75357a82 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -801,6 +801,9 @@ struct gpu_ops {
801 } volt; 801 } volt;
802 struct { 802 struct {
803 u32 (*get_vbios_clk_domain)(u32 vbios_domain); 803 u32 (*get_vbios_clk_domain)(u32 vbios_domain);
804 u32 (*clk_avfs_get_vin_cal_data)(struct gk20a *g,
805 struct avfsvinobjs *pvinobjs,
806 struct vin_device_v20 *pvindev);
804 }clk; 807 }clk;
805 } pmu_ver; 808 } pmu_ver;
806 struct { 809 struct {
diff --git a/drivers/gpu/nvgpu/include/nvgpu/bios.h b/drivers/gpu/nvgpu/include/nvgpu/bios.h
index eec057f2..0619fcb9 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/bios.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/bios.h
@@ -137,6 +137,9 @@ struct vin_descriptor_entry_10 {
137#define NV_VIN_DESC_FLAGS0_VIN_CAL_REVISION_MASK 0x7 137#define NV_VIN_DESC_FLAGS0_VIN_CAL_REVISION_MASK 0x7
138#define NV_VIN_DESC_FLAGS0_VIN_CAL_REVISION_SHIFT 0 138#define NV_VIN_DESC_FLAGS0_VIN_CAL_REVISION_SHIFT 0
139 139
140#define NV_VIN_DESC_FLAGS0_VIN_CAL_TYPE_MASK 0xF0
141#define NV_VIN_DESC_FLAGS0_VIN_CAL_TYPE_SHIFT 4
142
140#define NV_VIN_DESC_FLAGS0_DISABLE_CONTROL_MASK 0x8 143#define NV_VIN_DESC_FLAGS0_DISABLE_CONTROL_MASK 0x8
141#define NV_VIN_DESC_FLAGS0_DISABLE_CONTROL_SHIFT 3 144#define NV_VIN_DESC_FLAGS0_DISABLE_CONTROL_SHIFT 3
142 145
@@ -152,6 +155,12 @@ struct vin_descriptor_entry_10 {
152#define NV_VIN_DESC_VIN_CAL_INTERCEPT_INTEGER_MASK 0xFFC0000 155#define NV_VIN_DESC_VIN_CAL_INTERCEPT_INTEGER_MASK 0xFFC0000
153#define NV_VIN_DESC_VIN_CAL_INTERCEPT_INTEGER_SHIFT 18 156#define NV_VIN_DESC_VIN_CAL_INTERCEPT_INTEGER_SHIFT 18
154 157
158#define NV_VIN_DESC_VIN_CAL_OFFSET_MASK 0x7F
159#define NV_VIN_DESC_VIN_CAL_OFFSET_SHIFT 0
160
161#define NV_VIN_DESC_VIN_CAL_GAIN_MASK 0xF80
162#define NV_VIN_DESC_VIN_CAL_GAIN_SHIFT 7
163
155#define VBIOS_CLOCKS_TABLE_1X_HEADER_SIZE_07 0x07 164#define VBIOS_CLOCKS_TABLE_1X_HEADER_SIZE_07 0x07
156struct vbios_clocks_table_1x_header { 165struct vbios_clocks_table_1x_header {
157 u8 version; 166 u8 version;
diff --git a/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifclk.h b/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifclk.h
index 63bce913..e0a3313b 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifclk.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifclk.h
@@ -251,14 +251,24 @@ struct nv_pmu_clk_clk_vin_device_boardobj_set {
251 struct nv_pmu_boardobj super; 251 struct nv_pmu_boardobj super;
252 u8 id; 252 u8 id;
253 u8 volt_domain; 253 u8 volt_domain;
254 u32 slope;
255 u32 intercept;
256 u32 flls_shared_mask; 254 u32 flls_shared_mask;
257}; 255};
258 256
257struct nv_pmu_clk_clk_vin_device_v10_boardobj_set {
258 struct nv_pmu_clk_clk_vin_device_boardobj_set super;
259 struct ctrl_clk_vin_device_info_data_v10 data;
260};
261
262struct nv_pmu_clk_clk_vin_device_v20_boardobj_set {
263 struct nv_pmu_clk_clk_vin_device_boardobj_set super;
264 struct ctrl_clk_vin_device_info_data_v20 data;
265};
266
259union nv_pmu_clk_clk_vin_device_boardobj_set_union { 267union nv_pmu_clk_clk_vin_device_boardobj_set_union {
260 struct nv_pmu_boardobj board_obj; 268 struct nv_pmu_boardobj board_obj;
261 struct nv_pmu_clk_clk_vin_device_boardobj_set super; 269 struct nv_pmu_clk_clk_vin_device_boardobj_set super;
270 struct nv_pmu_clk_clk_vin_device_v10_boardobj_set v10;
271 struct nv_pmu_clk_clk_vin_device_v20_boardobj_set v20;
262}; 272};
263 273
264NV_PMU_BOARDOBJ_GRP_SET_MAKE_E32(clk, clk_vin_device); 274NV_PMU_BOARDOBJ_GRP_SET_MAKE_E32(clk, clk_vin_device);