Merge tag 'drm-misc-next-fixes-2021-09-09' of git://anongit.freedesktop.org/drm/drm...
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / display / dc / dce / dmub_psr.c
1 /*
2  * Copyright 2019 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: AMD
23  *
24  */
25
26 #include "dmub_psr.h"
27 #include "dc.h"
28 #include "dc_dmub_srv.h"
29 #include "dmub/dmub_srv.h"
30 #include "core_types.h"
31
32 #define DC_TRACE_LEVEL_MESSAGE(...)     do {} while (0) /* do nothing */
33
34 #define MAX_PIPES 6
35
36 /*
37  * Convert dmcub psr state to dmcu psr state.
38  */
39 static enum dc_psr_state convert_psr_state(uint32_t raw_state)
40 {
41         enum dc_psr_state state = PSR_STATE0;
42
43         if (raw_state == 0)
44                 state = PSR_STATE0;
45         else if (raw_state == 0x10)
46                 state = PSR_STATE1;
47         else if (raw_state == 0x11)
48                 state = PSR_STATE1a;
49         else if (raw_state == 0x20)
50                 state = PSR_STATE2;
51         else if (raw_state == 0x21)
52                 state = PSR_STATE2a;
53         else if (raw_state == 0x30)
54                 state = PSR_STATE3;
55         else if (raw_state == 0x31)
56                 state = PSR_STATE3Init;
57         else if (raw_state == 0x40)
58                 state = PSR_STATE4;
59         else if (raw_state == 0x41)
60                 state = PSR_STATE4a;
61         else if (raw_state == 0x42)
62                 state = PSR_STATE4b;
63         else if (raw_state == 0x43)
64                 state = PSR_STATE4c;
65         else if (raw_state == 0x44)
66                 state = PSR_STATE4d;
67         else if (raw_state == 0x50)
68                 state = PSR_STATE5;
69         else if (raw_state == 0x51)
70                 state = PSR_STATE5a;
71         else if (raw_state == 0x52)
72                 state = PSR_STATE5b;
73         else if (raw_state == 0x53)
74                 state = PSR_STATE5c;
75
76         return state;
77 }
78
79 /*
80  * Get PSR state from firmware.
81  */
82 static void dmub_psr_get_state(struct dmub_psr *dmub, enum dc_psr_state *state, uint8_t panel_inst)
83 {
84         struct dmub_srv *srv = dmub->ctx->dmub_srv->dmub;
85         uint32_t raw_state = 0;
86         uint32_t retry_count = 0;
87         enum dmub_status status;
88
89         do {
90                 // Send gpint command and wait for ack
91                 status = dmub_srv_send_gpint_command(srv, DMUB_GPINT__GET_PSR_STATE, panel_inst, 30);
92
93                 if (status == DMUB_STATUS_OK) {
94                         // GPINT was executed, get response
95                         dmub_srv_get_gpint_response(srv, &raw_state);
96                         *state = convert_psr_state(raw_state);
97                 } else
98                         // Return invalid state when GPINT times out
99                         *state = PSR_STATE_INVALID;
100
101         } while (++retry_count <= 1000 && *state == PSR_STATE_INVALID);
102
103         // Assert if max retry hit
104         if (retry_count >= 1000 && *state == PSR_STATE_INVALID) {
105                 ASSERT(0);
106                 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR,
107                                 WPP_BIT_FLAG_Firmware_PsrState,
108                                 "Unable to get PSR state from FW.");
109         } else
110                 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_VERBOSE,
111                                 WPP_BIT_FLAG_Firmware_PsrState,
112                                 "Got PSR state from FW. PSR state: %d, Retry count: %d",
113                                 *state, retry_count);
114 }
115
116 /*
117  * Set PSR version.
118  */
119 static bool dmub_psr_set_version(struct dmub_psr *dmub, struct dc_stream_state *stream, uint8_t panel_inst)
120 {
121         union dmub_rb_cmd cmd;
122         struct dc_context *dc = dmub->ctx;
123
124         if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_UNSUPPORTED)
125                 return false;
126
127         memset(&cmd, 0, sizeof(cmd));
128         cmd.psr_set_version.header.type = DMUB_CMD__PSR;
129         cmd.psr_set_version.header.sub_type = DMUB_CMD__PSR_SET_VERSION;
130         switch (stream->link->psr_settings.psr_version) {
131         case DC_PSR_VERSION_1:
132                 cmd.psr_set_version.psr_set_version_data.version = PSR_VERSION_1;
133                 break;
134         case DC_PSR_VERSION_UNSUPPORTED:
135         default:
136                 cmd.psr_set_version.psr_set_version_data.version = PSR_VERSION_UNSUPPORTED;
137                 break;
138         }
139         cmd.psr_set_version.psr_set_version_data.cmd_version = DMUB_CMD_PSR_CONTROL_VERSION_1;
140         cmd.psr_set_version.psr_set_version_data.panel_inst = panel_inst;
141         cmd.psr_set_version.header.payload_bytes = sizeof(struct dmub_cmd_psr_set_version_data);
142
143         dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
144         dc_dmub_srv_cmd_execute(dc->dmub_srv);
145         dc_dmub_srv_wait_idle(dc->dmub_srv);
146
147         return true;
148 }
149
150 /*
151  * Enable/Disable PSR.
152  */
153 static void dmub_psr_enable(struct dmub_psr *dmub, bool enable, bool wait, uint8_t panel_inst)
154 {
155         union dmub_rb_cmd cmd;
156         struct dc_context *dc = dmub->ctx;
157         uint32_t retry_count;
158         enum dc_psr_state state = PSR_STATE0;
159
160         memset(&cmd, 0, sizeof(cmd));
161         cmd.psr_enable.header.type = DMUB_CMD__PSR;
162
163         cmd.psr_enable.data.cmd_version = DMUB_CMD_PSR_CONTROL_VERSION_1;
164         cmd.psr_enable.data.panel_inst = panel_inst;
165
166         if (enable)
167                 cmd.psr_enable.header.sub_type = DMUB_CMD__PSR_ENABLE;
168         else
169                 cmd.psr_enable.header.sub_type = DMUB_CMD__PSR_DISABLE;
170
171         cmd.psr_enable.header.payload_bytes = 0; // Send header only
172
173         dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
174         dc_dmub_srv_cmd_execute(dc->dmub_srv);
175         dc_dmub_srv_wait_idle(dc->dmub_srv);
176
177         /* Below loops 1000 x 500us = 500 ms.
178          *  Exit PSR may need to wait 1-2 frames to power up. Timeout after at
179          *  least a few frames. Should never hit the max retry assert below.
180          */
181         if (wait) {
182                 for (retry_count = 0; retry_count <= 1000; retry_count++) {
183                         dmub_psr_get_state(dmub, &state, panel_inst);
184
185                         if (enable) {
186                                 if (state != PSR_STATE0)
187                                         break;
188                         } else {
189                                 if (state == PSR_STATE0)
190                                         break;
191                         }
192
193                         udelay(500);
194                 }
195
196                 /* assert if max retry hit */
197                 if (retry_count >= 1000)
198                         ASSERT(0);
199         }
200 }
201
202 /*
203  * Set PSR level.
204  */
205 static void dmub_psr_set_level(struct dmub_psr *dmub, uint16_t psr_level, uint8_t panel_inst)
206 {
207         union dmub_rb_cmd cmd;
208         enum dc_psr_state state = PSR_STATE0;
209         struct dc_context *dc = dmub->ctx;
210
211         dmub_psr_get_state(dmub, &state, panel_inst);
212
213         if (state == PSR_STATE0)
214                 return;
215
216         memset(&cmd, 0, sizeof(cmd));
217         cmd.psr_set_level.header.type = DMUB_CMD__PSR;
218         cmd.psr_set_level.header.sub_type = DMUB_CMD__PSR_SET_LEVEL;
219         cmd.psr_set_level.header.payload_bytes = sizeof(struct dmub_cmd_psr_set_level_data);
220         cmd.psr_set_level.psr_set_level_data.psr_level = psr_level;
221         cmd.psr_set_level.psr_set_level_data.cmd_version = DMUB_CMD_PSR_CONTROL_VERSION_1;
222         cmd.psr_set_level.psr_set_level_data.panel_inst = panel_inst;
223         dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
224         dc_dmub_srv_cmd_execute(dc->dmub_srv);
225         dc_dmub_srv_wait_idle(dc->dmub_srv);
226 }
227
228 /*
229  * Setup PSR by programming phy registers and sending psr hw context values to firmware.
230  */
231 static bool dmub_psr_copy_settings(struct dmub_psr *dmub,
232                 struct dc_link *link,
233                 struct psr_context *psr_context,
234                 uint8_t panel_inst)
235 {
236         union dmub_rb_cmd cmd;
237         struct dc_context *dc = dmub->ctx;
238         struct dmub_cmd_psr_copy_settings_data *copy_settings_data
239                 = &cmd.psr_copy_settings.psr_copy_settings_data;
240         struct pipe_ctx *pipe_ctx = NULL;
241         struct resource_context *res_ctx = &link->ctx->dc->current_state->res_ctx;
242         int i = 0;
243
244         for (i = 0; i < MAX_PIPES; i++) {
245                 if (res_ctx->pipe_ctx[i].stream &&
246                     res_ctx->pipe_ctx[i].stream->link == link &&
247                     res_ctx->pipe_ctx[i].stream->link->connector_signal == SIGNAL_TYPE_EDP) {
248                         pipe_ctx = &res_ctx->pipe_ctx[i];
249                         //TODO: refactor for multi edp support
250                         break;
251                 }
252         }
253
254         if (!pipe_ctx)
255                 return false;
256
257         // First, set the psr version
258         if (!dmub_psr_set_version(dmub, pipe_ctx->stream, panel_inst))
259                 return false;
260
261         // Program DP DPHY fast training registers
262         link->link_enc->funcs->psr_program_dp_dphy_fast_training(link->link_enc,
263                         psr_context->psrExitLinkTrainingRequired);
264
265         // Program DP_SEC_CNTL1 register to set transmission GPS0 line num and priority to high
266         link->link_enc->funcs->psr_program_secondary_packet(link->link_enc,
267                         psr_context->sdpTransmitLineNumDeadline);
268
269         memset(&cmd, 0, sizeof(cmd));
270         cmd.psr_copy_settings.header.type = DMUB_CMD__PSR;
271         cmd.psr_copy_settings.header.sub_type = DMUB_CMD__PSR_COPY_SETTINGS;
272         cmd.psr_copy_settings.header.payload_bytes = sizeof(struct dmub_cmd_psr_copy_settings_data);
273
274         // Hw insts
275         copy_settings_data->dpphy_inst                          = psr_context->transmitterId;
276         copy_settings_data->aux_inst                            = psr_context->channel;
277         copy_settings_data->digfe_inst                          = psr_context->engineId;
278         copy_settings_data->digbe_inst                          = psr_context->transmitterId;
279
280         copy_settings_data->mpcc_inst                           = pipe_ctx->plane_res.mpcc_inst;
281
282         if (pipe_ctx->plane_res.dpp)
283                 copy_settings_data->dpp_inst                    = pipe_ctx->plane_res.dpp->inst;
284         else
285                 copy_settings_data->dpp_inst                    = 0;
286         if (pipe_ctx->stream_res.opp)
287                 copy_settings_data->opp_inst                    = pipe_ctx->stream_res.opp->inst;
288         else
289                 copy_settings_data->opp_inst                    = 0;
290         if (pipe_ctx->stream_res.tg)
291                 copy_settings_data->otg_inst                    = pipe_ctx->stream_res.tg->inst;
292         else
293                 copy_settings_data->otg_inst                    = 0;
294
295         // Misc
296         copy_settings_data->psr_level                           = psr_context->psr_level.u32all;
297         copy_settings_data->smu_optimizations_en                = psr_context->allow_smu_optimizations;
298         copy_settings_data->multi_disp_optimizations_en = psr_context->allow_multi_disp_optimizations;
299         copy_settings_data->frame_delay                         = psr_context->frame_delay;
300         copy_settings_data->frame_cap_ind                       = psr_context->psrFrameCaptureIndicationReq;
301         copy_settings_data->init_sdp_deadline                   = psr_context->sdpTransmitLineNumDeadline;
302         copy_settings_data->debug.u32All = 0;
303         copy_settings_data->debug.bitfields.visual_confirm      = dc->dc->debug.visual_confirm == VISUAL_CONFIRM_PSR;
304         copy_settings_data->debug.bitfields.use_hw_lock_mgr             = 1;
305         copy_settings_data->fec_enable_status = (link->fec_state == dc_link_fec_enabled);
306         copy_settings_data->fec_enable_delay_in100us = link->dc->debug.fec_enable_delay_in100us;
307         copy_settings_data->cmd_version =  DMUB_CMD_PSR_CONTROL_VERSION_1;
308         copy_settings_data->panel_inst = panel_inst;
309
310         dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
311         dc_dmub_srv_cmd_execute(dc->dmub_srv);
312         dc_dmub_srv_wait_idle(dc->dmub_srv);
313
314         return true;
315 }
316
317 /*
318  * Send command to PSR to force static ENTER and ignore all state changes until exit
319  */
320 static void dmub_psr_force_static(struct dmub_psr *dmub, uint8_t panel_inst)
321 {
322         union dmub_rb_cmd cmd;
323         struct dc_context *dc = dmub->ctx;
324
325         memset(&cmd, 0, sizeof(cmd));
326
327         cmd.psr_force_static.psr_force_static_data.panel_inst = panel_inst;
328         cmd.psr_force_static.psr_force_static_data.cmd_version = DMUB_CMD_PSR_CONTROL_VERSION_1;
329         cmd.psr_force_static.header.type = DMUB_CMD__PSR;
330         cmd.psr_force_static.header.sub_type = DMUB_CMD__PSR_FORCE_STATIC;
331         cmd.psr_enable.header.payload_bytes = 0;
332
333         dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
334         dc_dmub_srv_cmd_execute(dc->dmub_srv);
335         dc_dmub_srv_wait_idle(dc->dmub_srv);
336 }
337
338 /*
339  * Get PSR residency from firmware.
340  */
341 static void dmub_psr_get_residency(struct dmub_psr *dmub, uint32_t *residency, uint8_t panel_inst)
342 {
343         struct dmub_srv *srv = dmub->ctx->dmub_srv->dmub;
344         uint16_t param = (uint16_t)(panel_inst << 8);
345
346         /* Send gpint command and wait for ack */
347         dmub_srv_send_gpint_command(srv, DMUB_GPINT__PSR_RESIDENCY, param, 30);
348
349         dmub_srv_get_gpint_response(srv, residency);
350 }
351
352 static const struct dmub_psr_funcs psr_funcs = {
353         .psr_copy_settings              = dmub_psr_copy_settings,
354         .psr_enable                     = dmub_psr_enable,
355         .psr_get_state                  = dmub_psr_get_state,
356         .psr_set_level                  = dmub_psr_set_level,
357         .psr_force_static               = dmub_psr_force_static,
358         .psr_get_residency              = dmub_psr_get_residency,
359 };
360
361 /*
362  * Construct PSR object.
363  */
364 static void dmub_psr_construct(struct dmub_psr *psr, struct dc_context *ctx)
365 {
366         psr->ctx = ctx;
367         psr->funcs = &psr_funcs;
368 }
369
370 /*
371  * Allocate and initialize PSR object.
372  */
373 struct dmub_psr *dmub_psr_create(struct dc_context *ctx)
374 {
375         struct dmub_psr *psr = kzalloc(sizeof(struct dmub_psr), GFP_KERNEL);
376
377         if (psr == NULL) {
378                 BREAK_TO_DEBUGGER();
379                 return NULL;
380         }
381
382         dmub_psr_construct(psr, ctx);
383
384         return psr;
385 }
386
387 /*
388  * Deallocate PSR object.
389  */
390 void dmub_psr_destroy(struct dmub_psr **dmub)
391 {
392         kfree(*dmub);
393         *dmub = NULL;
394 }