[Intel-xe] [RFC PATCH v2 2/3] drm/xe: Introduce function pointers in xe_guc_pc.c with local structure

Francois Dugast francois.dugast at intel.com
Tue Mar 14 15:51:10 UTC 2023


This is similar to the previous commit which was for xe_gt.c.
A local structure of function pointers is used as a minimal
hardware abstraction layer to split between common and platform
specific code. This structure is initialized once with the
functions matching the platform, then it is used in the common
code with no need for switch or if/else to detect the platform.
For now only the functions init_fused_rp_values() and
update_rpe_value() are refactored.

Signed-off-by: Francois Dugast <francois.dugast at intel.com>
---
 drivers/gpu/drm/xe/xe_device_types.h |  1 +
 drivers/gpu/drm/xe/xe_guc_pc.c       | 43 ++++++++++++++++++++++------
 2 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
index 411e7a62d28a..bc26c6e050d4 100644
--- a/drivers/gpu/drm/xe/xe_device_types.h
+++ b/drivers/gpu/drm/xe/xe_device_types.h
@@ -312,6 +312,7 @@ struct xe_device {
 	} params;
 #endif
 	struct xe_gt_platform_funcs *gt_funcs;
+	struct xe_guc_pc_platform_funcs *guc_pc_funcs;
 };
 
 /**
diff --git a/drivers/gpu/drm/xe/xe_guc_pc.c b/drivers/gpu/drm/xe/xe_guc_pc.c
index 5a8d827ba770..71d48148061c 100644
--- a/drivers/gpu/drm/xe/xe_guc_pc.c
+++ b/drivers/gpu/drm/xe/xe_guc_pc.c
@@ -117,7 +117,12 @@ pc_to_maps(struct xe_guc_pc *pc)
 	return &pc->bo->vmap;
 }
 
-#define slpc_shared_data_read(pc_, field_) \
+struct xe_guc_pc_platform_funcs {
+	void (*init_fused_rp_values)(struct xe_guc_pc *pc);
+	void (*update_rpe_value)(struct xe_guc_pc *pc);
+};
+
+#define slpc_shared_data_read(pc_, field_)		   \
 	xe_map_rd_field(pc_to_xe(pc_), pc_to_maps(pc_), 0, \
 			struct slpc_shared_data, field_)
 
@@ -348,10 +353,8 @@ static void pc_update_rp_values(struct xe_guc_pc *pc)
 	struct xe_gt *gt = pc_to_gt(pc);
 	struct xe_device *xe = gt_to_xe(gt);
 
-	if (xe->info.platform == XE_METEORLAKE)
-		mtl_update_rpe_value(pc);
-	else
-		tgl_update_rpe_value(pc);
+	if (xe->guc_pc_funcs->update_rpe_value)
+		xe->guc_pc_funcs->update_rpe_value(pc);
 
 	/*
 	 * RPe is decided at runtime by PCODE. In the rare case where that's
@@ -676,11 +679,10 @@ static void pc_init_fused_rp_values(struct xe_guc_pc *pc)
 	struct xe_gt *gt = pc_to_gt(pc);
 	struct xe_device *xe = gt_to_xe(gt);
 
-	if (xe->info.platform == XE_METEORLAKE)
-		mtl_init_fused_rp_values(pc);
-	else
-		tgl_init_fused_rp_values(pc);
+	if (xe->guc_pc_funcs->init_fused_rp_values)
+		xe->guc_pc_funcs->init_fused_rp_values(pc);
 }
+
 static int pc_adjust_freq_bounds(struct xe_guc_pc *pc)
 {
 	int ret;
@@ -875,10 +877,12 @@ int xe_guc_pc_stop(struct xe_guc_pc *pc)
 static void pc_fini(struct drm_device *drm, void *arg)
 {
 	struct xe_guc_pc *pc = arg;
+	struct xe_device *xe = pc_to_xe(pc);
 
 	XE_WARN_ON(xe_guc_pc_stop(pc));
 	sysfs_remove_files(pc_to_gt(pc)->sysfs, pc_attrs);
 	xe_bo_unpin_map_no_vm(pc->bo);
+	kfree(xe->guc_pc_funcs);
 }
 
 /**
@@ -893,6 +897,27 @@ int xe_guc_pc_init(struct xe_guc_pc *pc)
 	u32 size = PAGE_ALIGN(sizeof(struct slpc_shared_data));
 	int err;
 
+	xe->guc_pc_funcs = kzalloc(sizeof(*xe->guc_pc_funcs), GFP_KERNEL);
+	switch (xe->info.platform) {
+	case XE_METEORLAKE:
+		xe->guc_pc_funcs->init_fused_rp_values = mtl_init_fused_rp_values;
+		xe->guc_pc_funcs->update_rpe_value = mtl_update_rpe_value;
+		break;
+	case XE_PVC:
+	case XE_ROCKETLAKE:
+	case XE_DG1:
+	case XE_DG2:
+	case XE_ALDERLAKE_S:
+	case XE_ALDERLAKE_P:
+	case XE_TIGERLAKE:
+		xe->guc_pc_funcs->init_fused_rp_values = tgl_init_fused_rp_values;
+		xe->guc_pc_funcs->update_rpe_value = tgl_update_rpe_value;
+		break;
+	default:
+		DRM_ERROR("Unsupported platform\n");
+		break;
+	}
+
 	mutex_init(&pc->freq_lock);
 
 	bo = xe_bo_create_pin_map(xe, gt, NULL, size,
-- 
2.25.1



More information about the Intel-xe mailing list