Skip to content

Commit

Permalink
ipts: Move ipts_fw_config.bin into the companion
Browse files Browse the repository at this point in the history
Since ipts_fw_config.bin is mapped directly onto C structs by the IPTS
driver, we can declare those values ourselves, instead of putting them
into an obscure binary file that was provided by Intel ages ago.

This could also open up the door to modifying the firmware config in
case anyone ever understands IPTS that much.

Signed-off-by: Dorian Stoll <dorian.stoll@tmsp.io>
  • Loading branch information
StollD committed Oct 25, 2019
1 parent d33ba93 commit 240ac22
Show file tree
Hide file tree
Showing 10 changed files with 203 additions and 83 deletions.
33 changes: 32 additions & 1 deletion drivers/misc/ipts/companion/ipts-surface.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#define IPTS_SURFACE_FIRMWARE(X) \
MODULE_FIRMWARE("intel/ipts/" X "/config.bin"); \
MODULE_FIRMWARE("intel/ipts/" X "/intel_desc.bin"); \
MODULE_FIRMWARE("intel/ipts/" X "/ipts_fw_config.bin"); \
MODULE_FIRMWARE("intel/ipts/" X "/vendor_desc.bin"); \
MODULE_FIRMWARE("intel/ipts/" X "/vendor_kernel.bin"); \

Expand All @@ -28,8 +27,40 @@ int ipts_surface_request_firmware(const struct firmware **fw, const char *name,
return request_firmware(fw, fw_path, device);
}

static ipts_bin_fw_info_t ipts_surface_vendor_kernel = {
.fw_name = "vendor_kernel.bin",
.vendor_output = -1,
.num_of_data_files = 3,
.data_file = {
{
.io_buffer_type = IPTS_CONFIGURATION,
.flags = IPTS_DATA_FILE_FLAG_NONE,
.file_name = "config.bin",
},

// The following files are part of the config, but they don't
// exist, and the driver never requests them.
{
.io_buffer_type = IPTS_CALIBRATION,
.flags = IPTS_DATA_FILE_FLAG_NONE,
.file_name = "calib.bin",
},
{
.io_buffer_type = IPTS_FEATURE,
.flags = IPTS_DATA_FILE_FLAG_SHARE,
.file_name = "feature.bin",
},
},
};

static ipts_bin_fw_info_t *ipts_surface_fw_config[] = {
&ipts_surface_vendor_kernel,
NULL,
};

static ipts_companion_t ipts_surface_companion = {
.firmware_request = &ipts_surface_request_firmware,
.firmware_config = ipts_surface_fw_config,
.name = "ipts_surface",
};

Expand Down
85 changes: 85 additions & 0 deletions drivers/misc/ipts/ipts-companion.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <linux/firmware.h>
#include <linux/ipts.h>
#include <linux/ipts-binary.h>
#include <linux/ipts-companion.h>
#include <linux/mutex.h>

Expand All @@ -8,6 +9,7 @@
#include "ipts-params.h"

#define IPTS_FW_PATH_FMT "intel/ipts/%s"
#define IPTS_FW_CONFIG_FILE "ipts_fw_config.bin"

ipts_companion_t *ipts_companion;
DEFINE_MUTEX(ipts_companion_lock);
Expand Down Expand Up @@ -116,3 +118,86 @@ int ipts_request_firmware(const struct firmware **fw, const char *name,
mutex_unlock(&ipts_companion_lock);
return ret;
}

ipts_bin_fw_list_t *ipts_alloc_fw_list(ipts_bin_fw_info_t **fw)
{
int size, len, i, j;
ipts_bin_fw_list_t *fw_list;
char *itr;

// Figure out the amount of firmware files inside of the array
len = 0;
while (fw[len] != NULL) {
len++;
}

// Determine the size that the final list will need in memory
size = sizeof(ipts_bin_fw_list_t);
for (i = 0; i < len; i++) {
size += sizeof(ipts_bin_fw_info_t);
size += sizeof(ipts_bin_data_file_info_t) *
fw[i]->num_of_data_files;
}

fw_list = kmalloc(size, GFP_KERNEL);
fw_list->num_of_fws = len;
itr = (char *)fw_list->fw_info;
for (i = 0; i < len; i++) {
*(ipts_bin_fw_info_t *)itr = *fw[i];
itr += sizeof(ipts_bin_fw_info_t);

for (j = 0; j < fw[i]->num_of_data_files; j++) {
*(ipts_bin_data_file_info_t *)itr = fw[i]->data_file[j];
itr += sizeof(ipts_bin_data_file_info_t);
}
}

return fw_list;
}

