Skip to content

Commit 45832bf

Browse files
bnilawarlucasdemarchi
authored andcommitted
drm/xe/xe_late_bind_fw: Initialize late binding firmware
Search for late binding firmware binaries and populate the meta data of firmware structures. v2 (Daniele): - drm_err if firmware size is more than max pay load size - s/request_firmware/firmware_request_nowarn/ as firmware will not be available for all possible cards v3 (Daniele): - init firmware from within xe_late_bind_init, propagate error - switch late_bind_fw to array to handle multiple firmware types v4 (Daniele): - Alloc payload dynamically, fix nits v6 (Daniele) - %s/MAX_PAYLOAD_SIZE/XE_LB_MAX_PAYLOAD_SIZE/ Signed-off-by: Badal Nilawar <badal.nilawar@intel.com> Reviewed-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://lore.kernel.org/r/20250905154953.3974335-5-badal.nilawar@intel.com Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
1 parent 918bd78 commit 45832bf

File tree

2 files changed

+129
-1
lines changed

2 files changed

+129
-1
lines changed

drivers/gpu/drm/xe/xe_late_bind_fw.c

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include <linux/component.h>
77
#include <linux/delay.h>
8+
#include <linux/firmware.h>
89

910
#include <drm/drm_managed.h>
1011
#include <drm/intel/i915_component.h>
@@ -13,13 +14,106 @@
1314

1415
#include "xe_device.h"
1516
#include "xe_late_bind_fw.h"
17+
#include "xe_pcode.h"
18+
#include "xe_pcode_api.h"
19+
20+
static const u32 fw_id_to_type[] = {
21+
[XE_LB_FW_FAN_CONTROL] = INTEL_LB_TYPE_FAN_CONTROL,
22+
};
23+
24+
static const char * const fw_id_to_name[] = {
25+
[XE_LB_FW_FAN_CONTROL] = "fan_control",
26+
};
1627

1728
static struct xe_device *
1829
late_bind_to_xe(struct xe_late_bind *late_bind)
1930
{
2031
return container_of(late_bind, struct xe_device, late_bind);
2132
}
2233

