diff mbox

[v12,8/8] RFC: drm/i915: reuse new chipset/driver query in getparam

Message ID 20180129163146.20251-9-lionel.g.landwerlin@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Lionel Landwerlin Jan. 29, 2018, 4:31 p.m. UTC
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c | 212 ++++++++++++++++++++++------------------
 1 file changed, 119 insertions(+), 93 deletions(-)
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index ebb2e4241cf7..cc0342e8a400 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -278,11 +278,123 @@  static void intel_detect_pch(struct drm_i915_private *dev_priv)
 	pci_dev_put(pch);
 }
 
+static int read_unsigned_struct_field(void *data, uint32_t offset, uint32_t size)
+{
+	switch (size) {
+	case 1:
+		return *(uint8_t *)(data + offset);
+	case 2:
+		return *(uint16_t *)(data + offset);
+	case 4:
+		return *(uint32_t *)(data + offset);
+	case 8:
+		return *(uint64_t *)(data + offset);
+	}
+
+	GEM_BUG_ON(true);
+	return 0;
+}
+
+static const struct {
+	uint32_t param;
+	uint32_t offset;
+	uint8_t size;
+} i915_param_chipset_mapping[] = {
+#define MEMBER_OFFSET_SIZE(param, member) \
+	{ param, \
+	  offsetof(struct drm_i915_query_chipset_info, member),	\
+	  sizeof(((struct drm_i915_query_chipset_info *)0)->member), }
+	MEMBER_OFFSET_SIZE(I915_PARAM_CHIPSET_ID,		chipset_id),
+	MEMBER_OFFSET_SIZE(I915_PARAM_REVISION,			chipset_revision),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_LLC,			has_llc),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_WT,			has_writethrough),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_SEMAPHORES,		has_semaphores),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_OVERLAY,		has_overlay),
+	MEMBER_OFFSET_SIZE(I915_PARAM_NUM_FENCES_AVAIL,		num_fences_available),
+	MEMBER_OFFSET_SIZE(I915_PARAM_CS_TIMESTAMP_FREQUENCY,	cs_timestamp_frequency),
+#undef MEMBER_OFFSET_SIZE
+};
+static bool i915_getparam_chipset(struct drm_i915_private *dev_priv,
+				  s32 param, int *value)
+{
+	struct drm_i915_query_chipset_info chipset_info;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(i915_param_chipset_mapping); i++) {
+		if (i915_param_chipset_mapping[i].param == param) {
+			i915_query_fill_chipset_info(dev_priv, &chipset_info);
+			*value = read_unsigned_struct_field(&chipset_info,
+							    i915_param_chipset_mapping[i].offset,
+							    i915_param_chipset_mapping[i].size);
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static const struct {
+	uint32_t param;
+	uint32_t offset;
+	uint8_t size;
+} i915_param_driver_mapping[] = {
+#define MEMBER_OFFSET_SIZE(param, member) \
+	{ param, \
+	  offsetof(struct drm_i915_query_driver_info, member), \
+	  sizeof(((struct drm_i915_query_driver_info *)0)->member), }
+	MEMBER_OFFSET_SIZE(I915_PARAM_CMD_PARSER_VERSION,	cmd_parser_version),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_ALIASING_PPGTT,	has_aliasing_ppgtt),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_CONTEXT_ISOLATION,	has_context_isolation),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_COHERENT_PHYS_GTT,	has_coherent_phys_gtt),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_COHERENT_RINGS,	has_coherent_rings),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_GEM,			has_gem),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_GEN7_SOL_RESET,	has_gen7_sol_reset),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_GPU_RESET,		has_gpu_reset),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_PAGEFLIPPING,		has_pageflipping),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_EXEC_ASYNC,		has_exec_async),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_EXEC_BATCH_FIRST,	has_exec_batch_first),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_EXEC_CAPTURE,		has_exec_capture),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_EXEC_NO_RELOC,	has_exec_no_reloc),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_EXEC_FENCE,		has_exec_fence),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_EXEC_FENCE_ARRAY,	has_exec_fence_array),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_EXEC_HANDLE_LUT,	has_exec_handle_lut),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_EXEC_SOFTPIN,		has_exec_softpin),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_PINNED_BATCHES,	has_pinned_batches),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_PRIME_VMAP_FLUSH,	has_prime_vmap_flush),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_RELAXED_DELTA,	has_relaxed_delta),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_RELAXED_FENCING,	has_relaxed_fencing),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_RESOURCE_STREAMER,	has_resource_streamer),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_SCHEDULER,		has_scheduler),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_SECURE_BATCHES,	has_secure_batches),
+	MEMBER_OFFSET_SIZE(I915_PARAM_HAS_WAIT_TIMEOUT,		has_wait_timeout),
+	MEMBER_OFFSET_SIZE(I915_PARAM_MMAP_GTT_VERSION,		mmap_gtt_version),
+	MEMBER_OFFSET_SIZE(I915_PARAM_MMAP_VERSION,		mmap_version),
+#undef MEMBER_OFFSET_SIZE
+};
+
+static bool i915_getparam_driver(struct drm_i915_private *dev_priv,
+				  s32 param, int *value)
+{
+	struct drm_i915_query_driver_info driver_info;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(i915_param_driver_mapping); i++) {
+		if (i915_param_driver_mapping[i].param == param) {
+			i915_query_fill_driver_info(dev_priv, &driver_info);
+			*value = read_unsigned_struct_field(&driver_info,
+							    i915_param_driver_mapping[i].offset,
+							    i915_param_driver_mapping[i].size);
+			return true;
+		}
+	}
+
+	return false;
+}
+
 static int i915_getparam(struct drm_device *dev, void *data,
 			 struct drm_file *file_priv)
 {
 	struct drm_i915_private *dev_priv = to_i915(dev);
-	struct pci_dev *pdev = dev_priv->drm.pdev;
 	drm_i915_getparam_t *param = data;
 	int value;
 
@@ -293,18 +405,6 @@  static int i915_getparam(struct drm_device *dev, void *data,
 	case I915_PARAM_HAS_EXEC_CONSTANTS:
 		/* Reject all old ums/dri params. */
 		return -ENODEV;
-	case I915_PARAM_CHIPSET_ID:
-		value = pdev->device;
-		break;
-	case I915_PARAM_REVISION:
-		value = pdev->revision;
-		break;
-	case I915_PARAM_NUM_FENCES_AVAIL:
-		value = dev_priv->num_fence_regs;
-		break;
-	case I915_PARAM_HAS_OVERLAY:
-		value = dev_priv->overlay ? 1 : 0;
-		break;
 	case I915_PARAM_HAS_BSD:
 		value = !!dev_priv->engine[VCS];
 		break;
@@ -317,24 +417,6 @@  static int i915_getparam(struct drm_device *dev, void *data,
 	case I915_PARAM_HAS_BSD2:
 		value = !!dev_priv->engine[VCS2];
 		break;
-	case I915_PARAM_HAS_LLC:
-		value = HAS_LLC(dev_priv);
-		break;
-	case I915_PARAM_HAS_WT:
-		value = HAS_WT(dev_priv);
-		break;
-	case I915_PARAM_HAS_ALIASING_PPGTT:
-		value = USES_PPGTT(dev_priv);
-		break;
-	case I915_PARAM_HAS_SEMAPHORES:
-		value = HAS_LEGACY_SEMAPHORES(dev_priv);
-		break;
-	case I915_PARAM_HAS_SECURE_BATCHES:
-		value = capable(CAP_SYS_ADMIN);
-		break;
-	case I915_PARAM_CMD_PARSER_VERSION:
-		value = i915_cmd_parser_get_version(dev_priv);
-		break;
 	case I915_PARAM_SUBSLICE_TOTAL:
 		value = sseu_subslice_total(&INTEL_INFO(dev_priv)->sseu);
 		if (!value)
@@ -345,15 +427,6 @@  static int i915_getparam(struct drm_device *dev, void *data,
 		if (!value)
 			return -ENODEV;
 		break;
-	case I915_PARAM_HAS_GPU_RESET:
-		value = i915_modparams.enable_hangcheck &&
-			intel_has_gpu_reset(dev_priv);
-		if (value && intel_has_reset_engine(dev_priv))
-			value = 2;
-		break;
-	case I915_PARAM_HAS_RESOURCE_STREAMER:
-		value = HAS_RESOURCE_STREAMER(dev_priv);
-		break;
 	case I915_PARAM_HAS_POOLED_EU:
 		value = HAS_POOLED_EU(dev_priv);
 		break;
@@ -365,54 +438,6 @@  static int i915_getparam(struct drm_device *dev, void *data,
 		value = I915_READ(HUC_STATUS2) & HUC_FW_VERIFIED;
 		intel_runtime_pm_put(dev_priv);
 		break;
-	case I915_PARAM_MMAP_GTT_VERSION:
-		/* Though we've started our numbering from 1, and so class all
-		 * earlier versions as 0, in effect their value is undefined as
-		 * the ioctl will report EINVAL for the unknown param!
-		 */
-		value = i915_gem_mmap_gtt_version();
-		break;
-	case I915_PARAM_HAS_SCHEDULER:
-		value = 0;
-		if (dev_priv->engine[RCS] && dev_priv->engine[RCS]->schedule) {
-			value |= I915_SCHEDULER_CAP_ENABLED;
-			value |= I915_SCHEDULER_CAP_PRIORITY;
-			if (HAS_LOGICAL_RING_PREEMPTION(dev_priv))
-				value |= I915_SCHEDULER_CAP_PREEMPTION;
-		}
-		break;
-
-	case I915_PARAM_MMAP_VERSION:
-		/* Remember to bump this if the version changes! */
-	case I915_PARAM_HAS_GEM:
-	case I915_PARAM_HAS_PAGEFLIPPING:
-	case I915_PARAM_HAS_EXECBUF2: /* depends on GEM */
-	case I915_PARAM_HAS_RELAXED_FENCING:
-	case I915_PARAM_HAS_COHERENT_RINGS:
-	case I915_PARAM_HAS_RELAXED_DELTA:
-	case I915_PARAM_HAS_GEN7_SOL_RESET:
-	case I915_PARAM_HAS_WAIT_TIMEOUT:
-	case I915_PARAM_HAS_PRIME_VMAP_FLUSH:
-	case I915_PARAM_HAS_PINNED_BATCHES:
-	case I915_PARAM_HAS_EXEC_NO_RELOC:
-	case I915_PARAM_HAS_EXEC_HANDLE_LUT:
-	case I915_PARAM_HAS_COHERENT_PHYS_GTT:
-	case I915_PARAM_HAS_EXEC_SOFTPIN:
-	case I915_PARAM_HAS_EXEC_ASYNC:
-	case I915_PARAM_HAS_EXEC_FENCE:
-	case I915_PARAM_HAS_EXEC_CAPTURE:
-	case I915_PARAM_HAS_EXEC_BATCH_FIRST:
-	case I915_PARAM_HAS_EXEC_FENCE_ARRAY:
-		/* For the time being all of these are always true;
-		 * if some supported hardware does not have one of these
-		 * features this value needs to be provided from
-		 * INTEL_INFO(), a feature macro, or similar.
-		 */
-		value = 1;
-		break;
-	case I915_PARAM_HAS_CONTEXT_ISOLATION:
-		value = intel_engines_has_context_isolation(dev_priv);
-		break;
 	case I915_PARAM_SLICE_MASK:
 		value = INTEL_INFO(dev_priv)->sseu.slice_mask;
 		if (!value)
@@ -423,12 +448,13 @@  static int i915_getparam(struct drm_device *dev, void *data,
 		if (!value)
 			return -ENODEV;
 		break;
-	case I915_PARAM_CS_TIMESTAMP_FREQUENCY:
-		value = 1000 * INTEL_INFO(dev_priv)->cs_timestamp_frequency_khz;
-		break;
 	default:
-		DRM_DEBUG("Unknown parameter %d\n", param->param);
-		return -EINVAL;
+		if (!i915_getparam_chipset(dev_priv, param->param, &value) &&
+		    !i915_getparam_driver(dev_priv, param->param, &value)) {
+			DRM_DEBUG("Unknown parameter %d\n", param->param);
+			return -EINVAL;
+		}
+		break;
 	}
 
 	if (put_user(value, param->value))