int ipts_request_firmware_config(ipts_info_t *ipts, ipts_bin_fw_list_t **cfg)
{
int ret = 0;
const struct firmware *config_fw = NULL;
mutex_lock(&ipts_companion_lock);

// Check if a companion was registered. If not, skip
// forward and try to load the firmware config from a file
if (ipts_modparams.ignore_companion || ipts_companion == NULL) {
goto config_fallback;
}

if (ipts_companion->firmware_config != NULL) {
*cfg = ipts_alloc_fw_list(ipts_companion->firmware_config);
goto config_return;
}

config_fallback:

// If fallback loading for the firmware config was disabled, abort.
// Return -ENOENT as no config file was found.
if (ipts_modparams.ignore_config_fallback) {
ret = -ENOENT;
goto config_return;
}

// No firmware config was found by the companion driver,
// try loading it from a file now
mutex_unlock(&ipts_companion_lock);
ret = ipts_request_firmware(&config_fw, IPTS_FW_CONFIG_FILE,
&ipts->cldev->dev);
mutex_lock(&ipts_companion_lock);

if (!ret) {
*cfg = (ipts_bin_fw_list_t *)config_fw->data;
goto config_return;
}

release_firmware(config_fw);

config_return:

mutex_unlock(&ipts_companion_lock);
return ret;

}
5 changes: 5 additions & 0 deletions drivers/misc/ipts/ipts-companion.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@
#define _IPTS_COMPANION_H_

#include <linux/firmware.h>
#include <linux/ipts-binary.h>

#include "ipts.h"

bool ipts_companion_available(void);
int ipts_request_firmware(const struct firmware **fw, const char *name,
struct device *device);
int ipts_request_firmware_config(ipts_info_t *ipts,
ipts_bin_fw_list_t **firmware_config);

#endif // _IPTS_COMPANION_H_
71 changes: 18 additions & 53 deletions drivers/misc/ipts/ipts-kernel.c
Original file line number Diff line number Diff line change
@@ -1,38 +1,16 @@
#include <linux/module.h>
#include <linux/firmware.h>
#include <linux/ipts.h>
#include <linux/ipts-binary.h>
#include <linux/vmalloc.h>

#include "ipts.h"
#include "ipts-companion.h"
#include "ipts-resource.h"
#include "ipts-binary-spec.h"
#include "ipts-state.h"
#include "ipts-msg-handler.h"
#include "ipts-gfx.h"

#pragma pack(1)
typedef struct bin_data_file_info {
u32 io_buffer_type;
u32 flags;
char file_name[MAX_IOCL_FILE_NAME_LEN];
} bin_data_file_info_t;

typedef struct bin_fw_info {
char fw_name[MAX_IOCL_FILE_NAME_LEN];

/* list of parameters to load a kernel */
s32 vendor_output; /* output index. -1 for no use */
u32 num_of_data_files;
bin_data_file_info_t data_file[];
} bin_fw_info_t;

typedef struct bin_fw_list {
u32 num_of_fws;
bin_fw_info_t fw_info[];
} bin_fw_list_t;
#pragma pack()

