/*
 * SPDX-License-Identifier: MIT
 *
 * Copyright © 2016 Intel Corporation
 */

#ifndef I915_SCATTERLIST_H
#define I915_SCATTERLIST_H

#include <linux/pfn.h>
#include <linux/scatterlist.h>
#include <linux/dma-mapping.h>
#include <xen/xen.h>

#include "i915_gem.h"

struct drm_mm_node;
struct ttm_resource;

/*
 * Optimised SGL iterator for GEM objects
 */
static __always_inline struct sgt_iter {
	struct scatterlist *sgp;
	union {
		unsigned long pfn;
		dma_addr_t dma;
	};
	unsigned int curr;
	unsigned int max;
} __sgt_iter(struct scatterlist *sgl, bool dma) {
	struct sgt_iter s = { .sgp = sgl };

	if (dma && s.sgp && sg_dma_len(s.sgp) == 0) {
		s.sgp = NULL;
	} else if (s.sgp) {
		s.max = s.curr = s.sgp->offset;
		if (dma) {
			s.dma = sg_dma_address(s.sgp);
			s.max += sg_dma_len(s.sgp);
		} else {
			s.pfn = page_to_pfn(sg_page(s.sgp));
			s.max += s.sgp->length;
		}
	}

	return s;
}

static inline int __sg_page_count(const struct scatterlist *sg)
{
	return sg->length >> PAGE_SHIFT;
}

static inline int __sg_dma_page_count(const struct scatterlist *sg)
{
	return sg_dma_len(sg) >> PAGE_SHIFT;
}

static inline struct scatterlist *____sg_next(struct scatterlist *sg)
{
	++sg;
	if (unlikely(sg_is_chain(sg)))
		sg = sg_chain_ptr(sg);
	return sg;
}

/**
 * __sg_next - return the next scatterlist entry in a list
 * @sg:		The current sg entry
 *
 * Description:
 *   If the entry is the last, return NULL; otherwise, step to the next
 *   element in the array (@sg@+1). If that's a chain pointer, follow it;
 *   otherwise just return the pointer to the current element.
 **/
static inline struct scatterlist *__sg_next(struct scatterlist *sg)
{
	return sg_is_last(sg) ? NULL : ____sg_next(sg);
}

/**
 * __for_each_sgt_daddr - iterate over the device addresses of the given sg_table
 * @__dp:	Device address (output)
 * @__iter:	'struct sgt_iter' (iterator state, internal)
 * @__sgt:	sg_table to iterate over (input)
 * @__step:	step size
 */
#define __for_each_sgt_daddr(__dp, __iter, __sgt, __step)		\
	for ((__iter) = __sgt_iter((__sgt)->sgl, true);			\
	     ((__dp) = (__iter).dma + (__iter).curr), (__iter).sgp;	\
	     (((__iter).curr += (__step)) >= (__iter).max) ?		\
	     (__iter) = __sgt_iter(__sg_next((__iter).sgp), true), 0 : 0)
/**
 * __for_each_daddr_next - iterates over the device addresses with pre-initialized iterator.
 * @__dp:	Device address (output)
 * @__iter:	'struct sgt_iter' (iterator state, external)
 * @__step:	step size
 */
#define __for_each_daddr_next(__dp, __iter, __step)                  \
	for (; ((__dp) = (__iter).dma + (__iter).curr), (__iter).sgp;   \
	     (((__iter).curr += (__step)) >= (__iter).max) ?            \
	     (__iter) = __sgt_iter(__sg_next((__iter).sgp), true), 0 : 0)

/**
 * for_each_sgt_page - iterate over the pages of the given sg_table
 * @__pp:	page pointer (output)
 * @__iter:	'struct sgt_iter' (iterator state, internal)
 * @__sgt:	sg_table to iterate over (input)
 */
#define for_each_sgt_page(__pp, __iter, __sgt)				\
	for ((__iter) = __sgt_iter((__sgt)->sgl, false);		\
	     ((__pp) = (__iter).pfn == 0 ? NULL :			\
	      pfn_to_page((__iter).pfn + ((__iter).curr >> PAGE_SHIFT))); \
	     (((__iter).curr += PAGE_SIZE) >= (__iter).max) ?		\
	     (__iter) = __sgt_iter(__sg_next((__iter).sgp), false), 0 : 0)

