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/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 +- 4 files changed, 155 insertions(+), 10 deletions(-) (limited to 'drivers/gpu/nvgpu/volt') 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