Commit d9a07577 authored by Jun Lei's avatar Jun Lei Committed by Alex Deucher
Browse files

drm/amd/display: add oem i2c implemenation in dc



[why]
Need it for some OEM I2C devices in Nv10

[how]
Link up code to parse OEM table and expose DC interface
to access the pins

Signed-off-by: default avatarJun Lei <Jun.Lei@amd.com>
Reviewed-by: default avatarAric Cyr <Aric.Cyr@amd.com>
Acked-by: default avatarBhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent ae8cf977
Loading
Loading
Loading
Loading
+39 −24
Original line number Diff line number Diff line
@@ -294,11 +294,21 @@ static enum bp_result bios_parser_get_i2c_info(struct dc_bios *dcb,
	struct atom_display_object_path_v2 *object;
	struct atom_common_record_header *header;
	struct atom_i2c_record *record;
	struct atom_i2c_record dummy_record = {0};
	struct bios_parser *bp = BP_FROM_DCB(dcb);

	if (!info)
		return BP_RESULT_BADINPUT;

	if (id.type == OBJECT_TYPE_GENERIC) {
		dummy_record.i2c_id = id.id;

		if (get_gpio_i2c_info(bp, &dummy_record, info) == BP_RESULT_OK)
			return BP_RESULT_OK;
		else
			return BP_RESULT_NORECORD;
	}

	object = get_bios_object(bp, id);

	if (!object)
@@ -341,6 +351,7 @@ static enum bp_result get_gpio_i2c_info(
	struct atom_gpio_pin_lut_v2_1 *header;
	uint32_t count = 0;
	unsigned int table_index = 0;
	bool find_valid = false;

	if (!info)
		return BP_RESULT_BADINPUT;
@@ -368,11 +379,6 @@ static enum bp_result get_gpio_i2c_info(
			- sizeof(struct atom_common_table_header))
				/ sizeof(struct atom_gpio_pin_assignment);

	table_index = record->i2c_id  & I2C_HW_LANE_MUX;

	if (count < table_index) {
		bool find_valid = false;

	for (table_index = 0; table_index < count; table_index++) {
		if (((record->i2c_id & I2C_HW_CAP) == (
		header->gpio_pin[table_index].gpio_id &
@@ -388,12 +394,12 @@ static enum bp_result get_gpio_i2c_info(
			break;
		}
	}

	/* If we don't find the entry that we are looking for then
	 *  we will return BP_Result_BadBiosTable.
	 */
	if (find_valid == false)
		return BP_RESULT_BADBIOSTABLE;
	}

	/* get the GPIO_I2C_INFO */
	info->i2c_hw_assist = (record->i2c_id & I2C_HW_CAP) ? true : false;
@@ -1205,6 +1211,8 @@ static enum bp_result get_firmware_info_v3_1(
				bp->cmd_tbl.get_smu_clock_info(bp, SMU9_SYSPLL0_ID) * 10;
	}

	info->oem_i2c_present = false;

	return BP_RESULT_OK;
}

@@ -1283,6 +1291,13 @@ static enum bp_result get_firmware_info_v3_2(
					bp->cmd_tbl.get_smu_clock_info(bp, SMU11_SYSPLL3_0_ID) * 10;
	}

	if (firmware_info->board_i2c_feature_id == 0x2) {
		info->oem_i2c_present = true;
		info->oem_i2c_obj_id = firmware_info->board_i2c_feature_gpio_id;
	} else {
		info->oem_i2c_present = false;
	}

	return BP_RESULT_OK;
}

+11 −0
Original line number Diff line number Diff line
@@ -2502,6 +2502,17 @@ bool dc_submit_i2c(
		cmd);
}

bool dc_submit_i2c_oem(
		struct dc *dc,
		struct i2c_command *cmd)
{
	struct ddc_service *ddc = dc->res_pool->oem_device;
	return dce_i2c_submit_command(
		dc->res_pool,
		ddc->ddc_pin,
		cmd);
}

static bool link_add_remote_sink_helper(struct dc_link *dc_link, struct dc_sink *sink)
{
	if (dc_link->sink_count >= MAX_SINKS_PER_LINK) {
+4 −1
Original line number Diff line number Diff line
@@ -206,7 +206,10 @@ static void construct(
		ddc_service->ddc_pin = NULL;
	} else {
		hw_info.ddc_channel = i2c_info.i2c_line;
		if (ddc_service->link != NULL)
			hw_info.hw_supported = i2c_info.i2c_hw_assist;
		else
			hw_info.hw_supported = false;

		ddc_service->ddc_pin = dal_gpio_create_ddc(
			gpio_service,
+4 −0
Original line number Diff line number Diff line
@@ -305,6 +305,10 @@ bool dc_submit_i2c(
		uint32_t link_index,
		struct i2c_command *cmd);

bool dc_submit_i2c_oem(
		struct dc *dc,
		struct i2c_command *cmd);

uint32_t dc_bandwidth_in_kbps_from_timing(
	const struct dc_crtc_timing *timing);
#endif /* DC_LINK_H_ */
+8 −11
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@ bool dce_i2c_submit_command(
	struct i2c_command *cmd)
{
	struct dce_i2c_hw *dce_i2c_hw;
	struct dce_i2c_sw *dce_i2c_sw;
	struct dce_i2c_sw dce_i2c_sw = {0};

	if (!ddc) {
		BREAK_TO_DEBUGGER();
@@ -43,18 +43,15 @@ bool dce_i2c_submit_command(
		return false;
	}

	/* The software engine is only available on dce8 */
	dce_i2c_sw = dce_i2c_acquire_i2c_sw_engine(pool, ddc);

	if (!dce_i2c_sw) {
	dce_i2c_hw = acquire_i2c_hw_engine(pool, ddc);

		if (!dce_i2c_hw)
			return false;

	if (dce_i2c_hw)
		return dce_i2c_submit_command_hw(pool, ddc, cmd, dce_i2c_hw);
	}

	return dce_i2c_submit_command_sw(pool, ddc, cmd, dce_i2c_sw);
	dce_i2c_sw.ctx = ddc->ctx;
	if (dce_i2c_engine_acquire_sw(&dce_i2c_sw, ddc)) {
		return dce_i2c_submit_command_sw(pool, ddc, cmd, &dce_i2c_sw);
	}

	return false;
}
Loading