34+
static int xe_late_bind_fw_num_fans(struct xe_late_bind *late_bind)
35+
{
36+
struct xe_device *xe = late_bind_to_xe(late_bind);
37+
struct xe_tile *root_tile = xe_device_get_root_tile(xe);
38+
u32 uval;
39+
40+
if (!xe_pcode_read(root_tile,
41+
PCODE_MBOX(FAN_SPEED_CONTROL, FSC_READ_NUM_FANS, 0), &uval, NULL))
42+
return uval;
43+
else
44+
return 0;
45+
}
46+
47+
static int __xe_late_bind_fw_init(struct xe_late_bind *late_bind, u32 fw_id)
48+
{
49+
struct xe_device *xe = late_bind_to_xe(late_bind);
50+
struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
51+
struct xe_late_bind_fw *lb_fw;
52+
const struct firmware *fw;
53+
u32 num_fans;
54+
int ret;
55+
56+
if (fw_id >= XE_LB_FW_MAX_ID)
57+
return -EINVAL;
58+
59+
lb_fw = &late_bind->late_bind_fw[fw_id];
60+
61+
lb_fw->id = fw_id;
62+
lb_fw->type = fw_id_to_type[lb_fw->id];
63+
lb_fw->flags &= ~INTEL_LB_FLAG_IS_PERSISTENT;
64+
65+
if (lb_fw->type == INTEL_LB_TYPE_FAN_CONTROL) {
66+
num_fans = xe_late_bind_fw_num_fans(late_bind);
67+
drm_dbg(&xe->drm, "Number of Fans: %d\n", num_fans);
68+
if (!num_fans)
69+
return 0;
70+
}
71+
72+
snprintf(lb_fw->blob_path, sizeof(lb_fw->blob_path), "xe/%s_8086_%04x_%04x_%04x.bin",
73+
fw_id_to_name[lb_fw->id], pdev->device,
74+
pdev->subsystem_vendor, pdev->subsystem_device);
75+
76+
drm_dbg(&xe->drm, "Request late binding firmware %s\n", lb_fw->blob_path);
77+
ret = firmware_request_nowarn(&fw, lb_fw->blob_path, xe->drm.dev);
78+
if (ret) {
79+
drm_dbg(&xe->drm, "%s late binding fw not available for current device",
80+
fw_id_to_name[lb_fw->id]);
81+
return 0;
82+
}
83+
84+
if (fw->size > XE_LB_MAX_PAYLOAD_SIZE) {
85+
drm_err(&xe->drm, "Firmware %s size %zu is larger than max pay load size %u\n",
86+
lb_fw->blob_path, fw->size, XE_LB_MAX_PAYLOAD_SIZE);
87+
release_firmware(fw);
88+
return -ENODATA;
89+
}
90+
91+
lb_fw->payload_size = fw->size;
92+
lb_fw->payload = drmm_kzalloc(&xe->drm, lb_fw->payload_size, GFP_KERNEL);
93+
if (!lb_fw->payload) {
94+
release_firmware(fw);
95+
return -ENOMEM;
96+
}
97+
98+
memcpy((void *)lb_fw->payload, fw->data, lb_fw->payload_size);
99+
release_firmware(fw);
100+
101+
return 0;
102+
}
103+
104+
static int xe_late_bind_fw_init(struct xe_late_bind *late_bind)
105+
{
106+
int ret;
107+
int fw_id;
108+
109+
for (fw_id = 0; fw_id < XE_LB_FW_MAX_ID; fw_id++) {
110+
ret = __xe_late_bind_fw_init(late_bind, fw_id);
111+
if (ret)
112+
return ret;
113+
}
114+
return 0;
115+
}
116+
23117
static int xe_late_bind_component_bind(struct device *xe_kdev,
24118
struct device *mei_kdev, void *data)
25119
{
@@ -80,5 +174,9 @@ int xe_late_bind_init(struct xe_late_bind *late_bind)
80174
return err;
81175
}
82176

83-
return devm_add_action_or_reset(xe->drm.dev, xe_late_bind_remove, late_bind);
177+
err = devm_add_action_or_reset(xe->drm.dev, xe_late_bind_remove, late_bind);
178+
if (err)
179+
return err;
180+
181+
return xe_late_bind_fw_init(late_bind);
84182
}

drivers/gpu/drm/xe/xe_late_bind_fw_types.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,34 @@
1010
#include <linux/mutex.h>
1111
#include <linux/types.h>
1212

13+
#define XE_LB_MAX_PAYLOAD_SIZE SZ_4K
14+
15+
/**
16+
* xe_late_bind_fw_id - enum to determine late binding fw index
17+
*/
18+
enum xe_late_bind_fw_id {
19+
XE_LB_FW_FAN_CONTROL = 0,
20+
XE_LB_FW_MAX_ID
21+
};
22+
23+
/**
24+
* struct xe_late_bind_fw
25+
*/
26+
struct xe_late_bind_fw {
27+
/** @id: firmware index */
28+
u32 id;
29+
/** @blob_path: firmware binary path */
30+
char blob_path[PATH_MAX];
31+
/** @type: firmware type */
32+
u32 type;
33+
/** @flags: firmware flags */
34+
u32 flags;
35+
/** @payload: to store the late binding blob */
36+
const u8 *payload;
37+
/** @payload_size: late binding blob payload_size */
38+
size_t payload_size;
39+
};
40+
1341
/**
1442
* struct xe_late_bind_component - Late Binding services component
1543
* @mei_dev: device that provide Late Binding service.
@@ -28,6 +56,8 @@ struct xe_late_bind_component {
2856
struct xe_late_bind {
2957
/** @component: struct for communication with mei component */
3058
struct xe_late_bind_component component;
59+
/** @late_bind_fw: late binding firmware array */
60+
struct xe_late_bind_fw late_bind_fw[XE_LB_FW_MAX_ID];
3161
};
3262

3363
#endif

0 commit comments

Comments
 (0)