From d3f96dfa96a8aafe6f5035e2ed24425141e4202e Mon Sep 17 00:00:00 2001 From: Mahantesh Kumbar Date: Wed, 14 Feb 2018 14:31:01 +0530 Subject: gpu: nvgpu: gv10x volt rail boardobj changes - Created volt ops under pmu_ver to support volt_set_voltage, volt_get_voltage & volt_send_load_cmd_to_pmu. - Renamed volt load, set_voltage & get_voltage gp10x method names. - Added new volt load, set_voltage & get_voltage methods for gv10x using RPC & added code to handle ack in pmu_rpc_handler() along with struct rail_list changes. - Updated volt ops of gp106 & gv100 to point to respective methods. - Added member volt_dev_idx_ipc_vmin & volt_scale_exp_pwr_equ_idx to "struct nv_pmu_volt_volt_rail_boardobj_set" & "struct voltage_rail" made changes to update members as needed. - Added member volt_scale_exp_pwr_equ_idx to "struct vbios_voltage_rail_table_1x_entry" to read value from VBIOS table & update rail boardobj set interface. - Defines for volt RPC "NV_PMU_RPC_ID_VOLT_*" - Define struct's volt load, set_voltage & get_voltage to execute volt RPC. Change-Id: I4a41adcf7536468beaa8a73f551b1d608aabd161 Signed-off-by: Mahantesh Kumbar Reviewed-on: https://git-master.nvidia.com/r/1659728 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Vijayakumar Subbu Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/pmu/pmu_fw.c | 12 +++ drivers/gpu/nvgpu/common/pmu/pmu_ipc.c | 19 ++++ drivers/gpu/nvgpu/ctrl/ctrlvolt.h | 15 ++- drivers/gpu/nvgpu/gk20a/gk20a.h | 7 ++ drivers/gpu/nvgpu/include/nvgpu/bios.h | 2 + drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifvolt.h | 61 +++++++++++- drivers/gpu/nvgpu/pstate/pstate.c | 4 +- drivers/gpu/nvgpu/volt/volt_pmu.c | 110 +++++++++++++++++++-- drivers/gpu/nvgpu/volt/volt_pmu.h | 16 ++- drivers/gpu/nvgpu/volt/volt_rail.c | 35 ++++++- drivers/gpu/nvgpu/volt/volt_rail.h | 4 +- 11 files changed, 270 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_fw.c b/drivers/gpu/nvgpu/common/pmu/pmu_fw.c index 6a038317..1070579e 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu_fw.c +++ b/drivers/gpu/nvgpu/common/pmu/pmu_fw.c @@ -1299,6 +1299,12 @@ static int nvgpu_init_pmu_fw_ver_ops(struct nvgpu_pmu *pmu) boardobjgrp_pmugetstatus_impl_v1; g->ops.pmu_ver.boardobj.is_boardobjgrp_pmucmd_id_valid = is_boardobjgrp_pmucmd_id_valid_v1; + g->ops.pmu_ver.volt.volt_set_voltage = + nvgpu_volt_set_voltage_gv10x; + g->ops.pmu_ver.volt.volt_get_voltage = + nvgpu_volt_rail_get_voltage_gv10x; + g->ops.pmu_ver.volt.volt_send_load_cmd_to_pmu = + nvgpu_volt_send_load_cmd_to_pmu_gv10x; } else { g->ops.pmu_ver.get_pmu_init_msg_pmu_queue_params = get_pmu_init_msg_pmu_queue_params_v4; @@ -1458,6 +1464,12 @@ static int nvgpu_init_pmu_fw_ver_ops(struct nvgpu_pmu *pmu) boardobjgrp_pmugetstatus_impl; g->ops.pmu_ver.boardobj.is_boardobjgrp_pmucmd_id_valid = is_boardobjgrp_pmucmd_id_valid_v0; + g->ops.pmu_ver.volt.volt_set_voltage = + nvgpu_volt_set_voltage_gp10x; + g->ops.pmu_ver.volt.volt_get_voltage = + nvgpu_volt_rail_get_voltage_gp10x; + g->ops.pmu_ver.volt.volt_send_load_cmd_to_pmu = + nvgpu_volt_send_load_cmd_to_pmu_gp10x; break; case APP_VERSION_GM20B: g->ops.pmu_ver.pg_cmd_eng_buf_load_size = diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_ipc.c b/drivers/gpu/nvgpu/common/pmu/pmu_ipc.c index bb4edf38..d1058864 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu_ipc.c +++ b/drivers/gpu/nvgpu/common/pmu/pmu_ipc.c @@ -1035,6 +1035,25 @@ static void pmu_rpc_handler(struct gk20a *g, struct pmu_msg *msg, break; } break; + case PMU_UNIT_VOLT: + switch (rpc.function) { + case NV_PMU_RPC_ID_VOLT_BOARD_OBJ_GRP_CMD: + nvgpu_pmu_dbg(g, + "reply NV_PMU_RPC_ID_VOLT_BOARD_OBJ_GRP_CMD"); + break; + case NV_PMU_RPC_ID_VOLT_VOLT_SET_VOLTAGE: + nvgpu_pmu_dbg(g, + "reply NV_PMU_RPC_ID_VOLT_VOLT_SET_VOLTAGE"); + break; + case NV_PMU_RPC_ID_VOLT_VOLT_RAIL_GET_VOLTAGE: + nvgpu_pmu_dbg(g, + "reply NV_PMU_RPC_ID_VOLT_VOLT_RAIL_GET_VOLTAGE"); + break; + case NV_PMU_RPC_ID_VOLT_LOAD: + nvgpu_pmu_dbg(g, + "reply NV_PMU_RPC_ID_VOLT_LOAD"); + } + break; /* TBD case will be added */ default: nvgpu_err(g, " Invalid RPC response, stats 0x%x", diff --git a/drivers/gpu/nvgpu/ctrl/ctrlvolt.h b/drivers/gpu/nvgpu/ctrl/ctrlvolt.h index c99aa79f..1a82fbed 100644 --- a/drivers/gpu/nvgpu/ctrl/ctrlvolt.h +++ b/drivers/gpu/nvgpu/ctrl/ctrlvolt.h @@ -1,7 +1,7 @@ /* * general p state infrastructure * - * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2016-2018, 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"), @@ -89,6 +89,7 @@ enum nv_pmu_pmgr_pwm_source { #define CTRL_VOLT_DEVICE_OPERATION_TYPE_DEFAULT 0x01 #define CTRL_VOLT_DEVICE_OPERATION_TYPE_LPWR_STEADY_STATE 0x02 #define CTRL_VOLT_DEVICE_OPERATION_TYPE_LPWR_SLEEP_STATE 0x03 +#define CTRL_VOLT_VOLT_DEVICE_OPERATION_TYPE_IPC_VMIN 0x04 /*! * Macros for Voltage Domains. @@ -126,4 +127,16 @@ struct ctrl_volt_volt_rail_list { rails[CTRL_VOLT_VOLT_RAIL_MAX_RAILS]; }; +struct ctrl_volt_volt_rail_list_item_v1 { + u8 rail_idx; + u32 voltage_uv; + u32 voltage_min_noise_unaware_uv; +}; + +struct ctrl_volt_volt_rail_list_v1 { + u8 num_rails; + struct ctrl_volt_volt_rail_list_item_v1 + rails[CTRL_VOLT_VOLT_RAIL_MAX_RAILS]; +}; + #endif diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 9a0cfd02..58570d6d 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -747,6 +747,13 @@ struct gpu_ops { struct boardobjgrp *pboardobjgrp, struct boardobjgrp_pmu_cmd *cmd); } boardobj; + struct { + u32 (*volt_set_voltage)(struct gk20a *g, + u32 logic_voltage_uv, u32 sram_voltage_uv); + u32 (*volt_get_voltage)(struct gk20a *g, + u8 volt_domain, u32 *pvoltage_uv); + u32 (*volt_send_load_cmd_to_pmu)(struct gk20a *g); + } volt; } pmu_ver; struct { int (*get_netlist_name)(struct gk20a *g, int index, char *name); diff --git a/drivers/gpu/nvgpu/include/nvgpu/bios.h b/drivers/gpu/nvgpu/include/nvgpu/bios.h index fb0a313f..75f8da35 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/bios.h +++ b/drivers/gpu/nvgpu/include/nvgpu/bios.h @@ -725,6 +725,7 @@ struct vbios_voltage_rail_table_1x_header { #define NV_VBIOS_VOLTAGE_RAIL_1X_ENTRY_SIZE_09 0X00000009 #define NV_VBIOS_VOLTAGE_RAIL_1X_ENTRY_SIZE_0A 0X0000000A #define NV_VBIOS_VOLTAGE_RAIL_1X_ENTRY_SIZE_0B 0X0000000B +#define NV_VBIOS_VOLTAGE_RAIL_1X_ENTRY_SIZE_0C 0X0000000C struct vbios_voltage_rail_table_1x_entry { u32 boot_voltage_uv; @@ -735,6 +736,7 @@ struct vbios_voltage_rail_table_1x_entry { u8 boot_volt_vfe_equ_idx; u8 vmin_limit_vfe_equ_idx; u8 volt_margin_limit_vfe_equ_idx; + u8 volt_scale_exp_pwr_equ_idx; } __packed; /* Voltage Device Table */ diff --git a/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifvolt.h b/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifvolt.h index c3d540cc..3b286139 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifvolt.h +++ b/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifvolt.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. +* Copyright (c) 2016-2018, 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"), @@ -49,6 +49,8 @@ struct nv_pmu_volt_volt_rail_boardobj_set { u8 volt_margin_limit_vfe_equ_idx; u8 pwr_equ_idx; u8 volt_dev_idx_default; + u8 volt_dev_idx_ipc_vmin; + u8 volt_scale_exp_pwr_equ_idx; struct ctrl_boardobjgrp_mask_e32 volt_dev_mask; s32 volt_delta_uv[CTRL_VOLT_RAIL_VOLT_DELTA_MAX_ENTRIES]; }; @@ -101,7 +103,6 @@ NV_PMU_BOARDOBJ_GRP_SET_MAKE_E32(volt, volt_device); /* ------------ VOLT_POLICY's GRP_SET defines and structures ------------ */ struct nv_pmu_volt_volt_policy_boardobjgrp_set_header { - struct nv_pmu_boardobjgrp_e32 super; }; @@ -332,4 +333,60 @@ struct nv_pmu_volt_volt_rail_list { rails[NV_PMU_VF_INJECT_MAX_VOLT_RAILS]; }; +struct nv_pmu_volt_volt_rail_list_V1 { + u8 num_rails; + struct ctrl_volt_volt_rail_list_item_v1 + rails[NV_PMU_VF_INJECT_MAX_VOLT_RAILS]; +}; + +/* VOLT RPC */ +#define NV_PMU_RPC_ID_VOLT_BOARD_OBJ_GRP_CMD 0x00 +#define NV_PMU_RPC_ID_VOLT_VOLT_SET_VOLTAGE 0x01 +#define NV_PMU_RPC_ID_VOLT_LOAD 0x02 +#define NV_PMU_RPC_ID_VOLT_VOLT_RAIL_GET_VOLTAGE 0x03 +#define NV_PMU_RPC_ID_VOLT_VOLT_POLICY_SANITY_CHECK 0x04 +#define NV_PMU_RPC_ID_VOLT_TEST_EXECUTE 0x05 +#define NV_PMU_RPC_ID_VOLT__COUNT 0x06 + +/* + * Defines the structure that holds data + * used to execute LOAD RPC. + */ +struct nv_pmu_rpc_struct_volt_load { + /*[IN/OUT] Must be first field in RPC structure */ + struct nv_pmu_rpc_header hdr; + u32 scratch[1]; +}; + +/* + * Defines the structure that holds data + * used to execute VOLT_SET_VOLTAGE RPC. + */ +struct nv_pmu_rpc_struct_volt_volt_set_voltage { + /*[IN/OUT] Must be first field in RPC structure */ + struct nv_pmu_rpc_header hdr; + /*[IN] ID of the client that wants to set the voltage */ + u8 client_id; + /* + * [IN] The list containing target voltage and + * noise-unaware Vmin value for the VOLT_RAILs. + */ + struct ctrl_volt_volt_rail_list_v1 rail_list; + u32 scratch[1]; +}; + +/* + * Defines the structure that holds data + * used to execute VOLT_RAIL_GET_VOLTAGE RPC. + */ +struct nv_pmu_rpc_struct_volt_volt_rail_get_voltage { + /*[IN/OUT] Must be first field in RPC structure */ + struct nv_pmu_rpc_header hdr; + /* [OUT] Current voltage in uv */ + u32 voltage_uv; + /* [IN] Voltage Rail Table Index */ + u8 rail_idx; + u32 scratch[1]; +}; + #endif /* _GPMUIFVOLT_H_*/ diff --git a/drivers/gpu/nvgpu/pstate/pstate.c b/drivers/gpu/nvgpu/pstate/pstate.c index e164cc83..c3f34027 100644 --- a/drivers/gpu/nvgpu/pstate/pstate.c +++ b/drivers/gpu/nvgpu/pstate/pstate.c @@ -1,7 +1,7 @@ /* * general p state infrastructure * - * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2016-2018, 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"), @@ -136,7 +136,7 @@ int gk20a_init_pstate_pmu_support(struct gk20a *g) if (err) return err; - err = volt_pmu_send_load_cmd_to_pmu(g); + err = g->ops.pmu_ver.volt.volt_send_load_cmd_to_pmu(g); if (err) { nvgpu_err(g, "Failed to send VOLT LOAD CMD to PMU: status = 0x%08x.", diff --git a/drivers/gpu/nvgpu/volt/volt_pmu.c b/drivers/gpu/nvgpu/volt/volt_pmu.c index 915db9a7..4608918c 100644 --- a/drivers/gpu/nvgpu/volt/volt_pmu.c +++ b/drivers/gpu/nvgpu/volt/volt_pmu.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2016-2018, 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"), @@ -115,7 +115,7 @@ volt_pmu_rpc_execute: return status; } -u32 volt_pmu_send_load_cmd_to_pmu(struct gk20a *g) +u32 nvgpu_volt_send_load_cmd_to_pmu_gp10x(struct gk20a *g) { struct nv_pmu_volt_rpc rpc_call = { 0 }; u32 status = 0; @@ -131,7 +131,23 @@ u32 volt_pmu_send_load_cmd_to_pmu(struct gk20a *g) return status; } -static u32 volt_rail_get_voltage(struct gk20a *g, +u32 nvgpu_volt_send_load_cmd_to_pmu_gv10x(struct gk20a *g) +{ + struct nvgpu_pmu *pmu = &g->pmu; + struct nv_pmu_rpc_struct_volt_load rpc; + u32 status = 0; + + memset(&rpc, 0, sizeof(struct nv_pmu_rpc_struct_volt_load)); + PMU_RPC_EXECUTE(status, pmu, VOLT, LOAD, &rpc, 0); + if (status) { + nvgpu_err(g, "Failed to execute RPC status=0x%x", + status); + } + + return status; +} + +u32 nvgpu_volt_rail_get_voltage_gp10x(struct gk20a *g, u8 volt_domain, u32 *pvoltage_uv) { struct nv_pmu_volt_rpc rpc_call = { 0 }; @@ -165,6 +181,37 @@ static u32 volt_rail_get_voltage(struct gk20a *g, return status; } +u32 nvgpu_volt_rail_get_voltage_gv10x(struct gk20a *g, + u8 volt_domain, u32 *pvoltage_uv) +{ + struct nvgpu_pmu *pmu = &g->pmu; + struct nv_pmu_rpc_struct_volt_volt_rail_get_voltage rpc; + u32 status = 0; + u8 rail_idx; + + rail_idx = volt_rail_volt_domain_convert_to_idx(g, volt_domain); + if ((rail_idx == CTRL_VOLT_RAIL_INDEX_INVALID) || + (!VOLT_RAIL_INDEX_IS_VALID(&g->perf_pmu.volt, rail_idx))) { + nvgpu_err(g, + "failed: volt_domain = %d, voltage rail table = %d.", + volt_domain, rail_idx); + return -EINVAL; + } + + memset(&rpc, 0, + sizeof(struct nv_pmu_rpc_struct_volt_volt_rail_get_voltage)); + rpc.rail_idx = rail_idx; + + PMU_RPC_EXECUTE_CPB(status, pmu, VOLT, VOLT_SET_VOLTAGE, &rpc, 0); + if (status) { + nvgpu_err(g, "Failed to execute RPC status=0x%x", + status); + } + + *pvoltage_uv = rpc.voltage_uv; + + return status; +} static u32 volt_policy_set_voltage(struct gk20a *g, u8 client_id, struct ctrl_perf_volt_rail_list *prail_list) @@ -217,9 +264,54 @@ exit: return status; } -u32 volt_set_voltage(struct gk20a *g, u32 logic_voltage_uv, u32 sram_voltage_uv) +static u32 volt_set_voltage_gv10x_rpc(struct gk20a *g, u8 client_id, + struct ctrl_volt_volt_rail_list_v1 *prail_list) { - u32 status = 0; + struct nvgpu_pmu *pmu = &g->pmu; + struct nv_pmu_rpc_struct_volt_volt_set_voltage rpc; + int status = 0; + + memset(&rpc, 0, sizeof(struct nv_pmu_rpc_struct_volt_volt_set_voltage)); + rpc.client_id = 0x1; + rpc.rail_list = *prail_list; + + PMU_RPC_EXECUTE(status, pmu, VOLT, VOLT_SET_VOLTAGE, &rpc, 0); + if (status) { + nvgpu_err(g, "Failed to execute RPC status=0x%x", + status); + } + + return status; +} + +u32 nvgpu_volt_set_voltage_gv10x(struct gk20a *g, u32 logic_voltage_uv, + u32 sram_voltage_uv) +{ + int status = 0; + struct ctrl_volt_volt_rail_list_v1 rail_list = { 0 }; + + rail_list.num_rails = RAIL_COUNT; + rail_list.rails[0].rail_idx = + volt_rail_volt_domain_convert_to_idx(g, + CTRL_VOLT_DOMAIN_LOGIC); + rail_list.rails[0].voltage_uv = logic_voltage_uv; + rail_list.rails[0].voltage_min_noise_unaware_uv = logic_voltage_uv; + rail_list.rails[1].rail_idx = + volt_rail_volt_domain_convert_to_idx(g, + CTRL_VOLT_DOMAIN_SRAM); + rail_list.rails[1].voltage_uv = sram_voltage_uv; + rail_list.rails[1].voltage_min_noise_unaware_uv = sram_voltage_uv; + + status = volt_set_voltage_gv10x_rpc(g, + CTRL_VOLT_POLICY_CLIENT_PERF_CORE_VF_SEQ, &rail_list); + + return status; +} + +u32 nvgpu_volt_set_voltage_gp10x(struct gk20a *g, u32 logic_voltage_uv, + u32 sram_voltage_uv) +{ + int status = 0; struct ctrl_perf_volt_rail_list rail_list = { 0 }; rail_list.num_rails = RAIL_COUNT; @@ -234,12 +326,18 @@ u32 volt_set_voltage(struct gk20a *g, u32 logic_voltage_uv, u32 sram_voltage_uv) CTRL_VOLT_POLICY_CLIENT_PERF_CORE_VF_SEQ, &rail_list); return status; +} +u32 volt_set_voltage(struct gk20a *g, u32 logic_voltage_uv, u32 sram_voltage_uv) +{ + return g->ops.pmu_ver.volt.volt_set_voltage(g, + logic_voltage_uv, sram_voltage_uv); } u32 volt_get_voltage(struct gk20a *g, u32 volt_domain, u32 *voltage_uv) { - return volt_rail_get_voltage(g, volt_domain, voltage_uv); + return g->ops.pmu_ver.volt.volt_get_voltage(g, + volt_domain, voltage_uv); } static int volt_policy_set_noiseaware_vmin(struct gk20a *g, diff --git a/drivers/gpu/nvgpu/volt/volt_pmu.h b/drivers/gpu/nvgpu/volt/volt_pmu.h index 55be9c45..fbdf7c1e 100644 --- a/drivers/gpu/nvgpu/volt/volt_pmu.h +++ b/drivers/gpu/nvgpu/volt/volt_pmu.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +* Copyright (c) 2016-2018, 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"), @@ -29,4 +29,18 @@ u32 volt_set_voltage(struct gk20a *g, u32 logic_voltage_uv, u32 volt_get_voltage(struct gk20a *g, u32 volt_domain, u32 *voltage_uv); int volt_set_noiseaware_vmin(struct gk20a *g, u32 logic_voltage_uv, u32 sram_voltage_uv); + +u32 nvgpu_volt_set_voltage_gp10x(struct gk20a *g, u32 logic_voltage_uv, + u32 sram_voltage_uv); +u32 nvgpu_volt_rail_get_voltage_gp10x(struct gk20a *g, + u8 volt_domain, u32 *pvoltage_uv); +u32 nvgpu_volt_send_load_cmd_to_pmu_gp10x(struct gk20a *g); + +u32 nvgpu_volt_set_voltage_gv10x(struct gk20a *g, u32 logic_voltage_uv, + u32 sram_voltage_uv); +u32 nvgpu_volt_rail_get_voltage_gv10x(struct gk20a *g, + u8 volt_domain, u32 *pvoltage_uv); +u32 nvgpu_volt_send_load_cmd_to_pmu_gv10x(struct gk20a *g); + + #endif diff --git a/drivers/gpu/nvgpu/volt/volt_rail.c b/drivers/gpu/nvgpu/volt/volt_rail.c index f78fc315..3461653f 100644 --- a/drivers/gpu/nvgpu/volt/volt_rail.c +++ b/drivers/gpu/nvgpu/volt/volt_rail.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2016-2018, 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"), @@ -34,8 +34,10 @@ u8 volt_rail_volt_domain_convert_to_idx(struct gk20a *g, u8 volt_domain) { switch (g->perf_pmu.volt.volt_rail_metadata.volt_domain_hal) { case CTRL_VOLT_DOMAIN_HAL_GP10X_SINGLE_RAIL: - if (volt_domain == CTRL_BOARDOBJ_IDX_INVALID) + switch (volt_domain) { + case CTRL_VOLT_DOMAIN_LOGIC: return 0; + } break; case CTRL_VOLT_DOMAIN_HAL_GP10X_SPLIT_RAIL: switch (volt_domain) { @@ -63,6 +65,22 @@ u32 volt_rail_volt_dev_register(struct gk20a *g, struct voltage_rail status = -EINVAL; goto exit; } + } else if (operation_type == + CTRL_VOLT_VOLT_DEVICE_OPERATION_TYPE_IPC_VMIN) { + if (pvolt_rail->volt_dev_idx_ipc_vmin == + CTRL_BOARDOBJ_IDX_INVALID) { + pvolt_rail->volt_dev_idx_ipc_vmin = volt_dev_idx; + /* + * Exit on purpose as we do not want to register + * IPC_VMIN device against the rail to avoid + * setting current voltage instead of + * IPC Vmin voltage. + */ + goto exit; + } else { + status = -EINVAL; + goto exit; + } } else { goto exit; } @@ -136,6 +154,9 @@ static u32 volt_rail_init_pmudata_super(struct gk20a *g, prail->volt_margin_limit_vfe_equ_idx; rail_pmu_data->pwr_equ_idx = prail->pwr_equ_idx; rail_pmu_data->volt_dev_idx_default = prail->volt_dev_idx_default; + rail_pmu_data->volt_scale_exp_pwr_equ_idx = + prail->volt_scale_exp_pwr_equ_idx; + rail_pmu_data->volt_dev_idx_ipc_vmin = prail->volt_dev_idx_ipc_vmin; for (i = 0; i < CTRL_VOLT_RAIL_VOLT_DELTA_MAX_ENTRIES; i++) { rail_pmu_data->volt_delta_uv[i] = prail->volt_delta_uv[i] + @@ -187,6 +208,8 @@ static struct voltage_rail *construct_volt_rail(struct gk20a *g, void *pargs) ptemp_rail->vmin_limit_vfe_equ_idx; board_obj_volt_rail_ptr->volt_margin_limit_vfe_equ_idx = ptemp_rail->volt_margin_limit_vfe_equ_idx; + board_obj_volt_rail_ptr->volt_scale_exp_pwr_equ_idx = + ptemp_rail->volt_scale_exp_pwr_equ_idx; gk20a_dbg_info("Done"); @@ -284,6 +307,14 @@ static u32 volt_get_volt_rail_table(struct gk20a *g, rail_type_data.volt_rail.ov_limit_vfe_equ_idx = (u8)entry.ov_limit_vfe_equ_idx; + if (header.table_entry_size >= + NV_VBIOS_VOLTAGE_RAIL_1X_ENTRY_SIZE_0C) + rail_type_data.volt_rail.volt_scale_exp_pwr_equ_idx = + (u8)entry.volt_scale_exp_pwr_equ_idx; + else + rail_type_data.volt_rail.volt_scale_exp_pwr_equ_idx = + CTRL_BOARDOBJ_IDX_INVALID; + if (header.table_entry_size >= NV_VBIOS_VOLTAGE_RAIL_1X_ENTRY_SIZE_0B) rail_type_data.volt_rail.volt_margin_limit_vfe_equ_idx = diff --git a/drivers/gpu/nvgpu/volt/volt_rail.h b/drivers/gpu/nvgpu/volt/volt_rail.h index 9a3fcda0..be3cbb72 100644 --- a/drivers/gpu/nvgpu/volt/volt_rail.h +++ b/drivers/gpu/nvgpu/volt/volt_rail.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +* Copyright (c) 2016-2018, 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"), @@ -51,7 +51,9 @@ struct voltage_rail { u8 alt_rel_limit_vfe_equ_idx; u8 ov_limit_vfe_equ_idx; u8 pwr_equ_idx; + u8 volt_scale_exp_pwr_equ_idx; u8 volt_dev_idx_default; + u8 volt_dev_idx_ipc_vmin; u8 boot_volt_vfe_equ_idx; u8 vmin_limit_vfe_equ_idx; u8 volt_margin_limit_vfe_equ_idx; -- cgit v1.2.2