Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 02b6ed44 authored by Tina Zhang's avatar Tina Zhang Committed by Zhenyu Wang
Browse files

drm/i915/gvt: Initialize MMIO Block with HW state



MMIO block with tracked mmio, is introduced for the sake of performance
of searching tracked mmio. All the tracked mmio needs to get the initial
value from the HW state during vGPU being created. This patch is to
initialize the tracked registers in MMIO block with the HW state.

v2: Add "Fixes:" line for this patch (Zhenyu)

Fixes: 65f9f6fe ("drm/i915/gvt: Optimize MMIO register handling for some large MMIO blocks")
Signed-off-by: default avatarTina Zhang <tina.zhang@intel.com>
Signed-off-by: default avatarZhenyu Wang <zhenyuw@linux.intel.com>
parent f2e2c00a
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -72,11 +72,13 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt)
	struct intel_gvt_device_info *info = &gvt->device_info;
	struct pci_dev *pdev = gvt->dev_priv->drm.pdev;
	struct intel_gvt_mmio_info *e;
	struct gvt_mmio_block *block = gvt->mmio.mmio_block;
	int num = gvt->mmio.num_mmio_block;
	struct gvt_firmware_header *h;
	void *firmware;
	void *p;
	unsigned long size, crc32_start;
	int i;
	int i, j;
	int ret;

	size = sizeof(*h) + info->mmio_size + info->cfg_space_size;
@@ -105,6 +107,13 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt)
	hash_for_each(gvt->mmio.mmio_info_table, i, e, node)
		*(u32 *)(p + e->offset) = I915_READ_NOTRACE(_MMIO(e->offset));

	for (i = 0; i < num; i++, block++) {
		for (j = 0; j < block->size; j += 4)
			*(u32 *)(p + INTEL_GVT_MMIO_OFFSET(block->offset) + j) =
				I915_READ_NOTRACE(_MMIO(INTEL_GVT_MMIO_OFFSET(
							block->offset) + j));
	}

	memcpy(gvt->firmware.mmio, p, info->mmio_size);

	crc32_start = offsetof(struct gvt_firmware_header, crc32) + 4;
+12 −0
Original line number Diff line number Diff line
@@ -195,6 +195,15 @@ struct intel_gvt_fence {
	unsigned long vgpu_allocated_fence_num;
};

/* Special MMIO blocks. */
struct gvt_mmio_block {
	unsigned int device;
	i915_reg_t   offset;
	unsigned int size;
	gvt_mmio_func read;
	gvt_mmio_func write;
};

#define INTEL_GVT_MMIO_HASH_BITS 11

struct intel_gvt_mmio {
@@ -214,6 +223,9 @@ struct intel_gvt_mmio {
/* This reg could be accessed by unaligned address */
#define F_UNALIGN	(1 << 6)

	struct gvt_mmio_block *mmio_block;
	unsigned int num_mmio_block;

	DECLARE_HASHTABLE(mmio_info_table, INTEL_GVT_MMIO_HASH_BITS);
	unsigned int num_tracked_mmio;
};
+17 −19
Original line number Diff line number Diff line
@@ -2857,31 +2857,15 @@ static int init_skl_mmio_info(struct intel_gvt *gvt)
	return 0;
}

/* Special MMIO blocks. */
static struct gvt_mmio_block {
	unsigned int device;
	i915_reg_t   offset;
	unsigned int size;
	gvt_mmio_func read;
	gvt_mmio_func write;
} gvt_mmio_blocks[] = {
	{D_SKL_PLUS, _MMIO(CSR_MMIO_START_RANGE), 0x3000, NULL, NULL},
	{D_ALL, _MMIO(MCHBAR_MIRROR_BASE_SNB), 0x40000, NULL, NULL},
	{D_ALL, _MMIO(VGT_PVINFO_PAGE), VGT_PVINFO_SIZE,
		pvinfo_mmio_read, pvinfo_mmio_write},
	{D_ALL, LGC_PALETTE(PIPE_A, 0), 1024, NULL, NULL},
	{D_ALL, LGC_PALETTE(PIPE_B, 0), 1024, NULL, NULL},
	{D_ALL, LGC_PALETTE(PIPE_C, 0), 1024, NULL, NULL},
};

static struct gvt_mmio_block *find_mmio_block(struct intel_gvt *gvt,
					      unsigned int offset)
{
	unsigned long device = intel_gvt_get_device_type(gvt);
	struct gvt_mmio_block *block = gvt_mmio_blocks;
	struct gvt_mmio_block *block = gvt->mmio.mmio_block;
	int num = gvt->mmio.num_mmio_block;
	int i;

	for (i = 0; i < ARRAY_SIZE(gvt_mmio_blocks); i++, block++) {
	for (i = 0; i < num; i++, block++) {
		if (!(device & block->device))
			continue;
		if (offset >= INTEL_GVT_MMIO_OFFSET(block->offset) &&
@@ -2912,6 +2896,17 @@ void intel_gvt_clean_mmio_info(struct intel_gvt *gvt)
	gvt->mmio.mmio_attribute = NULL;
}

/* Special MMIO blocks. */
static struct gvt_mmio_block mmio_blocks[] = {
	{D_SKL_PLUS, _MMIO(CSR_MMIO_START_RANGE), 0x3000, NULL, NULL},
	{D_ALL, _MMIO(MCHBAR_MIRROR_BASE_SNB), 0x40000, NULL, NULL},
	{D_ALL, _MMIO(VGT_PVINFO_PAGE), VGT_PVINFO_SIZE,
		pvinfo_mmio_read, pvinfo_mmio_write},
	{D_ALL, LGC_PALETTE(PIPE_A, 0), 1024, NULL, NULL},
	{D_ALL, LGC_PALETTE(PIPE_B, 0), 1024, NULL, NULL},
	{D_ALL, LGC_PALETTE(PIPE_C, 0), 1024, NULL, NULL},
};

/**
 * intel_gvt_setup_mmio_info - setup MMIO information table for GVT device
 * @gvt: GVT device
@@ -2951,6 +2946,9 @@ int intel_gvt_setup_mmio_info(struct intel_gvt *gvt)
			goto err;
	}

	gvt->mmio.mmio_block = mmio_blocks;
	gvt->mmio.num_mmio_block = ARRAY_SIZE(mmio_blocks);

	gvt_dbg_mmio("traced %u virtual mmio registers\n",
		     gvt->mmio.num_tracked_mmio);
	return 0;