/**
 * i915_sg_dma_sizes - Record the dma segment sizes of a scatterlist
 * @sg: The scatterlist
 *
 * Return: An unsigned int with segment sizes logically or'ed together.
 * A caller can use this information to determine what hardware page table
 * entry sizes can be used to map the memory represented by the scatterlist.
 */
static inline unsigned int i915_sg_dma_sizes(struct scatterlist *sg)
{
	unsigned int page_sizes;

	page_sizes = 0;
	while (sg && sg_dma_len(sg)) {
		GEM_BUG_ON(sg->offset);
		GEM_BUG_ON(!IS_ALIGNED(sg_dma_len(sg), PAGE_SIZE));
		page_sizes |= sg_dma_len(sg);
		sg = __sg_next(sg);
	}

	return page_sizes;
}

static inline unsigned int i915_sg_segment_size(struct device *dev)
{
	size_t max = min_t(size_t, UINT_MAX, dma_max_mapping_size(dev));

	/*
	 * For Xen PV guests pages aren't contiguous in DMA (machine) address
	 * space.  The DMA API takes care of that both in dma_alloc_* (by
	 * calling into the hypervisor to make the pages contiguous) and in
	 * dma_map_* (by bounce buffering).  But i915 abuses ignores the
	 * coherency aspects of the DMA API and thus can't cope with bounce
	 * buffering actually happening, so add a hack here to force small
	 * allocations and mappings when running in PV mode on Xen.
	 *
	 * Note this will still break if bounce buffering is required for other
	 * reasons, like confidential computing hypervisors or PCIe root ports
	 * with addressing limitations.
	 */
	if (xen_pv_domain())
		max = PAGE_SIZE;
	return round_down(max, PAGE_SIZE);
}

bool i915_sg_trim(struct sg_table *orig_st);

/**
 * struct i915_refct_sgt_ops - Operations structure for struct i915_refct_sgt
 */
struct i915_refct_sgt_ops {
	/**
	 * @release: Free the memory of the struct i915_refct_sgt
	 */
	void (*release)(struct kref *ref);
};

/**
 * struct i915_refct_sgt - A refcounted scatter-gather table
 * @kref: struct kref for refcounting
 * @table: struct sg_table holding the scatter-gather table itself. Note that
 * @table->sgl = NULL can be used to determine whether a scatter-gather table
 * is present or not.
 * @size: The size in bytes of the underlying memory buffer
 * @ops: The operations structure.
 */
struct i915_refct_sgt {
	struct kref kref;
	struct sg_table table;
	size_t size;
	const struct i915_refct_sgt_ops *ops;
};

/**
 * i915_refct_sgt_put - Put a refcounted sg-table
 * @rsgt: the struct i915_refct_sgt to put.
 */
static inline void i915_refct_sgt_put(struct i915_refct_sgt *rsgt)
{
	if (rsgt)
		kref_put(&rsgt->kref, rsgt->ops->release);
}

/**
 * i915_refct_sgt_get - Get a refcounted sg-table
 * @rsgt: the struct i915_refct_sgt to get.
 */
static inline struct i915_refct_sgt *
i915_refct_sgt_get(struct i915_refct_sgt *rsgt)
{
	kref_get(&rsgt->kref);
	return rsgt;
}

/**
 * __i915_refct_sgt_init - Initialize a refcounted sg-list with a custom
 * operations structure
 * @rsgt: The struct i915_refct_sgt to initialize.
 * @size: Size in bytes of the underlying memory buffer.
 * @ops: A customized operations structure in case the refcounted sg-list
 * is embedded into another structure.
 */
static inline void __i915_refct_sgt_init(struct i915_refct_sgt *rsgt,
					 size_t size,
					 const struct i915_refct_sgt_ops *ops)
{
	kref_init(&rsgt->kref);
	rsgt->table.sgl = NULL;
	rsgt->size = size;
	rsgt->ops = ops;
}

void i915_refct_sgt_init(struct i915_refct_sgt *rsgt, size_t size);

struct i915_refct_sgt *i915_rsgt_from_mm_node(const struct drm_mm_node *node,
					      u64 region_start,
					      u32 page_alignment);

struct i915_refct_sgt *i915_rsgt_from_buddy_resource(struct ttm_resource *res,
						     u64 region_start,
						     u32 page_alignment);

#endif
