2 * Copyright 2019 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
28 #include "dc_dmub_srv.h"
29 #include "../../dmub/inc/dmub_srv.h"
30 #include "dmub_fw_state.h"
31 #include "core_types.h"
37 * Get PSR state from firmware.
39 static void dmub_get_psr_state(uint32_t *psr_state
)
41 // Not yet implemented
42 // Trigger GPINT interrupt from firmware
48 static void dmub_set_psr_enable(struct dmub_psr
*dmub
, bool enable
)
50 union dmub_rb_cmd cmd
;
51 struct dc_context
*dc
= dmub
->ctx
;
53 cmd
.psr_enable
.header
.type
= DMUB_CMD__PSR
;
56 cmd
.psr_enable
.header
.sub_type
= DMUB_CMD__PSR_ENABLE
;
58 cmd
.psr_enable
.header
.sub_type
= DMUB_CMD__PSR_DISABLE
;
60 cmd
.psr_enable
.header
.payload_bytes
= 0; // Send header only
62 dc_dmub_srv_cmd_queue(dc
->dmub_srv
, &cmd
.psr_enable
.header
);
63 dc_dmub_srv_cmd_execute(dc
->dmub_srv
);
64 dc_dmub_srv_wait_idle(dc
->dmub_srv
);
70 static void dmub_set_psr_level(struct dmub_psr
*dmub
, uint16_t psr_level
)
72 union dmub_rb_cmd cmd
;
73 uint32_t psr_state
= 0;
74 struct dc_context
*dc
= dmub
->ctx
;
76 dmub_get_psr_state(&psr_state
);
81 cmd
.psr_set_level
.header
.type
= DMUB_CMD__PSR
;
82 cmd
.psr_set_level
.header
.sub_type
= DMUB_CMD__PSR_SET_LEVEL
;
83 cmd
.psr_set_level
.header
.payload_bytes
= sizeof(struct dmub_cmd_psr_set_level_data
);
84 cmd
.psr_set_level
.psr_set_level_data
.psr_level
= psr_level
;
86 dc_dmub_srv_cmd_queue(dc
->dmub_srv
, &cmd
.psr_set_level
.header
);
87 dc_dmub_srv_cmd_execute(dc
->dmub_srv
);
88 dc_dmub_srv_wait_idle(dc
->dmub_srv
);
92 * Setup PSR by programming phy registers and sending psr hw context values to firmware.
94 static bool dmub_setup_psr(struct dmub_psr
*dmub
,
96 struct psr_context
*psr_context
)
98 union dmub_rb_cmd cmd
;
99 struct dc_context
*dc
= dmub
->ctx
;
100 struct dmub_cmd_psr_copy_settings_data
*copy_settings_data
101 = &cmd
.psr_copy_settings
.psr_copy_settings_data
;
102 struct pipe_ctx
*pipe_ctx
= NULL
;
103 struct resource_context
*res_ctx
= &link
->ctx
->dc
->current_state
->res_ctx
;
105 for (int i
= 0; i
< MAX_PIPES
; i
++) {
107 res_ctx
->pipe_ctx
[i
].stream
&&
108 res_ctx
->pipe_ctx
[i
].stream
->link
&&
109 res_ctx
->pipe_ctx
[i
].stream
->link
== link
&&
110 res_ctx
->pipe_ctx
[i
].stream
->link
->connector_signal
== SIGNAL_TYPE_EDP
) {
111 pipe_ctx
= &res_ctx
->pipe_ctx
[i
];
117 !&pipe_ctx
->plane_res
||
118 !&pipe_ctx
->stream_res
)
121 // Program DP DPHY fast training registers
122 link
->link_enc
->funcs
->psr_program_dp_dphy_fast_training(link
->link_enc
,
123 psr_context
->psrExitLinkTrainingRequired
);
125 // Program DP_SEC_CNTL1 register to set transmission GPS0 line num and priority to high
126 link
->link_enc
->funcs
->psr_program_secondary_packet(link
->link_enc
,
127 psr_context
->sdpTransmitLineNumDeadline
);
129 cmd
.psr_copy_settings
.header
.type
= DMUB_CMD__PSR
;
130 cmd
.psr_copy_settings
.header
.sub_type
= DMUB_CMD__PSR_COPY_SETTINGS
;
131 cmd
.psr_copy_settings
.header
.payload_bytes
= sizeof(struct dmub_cmd_psr_copy_settings_data
);
134 copy_settings_data
->dpphy_inst
= psr_context
->phyType
;
135 copy_settings_data
->aux_inst
= psr_context
->channel
;
136 copy_settings_data
->digfe_inst
= psr_context
->engineId
;
137 copy_settings_data
->digbe_inst
= psr_context
->transmitterId
;
139 copy_settings_data
->mpcc_inst
= pipe_ctx
->plane_res
.mpcc_inst
;
141 if (pipe_ctx
->plane_res
.hubp
)
142 copy_settings_data
->hubp_inst
= pipe_ctx
->plane_res
.hubp
->inst
;
144 copy_settings_data
->hubp_inst
= 0;
145 if (pipe_ctx
->plane_res
.dpp
)
146 copy_settings_data
->dpp_inst
= pipe_ctx
->plane_res
.dpp
->inst
;
148 copy_settings_data
->dpp_inst
= 0;
149 if (pipe_ctx
->stream_res
.opp
)
150 copy_settings_data
->opp_inst
= pipe_ctx
->stream_res
.opp
->inst
;
152 copy_settings_data
->opp_inst
= 0;
153 if (pipe_ctx
->stream_res
.tg
)
154 copy_settings_data
->otg_inst
= pipe_ctx
->stream_res
.tg
->inst
;
156 copy_settings_data
->otg_inst
= 0;
159 copy_settings_data
->psr_level
= psr_context
->psr_level
.u32all
;
160 copy_settings_data
->hyst_frames
= psr_context
->timehyst_frames
;
161 copy_settings_data
->hyst_lines
= psr_context
->hyst_lines
;
162 copy_settings_data
->phy_type
= psr_context
->phyType
;
163 copy_settings_data
->aux_repeat
= psr_context
->aux_repeats
;
164 copy_settings_data
->smu_optimizations_en
= psr_context
->allow_smu_optimizations
;
165 copy_settings_data
->skip_wait_for_pll_lock
= psr_context
->skipPsrWaitForPllLock
;
166 copy_settings_data
->frame_delay
= psr_context
->frame_delay
;
167 copy_settings_data
->smu_phy_id
= psr_context
->smuPhyId
;
168 copy_settings_data
->num_of_controllers
= psr_context
->numberOfControllers
;
169 copy_settings_data
->frame_cap_ind
= psr_context
->psrFrameCaptureIndicationReq
;
170 copy_settings_data
->phy_num
= psr_context
->frame_delay
& 0x7;
171 copy_settings_data
->link_rate
= psr_context
->frame_delay
& 0xF;
173 dc_dmub_srv_cmd_queue(dc
->dmub_srv
, &cmd
.psr_copy_settings
.header
);
174 dc_dmub_srv_cmd_execute(dc
->dmub_srv
);
175 dc_dmub_srv_wait_idle(dc
->dmub_srv
);
180 static const struct dmub_psr_funcs psr_funcs
= {
181 .set_psr_enable
= dmub_set_psr_enable
,
182 .setup_psr
= dmub_setup_psr
,
183 .get_psr_state
= dmub_get_psr_state
,
184 .set_psr_level
= dmub_set_psr_level
,
188 * Construct PSR object.
190 static void dmub_psr_construct(struct dmub_psr
*psr
, struct dc_context
*ctx
)
193 psr
->funcs
= &psr_funcs
;
197 * Allocate and initialize PSR object.
199 struct dmub_psr
*dmub_psr_create(struct dc_context
*ctx
)
201 struct dmub_psr
*psr
= kzalloc(sizeof(struct dmub_psr
), GFP_KERNEL
);
208 dmub_psr_construct(psr
, ctx
);
214 * Deallocate PSR object.
216 void dmub_psr_destroy(struct dmub_psr
**dmub
)