diff options
author | Lakshmanan M <lm@nvidia.com> | 2016-11-07 05:24:56 -0500 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-01-10 06:55:05 -0500 |
commit | d06966c4d9eefa823dd25b87224c2c4c489630e2 (patch) | |
tree | 034e9b4b566d01738fe860dedd0d822d5a311a74 | |
parent | 8a63a431c4ab42e8531614fd69e460b7fdc5e31f (diff) |
gpu: nvgpu: Add thermal alert event handling
* Added the thermal alert event handling
* Added the thermal alert event PMU RPC
JIRA DNVGPU-130
Bug 200231080
Change-Id: I54ab0dc35a940e70733238fd95669db28389619a
Signed-off-by: Lakshmanan M <lm@nvidia.com>
Reviewed-on: http://git-master/r/1248968
(cherry picked from commit a20593c89a374d64201e4720552160a65533ecc3)
Reviewed-on: http://git-master/r/1282076
GVS: Gerrit_Virtual_Submit
Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com>
-rw-r--r-- | drivers/gpu/nvgpu/gp106/therm_gp106.c | 14 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/therm/thrmpmu.c | 137 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/therm/thrmpmu.h | 2 |
3 files changed, 139 insertions, 14 deletions
diff --git a/drivers/gpu/nvgpu/gp106/therm_gp106.c b/drivers/gpu/nvgpu/gp106/therm_gp106.c index 7bdf0b9e..bbcc5c80 100644 --- a/drivers/gpu/nvgpu/gp106/therm_gp106.c +++ b/drivers/gpu/nvgpu/gp106/therm_gp106.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include "therm_gp106.h" | 14 | #include "therm_gp106.h" |
15 | #include <linux/debugfs.h> | 15 | #include <linux/debugfs.h> |
16 | #include "hw_therm_gp106.h" | 16 | #include "hw_therm_gp106.h" |
17 | #include "therm/thrmpmu.h" | ||
17 | 18 | ||
18 | static void gp106_get_internal_sensor_limits(s32 *max_24_8, s32 *min_24_8) | 19 | static void gp106_get_internal_sensor_limits(s32 *max_24_8, s32 *min_24_8) |
19 | { | 20 | { |
@@ -117,6 +118,18 @@ static int gp106_elcg_init_idle_filters(struct gk20a *g) | |||
117 | return 0; | 118 | return 0; |
118 | } | 119 | } |
119 | 120 | ||
121 | static u32 gp106_configure_therm_alert(struct gk20a *g, s32 curr_warn_temp) | ||
122 | { | ||
123 | u32 err = 0; | ||
124 | |||
125 | if (g->curr_warn_temp != curr_warn_temp) { | ||
126 | g->curr_warn_temp = curr_warn_temp; | ||
127 | err = therm_configure_therm_alert(g); | ||
128 | } | ||
129 | |||
130 | return err; | ||
131 | } | ||
132 | |||
120 | void gp106_init_therm_ops(struct gpu_ops *gops) { | 133 | void gp106_init_therm_ops(struct gpu_ops *gops) { |
121 | #ifdef CONFIG_DEBUG_FS | 134 | #ifdef CONFIG_DEBUG_FS |
122 | gops->therm.therm_debugfs_init = gp106_therm_debugfs_init; | 135 | gops->therm.therm_debugfs_init = gp106_therm_debugfs_init; |
@@ -125,4 +138,5 @@ void gp106_init_therm_ops(struct gpu_ops *gops) { | |||
125 | gops->therm.get_internal_sensor_curr_temp = gp106_get_internal_sensor_curr_temp; | 138 | gops->therm.get_internal_sensor_curr_temp = gp106_get_internal_sensor_curr_temp; |
126 | gops->therm.get_internal_sensor_limits = | 139 | gops->therm.get_internal_sensor_limits = |
127 | gp106_get_internal_sensor_limits; | 140 | gp106_get_internal_sensor_limits; |
141 | gops->therm.configure_therm_alert = gp106_configure_therm_alert; | ||
128 | } | 142 | } |
diff --git a/drivers/gpu/nvgpu/therm/thrmpmu.c b/drivers/gpu/nvgpu/therm/thrmpmu.c index 0d0a4b3a..0f780730 100644 --- a/drivers/gpu/nvgpu/therm/thrmpmu.c +++ b/drivers/gpu/nvgpu/therm/thrmpmu.c | |||
@@ -77,9 +77,47 @@ exit: | |||
77 | return status; | 77 | return status; |
78 | } | 78 | } |
79 | 79 | ||
80 | u32 therm_set_warn_temp_limit(struct gk20a *g) | 80 | static u32 therm_pmu_cmd_post(struct gk20a *g, struct pmu_cmd *cmd, |
81 | struct pmu_msg *msg, struct pmu_payload *payload, | ||
82 | u32 queue_id, pmu_callback callback, void* cb_param, | ||
83 | u32 *seq_desc, unsigned long timeout) | ||
81 | { | 84 | { |
82 | u32 status; | 85 | u32 status; |
86 | struct therm_pmucmdhandler_params *handlerparams = NULL; | ||
87 | |||
88 | status = gk20a_pmu_cmd_post(g, cmd, msg, payload, | ||
89 | queue_id, | ||
90 | callback, | ||
91 | cb_param, | ||
92 | seq_desc, | ||
93 | timeout); | ||
94 | if (status) { | ||
95 | gk20a_err(dev_from_gk20a(g), | ||
96 | "unable to post therm cmd for unit %x cmd id %x size %x", | ||
97 | cmd->hdr.unit_id, cmd->cmd.therm.cmd_type, cmd->hdr.size); | ||
98 | goto exit; | ||
99 | } | ||
100 | |||
101 | if (cb_param) { | ||
102 | handlerparams = (struct therm_pmucmdhandler_params*)cb_param; | ||
103 | |||
104 | pmu_wait_message_cond(&g->pmu, | ||
105 | gk20a_get_gr_idle_timeout(g), | ||
106 | &handlerparams->success, 1); | ||
107 | |||
108 | if (handlerparams->success == 0) { | ||
109 | gk20a_err(dev_from_gk20a(g), "could not process cmd\n"); | ||
110 | status = -ETIMEDOUT; | ||
111 | goto exit; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | exit: | ||
116 | return status; | ||
117 | } | ||
118 | |||
119 | static u32 therm_set_warn_temp_limit(struct gk20a *g) | ||
120 | { | ||
83 | u32 seqdesc = 0; | 121 | u32 seqdesc = 0; |
84 | struct pmu_cmd cmd = { {0} }; | 122 | struct pmu_cmd cmd = { {0} }; |
85 | struct pmu_msg msg = { {0} }; | 123 | struct pmu_msg msg = { {0} }; |
@@ -94,7 +132,69 @@ u32 therm_set_warn_temp_limit(struct gk20a *g) | |||
94 | rpccall.b_supported = 0; | 132 | rpccall.b_supported = 0; |
95 | 133 | ||
96 | cmd.hdr.unit_id = PMU_UNIT_THERM; | 134 | cmd.hdr.unit_id = PMU_UNIT_THERM; |
97 | cmd.hdr.size = ((u32)sizeof(struct nv_pmu_therm_cmd) + | 135 | cmd.hdr.size = ((u32)sizeof(struct nv_pmu_therm_cmd_rpc) + |
136 | (u32)sizeof(struct pmu_hdr)); | ||
137 | cmd.cmd.therm.cmd_type = NV_PMU_THERM_CMD_ID_RPC; | ||
138 | |||
139 | msg.hdr.size = sizeof(struct pmu_msg); | ||
140 | |||
141 | payload.in.buf = (u8 *)&rpccall; | ||
142 | payload.in.size = (u32)sizeof(struct nv_pmu_therm_rpc); | ||
143 | payload.in.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; | ||
144 | payload.in.offset = NV_PMU_THERM_CMD_RPC_ALLOC_OFFSET; | ||
145 | |||
146 | payload.out.buf = (u8 *)&rpccall; | ||
147 | payload.out.size = (u32)sizeof(struct nv_pmu_therm_rpc); | ||
148 | payload.out.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; | ||
149 | payload.out.offset = NV_PMU_CLK_MSG_RPC_ALLOC_OFFSET; | ||
150 | |||
151 | /* Setup the handler params to communicate back results.*/ | ||
152 | handlerparams.success = 0; | ||
153 | handlerparams.prpccall = &rpccall; | ||
154 | |||
155 | return therm_pmu_cmd_post(g, &cmd, NULL, &payload, | ||
156 | PMU_COMMAND_QUEUE_LPQ, | ||
157 | therm_pmucmdhandler, | ||
158 | (void *)&handlerparams, | ||
159 | &seqdesc, ~0); | ||
160 | } | ||
161 | |||
162 | static u32 therm_enable_slct_notification_request(struct gk20a *g) | ||
163 | { | ||
164 | u32 seqdesc = 0; | ||
165 | struct pmu_cmd cmd = { {0} }; | ||
166 | |||
167 | cmd.hdr.unit_id = PMU_UNIT_THERM; | ||
168 | cmd.hdr.size = ((u32)sizeof(struct nv_pmu_therm_cmd_hw_slowdown_notification) + | ||
169 | (u32)sizeof(struct pmu_hdr)); | ||
170 | |||
171 | cmd.cmd.therm.cmd_type = NV_PMU_THERM_CMD_ID_HW_SLOWDOWN_NOTIFICATION; | ||
172 | cmd.cmd.therm.hw_slct_notification.request = | ||
173 | NV_RM_PMU_THERM_HW_SLOWDOWN_NOTIFICATION_REQUEST_ENABLE; | ||
174 | |||
175 | return therm_pmu_cmd_post(g, &cmd, NULL, NULL, | ||
176 | PMU_COMMAND_QUEUE_LPQ, | ||
177 | NULL, | ||
178 | NULL, | ||
179 | &seqdesc, ~0); | ||
180 | } | ||
181 | |||
182 | static u32 therm_send_slct_configuration_to_pmu(struct gk20a *g) | ||
183 | { | ||
184 | u32 seqdesc = 0; | ||
185 | struct pmu_cmd cmd = { {0} }; | ||
186 | struct pmu_msg msg = { {0} }; | ||
187 | struct pmu_payload payload = { {0} }; | ||
188 | struct nv_pmu_therm_rpc rpccall = {0}; | ||
189 | struct therm_pmucmdhandler_params handlerparams = {0}; | ||
190 | |||
191 | rpccall.function = NV_PMU_THERM_RPC_ID_SLCT; | ||
192 | rpccall.params.slct.mask_enabled = | ||
193 | (1 << NV_PMU_THERM_EVENT_THERMAL_1); | ||
194 | rpccall.b_supported = 0; | ||
195 | |||
196 | cmd.hdr.unit_id = PMU_UNIT_THERM; | ||
197 | cmd.hdr.size = ((u32)sizeof(struct nv_pmu_therm_cmd_rpc) + | ||
98 | (u32)sizeof(struct pmu_hdr)); | 198 | (u32)sizeof(struct pmu_hdr)); |
99 | cmd.cmd.therm.cmd_type = NV_PMU_THERM_CMD_ID_RPC; | 199 | cmd.cmd.therm.cmd_type = NV_PMU_THERM_CMD_ID_RPC; |
100 | 200 | ||
@@ -114,29 +214,40 @@ u32 therm_set_warn_temp_limit(struct gk20a *g) | |||
114 | handlerparams.success = 0; | 214 | handlerparams.success = 0; |
115 | handlerparams.prpccall = &rpccall; | 215 | handlerparams.prpccall = &rpccall; |
116 | 216 | ||
117 | status = gk20a_pmu_cmd_post(g, &cmd, NULL, &payload, | 217 | return therm_pmu_cmd_post(g, &cmd, NULL, &payload, |
118 | PMU_COMMAND_QUEUE_LPQ, | 218 | PMU_COMMAND_QUEUE_LPQ, |
119 | therm_pmucmdhandler, | 219 | therm_pmucmdhandler, |
120 | (void *)&handlerparams, | 220 | (void *)&handlerparams, |
121 | &seqdesc, ~0); | 221 | &seqdesc, ~0); |
222 | } | ||
223 | |||
224 | u32 therm_configure_therm_alert(struct gk20a *g) | ||
225 | { | ||
226 | u32 status; | ||
227 | |||
228 | status = therm_enable_slct_notification_request(g); | ||
122 | if (status) { | 229 | if (status) { |
123 | gk20a_err(dev_from_gk20a(g), | 230 | gk20a_err(dev_from_gk20a(g), |
124 | "unable to post pmgr cmd for unit %x cmd id %x size %x", | 231 | "therm_enable_slct_notification_request-failed %d", |
125 | cmd.hdr.unit_id, cmd.cmd.therm.cmd_type, cmd.hdr.size); | 232 | status); |
126 | goto exit; | 233 | goto exit; |
127 | } | 234 | } |
128 | 235 | ||
129 | pmu_wait_message_cond(&g->pmu, | 236 | status = therm_send_slct_configuration_to_pmu(g); |
130 | gk20a_get_gr_idle_timeout(g), | 237 | if (status) { |
131 | &handlerparams.success, 1); | 238 | gk20a_err(dev_from_gk20a(g), |
132 | 239 | "therm_send_slct_configuration_to_pmu-failed %d", | |
133 | if (handlerparams.success == 0) { | 240 | status); |
134 | gk20a_err(dev_from_gk20a(g), "could not process cmd\n"); | ||
135 | status = -ETIMEDOUT; | ||
136 | goto exit; | 241 | goto exit; |
137 | } | 242 | } |
138 | 243 | ||
244 | status = therm_set_warn_temp_limit(g); | ||
245 | if (status) { | ||
246 | gk20a_err(dev_from_gk20a(g), | ||
247 | "therm_set_warn_temp_limit-failed %d", | ||
248 | status); | ||
249 | goto exit; | ||
250 | } | ||
139 | exit: | 251 | exit: |
140 | return status; | 252 | return status; |
141 | } | 253 | } |
142 | |||
diff --git a/drivers/gpu/nvgpu/therm/thrmpmu.h b/drivers/gpu/nvgpu/therm/thrmpmu.h index e6f70411..8f0d7501 100644 --- a/drivers/gpu/nvgpu/therm/thrmpmu.h +++ b/drivers/gpu/nvgpu/therm/thrmpmu.h | |||
@@ -17,6 +17,6 @@ | |||
17 | 17 | ||
18 | u32 therm_send_pmgr_tables_to_pmu(struct gk20a *g); | 18 | u32 therm_send_pmgr_tables_to_pmu(struct gk20a *g); |
19 | 19 | ||
20 | u32 therm_set_warn_temp_limit(struct gk20a *g); | 20 | u32 therm_configure_therm_alert(struct gk20a *g); |
21 | 21 | ||
22 | #endif | 22 | #endif |