[bug report] drm/amd/display: Add DCN3 HWSEQ

Dan Carpenter dan.carpenter at oracle.com
Fri Jun 5 13:28:13 UTC 2020


Hello Bhawanpreet Lakha,

This is a semi-automatic email about new static checker warnings.

The patch 581b9589487e: "drm/amd/display: Add DCN3 HWSEQ" from May
21, 2020, leads to the following Smatch complaint:

    drivers/gpu/drm/amd/amdgpu/../display/dc/dcn30/dcn30_hwseq.c:618 dcn30_init_hw()
    error: we previously assumed 'dc->clk_mgr' could be null (see line 433)

drivers/gpu/drm/amd/amdgpu/../display/dc/dcn30/dcn30_hwseq.c
   432	
   433		if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
                    ^^^^^^^^^^^
This code assumes ->clk_mgr can be NULL.

   434			dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
   435	
   436		// Initialize the dccg
   437		if (res_pool->dccg->funcs->dccg_init)
   438			res_pool->dccg->funcs->dccg_init(res_pool->dccg);
   439	
   440		//Enable ability to power gate / don't force power on permanently
   441		hws->funcs.enable_power_gating_plane(dc->hwseq, true);
   442	
   443		if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
   444			REG_WRITE(RBBMIF_TIMEOUT_DIS, 0xFFFFFFFF);
   445			REG_WRITE(RBBMIF_TIMEOUT_DIS_2, 0xFFFFFFFF);
   446	
   447			hws->funcs.dccg_init(hws);
   448	
   449			REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, 2);
   450			REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1);
   451			REG_WRITE(REFCLK_CNTL, 0);
   452		} else {
   453			if (!dcb->funcs->is_accelerated_mode(dcb)) {
   454				hws->funcs.bios_golden_init(dc);
   455				hws->funcs.disable_vga(dc->hwseq);
   456			}
   457	
   458			if (dc->ctx->dc_bios->fw_info_valid) {
   459				res_pool->ref_clocks.xtalin_clock_inKhz =
   460						dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
   461	
   462				if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
   463					if (res_pool->dccg && res_pool->hubbub) {
   464	
   465						(res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
   466								dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
   467								&res_pool->ref_clocks.dccg_ref_clock_inKhz);
   468	
   469						(res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
   470								res_pool->ref_clocks.dccg_ref_clock_inKhz,
   471								&res_pool->ref_clocks.dchub_ref_clock_inKhz);
   472					} else {
   473						// Not all ASICs have DCCG sw component
   474						res_pool->ref_clocks.dccg_ref_clock_inKhz =
   475								res_pool->ref_clocks.xtalin_clock_inKhz;
   476						res_pool->ref_clocks.dchub_ref_clock_inKhz =
   477								res_pool->ref_clocks.xtalin_clock_inKhz;
   478					}
   479				}
   480			} else
   481				ASSERT_CRITICAL(false);
   482	
   483			for (i = 0; i < dc->link_count; i++) {
   484				/* Power up AND update implementation according to the
   485				 * required signal (which may be different from the
   486				 * default signal on connector).
   487				 */
   488				struct dc_link *link = dc->links[i];
   489	
   490				link->link_enc->funcs->hw_init(link->link_enc);
   491			}
   492		}
   493	
   494		/* Power gate DSCs */
   495		for (i = 0; i < res_pool->res_cap->num_dsc; i++)
   496			hws->funcs.dsc_pg_control(hws, res_pool->dscs[i]->inst, false);
   497	
   498		/* Blank pixel data with OPP DPG */
   499		for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
   500			struct timing_generator *tg = dc->res_pool->timing_generators[i];
   501	
   502			if (tg->funcs->is_tg_enabled(tg))
   503				hws->funcs.init_blank(dc, tg);
   504		}
   505	
   506		for (i = 0; i < res_pool->timing_generator_count; i++) {
   507			struct timing_generator *tg = dc->res_pool->timing_generators[i];
   508	
   509			if (tg->funcs->is_tg_enabled(tg))
   510				tg->funcs->lock(tg);
   511		}
   512	
   513		for (i = 0; i < dc->res_pool->pipe_count; i++) {
   514			struct dpp *dpp = res_pool->dpps[i];
   515	
   516			dpp->funcs->dpp_reset(dpp);
   517		}
   518	
   519		/* Reset all MPCC muxes */
   520		res_pool->mpc->funcs->mpc_init(res_pool->mpc);
   521	
   522		/* initialize OPP mpc_tree parameter */
   523		for (i = 0; i < dc->res_pool->res_cap->num_opp; i++) {
   524			res_pool->opps[i]->mpc_tree_params.opp_id = res_pool->opps[i]->inst;
   525			res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
   526			for (j = 0; j < MAX_PIPES; j++)
   527				res_pool->opps[i]->mpcc_disconnect_pending[j] = false;
   528		}
   529	
   530		for (i = 0; i < dc->res_pool->pipe_count; i++) {
   531			struct timing_generator *tg = dc->res_pool->timing_generators[i];
   532			struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
   533			struct hubp *hubp = dc->res_pool->hubps[i];
   534			struct dpp *dpp = dc->res_pool->dpps[i];
   535	
   536			pipe_ctx->stream_res.tg = tg;
   537			pipe_ctx->pipe_idx = i;
   538	
   539			pipe_ctx->plane_res.hubp = hubp;
   540			pipe_ctx->plane_res.dpp = dpp;
   541			pipe_ctx->plane_res.mpcc_inst = dpp->inst;
   542			hubp->mpcc_id = dpp->inst;
   543			hubp->opp_id = OPP_ID_INVALID;
   544			hubp->power_gated = false;
   545			pipe_ctx->stream_res.opp = NULL;
   546	
   547			hubp->funcs->hubp_init(hubp);
   548	
   549			//dc->res_pool->opps[i]->mpc_tree_params.opp_id = dc->res_pool->opps[i]->inst;
   550			//dc->res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
   551			dc->res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
   552			pipe_ctx->stream_res.opp = dc->res_pool->opps[i];
   553			/*to do*/
   554			hws->funcs.plane_atomic_disconnect(dc, pipe_ctx);
   555		}
   556	
   557		/* initialize DWB pointer to MCIF_WB */
   558		for (i = 0; i < res_pool->res_cap->num_dwb; i++)
   559			res_pool->dwbc[i]->mcif = res_pool->mcif_wb[i];
   560	
   561		for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
   562			struct timing_generator *tg = dc->res_pool->timing_generators[i];
   563	
   564			if (tg->funcs->is_tg_enabled(tg))
   565				tg->funcs->unlock(tg);
   566		}
   567	
   568		for (i = 0; i < dc->res_pool->pipe_count; i++) {
   569			struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
   570	
   571			dc->hwss.disable_plane(dc, pipe_ctx);
   572	
   573			pipe_ctx->stream_res.tg = NULL;
   574			pipe_ctx->plane_res.hubp = NULL;
   575		}
   576	
   577		for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
   578			struct timing_generator *tg = dc->res_pool->timing_generators[i];
   579	
   580			tg->funcs->tg_init(tg);
   581		}
   582	
   583		/* end of FPGA. Below if real ASIC */
   584		if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
   585			return;
   586	
   587	
   588		for (i = 0; i < res_pool->audio_count; i++) {
   589			struct audio *audio = res_pool->audios[i];
   590	
   591			audio->funcs->hw_init(audio);
   592		}
   593	
   594		for (i = 0; i < dc->link_count; i++) {
   595			struct dc_link *link = dc->links[i];
   596	
   597			if (link->panel_cntl)
   598				backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
   599		}
   600	
   601		for (i = 0; i < dc->res_pool->pipe_count; i++) {
   602			if (abms[i] != NULL)
   603				abms[i]->funcs->abm_init(abms[i], backlight);
   604		}
   605	
   606		/* power AFMT HDMI memory TODO: may move to dis/en output save power*/
   607		REG_WRITE(DIO_MEM_PWR_CTRL, 0);
   608	
   609		if (!dc->debug.disable_clock_gate) {
   610			/* enable all DCN clock gating */
   611			REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
   612	
   613			REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
   614	
   615			REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
   616		}
   617	
   618		if (dc->clk_mgr->funcs->notify_wm_ranges)
                    ^^^^^^^^^^^
This code dereferences it without checking for NULL.

   619			dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
   620	

regards,
dan carpenter


More information about the amd-gfx mailing list