All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeykumar Sankaran <jsanka-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
To: Sean Paul <seanpaul-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
Cc: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	abhinavk-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org,
	robdclark-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
	hoegsberg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
Subject: Re: [DPU PATCH 11/11] drm/msm: Remove dpu input fences
Date: Fri, 02 Mar 2018 16:50:37 -0800	[thread overview]
Message-ID: <95e182e0c7589d1e19d4aaea1acc9c37@codeaurora.org> (raw)
In-Reply-To: <20180228191906.185417-12-seanpaul-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>

On 2018-02-28 11:19, Sean Paul wrote:
> These are already provided by drm atomic core.
> 
> In conjunction with the output fences removed earlier, this obsoletes
> dpu_fence, and it can be entirely removed as well.
> 
> Change-Id: Ida4924a09c455d7a84bfee569bd0d2fb436418de
> Signed-off-by: Sean Paul <seanpaul@chromium.org>

Reviewed-by: Jeykumar Sankaran <jsanka@codeaurora.org>

> ---
>  drivers/gpu/drm/msm/Makefile              |   1 -
>  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  |  84 -----
>  drivers/gpu/drm/msm/disp/dpu1/dpu_fence.c | 404 ----------------------
>  drivers/gpu/drm/msm/disp/dpu1/dpu_fence.h | 190 ----------
>  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 104 ------
>  drivers/gpu/drm/msm/msm_drv.h             |   4 +-
>  6 files changed, 1 insertion(+), 786 deletions(-)
>  delete mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_fence.c
>  delete mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_fence.h
> 
> diff --git a/drivers/gpu/drm/msm/Makefile 
> b/drivers/gpu/drm/msm/Makefile
> index 2fb9ba11df19..b47ef5267e19 100644
> --- a/drivers/gpu/drm/msm/Makefile
> +++ b/drivers/gpu/drm/msm/Makefile
> @@ -55,7 +55,6 @@ msm-y := \
>  	disp/dpu1/dpu_encoder.o \
>  	disp/dpu1/dpu_encoder_phys_cmd.o \
>  	disp/dpu1/dpu_encoder_phys_vid.o \
> -	disp/dpu1/dpu_fence.o \
>  	disp/dpu1/dpu_formats.o \
>  	disp/dpu1/dpu_hw_ad4.o \
>  	disp/dpu1/dpu_hw_blk.o \
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index 2d44989ade7a..8dd986e476bd 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -64,16 +64,6 @@ static struct dpu_crtc_custom_events custom_events[] 
> =
> {
>  	{DRM_EVENT_IDLE_NOTIFY, dpu_crtc_idle_interrupt_handler}
>  };
> 
> -/* default input fence timeout, in ms */
> -#define DPU_CRTC_INPUT_FENCE_TIMEOUT    10000
> -
> -/*
> - * The default input fence timeout is 2 seconds while max allowed
> - * range is 10 seconds. Any value above 10 seconds adds glitches 
> beyond
> - * tolerance limit.
> - */
> -#define DPU_CRTC_MAX_INPUT_FENCE_TIMEOUT 10000
> -
>  /* layer mixer index on dpu_crtc */
>  #define LEFT_MIXER 0
>  #define RIGHT_MIXER 1
> @@ -1946,21 +1936,6 @@ static void _dpu_crtc_set_idle_timeout(struct
> drm_crtc *crtc, u64 val)
>  	}
>  }
> 
> -/**
> - * _dpu_crtc_set_input_fence_timeout - update ns version of in fence
> timeout
> - * @cstate: Pointer to dpu crtc state
> - */
> -static void _dpu_crtc_set_input_fence_timeout(struct dpu_crtc_state
> *cstate)
> -{
> -	if (!cstate) {
> -		DPU_ERROR("invalid cstate\n");
> -		return;
> -	}
> -	cstate->input_fence_timeout_ns =
> -		dpu_crtc_get_property(cstate,
> CRTC_PROP_INPUT_FENCE_TIMEOUT);
> -	cstate->input_fence_timeout_ns *= NSEC_PER_MSEC;
> -}
> -
>  /**
>   * _dpu_crtc_set_dim_layer_v1 - copy dim layer settings from userspace
>   * @cstate:      Pointer to dpu crtc state
> @@ -2385,53 +2360,6 @@ static int 
> _dpu_crtc_check_dest_scaler_data(struct
> drm_crtc *crtc,
>  	return ret;
>  }
> 
> -/**
> - * _dpu_crtc_wait_for_fences - wait for incoming framebuffer sync 
> fences
> - * @crtc: Pointer to CRTC object
> - */
> -static void _dpu_crtc_wait_for_fences(struct drm_crtc *crtc)
> -{
> -	struct drm_plane *plane = NULL;
> -	uint32_t wait_ms = 1;
> -	ktime_t kt_end, kt_wait;
> -	int rc = 0;
> -
> -	DPU_DEBUG("\n");
> -
> -	if (!crtc || !crtc->state) {
> -		DPU_ERROR("invalid crtc/state %pK\n", crtc);
> -		return;
> -	}
> -
> -	/* use monotonic timer to limit total fence wait time */
> -	kt_end = ktime_add_ns(ktime_get(),
> -		to_dpu_crtc_state(crtc->state)->input_fence_timeout_ns);
> -
> -	/*
> -	 * Wait for fences sequentially, as all of them need to be
> signalled
> -	 * before we can proceed.
> -	 *
> -	 * Limit total wait time to INPUT_FENCE_TIMEOUT, but still call
> -	 * dpu_plane_wait_input_fence with wait_ms == 0 after the timeout
> so
> -	 * that each plane can check its fence status and react
> appropriately
> -	 * if its fence has timed out. Call input fence wait multiple
> times if
> -	 * fence wait is interrupted due to interrupt call.
> -	 */
> -	DPU_ATRACE_BEGIN("plane_wait_input_fence");
> -	drm_atomic_crtc_for_each_plane(plane, crtc) {
> -		do {
> -			kt_wait = ktime_sub(kt_end, ktime_get());
> -			if (ktime_compare(kt_wait, ktime_set(0, 0)) >= 0)
> -				wait_ms = ktime_to_ms(kt_wait);
> -			else
> -				wait_ms = 0;
> -
> -			rc = dpu_plane_wait_input_fence(plane, wait_ms);
> -		} while (wait_ms && rc == -ERESTARTSYS);
> -	}
> -	DPU_ATRACE_END("plane_wait_input_fence");
> -}
> -
>  static void _dpu_crtc_setup_mixer_for_encoder(
>  		struct drm_crtc *crtc,
>  		struct drm_encoder *enc)
> @@ -2716,9 +2644,6 @@ static void dpu_crtc_atomic_flush(struct drm_crtc
> *crtc,
>  	drm_atomic_crtc_for_each_plane(plane, crtc)
>  		dpu_plane_restore(plane);
> 
> -	/* wait for acquire fences before anything else is done */
> -	_dpu_crtc_wait_for_fences(crtc);
> -
>  	if (!cstate->rsc_update) {
>  		drm_for_each_encoder(encoder, dev) {
>  			if (encoder->crtc != crtc)
> @@ -3178,8 +3103,6 @@ static void dpu_crtc_reset(struct drm_crtc *crtc)
>  			&cstate->property_state,
>  			cstate->property_values);
> 
> -	_dpu_crtc_set_input_fence_timeout(cstate);
> -
>  	_dpu_crtc_rp_reset(&cstate->rp, &dpu_crtc->rp_lock,
>  			&dpu_crtc->rp_head);
> 
> @@ -3929,10 +3852,6 @@ static void dpu_crtc_install_properties(struct
> drm_crtc *crtc,
>  	}
> 
>  	/* range properties */
> -	msm_property_install_range(&dpu_crtc->property_info,
> -		"input_fence_timeout", 0x0, 0,
> DPU_CRTC_MAX_INPUT_FENCE_TIMEOUT,
> -		DPU_CRTC_INPUT_FENCE_TIMEOUT,
> CRTC_PROP_INPUT_FENCE_TIMEOUT);
> -
>  	msm_property_install_range(&dpu_crtc->property_info,
>  			"core_clk", 0x0, 0, U64_MAX,
>  			dpu_kms->perf.max_core_clk_rate,
> @@ -4121,9 +4040,6 @@ static int dpu_crtc_atomic_set_property(struct
> drm_crtc *crtc,
>  			idx = msm_property_index(&dpu_crtc->property_info,
>  					property);
>  			switch (idx) {
> -			case CRTC_PROP_INPUT_FENCE_TIMEOUT:
> -				_dpu_crtc_set_input_fence_timeout(cstate);
> -				break;
>  			case CRTC_PROP_DIM_LAYER_V1:
>  				_dpu_crtc_set_dim_layer_v1(cstate,
>  							(void __user
> *)val);
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_fence.c
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_fence.c
> deleted file mode 100644
> index 49ffd7138eba..000000000000
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_fence.c
> +++ /dev/null
> @@ -1,404 +0,0 @@
> -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
> - *
> - * This program is free software; you can redistribute it and/or 
> modify
> - * it under the terms of the GNU General Public License version 2 and
> - * only version 2 as published by the Free Software Foundation.
> - *
> - * This program is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - * GNU General Public License for more details.
> - */
> -
> -#include <linux/sync_file.h>
> -#include <linux/dma-fence.h>
> -#include "msm_drv.h"
> -#include "dpu_kms.h"
> -#include "dpu_fence.h"
> -
> -#define TIMELINE_VAL_LENGTH		128
> -
> -void *dpu_sync_get(uint64_t fd)
> -{
> -	/* force signed compare, fdget accepts an int argument */
> -	return (signed int)fd >= 0 ? sync_file_get_fence(fd) : NULL;
> -}
> -
> -void dpu_sync_put(void *fence)
> -{
> -	if (fence)
> -		dma_fence_put(fence);
> -}
> -
> -signed long dpu_sync_wait(void *fnc, long timeout_ms)
> -{
> -	struct dma_fence *fence = fnc;
> -	int rc;
> -	char timeline_str[TIMELINE_VAL_LENGTH];
> -
> -	if (!fence)
> -		return -EINVAL;
> -	else if (dma_fence_is_signaled(fence))
> -		return timeout_ms ? msecs_to_jiffies(timeout_ms) : 1;
> -
> -	rc = dma_fence_wait_timeout(fence, true,
> -				msecs_to_jiffies(timeout_ms));
> -	if (!rc || (rc == -EINVAL)) {
> -		if (fence->ops->timeline_value_str)
> -			fence->ops->timeline_value_str(fence,
> -					timeline_str,
> TIMELINE_VAL_LENGTH);
> -
> -		DPU_ERROR(
> -			"fence driver name:%s timeline name:%s seqno:0x%x
> timeline:%s signaled:0x%x\n",
> -			fence->ops->get_driver_name(fence),
> -			fence->ops->get_timeline_name(fence),
> -			fence->seqno, timeline_str,
> -			fence->ops->signaled ?
> -				fence->ops->signaled(fence) : 0xffffffff);
> -	}
> -
> -	return rc;
> -}
> -
> -uint32_t dpu_sync_get_name_prefix(void *fence)
> -{
> -	const char *name;
> -	uint32_t i, prefix;
> -	struct dma_fence *f = fence;
> -
> -	if (!fence)
> -		return 0;
> -
> -	name = f->ops->get_driver_name(f);
> -	if (!name)
> -		return 0;
> -
> -	prefix = 0x0;
> -	for (i = 0; i < sizeof(uint32_t) && name[i]; ++i)
> -		prefix = (prefix << CHAR_BIT) | name[i];
> -
> -	return prefix;
> -}
> -
> -/**
> - * struct dpu_fence - release/retire fence structure
> - * @fence: base fence structure
> - * @name: name of each fence- it is fence timeline + commit_count
> - * @fence_list: list to associated this fence on timeline/context
> - * @fd: fd attached to this fence - debugging purpose.
> - */
> -struct dpu_fence {
> -	struct dma_fence base;
> -	struct dpu_fence_context *ctx;
> -	char name[DPU_FENCE_NAME_SIZE];
> -	struct list_head	fence_list;
> -	int fd;
> -};
> -
> -static void dpu_fence_destroy(struct kref *kref)
> -{
> -}
> -
> -static inline struct dpu_fence *to_dpu_fence(struct dma_fence *fence)
> -{
> -	return container_of(fence, struct dpu_fence, base);
> -}
> -
> -static const char *dpu_fence_get_driver_name(struct dma_fence *fence)
> -{
> -	struct dpu_fence *f = to_dpu_fence(fence);
> -
> -	return f->name;
> -}
> -
> -static const char *dpu_fence_get_timeline_name(struct dma_fence 
> *fence)
> -{
> -	struct dpu_fence *f = to_dpu_fence(fence);
> -
> -	return f->ctx->name;
> -}
> -
> -static bool dpu_fence_enable_signaling(struct dma_fence *fence)
> -{
> -	return true;
> -}
> -
> -static bool dpu_fence_signaled(struct dma_fence *fence)
> -{
> -	struct dpu_fence *f = to_dpu_fence(fence);
> -	bool status;
> -
> -	status = (int)(fence->seqno - f->ctx->done_count) <= 0 ? true :
> false;
> -	DPU_DEBUG("status:%d fence seq:%d and timeline:%d\n",
> -			status, fence->seqno, f->ctx->done_count);
> -	return status;
> -}
> -
> -static void dpu_fence_release(struct dma_fence *fence)
> -{
> -	struct dpu_fence *f;
> -
> -	if (fence) {
> -		f = to_dpu_fence(fence);
> -		kfree(f);
> -	}
> -}
> -
> -static void dpu_fence_value_str(struct dma_fence *fence, char *str, 
> int
> size)
> -{
> -	if (!fence || !str)
> -		return;
> -
> -	snprintf(str, size, "%d", fence->seqno);
> -}
> -
> -static void dpu_fence_timeline_value_str(struct dma_fence *fence, char
> *str,
> -		int size)
> -{
> -	struct dpu_fence *f = to_dpu_fence(fence);
> -
> -	if (!fence || !f->ctx || !str)
> -		return;
> -
> -	snprintf(str, size, "%d", f->ctx->done_count);
> -}
> -
> -static struct dma_fence_ops dpu_fence_ops = {
> -	.get_driver_name = dpu_fence_get_driver_name,
> -	.get_timeline_name = dpu_fence_get_timeline_name,
> -	.enable_signaling = dpu_fence_enable_signaling,
> -	.signaled = dpu_fence_signaled,
> -	.wait = dma_fence_default_wait,
> -	.release = dpu_fence_release,
> -	.fence_value_str = dpu_fence_value_str,
> -	.timeline_value_str = dpu_fence_timeline_value_str,
> -};
> -
> -/**
> - * _dpu_fence_create_fd - create fence object and return an fd for it
> - * This function is NOT thread-safe.
> - * @timeline: Timeline to associate with fence
> - * @val: Timeline value at which to signal the fence
> - * Return: File descriptor on success, or error code on error
> - */
> -static int _dpu_fence_create_fd(void *fence_ctx, uint32_t val)
> -{
> -	struct dpu_fence *dpu_fence;
> -	struct sync_file *sync_file;
> -	signed int fd = -EINVAL;
> -	struct dpu_fence_context *ctx = fence_ctx;
> -
> -	if (!ctx) {
> -		DPU_ERROR("invalid context\n");
> -		goto exit;
> -	}
> -
> -	dpu_fence = kzalloc(sizeof(*dpu_fence), GFP_KERNEL);
> -	if (!dpu_fence)
> -		return -ENOMEM;
> -
> -	dpu_fence->ctx = fence_ctx;
> -	snprintf(dpu_fence->name, DPU_FENCE_NAME_SIZE, "dpu_fence:%s:%u",
> -						dpu_fence->ctx->name,
> val);
> -	dma_fence_init(&dpu_fence->base, &dpu_fence_ops, &ctx->lock,
> -		ctx->context, val);
> -
> -	/* create fd */
> -	fd = get_unused_fd_flags(0);
> -	if (fd < 0) {
> -		dma_fence_put(&dpu_fence->base);
> -		DPU_ERROR("failed to get_unused_fd_flags(), %s\n",
> -							dpu_fence->name);
> -		goto exit;
> -	}
> -
> -	/* create fence */
> -	sync_file = sync_file_create(&dpu_fence->base);
> -	if (sync_file == NULL) {
> -		put_unused_fd(fd);
> -		fd = -EINVAL;
> -		dma_fence_put(&dpu_fence->base);
> -		DPU_ERROR("couldn't create fence, %s\n", dpu_fence->name);
> -		goto exit;
> -	}
> -
> -	fd_install(fd, sync_file->file);
> -	dpu_fence->fd = fd;
> -	kref_get(&ctx->kref);
> -
> -	spin_lock(&ctx->list_lock);
> -	list_add_tail(&dpu_fence->fence_list, &ctx->fence_list_head);
> -	spin_unlock(&ctx->list_lock);
> -
> -exit:
> -	return fd;
> -}
> -
> -int dpu_fence_init(struct dpu_fence_context *ctx,
> -		const char *name, uint32_t drm_id)
> -{
> -	if (!ctx || !name) {
> -		DPU_ERROR("invalid argument(s)\n");
> -		return -EINVAL;
> -	}
> -	memset(ctx, 0, sizeof(*ctx));
> -
> -	strlcpy(ctx->name, name, ARRAY_SIZE(ctx->name));
> -	ctx->drm_id = drm_id;
> -	kref_init(&ctx->kref);
> -	ctx->context = dma_fence_context_alloc(1);
> -
> -	spin_lock_init(&ctx->lock);
> -	spin_lock_init(&ctx->list_lock);
> -	INIT_LIST_HEAD(&ctx->fence_list_head);
> -
> -	return 0;
> -}
> -
> -void dpu_fence_deinit(struct dpu_fence_context *ctx)
> -{
> -	if (!ctx) {
> -		DPU_ERROR("invalid fence\n");
> -		return;
> -	}
> -
> -	kref_put(&ctx->kref, dpu_fence_destroy);
> -}
> -
> -void dpu_fence_prepare(struct dpu_fence_context *ctx)
> -{
> -	unsigned long flags;
> -
> -	if (!ctx) {
> -		DPU_ERROR("invalid argument(s), fence %pK\n", ctx);
> -	} else {
> -		spin_lock_irqsave(&ctx->lock, flags);
> -		++ctx->commit_count;
> -		spin_unlock_irqrestore(&ctx->lock, flags);
> -	}
> -}
> -
> -static void _dpu_fence_trigger(struct dpu_fence_context *ctx, ktime_t 
> ts)
> -{
> -	unsigned long flags;
> -	struct dpu_fence *fc, *next;
> -	bool is_signaled = false;
> -	struct list_head local_list_head;
> -
> -	INIT_LIST_HEAD(&local_list_head);
> -
> -	spin_lock(&ctx->list_lock);
> -	if (list_empty(&ctx->fence_list_head)) {
> -		DPU_DEBUG("nothing to trigger!\n");
> -		spin_unlock(&ctx->list_lock);
> -		return;
> -	}
> -
> -	list_for_each_entry_safe(fc, next, &ctx->fence_list_head,
> fence_list)
> -		list_move(&fc->fence_list, &local_list_head);
> -	spin_unlock(&ctx->list_lock);
> -
> -	list_for_each_entry_safe(fc, next, &local_list_head, fence_list) {
> -		spin_lock_irqsave(&ctx->lock, flags);
> -		fc->base.timestamp = ts;
> -		is_signaled = dma_fence_is_signaled_locked(&fc->base);
> -		spin_unlock_irqrestore(&ctx->lock, flags);
> -
> -		if (is_signaled) {
> -			list_del_init(&fc->fence_list);
> -			dma_fence_put(&fc->base);
> -			kref_put(&ctx->kref, dpu_fence_destroy);
> -		} else {
> -			spin_lock(&ctx->list_lock);
> -			list_move(&fc->fence_list, &ctx->fence_list_head);
> -			spin_unlock(&ctx->list_lock);
> -		}
> -	}
> -}
> -
> -int dpu_fence_create(struct dpu_fence_context *ctx, uint64_t *val,
> -							uint32_t offset)
> -{
> -	uint32_t trigger_value;
> -	int fd, rc = -EINVAL;
> -	unsigned long flags;
> -
> -	if (!ctx || !val) {
> -		DPU_ERROR("invalid argument(s), fence %d, pval %d\n",
> -				ctx != NULL, val != NULL);
> -		return rc;
> -	}
> -
> -	/*
> -	 * Allow created fences to have a constant offset with respect
> -	 * to the timeline. This allows us to delay the fence signalling
> -	 * w.r.t. the commit completion (e.g., an offset of +1 would
> -	 * cause fences returned during a particular commit to signal
> -	 * after an additional delay of one commit, rather than at the
> -	 * end of the current one.
> -	 */
> -	spin_lock_irqsave(&ctx->lock, flags);
> -	trigger_value = ctx->commit_count + offset;
> -
> -	spin_unlock_irqrestore(&ctx->lock, flags);
> -
> -	fd = _dpu_fence_create_fd(ctx, trigger_value);
> -	*val = fd;
> -	DPU_DEBUG("fence_create::fd:%d trigger:%d commit:%d offset:%d\n",
> -				fd, trigger_value, ctx->commit_count,
> offset);
> -
> -	DPU_EVT32(ctx->drm_id, trigger_value, fd);
> -
> -	if (fd >= 0) {
> -		rc = 0;
> -		_dpu_fence_trigger(ctx, ktime_get());
> -	} else {
> -		rc = fd;
> -	}
> -
> -	return rc;
> -}
> -
> -void dpu_fence_signal(struct dpu_fence_context *ctx, ktime_t ts,
> -							bool
> reset_timeline)
> -{
> -	unsigned long flags;
> -
> -	if (!ctx) {
> -		DPU_ERROR("invalid ctx, %pK\n", ctx);
> -		return;
> -	}
> -
> -	spin_lock_irqsave(&ctx->lock, flags);
> -	if (reset_timeline) {
> -		if ((int)(ctx->done_count - ctx->commit_count) < 0) {
> -			DPU_ERROR(
> -				"timeline reset attempt! done count:%d
> commit:%d\n",
> -				ctx->done_count, ctx->commit_count);
> -			ctx->done_count = ctx->commit_count;
> -			DPU_EVT32(ctx->drm_id, ctx->done_count,
> -				ctx->commit_count, ktime_to_us(ts),
> -				reset_timeline, DPU_EVTLOG_FATAL);
> -		} else {
> -			spin_unlock_irqrestore(&ctx->lock, flags);
> -			return;
> -		}
> -	} else if ((int)(ctx->done_count - ctx->commit_count) < 0) {
> -		++ctx->done_count;
> -		DPU_DEBUG("fence_signal:done count:%d commit count:%d\n",
> -					ctx->done_count,
> ctx->commit_count);
> -	} else {
> -		DPU_ERROR("extra signal attempt! done count:%d
> commit:%d\n",
> -					ctx->done_count,
> ctx->commit_count);
> -		DPU_EVT32(ctx->drm_id, ctx->done_count, ctx->commit_count,
> -			ktime_to_us(ts), reset_timeline,
> DPU_EVTLOG_FATAL);
> -		spin_unlock_irqrestore(&ctx->lock, flags);
> -		return;
> -	}
> -	spin_unlock_irqrestore(&ctx->lock, flags);
> -
> -	DPU_EVT32(ctx->drm_id, ctx->done_count, ctx->commit_count,
> -			ktime_to_us(ts));
> -
> -	_dpu_fence_trigger(ctx, ts);
> -}
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_fence.h
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_fence.h
> deleted file mode 100644
> index f943046d96b8..000000000000
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_fence.h
> +++ /dev/null
> @@ -1,190 +0,0 @@
> -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
> - *
> - * This program is free software; you can redistribute it and/or 
> modify
> - * it under the terms of the GNU General Public License version 2 and
> - * only version 2 as published by the Free Software Foundation.
> - *
> - * This program is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - * GNU General Public License for more details.
> - */
> -
> -#ifndef _DPU_FENCE_H_
> -#define _DPU_FENCE_H_
> -
> -#include <linux/kernel.h>
> -#include <linux/errno.h>
> -#include <linux/mutex.h>
> -
> -#ifndef CHAR_BIT
> -#define CHAR_BIT 8 /* define this if limits.h not available */
> -#endif
> -
> -#define DPU_FENCE_NAME_SIZE	24
> -
> -/**
> - * struct dpu_fence_context - release/retire fence context/timeline
> structure
> - * @commit_count: Number of detected commits since bootup
> - * @done_count: Number of completed commits since bootup
> - * @drm_id: ID number of owning DRM Object
> - * @ref: kref counter on timeline
> - * @lock: spinlock for fence counter protection
> - * @list_lock: spinlock for timeline protection
> - * @context: fence context
> - * @list_head: fence list to hold all the fence created on this 
> context
> - * @name: name of fence context/timeline
> - */
> -struct dpu_fence_context {
> -	unsigned int commit_count;
> -	unsigned int done_count;
> -	uint32_t drm_id;
> -	struct kref kref;
> -	spinlock_t lock;
> -	spinlock_t list_lock;
> -	u64 context;
> -	struct list_head fence_list_head;
> -	char name[DPU_FENCE_NAME_SIZE];
> -};
> -
> -#if IS_ENABLED(CONFIG_SYNC_FILE)
> -/**
> - * dpu_sync_get - Query sync fence object from a file handle
> - *
> - * On success, this function also increments the refcount of the sync
> fence
> - *
> - * @fd: Integer sync fence handle
> - *
> - * Return: Pointer to sync fence object, or NULL
> - */
> -void *dpu_sync_get(uint64_t fd);
> -
> -/**
> - * dpu_sync_put - Releases a sync fence object acquired by 
> @dpu_sync_get
> - *
> - * This function decrements the sync fence's reference count; the 
> object
> will
> - * be released if the reference count goes to zero.
> - *
> - * @fence: Pointer to sync fence
> - */
> -void dpu_sync_put(void *fence);
> -
> -/**
> - * dpu_sync_wait - Query sync fence object from a file handle
> - *
> - * @fence: Pointer to sync fence
> - * @timeout_ms: Time to wait, in milliseconds. Waits forever if
> timeout_ms < 0
> - *
> - * Return:
> - * Zero if timed out
> - * -ERESTARTSYS if wait interrupted
> - * remaining jiffies in all other success cases.
> - */
> -signed long dpu_sync_wait(void *fence, long timeout_ms);
> -
> -/**
> - * dpu_sync_get_name_prefix - get integer representation of fence name
> prefix
> - * @fence: Pointer to opaque fence structure
> - *
> - * Return: 32-bit integer containing first 4 characters of fence name,
> - *         big-endian notation
> - */
> -uint32_t dpu_sync_get_name_prefix(void *fence);
> -
> -/**
> - * dpu_fence_init - initialize fence object
> - * @fence: Pointer to crtc fence object
> - * @drm_id: ID number of owning DRM Object
> - * @name: Timeline name
> - * Returns: Zero on success
> - */
> -int dpu_fence_init(struct dpu_fence_context *fence,
> -		const char *name,
> -		uint32_t drm_id);
> -
> -/**
> - * dpu_fence_deinit - deinit fence container
> - * @fence: Pointer fence container
> - */
> -void dpu_fence_deinit(struct dpu_fence_context *fence);
> -
> -/**
> - * dpu_fence_prepare - prepare to return fences for current commit
> - * @fence: Pointer fence container
> - * Returns: Zero on success
> - */
> -void dpu_fence_prepare(struct dpu_fence_context *fence);
> -/**
> - * dpu_fence_create - create output fence object
> - * @fence: Pointer fence container
> - * @val: Pointer to output value variable, fence fd will be placed 
> here
> - * @offset: Fence signal commit offset, e.g., +1 to signal on next 
> commit
> - * Returns: Zero on success
> - */
> -int dpu_fence_create(struct dpu_fence_context *fence, uint64_t *val,
> -							uint32_t offset);
> -
> -/**
> - * dpu_fence_signal - advance fence timeline to signal outstanding 
> fences
> - * @fence: Pointer fence container
> - * @ts: fence timestamp
> - * @reset_timeline: reset the fence timeline to done count equal to
> commit count
> - */
> -void dpu_fence_signal(struct dpu_fence_context *fence, ktime_t ts,
> -		bool reset_timeline);
> -#else
> -static inline void *dpu_sync_get(uint64_t fd)
> -{
> -	return NULL;
> -}
> -
> -static inline void dpu_sync_put(void *fence)
> -{
> -}
> -
> -static inline signed long dpu_sync_wait(void *fence, long timeout_ms)
> -{
> -	return 0;
> -}
> -
> -static inline uint32_t dpu_sync_get_name_prefix(void *fence)
> -{
> -	return 0x0;
> -}
> -static inline int dpu_fence_init(struct dpu_fence_context *fence,
> -		const char *name,
> -		uint32_t drm_id)
> -{
> -	/* do nothing */
> -	return 0;
> -}
> -
> -static inline void dpu_fence_deinit(struct dpu_fence_context *fence)
> -{
> -	/* do nothing */
> -}
> -
> -static inline int dpu_fence_get(struct dpu_fence_context *fence, 
> uint64_t
> *val)
> -{
> -	return -EINVAL;
> -}
> -
> -static inline void dpu_fence_signal(struct dpu_fence_context *fence,
> -						ktime_t ts, bool
> reset_timeline)
> -{
> -	/* do nothing */
> -}
> -
> -static inline void dpu_fence_prepare(struct dpu_fence_context *fence)
> -{
> -	/* do nothing */
> -}
> -
> -static inline int dpu_fence_create(struct dpu_fence_context *fence,
> -						uint64_t *val, uint32_t
> offset)
> -{
> -	return 0;
> -}
> -#endif /* IS_ENABLED(CONFIG_SW_SYNC) */
> -
> -#endif /* _DPU_FENCE_H_ */
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 29e72b39fd72..610e616f2e74 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -27,7 +27,6 @@
>  #include "msm_drv.h"
> 
>  #include "dpu_kms.h"
> -#include "dpu_fence.h"
>  #include "dpu_formats.h"
>  #include "dpu_hw_sspp.h"
>  #include "dpu_hw_catalog_format.h"
> @@ -676,26 +675,6 @@ static void _dpu_plane_set_ts_prefill(struct
> drm_plane *plane,
>  			pstate->multirect_index);
>  }
> 
> -/* helper to update a state's input fence pointer from the property */
> -static void _dpu_plane_set_input_fence(struct dpu_plane *pdpu,
> -		struct dpu_plane_state *pstate, uint64_t fd)
> -{
> -	if (!pdpu || !pstate) {
> -		DPU_ERROR("invalid arg(s), plane %d state %d\n",
> -				pdpu != 0, pstate != 0);
> -		return;
> -	}
> -
> -	/* clear previous reference */
> -	if (pstate->input_fence)
> -		dpu_sync_put(pstate->input_fence);
> -
> -	/* get fence pointer for later */
> -	pstate->input_fence = dpu_sync_get(fd);
> -
> -	DPU_DEBUG_PLANE(pdpu, "0x%llX\n", fd);
> -}
> -
>  /**
>   * _dpu_plane_inline_rot_set_ot_limit - set OT limit for the given 
> inline
>   * rotation xin client
> @@ -780,64 +759,6 @@ static void
> _dpu_plane_inline_rot_set_qos_remap(struct drm_plane *plane,
>  	dpu_vbif_set_qos_remap(dpu_kms, &qos_params);
>  }
> 
> -int dpu_plane_wait_input_fence(struct drm_plane *plane, uint32_t 
> wait_ms)
> -{
> -	struct dpu_plane *pdpu;
> -	struct dpu_plane_state *pstate;
> -	uint32_t prefix;
> -	void *input_fence;
> -	int ret = -EINVAL;
> -	signed long rc;
> -
> -	if (!plane) {
> -		DPU_ERROR("invalid plane\n");
> -	} else if (!plane->state) {
> -		DPU_ERROR_PLANE(to_dpu_plane(plane), "invalid state\n");
> -	} else {
> -		pdpu = to_dpu_plane(plane);
> -		pstate = to_dpu_plane_state(plane->state);
> -		input_fence = pstate->input_fence;
> -
> -		if (input_fence) {
> -			pdpu->is_error = false;
> -			prefix = dpu_sync_get_name_prefix(input_fence);
> -			rc = dpu_sync_wait(input_fence, wait_ms);
> -
> -			switch (rc) {
> -			case 0:
> -				DPU_ERROR_PLANE(pdpu, "%ums timeout on
> %08X\n",
> -						wait_ms, prefix);
> -				pdpu->is_error = true;
> -				ret = -ETIMEDOUT;
> -				break;
> -			case -ERESTARTSYS:
> -				DPU_ERROR_PLANE(pdpu,
> -					"%ums wait interrupted on %08X\n",
> -					wait_ms, prefix);
> -				pdpu->is_error = true;
> -				ret = -ERESTARTSYS;
> -				break;
> -			case -EINVAL:
> -				DPU_ERROR_PLANE(pdpu,
> -					"invalid fence param for %08X\n",
> -						prefix);
> -				pdpu->is_error = true;
> -				ret = -EINVAL;
> -				break;
> -			default:
> -				DPU_DEBUG_PLANE(pdpu, "signaled\n");
> -				ret = 0;
> -				break;
> -			}
> -
> -			DPU_EVT32_VERBOSE(DRMID(plane), -ret, prefix);
> -		} else {
> -			ret = 0;
> -		}
> -	}
> -	return ret;
> -}
> -
>  /**
>   * _dpu_plane_get_aspace: gets the address space
>   */
> @@ -3332,7 +3253,6 @@ static int dpu_plane_sspp_atomic_update(struct
> drm_plane *plane,
>  			break;
>  		case PLANE_PROP_INFO:
>  		case PLANE_PROP_ALPHA:
> -		case PLANE_PROP_INPUT_FENCE:
>  		case PLANE_PROP_BLEND_OP:
>  			/* no special action required */
>  			break;
> @@ -3703,10 +3623,6 @@ static void _dpu_plane_install_properties(struct
> drm_plane *plane,
>  	msm_property_install_range(&pdpu->property_info, "alpha",
>  		0x0, 0, 255, 255, PLANE_PROP_ALPHA);
> 
> -	/* linux default file descriptor range on each process */
> -	msm_property_install_range(&pdpu->property_info, "input_fence",
> -		0x0, 0, INR_OPEN_MAX, 0, PLANE_PROP_INPUT_FENCE);
> -
>  	if (!master_plane_id) {
>  		if (pdpu->pipe_sblk->maxhdeciexp) {
>  			msm_property_install_range(&pdpu->property_info,
> @@ -4076,9 +3992,6 @@ static int dpu_plane_atomic_set_property(struct
> drm_plane *plane,
>  			idx = msm_property_index(&pdpu->property_info,
>  					property);
>  			switch (idx) {
> -			case PLANE_PROP_INPUT_FENCE:
> -				_dpu_plane_set_input_fence(pdpu, pstate,
> val);
> -				break;
>  			case PLANE_PROP_CSC_V1:
>  				_dpu_plane_set_csc_v1(pdpu, (void *)val);
>  				break;
> @@ -4190,10 +4103,6 @@ static void dpu_plane_destroy_state(struct
> drm_plane *plane,
>  	if (state->fb)
>  		drm_framebuffer_put(state->fb);
> 
> -	/* remove ref count for fence */
> -	if (pstate->input_fence)
> -		dpu_sync_put(pstate->input_fence);
> -
>  	/* destroy value helper */
>  	msm_property_destroy_state(&pdpu->property_info, pstate,
>  			&pstate->property_state);
> @@ -4206,7 +4115,6 @@ dpu_plane_duplicate_state(struct drm_plane 
> *plane)
>  	struct dpu_plane_state *pstate;
>  	struct dpu_plane_state *old_state;
>  	struct drm_property *drm_prop;
> -	uint64_t input_fence_default;
> 
>  	if (!plane) {
>  		DPU_ERROR("invalid plane\n");
> @@ -4230,18 +4138,6 @@ dpu_plane_duplicate_state(struct drm_plane 
> *plane)
>  	msm_property_duplicate_state(&pdpu->property_info, old_state,
> pstate,
>  			&pstate->property_state, pstate->property_values);
> 
> -	/* clear out any input fence */
> -	pstate->input_fence = 0;
> -	input_fence_default = msm_property_get_default(
> -			&pdpu->property_info, PLANE_PROP_INPUT_FENCE);
> -	drm_prop = msm_property_index_to_drm_property(
> -				&pdpu->property_info,
> PLANE_PROP_INPUT_FENCE);
> -	if (msm_property_atomic_set(&pdpu->property_info,
> -				&pstate->property_state, drm_prop,
> -				input_fence_default))
> -		DPU_DEBUG_PLANE(pdpu,
> -				"error clearing duplicated input
> fence\n");
> -
>  	pstate->dirty = 0x0;
>  	pstate->pending = false;
> 
> diff --git a/drivers/gpu/drm/msm/msm_drv.h 
> b/drivers/gpu/drm/msm/msm_drv.h
> index 657ea052a1ee..75a24b81c89a 100644
> --- a/drivers/gpu/drm/msm/msm_drv.h
> +++ b/drivers/gpu/drm/msm/msm_drv.h
> @@ -99,7 +99,6 @@ enum msm_mdp_plane_property {
>  	PLANE_PROP_COLOR_FILL,
>  	PLANE_PROP_H_DECIMATE,
>  	PLANE_PROP_V_DECIMATE,
> -	PLANE_PROP_INPUT_FENCE,
>  	PLANE_PROP_HUE_ADJUST,
>  	PLANE_PROP_SATURATION_ADJUST,
>  	PLANE_PROP_VALUE_ADJUST,
> @@ -131,8 +130,7 @@ enum msm_mdp_crtc_property {
>  	CRTC_PROP_BLOBCOUNT,
> 
>  	/* range properties */
> -	CRTC_PROP_INPUT_FENCE_TIMEOUT = CRTC_PROP_BLOBCOUNT,
> -	CRTC_PROP_DIM_LAYER_V1,
> +	CRTC_PROP_DIM_LAYER_V1 = CRTC_PROP_BLOBCOUNT,
>  	CRTC_PROP_CORE_CLK,
>  	CRTC_PROP_CORE_AB,
>  	CRTC_PROP_CORE_IB,

-- 
Jeykumar S
_______________________________________________
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno

      parent reply	other threads:[~2018-03-03  0:50 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-28 19:18 [DPU PATCH 00/11] drm/msm: Use atomic helper functions for msm Sean Paul
     [not found] ` <20180228191906.185417-1-seanpaul-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2018-02-28 19:18   ` [DPU PATCH 01/11] drm/msm: Skip seamless disables in crtc/encoder Sean Paul
2018-03-03  0:04     ` jsanka
     [not found]       ` <d51bfdafccd143ee258fc995a7cafecc-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-03-12 20:14         ` Sean Paul
2018-03-13 18:10           ` Jeykumar Sankaran
2018-02-28 19:18   ` [DPU PATCH 02/11] drm/msm: Don't duplicate modeset_enables atomic helper Sean Paul
     [not found]     ` <20180228191906.185417-3-seanpaul-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2018-03-09  0:56       ` Jeykumar Sankaran
     [not found]         ` <aaf8f07e18801c60cdf7eb30b0cac123-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-03-12 20:21           ` Sean Paul
2018-03-13 23:57             ` Jeykumar Sankaran
     [not found]               ` <677c8c29a788a147aa45bc1e9768527e-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-03-14 15:14                 ` Sean Paul
2018-03-15  1:39                   ` Jeykumar Sankaran
     [not found]                     ` <645777c3f76662ce5b0b14bcf7b81acb-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-03-16 19:45                       ` [DPU PATCH v2] " Sean Paul
2018-03-16 20:57                         ` Jeykumar Sankaran
2018-02-28 19:18   ` [DPU PATCH 03/11] drm/msm: Refactor complete_commit() to look more the helpers Sean Paul
     [not found]     ` <20180228191906.185417-4-seanpaul-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2018-03-09  1:01       ` Jeykumar Sankaran
2018-02-28 19:18   ` [DPU PATCH 04/11] drm/msm: Move implicit sync fence handling to prepare_fb Sean Paul
     [not found]     ` <20180228191906.185417-5-seanpaul-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2018-03-03  0:20       ` jsanka-sgV2jX0FEOL9JmXXK+q4OQ
2018-02-28 19:19   ` [DPU PATCH 05/11] drm/msm: Mark the crtc->state->event consumed Sean Paul
2018-03-06  1:53     ` Jeykumar Sankaran
2018-02-28 19:19   ` [DPU PATCH 06/11] drm/msm: Remove msm_commit/kthread, use atomic helper commit Sean Paul
     [not found]     ` <20180228191906.185417-7-seanpaul-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2018-03-01  4:07       ` jsanka-sgV2jX0FEOL9JmXXK+q4OQ
2018-03-01 15:27         ` Sean Paul
2018-03-01 20:37           ` jsanka-sgV2jX0FEOL9JmXXK+q4OQ
     [not found]             ` <156ab33c41d436c79cc661e84bebc353-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-03-02  0:37               ` Rob Clark
     [not found]                 ` <CAF6AEGvDZ8sWYwwbyPYcQZN6Ba01Gc7db724GeehF3cLY6d-XQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-03-02 14:56                   ` Sean Paul
2018-03-09  1:08                     ` Jeykumar Sankaran
2018-03-12 20:23                       ` Sean Paul
2018-03-19 15:01                         ` Sean Paul
2018-03-19 19:54                           ` Jeykumar Sankaran
2018-02-28 19:19   ` [DPU PATCH 07/11] drm/msm: Use atomic private_obj instead of subclassing Sean Paul
     [not found]     ` <20180228191906.185417-8-seanpaul-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2018-03-09  1:59       ` Jeykumar Sankaran
     [not found]         ` <7fb92416ee99990f6a1280a617736051-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-03-12 20:28           ` Sean Paul
2018-03-19 17:31             ` [DPU PATCH v2] " Sean Paul
     [not found]               ` <20180319173113.94879-1-seanpaul-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2018-03-19 19:33                 ` Jeykumar Sankaran
2018-03-19 19:58                   ` [DPU PATCH v3] " Sean Paul
     [not found]                     ` <20180319195853.49006-1-seanpaul-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2018-03-20 11:01                       ` Archit Taneja
     [not found]                         ` <41aebf2e-48a0-a2e2-167c-70da912353f4-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-05-25  1:16                           ` Jeykumar Sankaran
2018-02-28 19:19   ` [DPU PATCH 08/11] drm/msm: Remove hand-rolled out fences Sean Paul
     [not found]     ` <20180228191906.185417-9-seanpaul-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2018-03-03  0:44       ` Jeykumar Sankaran
     [not found]         ` <1a1c79ddb6ddabbc72e4624b53460188-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-03-12 20:30           ` Sean Paul
2018-03-13 18:11             ` Jeykumar Sankaran
2018-02-28 19:19   ` [DPU PATCH 09/11] drm/msm: Remove prepare_fence kms_function Sean Paul
     [not found]     ` <20180228191906.185417-10-seanpaul-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2018-03-09  1:28       ` abhinavk-sgV2jX0FEOL9JmXXK+q4OQ
2018-02-28 19:19   ` [DPU PATCH 10/11] drm/msm: Switch to atomic_helper_commit() Sean Paul
     [not found]     ` <20180228191906.185417-11-seanpaul-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2018-03-09  3:28       ` abhinavk-sgV2jX0FEOL9JmXXK+q4OQ
     [not found]         ` <bf44a79fc08d00245640694c364b8b03-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-03-12 20:32           ` Sean Paul
2018-03-13  2:08             ` abhinavk-sgV2jX0FEOL9JmXXK+q4OQ
2018-02-28 19:19   ` [DPU PATCH 11/11] drm/msm: Remove dpu input fences Sean Paul
     [not found]     ` <20180228191906.185417-12-seanpaul-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2018-03-03  0:50       ` Jeykumar Sankaran [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=95e182e0c7589d1e19d4aaea1acc9c37@codeaurora.org \
    --to=jsanka-sgv2jx0feol9jmxxk+q4oq@public.gmane.org \
    --cc=abhinavk-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org \
    --cc=dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
    --cc=freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
    --cc=hoegsberg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org \
    --cc=linux-arm-msm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=robdclark-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=seanpaul-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.