Commit 3b00b53a authored by Jani Nikula's avatar Jani Nikula
Browse files

drm/dp: extract drm_dp_dpcd_write_payload()



SST with 128b/132b channel coding needs this too. Extract to a separate
helper, independent of MST.

v2: Clean up kernel-doc a bit

Cc: Lyude Paul <lyude@redhat.com>
Reviewed-by: default avatarImre Deak <imre.deak@intel.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/f626715ba4e348546770750aa3e10fac73a5cbd7.1733238941.git.jani.nikula@intel.com


Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
parent f2663f70
Loading
Loading
Loading
Loading
+57 −0
Original line number Diff line number Diff line
@@ -792,6 +792,63 @@ static int read_payload_update_status(struct drm_dp_aux *aux)
	return status;
}

/**
 * drm_dp_dpcd_write_payload() - Write Virtual Channel information to payload table
 * @aux: DisplayPort AUX channel
 * @vcpid: Virtual Channel Payload ID
 * @start_time_slot: Starting time slot
 * @time_slot_count: Time slot count
 *
 * Write the Virtual Channel payload allocation table, checking the payload
 * update status and retrying as necessary.
 *
 * Returns:
 * 0 on success, negative error otherwise
 */
int drm_dp_dpcd_write_payload(struct drm_dp_aux *aux,
			      int vcpid, u8 start_time_slot, u8 time_slot_count)
{
	u8 payload_alloc[3], status;
	int ret;
	int retries = 0;

	drm_dp_dpcd_writeb(aux, DP_PAYLOAD_TABLE_UPDATE_STATUS,
			   DP_PAYLOAD_TABLE_UPDATED);

	payload_alloc[0] = vcpid;
	payload_alloc[1] = start_time_slot;
	payload_alloc[2] = time_slot_count;

	ret = drm_dp_dpcd_write(aux, DP_PAYLOAD_ALLOCATE_SET, payload_alloc, 3);
	if (ret != 3) {
		drm_dbg_kms(aux->drm_dev, "failed to write payload allocation %d\n", ret);
		goto fail;
	}

retry:
	ret = drm_dp_dpcd_readb(aux, DP_PAYLOAD_TABLE_UPDATE_STATUS, &status);
	if (ret < 0) {
		drm_dbg_kms(aux->drm_dev, "failed to read payload table status %d\n", ret);
		goto fail;
	}

	if (!(status & DP_PAYLOAD_TABLE_UPDATED)) {
		retries++;
		if (retries < 20) {
			usleep_range(10000, 20000);
			goto retry;
		}
		drm_dbg_kms(aux->drm_dev, "status not set after read payload table status %d\n",
			    status);
		ret = -EINVAL;
		goto fail;
	}
	ret = 0;
fail:
	return ret;
}
EXPORT_SYMBOL(drm_dp_dpcd_write_payload);

/**
 * drm_dp_dpcd_poll_act_handled() - Poll for ACT handled status
 * @aux: DisplayPort AUX channel
+3 −49
Original line number Diff line number Diff line
@@ -67,9 +67,6 @@ static bool dump_dp_payload_table(struct drm_dp_mst_topology_mgr *mgr,

static void drm_dp_mst_topology_put_port(struct drm_dp_mst_port *port);

static int drm_dp_dpcd_write_payload(struct drm_dp_mst_topology_mgr *mgr,
				     int id, u8 start_slot, u8 num_slots);

static int drm_dp_send_dpcd_read(struct drm_dp_mst_topology_mgr *mgr,
				 struct drm_dp_mst_port *port,
				 int offset, int size, u8 *bytes);
@@ -3263,7 +3260,7 @@ EXPORT_SYMBOL(drm_dp_send_query_stream_enc_status);
static int drm_dp_create_payload_at_dfp(struct drm_dp_mst_topology_mgr *mgr,
					struct drm_dp_mst_atomic_payload *payload)
{
	return drm_dp_dpcd_write_payload(mgr, payload->vcpi, payload->vc_start_slot,
	return drm_dp_dpcd_write_payload(mgr->aux, payload->vcpi, payload->vc_start_slot,
					 payload->time_slots);
}

@@ -3294,7 +3291,7 @@ static void drm_dp_destroy_payload_at_remote_and_dfp(struct drm_dp_mst_topology_
	}

	if (payload->payload_allocation_status == DRM_DP_MST_PAYLOAD_ALLOCATION_DFP)
		drm_dp_dpcd_write_payload(mgr, payload->vcpi, payload->vc_start_slot, 0);
		drm_dp_dpcd_write_payload(mgr->aux, payload->vcpi, payload->vc_start_slot, 0);
}

/**
@@ -3682,7 +3679,7 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms
			goto out_unlock;

		/* Write reset payload */
		drm_dp_dpcd_write_payload(mgr, 0, 0, 0x3f);
		drm_dp_dpcd_write_payload(mgr->aux, 0, 0, 0x3f);

		drm_dp_mst_queue_probe_work(mgr);

@@ -4679,49 +4676,6 @@ void drm_dp_mst_update_slots(struct drm_dp_mst_topology_state *mst_state, uint8_
}
EXPORT_SYMBOL(drm_dp_mst_update_slots);

static int drm_dp_dpcd_write_payload(struct drm_dp_mst_topology_mgr *mgr,
				     int id, u8 start_slot, u8 num_slots)
{
	u8 payload_alloc[3], status;
	int ret;
	int retries = 0;

	drm_dp_dpcd_writeb(mgr->aux, DP_PAYLOAD_TABLE_UPDATE_STATUS,
			   DP_PAYLOAD_TABLE_UPDATED);

	payload_alloc[0] = id;
	payload_alloc[1] = start_slot;
	payload_alloc[2] = num_slots;

	ret = drm_dp_dpcd_write(mgr->aux, DP_PAYLOAD_ALLOCATE_SET, payload_alloc, 3);
	if (ret != 3) {
		drm_dbg_kms(mgr->dev, "failed to write payload allocation %d\n", ret);
		goto fail;
	}

retry:
	ret = drm_dp_dpcd_readb(mgr->aux, DP_PAYLOAD_TABLE_UPDATE_STATUS, &status);
	if (ret < 0) {
		drm_dbg_kms(mgr->dev, "failed to read payload table status %d\n", ret);
		goto fail;
	}

	if (!(status & DP_PAYLOAD_TABLE_UPDATED)) {
		retries++;
		if (retries < 20) {
			usleep_range(10000, 20000);
			goto retry;
		}
		drm_dbg_kms(mgr->dev, "status not set after read payload table status %d\n",
			    status);
		ret = -EINVAL;
		goto fail;
	}
	ret = 0;
fail:
	return ret;
}

/**
 * drm_dp_check_act_status() - Polls for ACT handled status.
 * @mgr: manager to use
+2 −0
Original line number Diff line number Diff line
@@ -567,6 +567,8 @@ int drm_dp_dpcd_read_phy_link_status(struct drm_dp_aux *aux,
				     enum drm_dp_phy dp_phy,
				     u8 link_status[DP_LINK_STATUS_SIZE]);

int drm_dp_dpcd_write_payload(struct drm_dp_aux *aux,
			      int vcpid, u8 start_time_slot, u8 time_slot_count);
int drm_dp_dpcd_poll_act_handled(struct drm_dp_aux *aux, int timeout_ms);

bool drm_dp_send_real_edid_checksum(struct drm_dp_aux *aux,