/* OpenCL kernel */
typedef struct bin_workload {
int cmdbuf_index;
Expand Down Expand Up @@ -80,7 +58,7 @@ typedef struct bin_parse_info {
int size;
int parsed;

bin_fw_info_t *fw_info;
ipts_bin_fw_info_t *fw_info;

/* only used by postprocessing */
bin_kernel_info_t *vendor_kernel;
Expand All @@ -92,17 +70,12 @@ typedef struct bin_parse_info {
#define SBA_OFFSET_BYTES 16384
#define LASTSUBMITID_DEFAULT_VALUE -1

#define IPTS_FW_CONFIG_FILE "ipts_fw_config.bin"

#define IPTS_INPUT_ON ((u32)1 << IPTS_INPUT)
#define IPTS_OUTPUT_ON ((u32)1 << IPTS_OUTPUT)
#define IPTS_CONFIGURATION_ON ((u32)1 << IPTS_CONFIGURATION)
#define IPTS_CALIBRATION_ON ((u32)1 << IPTS_CALIBRATION)
#define IPTS_FEATURE_ON ((u32)1 << IPTS_FEATURE)

#define DATA_FILE_FLAG_SHARE 0x00000001
#define DATA_FILE_FLAG_ALLOC_CONTIGUOUS 0x00000002

static int bin_read_fw(ipts_info_t *ipts, const char *fw_name,
u8* data, int size)
{
Expand Down Expand Up @@ -130,8 +103,8 @@ static int bin_read_fw(ipts_info_t *ipts, const char *fw_name,
}


static bin_data_file_info_t* bin_get_data_file_info(bin_fw_info_t* fw_info,
u32 io_buffer_type)
static ipts_bin_data_file_info_t* bin_get_data_file_info(
ipts_bin_fw_info_t* fw_info, u32 io_buffer_type)
{
int i;

Expand All @@ -146,18 +119,18 @@ static bin_data_file_info_t* bin_get_data_file_info(bin_fw_info_t* fw_info,
return &fw_info->data_file[i];
}

static inline bool is_shared_data(const bin_data_file_info_t *data_file)
static inline bool is_shared_data(const ipts_bin_data_file_info_t *data_file)
{
if (data_file)
return (!!(data_file->flags & DATA_FILE_FLAG_SHARE));
return (!!(data_file->flags & IPTS_DATA_FILE_FLAG_SHARE));

return false;
}

static inline bool is_alloc_cont_data(const bin_data_file_info_t *data_file)
static inline bool is_alloc_cont_data(const ipts_bin_data_file_info_t *data_file)
{
if (data_file)
return (!!(data_file->flags & DATA_FILE_FLAG_ALLOC_CONTIGUOUS));
return (!!(data_file->flags & IPTS_DATA_FILE_FLAG_ALLOC_CONTIGUOUS));

return false;
}
Expand Down Expand Up @@ -331,7 +304,7 @@ static int bin_read_res_list(ipts_info_t *ipts,
ipts_bin_res_list_t *res_list;
ipts_bin_res_t *res;
intel_ipts_mapbuffer_t *buf;
bin_data_file_info_t *data_file;
ipts_bin_data_file_info_t *data_file;
u8 *bin_data;
int i, size, parsed, parallel_idx, num_of_parallels, output_idx = -1;
int buf_idx, num_of_alloc;
Expand Down Expand Up @@ -879,13 +852,13 @@ static void unload_kernel(ipts_info_t *ipts, bin_kernel_info_t *kernel)
}
}

static int setup_kernel(ipts_info_t *ipts, bin_fw_list_t *fw_list)
static int setup_kernel(ipts_info_t *ipts, ipts_bin_fw_list_t *fw_list)
{
bin_kernel_list_t *kernel_list = NULL;
bin_kernel_info_t *kernel = NULL;
const struct firmware *fw = NULL;
bin_workload_t *wl;
bin_fw_info_t *fw_info;
ipts_bin_fw_info_t *fw_info;
char *fw_name, *fw_data;
bin_parse_info_t parse_info;
int ret = 0, kernel_idx = 0, num_of_kernels = 0;
Expand All @@ -902,7 +875,7 @@ static int setup_kernel(ipts_info_t *ipts, bin_fw_list_t *fw_list)

fw_data = (char *)&fw_list->fw_info[0];
for (kernel_idx = 0; kernel_idx < num_of_kernels; kernel_idx++) {
fw_info = (bin_fw_info_t *)fw_data;
fw_info = (ipts_bin_fw_info_t *)fw_data;
fw_name = &fw_info->fw_name[0];
vendor_output_idx = fw_info->vendor_output;
ret = ipts_request_firmware(&fw, fw_name, &ipts->cldev->dev);
Expand Down Expand Up @@ -930,8 +903,8 @@ static int setup_kernel(ipts_info_t *ipts, bin_fw_list_t *fw_list)
total_workload += kernel[kernel_idx].guc_wq_item->size;

/* advance to the next kernel */
fw_data += sizeof(bin_fw_info_t);
fw_data += sizeof(bin_data_file_info_t) * fw_info->num_of_data_files;
fw_data += sizeof(ipts_bin_fw_info_t);
fw_data += sizeof(ipts_bin_data_file_info_t) * fw_info->num_of_data_files;
}

ipts_set_wq_item_size(ipts, total_workload);
Expand Down Expand Up @@ -997,9 +970,7 @@ static void release_kernel(ipts_info_t *ipts)

int ipts_init_kernels(ipts_info_t *ipts)
{
const struct firmware *config_fw = NULL;
const char *config_fw_path = IPTS_FW_CONFIG_FILE;
bin_fw_list_t *fw_list;
ipts_bin_fw_list_t *fw_list;
int ret;

ret = ipts_open_gpu(ipts);
Expand All @@ -1008,26 +979,20 @@ int ipts_init_kernels(ipts_info_t *ipts)
return ret;
}

ret = ipts_request_firmware(&config_fw, config_fw_path, &ipts->cldev->dev);
ret = ipts_request_firmware_config(ipts, &fw_list);
if (ret) {
ipts_err(ipts, "request firmware error : %d\n", ret);
ipts_err(ipts, "request firmware config error : %d\n", ret);
goto close_gpu;
}

fw_list = (bin_fw_list_t *)config_fw->data;
ret = setup_kernel(ipts, fw_list);
if (ret) {
ipts_err(ipts, "setup kernel error : %d\n", ret);
goto close_firmware;
goto close_gpu;
}

release_firmware(config_fw);

return ret;

close_firmware:
release_firmware(config_fw);

close_gpu:
ipts_close_gpu(ipts);

Expand Down
2 changes: 1 addition & 1 deletion drivers/misc/ipts/ipts-mei.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@
#include <linux/hid.h>
#include <linux/dma-mapping.h>
#include <linux/kthread.h>
#include <linux/ipts-binary.h>

#include "ipts.h"
#include "ipts-companion.h"
#include "ipts-hid.h"
#include "ipts-params.h"
#include "ipts-msg-handler.h"
#include "ipts-mei-msgs.h"
#include "ipts-binary-spec.h"
#include "ipts-state.h"

#define IPTS_DRIVER_NAME "ipts"
Expand Down
4 changes: 4 additions & 0 deletions drivers/misc/ipts/ipts-params.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@

struct ipts_params ipts_modparams = {
.ignore_fw_fallback = false,
.ignore_config_fallback = false,
.ignore_companion = false,
.no_feedback = -1,
};

module_param_named(ignore_fw_fallback, ipts_modparams.ignore_fw_fallback, bool, 0400);
MODULE_PARM_DESC(ignore_fw_fallback, "Don't use the IPTS firmware fallback path");

module_param_named(ignore_config_fallback, ipts_modparams.ignore_config_fallback, bool, 0400);
MODULE_PARM_DESC(ignore_config_fallback, "Don't try to load the IPTS firmware config from a file");

module_param_named(ignore_companion, ipts_modparams.ignore_companion, bool, 0400);
MODULE_PARM_DESC(ignore_companion, "Don't use a companion driver to load firmware");

Expand Down
1 change: 1 addition & 0 deletions drivers/misc/ipts/ipts-params.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

struct ipts_params {
bool ignore_fw_fallback;
bool ignore_config_fallback;
bool ignore_companion;
int no_feedback;
};
Expand Down
Loading

0 comments on commit 240ac22

Please sign in to comment.