Bug Summary

File:dev/pci/drm/amd/display/dc/dcn201/dcn201_hwseq.c
Warning:line 545, column 2
Value stored to 'hubp' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name dcn201_hwseq.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -target-feature +retpoline-external-thunk -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/llvm16/lib/clang/16 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/legacy-dpm -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu13 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/inc -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc/pmfw_if -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D SUSPEND -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /home/ben/Projects/scan/2024-01-11-110808-61670-1 -x c /usr/src/sys/dev/pci/drm/amd/display/dc/dcn201/dcn201_hwseq.c
1/*
2 * Copyright 2016 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 "dm_services.h"
27#include "basics/dc_common.h"
28#include "core_types.h"
29#include "resource.h"
30#include "dcn201_hwseq.h"
31#include "dcn201_optc.h"
32#include "dce/dce_hwseq.h"
33#include "hubp.h"
34#include "dchubbub.h"
35#include "timing_generator.h"
36#include "opp.h"
37#include "ipp.h"
38#include "mpc.h"
39#include "dccg.h"
40#include "clk_mgr.h"
41#include "reg_helper.h"
42
43#define CTXhws->ctx \
44 hws->ctx
45
46#define REG(reg)hws->regs->reg\
47 hws->regs->reg
48
49#define DC_LOGGERdc->ctx->logger \
50 dc->ctx->logger
51
52#undef FN
53#define FN(reg_name, field_name)hws->shifts->field_name, hws->masks->field_name \
54 hws->shifts->field_name, hws->masks->field_name
55
56static bool_Bool patch_address_for_sbs_tb_stereo(
57 struct pipe_ctx *pipe_ctx, PHYSICAL_ADDRESS_LOCunion large_integer *addr)
58{
59 struct dc_plane_state *plane_state = pipe_ctx->plane_state;
60 bool_Bool sec_split = pipe_ctx->top_pipe &&
61 pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state;
62
63 if (sec_split && plane_state->address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
64 (pipe_ctx->stream->timing.timing_3d_format ==
65 TIMING_3D_FORMAT_SIDE_BY_SIDE ||
66 pipe_ctx->stream->timing.timing_3d_format ==
67 TIMING_3D_FORMAT_TOP_AND_BOTTOM)) {
68 *addr = plane_state->address.grph_stereo.left_addr;
69 plane_state->address.grph_stereo.left_addr =
70 plane_state->address.grph_stereo.right_addr;
71 return true1;
72 } else {
73 if (pipe_ctx->stream->view_format != VIEW_3D_FORMAT_NONE &&
74 plane_state->address.type != PLN_ADDR_TYPE_GRPH_STEREO) {
75 plane_state->address.type = PLN_ADDR_TYPE_GRPH_STEREO;
76 plane_state->address.grph_stereo.right_addr =
77 plane_state->address.grph_stereo.left_addr;
78 plane_state->address.grph_stereo.right_meta_addr =
79 plane_state->address.grph_stereo.left_meta_addr;
80 }
81 }
82 return false0;
83}
84
85static bool_Bool gpu_addr_to_uma(struct dce_hwseq *hwseq,
86 PHYSICAL_ADDRESS_LOCunion large_integer *addr)
87{
88 bool_Bool is_in_uma;
89
90 if (hwseq->fb_base.quad_part <= addr->quad_part &&
91 addr->quad_part < hwseq->fb_top.quad_part) {
92 addr->quad_part -= hwseq->fb_base.quad_part;
93 addr->quad_part += hwseq->fb_offset.quad_part;
94 is_in_uma = true1;
95 } else if (hwseq->fb_offset.quad_part <= addr->quad_part &&
96 addr->quad_part <= hwseq->uma_top.quad_part) {
97 is_in_uma = true1;
98 } else {
99 is_in_uma = false0;
100 }
101 return is_in_uma;
102}
103
104static void plane_address_in_gpu_space_to_uma(struct dce_hwseq *hwseq,
105 struct dc_plane_address *addr)
106{
107 switch (addr->type) {
108 case PLN_ADDR_TYPE_GRAPHICS:
109 gpu_addr_to_uma(hwseq, &addr->grph.addr);
110 gpu_addr_to_uma(hwseq, &addr->grph.meta_addr);
111 break;
112 case PLN_ADDR_TYPE_GRPH_STEREO:
113 gpu_addr_to_uma(hwseq, &addr->grph_stereo.left_addr);
114 gpu_addr_to_uma(hwseq, &addr->grph_stereo.left_meta_addr);
115 gpu_addr_to_uma(hwseq, &addr->grph_stereo.right_addr);
116 gpu_addr_to_uma(hwseq, &addr->grph_stereo.right_meta_addr);
117 break;
118 case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE:
119 gpu_addr_to_uma(hwseq, &addr->video_progressive.luma_addr);
120 gpu_addr_to_uma(hwseq, &addr->video_progressive.luma_meta_addr);
121 gpu_addr_to_uma(hwseq, &addr->video_progressive.chroma_addr);
122 gpu_addr_to_uma(hwseq, &addr->video_progressive.chroma_meta_addr);
123 break;
124 default:
125 BREAK_TO_DEBUGGER()do { ___drm_dbg(((void *)0), DRM_UT_DRIVER, "%s():%d\n", __func__
, 125); do {} while (0); } while (0)
;
126 break;
127 }
128}
129
130void dcn201_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_ctx)
131{
132 bool_Bool addr_patched = false0;
133 PHYSICAL_ADDRESS_LOCunion large_integer addr;
134 struct dc_plane_state *plane_state = pipe_ctx->plane_state;
135 struct dce_hwseq *hws = dc->hwseq;
136 struct dc_plane_address uma;
137
138 if (plane_state == NULL((void *)0))
139 return;
140
141 uma = plane_state->address;
142 addr_patched = patch_address_for_sbs_tb_stereo(pipe_ctx, &addr);
143
144 plane_address_in_gpu_space_to_uma(hws, &uma);
145
146 pipe_ctx->plane_res.hubp->funcs->hubp_program_surface_flip_and_addr(
147 pipe_ctx->plane_res.hubp,
148 &uma,
149 plane_state->flip_immediate);
150
151 plane_state->status.requested_address = plane_state->address;
152
153 if (plane_state->flip_immediate)
154 plane_state->status.current_address = plane_state->address;
155
156 if (addr_patched)
157 pipe_ctx->plane_state->address.grph_stereo.left_addr = addr;
158}
159
160/* Blank pixel data during initialization */
161void dcn201_init_blank(
162 struct dc *dc,
163 struct timing_generator *tg)
164{
165 struct dce_hwseq *hws = dc->hwseq;
166 enum dc_color_space color_space;
167 struct tg_color black_color = {0};
168 struct output_pixel_processor *opp = NULL((void *)0);
169 uint32_t num_opps, opp_id_src0, opp_id_src1;
170 uint32_t otg_active_width, otg_active_height;
171
172 /* program opp dpg blank color */
173 color_space = COLOR_SPACE_SRGB;
174 color_space_to_black_color(dc, color_space, &black_color);
175
176 /* get the OTG active size */
177 tg->funcs->get_otg_active_size(tg,
178 &otg_active_width,
179 &otg_active_height);
180
181 /* get the OPTC source */
182 tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1);
183 ASSERT(opp_id_src0 < dc->res_pool->res_cap->num_opp)do { if (({ static int __warned; int __ret = !!(!(opp_id_src0
< dc->res_pool->res_cap->num_opp)); if (__ret &&
!__warned) { printf("WARNING %s failed at %s:%d\n", "!(opp_id_src0 < dc->res_pool->res_cap->num_opp)"
, "/usr/src/sys/dev/pci/drm/amd/display/dc/dcn201/dcn201_hwseq.c"
, 183); __warned = 1; } __builtin_expect(!!(__ret), 0); })) do
{} while (0); } while (0)
;
184 opp = dc->res_pool->opps[opp_id_src0];
185
186 opp->funcs->opp_set_disp_pattern_generator(
187 opp,
188 CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR,
189 CONTROLLER_DP_COLOR_SPACE_UDEFINED,
190 COLOR_DEPTH_UNDEFINED,
191 &black_color,
192 otg_active_width,
193 otg_active_height,
194 0);
195
196 hws->funcs.wait_for_blank_complete(opp);
197}
198
199static void read_mmhub_vm_setup(struct dce_hwseq *hws)
200{
201 uint32_t fb_base = REG_READ(MC_VM_FB_LOCATION_BASE)dm_read_reg_func(hws->ctx, hws->regs->MC_VM_FB_LOCATION_BASE
, __func__)
;
202 uint32_t fb_top = REG_READ(MC_VM_FB_LOCATION_TOP)dm_read_reg_func(hws->ctx, hws->regs->MC_VM_FB_LOCATION_TOP
, __func__)
;
203 uint32_t fb_offset = REG_READ(MC_VM_FB_OFFSET)dm_read_reg_func(hws->ctx, hws->regs->MC_VM_FB_OFFSET
, __func__)
;
204
205 /* MC_VM_FB_LOCATION_TOP is in pages, actual top should add 1 */
206 fb_top++;
207
208 /* bit 23:0 in register map to bit 47:24 in address */
209 hws->fb_base.low_part = fb_base;
210 hws->fb_base.quad_part <<= 24;
211
212 hws->fb_top.low_part = fb_top;
213 hws->fb_top.quad_part <<= 24;
214 hws->fb_offset.low_part = fb_offset;
215 hws->fb_offset.quad_part <<= 24;
216
217 hws->uma_top.quad_part = hws->fb_top.quad_part
218 - hws->fb_base.quad_part + hws->fb_offset.quad_part;
219}
220
221void dcn201_init_hw(struct dc *dc)
222{
223 int i, j;
224 struct dce_hwseq *hws = dc->hwseq;
225 struct resource_pool *res_pool = dc->res_pool;
226 struct dc_state *context = dc->current_state;
227
228 if (res_pool->dccg->funcs->dccg_init)
229 res_pool->dccg->funcs->dccg_init(res_pool->dccg);
230
231 if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
232 dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
233
234 if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)(dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS)) {
235 REG_WRITE(RBBMIF_TIMEOUT_DIS, 0xFFFFFFFF)dm_write_reg_func(hws->ctx, hws->regs->RBBMIF_TIMEOUT_DIS
, 0xFFFFFFFF, __func__)
;
236 REG_WRITE(RBBMIF_TIMEOUT_DIS_2, 0xFFFFFFFF)dm_write_reg_func(hws->ctx, hws->regs->RBBMIF_TIMEOUT_DIS_2
, 0xFFFFFFFF, __func__)
;
237
238 hws->funcs.dccg_init(hws);
239
240 REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, 2)generic_reg_update_ex(hws->ctx, hws->regs->DCHUBBUB_GLOBAL_TIMER_CNTL
, 1, hws->shifts->DCHUBBUB_GLOBAL_TIMER_REFDIV, hws->
masks->DCHUBBUB_GLOBAL_TIMER_REFDIV, 2)
;
241 REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1)generic_reg_update_ex(hws->ctx, hws->regs->DCHUBBUB_GLOBAL_TIMER_CNTL
, 1, hws->shifts->DCHUBBUB_GLOBAL_TIMER_ENABLE, hws->
masks->DCHUBBUB_GLOBAL_TIMER_ENABLE, 1)
;
242 REG_WRITE(REFCLK_CNTL, 0)dm_write_reg_func(hws->ctx, hws->regs->REFCLK_CNTL, 0
, __func__)
;
243 } else {
244 hws->funcs.bios_golden_init(dc);
245
246 if (dc->ctx->dc_bios->fw_info_valid) {
247 res_pool->ref_clocks.xtalin_clock_inKhz =
248 dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
249
250 if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)(dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS)) {
251 if (res_pool->dccg && res_pool->hubbub) {
252 (res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
253 dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
254 &res_pool->ref_clocks.dccg_ref_clock_inKhz);
255
256 (res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
257 res_pool->ref_clocks.dccg_ref_clock_inKhz,
258 &res_pool->ref_clocks.dchub_ref_clock_inKhz);
259 } else {
260 res_pool->ref_clocks.dccg_ref_clock_inKhz =
261 res_pool->ref_clocks.xtalin_clock_inKhz;
262 res_pool->ref_clocks.dchub_ref_clock_inKhz =
263 res_pool->ref_clocks.xtalin_clock_inKhz;
264 }
265 }
266 } else
267 ASSERT_CRITICAL(false)do { if (({ int __ret = !!(!(0)); if (__ret) printf("WARNING %s failed at %s:%d\n"
, "!(0)", "/usr/src/sys/dev/pci/drm/amd/display/dc/dcn201/dcn201_hwseq.c"
, 267); __builtin_expect(!!(__ret), 0); })) do {} while (0); }
while (0)
;
268 for (i = 0; i < dc->link_count; i++) {
269 /* Power up AND update implementation according to the
270 * required signal (which may be different from the
271 * default signal on connector).
272 */
273 struct dc_link *link = dc->links[i];
274
275 link->link_enc->funcs->hw_init(link->link_enc);
276 }
277 if (hws->fb_offset.quad_part == 0)
278 read_mmhub_vm_setup(hws);
279 }
280
281 /* Blank pixel data with OPP DPG */
282 for (i = 0; i < res_pool->timing_generator_count; i++) {
283 struct timing_generator *tg = res_pool->timing_generators[i];
284
285 if (tg->funcs->is_tg_enabled(tg)) {
286 dcn201_init_blank(dc, tg);
287 }
288 }
289
290 for (i = 0; i < res_pool->timing_generator_count; i++) {
291 struct timing_generator *tg = res_pool->timing_generators[i];
292
293 if (tg->funcs->is_tg_enabled(tg))
294 tg->funcs->lock(tg);
295 }
296
297 for (i = 0; i < res_pool->pipe_count; i++) {
298 struct dpp *dpp = res_pool->dpps[i];
299
300 dpp->funcs->dpp_reset(dpp);
301 }
302
303 /* Reset all MPCC muxes */
304 res_pool->mpc->funcs->mpc_init(res_pool->mpc);
305
306 /* initialize OPP mpc_tree parameter */
307 for (i = 0; i < res_pool->res_cap->num_opp; i++) {
308 res_pool->opps[i]->mpc_tree_params.opp_id = res_pool->opps[i]->inst;
309 res_pool->opps[i]->mpc_tree_params.opp_list = NULL((void *)0);
310 for (j = 0; j < MAX_PIPES6; j++)
311 res_pool->opps[i]->mpcc_disconnect_pending[j] = false0;
312 }
313
314 for (i = 0; i < res_pool->timing_generator_count; i++) {
315 struct timing_generator *tg = res_pool->timing_generators[i];
316 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
317 struct hubp *hubp = res_pool->hubps[i];
318 struct dpp *dpp = res_pool->dpps[i];
319
320 pipe_ctx->stream_res.tg = tg;
321 pipe_ctx->pipe_idx = i;
322
323 pipe_ctx->plane_res.hubp = hubp;
324 pipe_ctx->plane_res.dpp = dpp;
325 pipe_ctx->plane_res.mpcc_inst = dpp->inst;
326 hubp->mpcc_id = dpp->inst;
327 hubp->opp_id = OPP_ID_INVALID0xf;
328 hubp->power_gated = false0;
329 pipe_ctx->stream_res.opp = NULL((void *)0);
330
331 hubp->funcs->hubp_init(hubp);
332
333 res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true1;
334 pipe_ctx->stream_res.opp = res_pool->opps[i];
335 /*To do: number of MPCC != number of opp*/
336 hws->funcs.plane_atomic_disconnect(dc, pipe_ctx);
337 }
338
339 /* initialize DWB pointer to MCIF_WB */
340 for (i = 0; i < res_pool->res_cap->num_dwb; i++)
341 res_pool->dwbc[i]->mcif = res_pool->mcif_wb[i];
342
343 for (i = 0; i < res_pool->timing_generator_count; i++) {
344 struct timing_generator *tg = res_pool->timing_generators[i];
345
346 if (tg->funcs->is_tg_enabled(tg))
347 tg->funcs->unlock(tg);
348 }
349
350 for (i = 0; i < res_pool->pipe_count; i++) {
351 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
352
353 dc->hwss.disable_plane(dc, pipe_ctx);
354
355 pipe_ctx->stream_res.tg = NULL((void *)0);
356 pipe_ctx->plane_res.hubp = NULL((void *)0);
357 }
358
359 for (i = 0; i < res_pool->timing_generator_count; i++) {
360 struct timing_generator *tg = res_pool->timing_generators[i];
361
362 tg->funcs->tg_init(tg);
363 }
364
365 /* end of FPGA. Below if real ASIC */
366 if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)(dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS))
367 return;
368
369 for (i = 0; i < res_pool->audio_count; i++) {
370 struct audio *audio = res_pool->audios[i];
371
372 audio->funcs->hw_init(audio);
373 }
374
375 /* power AFMT HDMI memory TODO: may move to dis/en output save power*/
376 REG_WRITE(DIO_MEM_PWR_CTRL, 0)dm_write_reg_func(hws->ctx, hws->regs->DIO_MEM_PWR_CTRL
, 0, __func__)
;
377
378 if (!dc->debug.disable_clock_gate) {
379 /* enable all DCN clock gating */
380 REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0)dm_write_reg_func(hws->ctx, hws->regs->DCCG_GATE_DISABLE_CNTL
, 0, __func__)
;
381
382 REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0)dm_write_reg_func(hws->ctx, hws->regs->DCCG_GATE_DISABLE_CNTL2
, 0, __func__)
;
383
384 REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0)generic_reg_update_ex(hws->ctx, hws->regs->DCFCLK_CNTL
, 1, hws->shifts->DCFCLK_GATE_DIS, hws->masks->DCFCLK_GATE_DIS
, 0)
;
385 }
386}
387
388/* trigger HW to start disconnect plane from stream on the next vsync */
389void dcn201_plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx)
390{
391 struct dce_hwseq *hws = dc->hwseq;
392 struct hubp *hubp = pipe_ctx->plane_res.hubp;
393 int dpp_id = pipe_ctx->plane_res.dpp->inst;
394 struct mpc *mpc = dc->res_pool->mpc;
395 struct mpc_tree *mpc_tree_params;
396 struct mpcc *mpcc_to_remove = NULL((void *)0);
397 struct output_pixel_processor *opp = pipe_ctx->stream_res.opp;
398 bool_Bool mpcc_removed = false0;
399
400 mpc_tree_params = &(opp->mpc_tree_params);
401
402 /* check if this plane is being used by an MPCC in the secondary blending chain */
403 if (mpc->funcs->get_mpcc_for_dpp_from_secondary)
404 mpcc_to_remove = mpc->funcs->get_mpcc_for_dpp_from_secondary(mpc_tree_params, dpp_id);
405
406 /* remove MPCC from secondary if being used */
407 if (mpcc_to_remove != NULL((void *)0) && mpc->funcs->remove_mpcc_from_secondary) {
408 mpc->funcs->remove_mpcc_from_secondary(mpc, mpc_tree_params, mpcc_to_remove);
409 mpcc_removed = true1;
410 }
411
412 /* check if this MPCC is already being used for this plane (dpp) in the primary blending chain */
413 mpcc_to_remove = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, dpp_id);
414 if (mpcc_to_remove != NULL((void *)0)) {
415 mpc->funcs->remove_mpcc(mpc, mpc_tree_params, mpcc_to_remove);
416 mpcc_removed = true1;
417 }
418
419 /*Already reset*/
420 if (mpcc_removed == false0)
421 return;
422
423 if (opp != NULL((void *)0))
424 opp->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true1;
425
426 dc->optimized_required = true1;
427
428 if (hubp->funcs->hubp_disconnect)
429 hubp->funcs->hubp_disconnect(hubp);
430
431 if (dc->debug.sanity_checks)
432 hws->funcs.verify_allow_pstate_change_high(dc);
433}
434
435void dcn201_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
436{
437 struct hubp *hubp = pipe_ctx->plane_res.hubp;
438 struct mpcc_blnd_cfg blnd_cfg;
439 bool_Bool per_pixel_alpha = pipe_ctx->plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe;
440 int mpcc_id, dpp_id;
441 struct mpcc *new_mpcc;
442 struct mpcc *remove_mpcc = NULL((void *)0);
443 struct mpc *mpc = dc->res_pool->mpc;
444 struct mpc_tree *mpc_tree_params = &(pipe_ctx->stream_res.opp->mpc_tree_params);
445
446 if (dc->debug.visual_confirm == VISUAL_CONFIRM_HDR) {
447 get_hdr_visual_confirm_color(
448 pipe_ctx, &blnd_cfg.black_color);
449 } else if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE) {
450 get_surface_visual_confirm_color(
451 pipe_ctx, &blnd_cfg.black_color);
452 } else {
453 color_space_to_black_color(
454 dc, pipe_ctx->stream->output_color_space,
455 &blnd_cfg.black_color);
456 }
457
458 if (per_pixel_alpha)
459 blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA;
460 else
461 blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA;
462
463 blnd_cfg.overlap_only = false0;
464
465 if (pipe_ctx->plane_state->global_alpha_value)
466 blnd_cfg.global_alpha = pipe_ctx->plane_state->global_alpha_value;
467 else
468 blnd_cfg.global_alpha = 0xff;
469
470 blnd_cfg.global_gain = 0xff;
471 blnd_cfg.background_color_bpc = 4;
472 blnd_cfg.bottom_gain_mode = 0;
473 blnd_cfg.top_gain = 0x1f000;
474 blnd_cfg.bottom_inside_gain = 0x1f000;
475 blnd_cfg.bottom_outside_gain = 0x1f000;
476 /*the input to MPCC is RGB*/
477 blnd_cfg.black_color.color_b_cb = 0;
478 blnd_cfg.black_color.color_g_y = 0;
479 blnd_cfg.black_color.color_r_cr = 0;
480
481 /* DCN1.0 has output CM before MPC which seems to screw with
482 * pre-multiplied alpha. This is a w/a hopefully unnecessary for DCN2.
483 */
484 blnd_cfg.pre_multiplied_alpha = per_pixel_alpha;
485
486 /*
487 * TODO: remove hack
488 * Note: currently there is a bug in init_hw such that
489 * on resume from hibernate, BIOS sets up MPCC0, and
490 * we do mpcc_remove but the mpcc cannot go to idle
491 * after remove. This cause us to pick mpcc1 here,
492 * which causes a pstate hang for yet unknown reason.
493 */
494 dpp_id = hubp->inst;
495 mpcc_id = dpp_id;
496
497 /* If there is no full update, don't need to touch MPC tree*/
498 if (!pipe_ctx->plane_state->update_flags.bits.full_update) {
499 dc->hwss.update_visual_confirm_color(dc, pipe_ctx, &blnd_cfg.black_color, mpcc_id);
500 mpc->funcs->update_blending(mpc, &blnd_cfg, mpcc_id);
501 return;
502 }
503
504 /* check if this plane is being used by an MPCC in the secondary blending chain */
505 if (mpc->funcs->get_mpcc_for_dpp_from_secondary)
506 remove_mpcc = mpc->funcs->get_mpcc_for_dpp_from_secondary(mpc_tree_params, dpp_id);
507
508 /* remove MPCC from secondary if being used */
509 if (remove_mpcc != NULL((void *)0) && mpc->funcs->remove_mpcc_from_secondary)
510 mpc->funcs->remove_mpcc_from_secondary(mpc, mpc_tree_params, remove_mpcc);
511
512 /* check if this MPCC is already being used for this plane (dpp) in the primary blending chain */
513 remove_mpcc = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, dpp_id);
514 /* remove MPCC if being used */
515
516 if (remove_mpcc != NULL((void *)0))
517 mpc->funcs->remove_mpcc(mpc, mpc_tree_params, remove_mpcc);
518 else
519 if (dc->debug.sanity_checks)
520 mpc->funcs->assert_mpcc_idle_before_connect(
521 dc->res_pool->mpc, mpcc_id);
522
523 /* Call MPC to insert new plane */
524 dc->hwss.update_visual_confirm_color(dc, pipe_ctx, &blnd_cfg.black_color, mpcc_id);
525 new_mpcc = mpc->funcs->insert_plane(dc->res_pool->mpc,
526 mpc_tree_params,
527 &blnd_cfg,
528 NULL((void *)0),
529 NULL((void *)0),
530 dpp_id,
531 mpcc_id);
532
533 ASSERT(new_mpcc != NULL)do { if (({ static int __warned; int __ret = !!(!(new_mpcc !=
((void *)0))); if (__ret && !__warned) { printf("WARNING %s failed at %s:%d\n"
, "!(new_mpcc != ((void *)0))", "/usr/src/sys/dev/pci/drm/amd/display/dc/dcn201/dcn201_hwseq.c"
, 533); __warned = 1; } __builtin_expect(!!(__ret), 0); })) do
{} while (0); } while (0)
;
534 hubp->opp_id = pipe_ctx->stream_res.opp->inst;
535 hubp->mpcc_id = mpcc_id;
536}
537
538void dcn201_pipe_control_lock(
539 struct dc *dc,
540 struct pipe_ctx *pipe,
541 bool_Bool lock)
542{
543 struct dce_hwseq *hws = dc->hwseq;
544 struct hubp *hubp = NULL((void *)0);
545 hubp = dc->res_pool->hubps[pipe->pipe_idx];
Value stored to 'hubp' is never read
546 /* use TG master update lock to lock everything on the TG
547 * therefore only top pipe need to lock
548 */
549 if (pipe->top_pipe)
550 return;
551
552 if (dc->debug.sanity_checks)
553 hws->funcs.verify_allow_pstate_change_high(dc);
554
555 if (pipe->plane_state != NULL((void *)0) && pipe->plane_state->triplebuffer_flips) {
556 if (lock)
557 pipe->stream_res.tg->funcs->triplebuffer_lock(pipe->stream_res.tg);
558 else
559 pipe->stream_res.tg->funcs->triplebuffer_unlock(pipe->stream_res.tg);
560 } else {
561 if (lock)
562 pipe->stream_res.tg->funcs->lock(pipe->stream_res.tg);
563 else
564 pipe->stream_res.tg->funcs->unlock(pipe->stream_res.tg);
565 }
566
567 if (dc->debug.sanity_checks)
568 hws->funcs.verify_allow_pstate_change_high(dc);
569}
570
571void dcn201_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
572{
573 struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes;
574
575 gpu_addr_to_uma(pipe_ctx->stream->ctx->dc->hwseq, &attributes->address);
576
577 pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes(
578 pipe_ctx->plane_res.hubp, attributes);
579 pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes(
580 pipe_ctx->plane_res.dpp, attributes);
581}
582
583void dcn201_set_dmdata_attributes(struct pipe_ctx *pipe_ctx)
584{
585 struct dc_dmdata_attributes attr = { 0 };
586 struct hubp *hubp = pipe_ctx->plane_res.hubp;
587
588 gpu_addr_to_uma(pipe_ctx->stream->ctx->dc->hwseq,
589 &pipe_ctx->stream->dmdata_address);
590
591 attr.dmdata_mode = DMDATA_HW_MODE;
592 attr.dmdata_size =
593 dc_is_hdmi_signal(pipe_ctx->stream->signal) ? 32 : 36;
594 attr.address.quad_part =
595 pipe_ctx->stream->dmdata_address.quad_part;
596 attr.dmdata_dl_delta = 0;
597 attr.dmdata_qos_mode = 0;
598 attr.dmdata_qos_level = 0;
599 attr.dmdata_repeat = 1; /* always repeat */
600 attr.dmdata_updated = 1;
601 attr.dmdata_sw_data = NULL((void *)0);
602
603 hubp->funcs->dmdata_set_attributes(hubp, &attr);
604}
605
606void dcn201_unblank_stream(struct pipe_ctx *pipe_ctx,
607 struct dc_link_settings *link_settings)
608{
609 struct encoder_unblank_param params = { { 0 } };
610 struct dc_stream_state *stream = pipe_ctx->stream;
611 struct dc_link *link = stream->link;
612 struct dce_hwseq *hws = link->dc->hwseq;
613
614 /* only 3 items below are used by unblank */
615 params.timing = pipe_ctx->stream->timing;
616
617 params.link_settings.link_rate = link_settings->link_rate;
618
619 if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
620 /*check whether it is half the rate*/
621 if (optc201_is_two_pixels_per_containter(&stream->timing))
622 params.timing.pix_clk_100hz /= 2;
623
624 pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(link, pipe_ctx->stream_res.stream_enc, &params);
625 }
626
627 if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
628 hws->funcs.edp_backlight_control(link, true1);
629 }
630}