Commit 55eeaaec authored by Dillon Varone's avatar Dillon Varone Committed by Alex Deucher
Browse files

drm/amd/display: Add support for FAMS2+ interface versions



Current driver interface does not allow for flexibility in coexistence
of multiple interface versions, so add support for checking minor
interface revisions and providing appropriate programming.

Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Reviewed-by: default avatarAlvin Lee <alvin.lee2@amd.com>
Signed-off-by: default avatarDillon Varone <dillon.varone@amd.com>
Signed-off-by: default avatarRodrigo Siqueira <rodrigo.siqueira@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 3f238a6b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1056,6 +1056,7 @@ struct dc_debug_options {
	bool dml21_force_pstate_method;
	uint32_t dml21_force_pstate_method_values[MAX_PIPES];
	uint32_t dml21_disable_pstate_method_mask;
	union fw_assisted_mclk_switch_version fams_version;
	union dmub_fams2_global_feature_config fams2_config;
	bool enable_legacy_clock_update;
	unsigned int force_cositing;
+18 −22
Original line number Diff line number Diff line
@@ -1714,30 +1714,26 @@ void dc_dmub_srv_fams2_update_config(struct dc *dc,

		/* construct per-stream configs */
		for (i = 0; i < context->bw_ctx.bw.dcn.fams2_global_config.num_streams; i++) {
			struct dmub_rb_cmd_fams2 *stream_cmd = &cmd[i+1].fams2_config;
			struct dmub_rb_cmd_fams2 *sub_state_cmd = &cmd[i+1+context->bw_ctx.bw.dcn.fams2_global_config.num_streams].fams2_config;
			struct dmub_rb_cmd_fams2 *stream_base_cmd = &cmd[i+1].fams2_config;
			struct dmub_rb_cmd_fams2 *stream_sub_state_cmd = &cmd[i+1+context->bw_ctx.bw.dcn.fams2_global_config.num_streams].fams2_config;

			/* configure command header */
			stream_cmd->header.type = DMUB_CMD__FW_ASSISTED_MCLK_SWITCH;
			stream_cmd->header.sub_type = DMUB_CMD__FAMS2_CONFIG;
			stream_cmd->header.payload_bytes = sizeof(struct dmub_rb_cmd_fams2) - sizeof(struct dmub_cmd_header);
			stream_cmd->header.multi_cmd_pending = 1;
			sub_state_cmd->header.type = DMUB_CMD__FW_ASSISTED_MCLK_SWITCH;
			sub_state_cmd->header.sub_type = DMUB_CMD__FAMS2_CONFIG;
			sub_state_cmd->header.payload_bytes = sizeof(struct dmub_rb_cmd_fams2) - sizeof(struct dmub_cmd_header);
			sub_state_cmd->header.multi_cmd_pending = 1;
			/* copy stream static state */
			memcpy(&stream_cmd->config.stream_v1.base,
					&context->bw_ctx.bw.dcn.fams2_stream_params[i],
					sizeof(struct dmub_fams2_cmd_stream_static_base_state));
			// TODO: Use the below memcpy call instead of the above once DML is updated
			/*memcpy(&stream_cmd->config.stream_v1.base,
					&context->bw_ctx.bw.dcn.fams2_stream_params[i].base,
					sizeof(struct dmub_fams2_cmd_stream_static_base_state));*/
			/* copy stream sub state */
			memcpy(&stream_cmd->config.stream_v1.sub_state,
					&context->bw_ctx.bw.dcn.fams2_stream_params[i].sub_state,
					sizeof(union dmub_fams2_cmd_stream_static_sub_state));
			stream_base_cmd->header.type = DMUB_CMD__FW_ASSISTED_MCLK_SWITCH;
			stream_base_cmd->header.sub_type = DMUB_CMD__FAMS2_CONFIG;
			stream_base_cmd->header.payload_bytes = sizeof(struct dmub_rb_cmd_fams2) - sizeof(struct dmub_cmd_header);
			stream_base_cmd->header.multi_cmd_pending = 1;
			stream_sub_state_cmd->header.type = DMUB_CMD__FW_ASSISTED_MCLK_SWITCH;
			stream_sub_state_cmd->header.sub_type = DMUB_CMD__FAMS2_CONFIG;
			stream_sub_state_cmd->header.payload_bytes = sizeof(struct dmub_rb_cmd_fams2) - sizeof(struct dmub_cmd_header);
			stream_sub_state_cmd->header.multi_cmd_pending = 1;
			/* copy stream static base state */
			memcpy(&stream_base_cmd->config,
					&context->bw_ctx.bw.dcn.fams2_stream_base_params[i],
					sizeof(union dmub_cmd_fams2_config));
			/* copy stream static sub state */
			memcpy(&stream_sub_state_cmd->config,
					&context->bw_ctx.bw.dcn.fams2_stream_sub_params[i],
					sizeof(union dmub_cmd_fams2_config));
		}
	}

+52 −28
Original line number Diff line number Diff line
@@ -482,7 +482,8 @@ void dml21_build_fams2_programming(const struct dc *dc,
	unsigned int num_fams2_streams = 0;

	/* reset fams2 data */
	memset(&context->bw_ctx.bw.dcn.fams2_stream_params, 0, sizeof(struct dmub_fams2_stream_static_state) * DML2_MAX_PLANES);
	memset(&context->bw_ctx.bw.dcn.fams2_stream_base_params, 0, sizeof(union dmub_cmd_fams2_config) * DML2_MAX_PLANES);
	memset(&context->bw_ctx.bw.dcn.fams2_stream_sub_params, 0, sizeof(union dmub_cmd_fams2_config) * DML2_MAX_PLANES);
	memset(&context->bw_ctx.bw.dcn.fams2_global_config, 0, sizeof(struct dmub_cmd_fams2_global_config));

	if (dml_ctx->v21.mode_programming.programming->fams2_required) {
@@ -490,8 +491,10 @@ void dml21_build_fams2_programming(const struct dc *dc,
			int dml_stream_idx;
			struct dc_stream_state *phantom_stream;
			struct dc_stream_status *phantom_status;
			enum fams2_stream_type type = 0;

			struct dmub_fams2_stream_static_state *static_state = &context->bw_ctx.bw.dcn.fams2_stream_params[num_fams2_streams];
			union dmub_cmd_fams2_config *static_base_state = &context->bw_ctx.bw.dcn.fams2_stream_base_params[num_fams2_streams];
			union dmub_cmd_fams2_config *static_sub_state = &context->bw_ctx.bw.dcn.fams2_stream_sub_params[num_fams2_streams];

			struct dc_stream_state *stream = context->streams[i];

@@ -508,13 +511,21 @@ void dml21_build_fams2_programming(const struct dc *dc,
			}

			/* copy static state from PMO */
			memcpy(static_state,
					&dml_ctx->v21.mode_programming.programming->stream_programming[dml_stream_idx].fams2_params,
					sizeof(struct dmub_fams2_stream_static_state));
			memcpy(static_base_state,
					&dml_ctx->v21.mode_programming.programming->stream_programming[dml_stream_idx].fams2_base_params,
					sizeof(union dmub_cmd_fams2_config));
			memcpy(static_sub_state,
					&dml_ctx->v21.mode_programming.programming->stream_programming[dml_stream_idx].fams2_sub_params,
					sizeof(union dmub_cmd_fams2_config));

			switch (dc->debug.fams_version.minor) {
			case 1:
			default:
				type = static_base_state->stream_v1.base.type;

				/* get information from context */
			static_state->num_planes = context->stream_status[i].plane_count;
			static_state->otg_inst = context->stream_status[i].primary_otg_inst;
				static_base_state->stream_v1.base.num_planes = context->stream_status[i].plane_count;
				static_base_state->stream_v1.base.otg_inst = context->stream_status[i].primary_otg_inst;

				/* populate pipe masks for planes */
				for (j = 0; j < context->stream_status[i].plane_count; j++) {
@@ -522,14 +533,16 @@ void dml21_build_fams2_programming(const struct dc *dc,
						if (context->res_ctx.pipe_ctx[k].stream &&
								context->res_ctx.pipe_ctx[k].stream->stream_id == stream->stream_id &&
								context->res_ctx.pipe_ctx[k].plane_state == context->stream_status[i].plane_states[j]) {
						static_state->pipe_mask |= (1 << k);
						static_state->plane_pipe_masks[j] |= (1 << k);
							static_base_state->stream_v1.base.pipe_mask |= (1 << k);
							static_base_state->stream_v1.base.plane_pipe_masks[j] |= (1 << k);
						}
					}
				}
			}


			/* get per method programming */
			switch (static_state->type) {
			switch (type) {
			case FAMS2_STREAM_TYPE_VBLANK:
			case FAMS2_STREAM_TYPE_VACTIVE:
			case FAMS2_STREAM_TYPE_DRR:
@@ -543,7 +556,13 @@ void dml21_build_fams2_programming(const struct dc *dc,

				/* phantom status should always be present */
				ASSERT(phantom_status);
				static_state->sub_state.subvp.phantom_otg_inst = phantom_status->primary_otg_inst;
				if (!phantom_status)
					break;

				switch (dc->debug.fams_version.minor) {
				case 1:
				default:
					static_sub_state->stream_v1.sub_state.subvp.phantom_otg_inst = phantom_status->primary_otg_inst;

					/* populate pipe masks for phantom planes */
					for (j = 0; j < phantom_status->plane_count; j++) {
@@ -551,8 +570,13 @@ void dml21_build_fams2_programming(const struct dc *dc,
							if (context->res_ctx.pipe_ctx[k].stream &&
									context->res_ctx.pipe_ctx[k].stream->stream_id == phantom_stream->stream_id &&
									context->res_ctx.pipe_ctx[k].plane_state == phantom_status->plane_states[j]) {
							static_state->sub_state.subvp.phantom_pipe_mask |= (1 << k);
							static_state->sub_state.subvp.phantom_plane_pipe_masks[j] |= (1 << k);
								switch (dc->debug.fams_version.minor) {
								case 1:
								default:
									static_sub_state->stream_v1.sub_state.subvp.phantom_pipe_mask |= (1 << k);
									static_sub_state->stream_v1.sub_state.subvp.phantom_plane_pipe_masks[j] |= (1 << k);
								}
							}
						}
					}
				}
+1 −1
Original line number Diff line number Diff line
@@ -354,7 +354,7 @@ static const struct dml2_ip_capabilities dml2_dcn401_max_ip_caps = {

	.fams2 = {
		.max_allow_delay_us = 100 * 1000,
		.scheduling_delay_us = 125,
		.scheduling_delay_us = 550,
		.vertical_interrupt_ack_delay_us = 40,
		.allow_programming_delay_us = 18,
		.min_allow_width_us = 20,
+2 −1
Original line number Diff line number Diff line
@@ -289,7 +289,8 @@ struct dml2_per_stream_programming {
		union dml2_global_sync_programming global_sync;
	} phantom_stream;

	struct dmub_fams2_stream_static_state fams2_params;
	union dmub_cmd_fams2_config fams2_base_params;
	union dmub_cmd_fams2_config fams2_sub_params;
};

//-----------------
Loading