diff options
author | steven kao <skao@nvidia.com> | 2018-01-02 19:07:00 -0800 |
---|---|---|
committer | Varun Wadekar <vwadekar@nvidia.com> | 2019-01-31 08:45:49 -0800 |
commit | ff605ba2eecb0d5dd640790eec6faae8836177b4 (patch) | |
tree | b3a00ef6a84c48d81858b76dfc164617db5f7f68 /plat/nvidia | |
parent | 8510376c26449b45973821f226d180c19a30a1e0 (diff) |
Tegra: bpmp_ipc: support to enable/disable module clocks
This patch adds support to the bpmp_ipc driver to allow clients to
enable/disable clocks to hardware blocks. Currently, the API only
supports SE devices.
Change-Id: I9a361e380c0bcda59f5a92ca51c86a46555b2e90
Signed-off-by: steven kao <skao@nvidia.com>
Diffstat (limited to 'plat/nvidia')
-rw-r--r-- | plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c | 48 | ||||
-rw-r--r-- | plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h | 61 | ||||
-rw-r--r-- | plat/nvidia/tegra/include/drivers/bpmp_ipc.h | 19 |
3 files changed, 122 insertions, 6 deletions
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c index 7faa2f09..2efa1bd9 100644 --- a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c +++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -302,3 +302,49 @@ int32_t tegra_bpmp_ipc_reset_module(uint32_t rst_id) return ret; } + +int tegra_bpmp_ipc_enable_clock(uint32_t clk_id) +{ + int ret; + struct mrq_clk_request req; + + /* only SE clocks are supported */ + if (clk_id != TEGRA_CLK_SE) { + return -ENOTSUP; + } + + /* prepare the MRQ_CLK command */ + req.cmd_and_id = make_mrq_clk_cmd(CMD_CLK_ENABLE, clk_id); + + ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, sizeof(req), + NULL, 0); + if (ret != 0) { + ERROR("%s: failed for module %d with error %d\n", __func__, + clk_id, ret); + } + + return ret; +} + +int tegra_bpmp_ipc_disable_clock(uint32_t clk_id) +{ + int ret; + struct mrq_clk_request req; + + /* only SE clocks are supported */ + if (clk_id != TEGRA_CLK_SE) { + return -ENOTSUP; + } + + /* prepare the MRQ_CLK command */ + req.cmd_and_id = make_mrq_clk_cmd(CMD_CLK_DISABLE, clk_id); + + ret = tegra_bpmp_ipc_send_req_atomic(MRQ_CLK, &req, sizeof(req), + NULL, 0); + if (ret != 0) { + ERROR("%s: failed for module %d with error %d\n", __func__, + clk_id, ret); + } + + return ret; +} diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h index 689f8bbb..7059c370 100644 --- a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h +++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,10 +11,10 @@ * Flags used in IPC req */ #define FLAG_DO_ACK (U(1) << 0) -#define FLAG_RING_DOORBELL (U(1) << 1) +#define FLAG_RING_DOORBELL (U(1) << 1) /* Bit 1 is designated for CCPlex in secure world */ -#define HSP_MASTER_CCPLEX_BIT (U(1) << 1) +#define HSP_MASTER_CCPLEX_BIT (U(1) << 1) /* Bit 19 is designated for BPMP in non-secure world */ #define HSP_MASTER_BPMP_BIT (U(1) << 19) /* Timeout to receive response from BPMP is 1 sec */ @@ -49,9 +49,10 @@ struct frame_data { */ /** - * MRQ code to issue a module reset command to BPMP + * MRQ command codes */ #define MRQ_RESET U(20) +#define MRQ_CLK U(22) /** * Reset sub-commands @@ -71,4 +72,56 @@ struct __attribute__((packed)) mrq_reset_request { uint32_t reset_id; }; +/** + * MRQ_CLK sub-commands + * + */ +enum { + CMD_CLK_GET_RATE = 1, + CMD_CLK_SET_RATE = 2, + CMD_CLK_ROUND_RATE = 3, + CMD_CLK_GET_PARENT = 4, + CMD_CLK_SET_PARENT = 5, + CMD_CLK_IS_ENABLED = 6, + CMD_CLK_ENABLE = 7, + CMD_CLK_DISABLE = 8, + CMD_CLK_GET_ALL_INFO = 14, + CMD_CLK_GET_MAX_CLK_ID = 15, + CMD_CLK_MAX, +}; + +/** + * Used by the sender of an #MRQ_CLK message to control clocks. The + * clk_request is split into several sub-commands. Some sub-commands + * require no additional data. Others have a sub-command specific + * payload + * + * |sub-command |payload | + * |----------------------------|-----------------------| + * |CMD_CLK_GET_RATE |- | + * |CMD_CLK_SET_RATE |clk_set_rate | + * |CMD_CLK_ROUND_RATE |clk_round_rate | + * |CMD_CLK_GET_PARENT |- | + * |CMD_CLK_SET_PARENT |clk_set_parent | + * |CMD_CLK_IS_ENABLED |- | + * |CMD_CLK_ENABLE |- | + * |CMD_CLK_DISABLE |- | + * |CMD_CLK_GET_ALL_INFO |- | + * |CMD_CLK_GET_MAX_CLK_ID |- | + * + */ +struct mrq_clk_request { + /** + * sub-command and clock id concatenated to 32-bit word. + * - bits[31..24] is the sub-cmd. + * - bits[23..0] is the clock id + */ + uint32_t cmd_and_id; +}; + +/** + * Macro to prepare the MRQ_CLK sub-command + */ +#define make_mrq_clk_cmd(cmd, id) (((cmd) << 24) | (id & 0xFFFFFF)) + #endif /* INTF_H */ diff --git a/plat/nvidia/tegra/include/drivers/bpmp_ipc.h b/plat/nvidia/tegra/include/drivers/bpmp_ipc.h index 9304150e..d4879560 100644 --- a/plat/nvidia/tegra/include/drivers/bpmp_ipc.h +++ b/plat/nvidia/tegra/include/drivers/bpmp_ipc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -18,6 +18,11 @@ #define TEGRA_RESET_ID_GPCDMA U(70) /** + * Clock identifier for the SE device + */ +#define TEGRA_CLK_SE U(124) + +/** * Function to initialise the IPC with the bpmp */ int32_t tegra_bpmp_ipc_init(void); @@ -27,4 +32,16 @@ int32_t tegra_bpmp_ipc_init(void); */ int32_t tegra_bpmp_ipc_reset_module(uint32_t rst_id); +/** + * Handler to enable clock to a module. Only SE device is + * supported for now. + */ +int tegra_bpmp_ipc_enable_clock(uint32_t clk_id); + +/** + * Handler to disable clock to a module. Only SE device is + * supported for now. + */ +int tegra_bpmp_ipc_disable_clock(uint32_t clk_id); + #endif /* __BPMP_IPC_H__ */ |