Commit 0b4e477e authored by Lyude Paul's avatar Lyude Paul
Browse files

drm/display/dp_mst: Add helper for finding payloads in atomic MST state



We already open-code this quite often, and will be iterating through
payloads even more once we've moved all of the payload tracking into the
atomic state. So, let's add a helper for doing this.

Signed-off-by: default avatarLyude Paul <lyude@redhat.com>
Cc: Wayne Lin <Wayne.Lin@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Fangzhi Zuo <Jerry.Zuo@amd.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Imre Deak <imre.deak@intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Sean Paul <sean@poorly.run>
Acked-by: default avatarJani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220817193847.557945-8-lyude@redhat.com
parent 0bee2ae2
Loading
Loading
Loading
Loading
+45 −64
Original line number Diff line number Diff line
@@ -1738,6 +1738,19 @@ drm_dp_mst_dump_port_topology_history(struct drm_dp_mst_port *port) {}
#define save_port_topology_ref(port, type)
#endif

static struct drm_dp_mst_atomic_payload *
drm_atomic_get_mst_payload_state(struct drm_dp_mst_topology_state *state,
				 struct drm_dp_mst_port *port)
{
	struct drm_dp_mst_atomic_payload *payload;

	list_for_each_entry(payload, &state->payloads, next)
		if (payload->port == port)
			return payload;

	return NULL;
}

static void drm_dp_destroy_mst_branch_device(struct kref *kref)
{
	struct drm_dp_mst_branch *mstb =
@@ -4370,17 +4383,16 @@ int drm_dp_atomic_find_time_slots(struct drm_atomic_state *state,
				  int pbn_div)
{
	struct drm_dp_mst_topology_state *topology_state;
	struct drm_dp_mst_atomic_payload *pos, *payload = NULL;
	int prev_slots, prev_bw, req_slots;
	struct drm_dp_mst_atomic_payload *payload = NULL;
	int prev_slots = 0, prev_bw = 0, req_slots;

	topology_state = drm_atomic_get_mst_topology_state(state, mgr);
	if (IS_ERR(topology_state))
		return PTR_ERR(topology_state);

	/* Find the current allocation for this port, if any */
	list_for_each_entry(pos, &topology_state->payloads, next) {
		if (pos->port == port) {
			payload = pos;
	payload = drm_atomic_get_mst_payload_state(topology_state, port);
	if (payload) {
		prev_slots = payload->time_slots;
		prev_bw = payload->pbn;

@@ -4395,13 +4407,6 @@ int drm_dp_atomic_find_time_slots(struct drm_atomic_state *state,
				port);
			return -EINVAL;
		}

			break;
		}
	}
	if (!payload) {
		prev_slots = 0;
		prev_bw = 0;
	}

	if (pbn_div <= 0)
@@ -4463,30 +4468,24 @@ int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state,
				     struct drm_dp_mst_port *port)
{
	struct drm_dp_mst_topology_state *topology_state;
	struct drm_dp_mst_atomic_payload *pos;
	bool found = false;
	struct drm_dp_mst_atomic_payload *payload;

	topology_state = drm_atomic_get_mst_topology_state(state, mgr);
	if (IS_ERR(topology_state))
		return PTR_ERR(topology_state);

	list_for_each_entry(pos, &topology_state->payloads, next) {
		if (pos->port == port) {
			found = true;
			break;
		}
	}
	if (WARN_ON(!found)) {
	payload = drm_atomic_get_mst_payload_state(topology_state, port);
	if (WARN_ON(!payload)) {
		drm_err(mgr->dev, "No payload for [MST PORT:%p] found in mst state %p\n",
			port, &topology_state->base);
		return -EINVAL;
	}

	drm_dbg_atomic(mgr->dev, "[MST PORT:%p] TU %d -> 0\n", port, pos->time_slots);
	if (pos->time_slots) {
	drm_dbg_atomic(mgr->dev, "[MST PORT:%p] TU %d -> 0\n", port, payload->time_slots);
	if (payload->time_slots) {
		drm_dp_mst_put_port_malloc(port);
		pos->time_slots = 0;
		pos->pbn = 0;
		payload->time_slots = 0;
		payload->pbn = 0;
	}

	return 0;
@@ -5182,18 +5181,8 @@ drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port,
		return 0;

	if (drm_dp_mst_is_end_device(port->pdt, port->mcs)) {
		bool found = false;

		list_for_each_entry(payload, &state->payloads, next) {
			if (payload->port != port)
				continue;
			if (!payload->pbn)
				return 0;

			found = true;
			break;
		}
		if (!found)
		payload = drm_atomic_get_mst_payload_state(state, port);
		if (!payload)
			return 0;

		/*
@@ -5348,34 +5337,26 @@ int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state,
				 bool enable)
{
	struct drm_dp_mst_topology_state *mst_state;
	struct drm_dp_mst_atomic_payload *pos;
	bool found = false;
	struct drm_dp_mst_atomic_payload *payload;
	int time_slots = 0;

	mst_state = drm_atomic_get_mst_topology_state(state, port->mgr);

	if (IS_ERR(mst_state))
		return PTR_ERR(mst_state);

	list_for_each_entry(pos, &mst_state->payloads, next) {
		if (pos->port == port) {
			found = true;
			break;
		}
	}

	if (!found) {
	payload = drm_atomic_get_mst_payload_state(mst_state, port);
	if (!payload) {
		drm_dbg_atomic(state->dev,
			       "[MST PORT:%p] Couldn't find payload in mst state %p\n",
			       port, mst_state);
		return -EINVAL;
	}

	if (pos->dsc_enabled == enable) {
	if (payload->dsc_enabled == enable) {
		drm_dbg_atomic(state->dev,
			       "[MST PORT:%p] DSC flag is already set to %d, returning %d time slots\n",
			       port, enable, pos->time_slots);
		time_slots = pos->time_slots;
			       port, enable, payload->time_slots);
		time_slots = payload->time_slots;
	}

	if (enable) {
@@ -5387,7 +5368,7 @@ int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state,
			return -EINVAL;
	}

	pos->dsc_enabled = enable;
	payload->dsc_enabled = enable;

	return time_slots;
}