diff options
-rw-r--r-- | drivers/gpu/nvgpu/clk/clk_vin.c | 407 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/clk/clk_vin.h | 20 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/pmu/pmu_fw.c | 4 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/ctrl/ctrlclk.h | 24 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/ctrl/ctrlclkavfs.h | 8 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/include/nvgpu/bios.h | 9 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifclk.h | 14 |
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 @@ | |||
40 | static u32 devinit_get_vin_device_table(struct gk20a *g, | 40 | static u32 devinit_get_vin_device_table(struct gk20a *g, |
41 | struct avfsvinobjs *pvinobjs); | 41 | struct avfsvinobjs *pvinobjs); |
42 | 42 | ||
43 | static u32 vin_device_construct_v10(struct gk20a *g, | ||
44 | struct boardobj **ppboardobj, | ||
45 | u16 size, void *pargs); | ||
46 | static u32 vin_device_construct_v20(struct gk20a *g, | ||
47 | struct boardobj **ppboardobj, | ||
48 | u16 size, void *pargs); | ||
49 | static u32 vin_device_construct_super(struct gk20a *g, | ||
50 | struct boardobj **ppboardobj, | ||
51 | u16 size, void *pargs); | ||
43 | static struct vin_device *construct_vin_device(struct gk20a *g, void *pargs); | 52 | static struct vin_device *construct_vin_device(struct gk20a *g, void *pargs); |
44 | 53 | ||
54 | static u32 vin_device_init_pmudata_v10(struct gk20a *g, | ||
55 | struct boardobj *board_obj_ptr, | ||
56 | struct nv_pmu_boardobj *ppmudata); | ||
57 | static u32 vin_device_init_pmudata_v20(struct gk20a *g, | ||
58 | struct boardobj *board_obj_ptr, | ||
59 | struct nv_pmu_boardobj *ppmudata); | ||
45 | static u32 vin_device_init_pmudata_super(struct gk20a *g, | 60 | static 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 | ||
202 | static 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 | |||
254 | u32 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 | |||
285 | u32 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 | |||
187 | static u32 _clk_vin_devgrp_pmudatainit_super(struct gk20a *g, | 316 | static 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 | ||
564 | static 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 | |||
592 | static 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 | } | ||
619 | static 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 | } | ||
419 | static struct vin_device *construct_vin_device(struct gk20a *g, void *pargs) | 643 | static 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 | |||
674 | static 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 | |||
700 | static 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 | |||
449 | static u32 vin_device_init_pmudata_super(struct gk20a *g, | 726 | static 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 | ||
52 | struct vin_device_v10 { | ||
53 | struct vin_device super; | ||
54 | struct ctrl_clk_vin_device_info_data_v10 data; | ||
55 | }; | ||
56 | |||
57 | struct 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 | ||
62 | u32 clk_vin_sw_setup(struct gk20a *g); | 70 | u32 clk_vin_sw_setup(struct gk20a *g); |
63 | u32 clk_vin_pmu_setup(struct gk20a *g); | 71 | u32 clk_vin_pmu_setup(struct gk20a *g); |
72 | u32 clk_avfs_get_vin_cal_fuse_v10(struct gk20a *g, | ||
73 | struct avfsvinobjs *pvinobjs, | ||
74 | struct vin_device_v20 *pvindev); | ||
75 | u32 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 | ||
138 | struct ctrl_clk_vin_v10 { | ||
139 | u32 slope; | ||
140 | u32 intercept; | ||
141 | }; | ||
142 | |||
143 | struct ctrl_clk_vin_v20 { | ||
144 | s8 offset; | ||
145 | s8 gain; | ||
146 | }; | ||
147 | |||
148 | union ctrl_clk_vin_data_v20 { | ||
149 | struct ctrl_clk_vin_v10 cal_v10; | ||
150 | struct ctrl_clk_vin_v20 cal_v20; | ||
151 | }; | ||
152 | |||
153 | struct ctrl_clk_vin_device_info_data_v10 { | ||
154 | struct ctrl_clk_vin_v10 vin_cal; | ||
155 | }; | ||
156 | |||
157 | struct ctrl_clk_vin_device_info_data_v20 { | ||
158 | u8 cal_type; | ||
159 | union ctrl_clk_vin_data_v20 vin_cal; | ||
160 | }; | ||
161 | |||
138 | union ctrl_clk_clk_prog_1x_source_data { | 162 | union 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 |
156 | struct vbios_clocks_table_1x_header { | 165 | struct 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 | ||
257 | struct 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 | |||
262 | struct 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 | |||
259 | union nv_pmu_clk_clk_vin_device_boardobj_set_union { | 267 | union 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 | ||
264 | NV_PMU_BOARDOBJ_GRP_SET_MAKE_E32(clk, clk_vin_device); | 274 | NV_PMU_BOARDOBJ_GRP_SET_MAKE_E32(clk, clk_vin_device); |