drivers/firmware/cirrus/test/cs_dsp_test_wmfw.c

Source file repositories/reference/linux-study-clean/drivers/firmware/cirrus/test/cs_dsp_test_wmfw.c

File Facts

System
Linux kernel
Corpus path
drivers/firmware/cirrus/test/cs_dsp_test_wmfw.c
Extension
.c
Size
86912 bytes
Lines
2242
Domain
Driver Families
Bucket
drivers/firmware
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct cs_dsp_test_local {
	struct cs_dsp_mock_xm_header *xm_header;
	struct cs_dsp_mock_wmfw_builder *wmfw_builder;
	int wmfw_version;
};

struct cs_dsp_wmfw_test_param {
	unsigned int num_blocks;
	int mem_type;
};

static const struct cs_dsp_mock_alg_def cs_dsp_wmfw_test_mock_algs[] = {
	{
		.id = 0xfafa,
		.ver = 0x100000,
		.xm_size_words = 164,
		.ym_size_words = 164,
		.zm_size_words = 164,
	},
};

/*
 * wmfw that writes the XM header.
 * cs_dsp always reads this back from unpacked XM.
 */
static void wmfw_write_xm_header_unpacked(struct kunit *test)
{
	struct cs_dsp_test *priv = test->priv;
	struct cs_dsp_test_local *local = priv->local;
	struct firmware *wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
	unsigned int reg_addr;
	u8 *readback;

	/* XM header payload was added to wmfw by test case init function */

	KUNIT_EXPECT_EQ(test,
			cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),
			0);

	/* Read raw so endianness and register width don't matter */
	readback = kunit_kzalloc(test, local->xm_header->blob_size_bytes, GFP_KERNEL);
	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);

	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, WMFW_ADSP2_XM);
	KUNIT_EXPECT_EQ(test,
			regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
					local->xm_header->blob_size_bytes),
			0);
	KUNIT_EXPECT_MEMEQ(test, readback, local->xm_header->blob_data,
			   local->xm_header->blob_size_bytes);

	/* Drop expected writes and the cache should then be clean */
	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
}

/* Write one payload of length param->num_blocks */
static void wmfw_write_one_payload(struct kunit *test)
{
	const struct cs_dsp_wmfw_test_param *param = test->param_value;
	struct cs_dsp_test *priv = test->priv;
	struct cs_dsp_test_local *local = priv->local;
	struct firmware *wmfw;
	unsigned int reg_addr;
	u8 *payload_data, *readback;
	unsigned int mem_offset_dsp_words = 0;
	unsigned int payload_size_bytes;

	payload_size_bytes = param->num_blocks *
			     cs_dsp_mock_reg_block_length_bytes(priv, param->mem_type);

	/* payloads must be a multiple of 4 bytes and a whole number of DSP registers */
	do {
		payload_size_bytes += cs_dsp_mock_reg_block_length_bytes(priv, param->mem_type);
	} while (payload_size_bytes % 4);

	payload_data = kunit_kmalloc(test, payload_size_bytes, GFP_KERNEL);
	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, payload_data);
	get_random_bytes(payload_data, payload_size_bytes);

	readback = kunit_kzalloc(test, payload_size_bytes, GFP_KERNEL);
	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);

	/* Tests on XM must be after the XM header */
	if (param->mem_type == WMFW_ADSP2_XM)
		mem_offset_dsp_words += local->xm_header->blob_size_bytes / sizeof(u32);

	/* Add a single payload */
	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
					param->mem_type, mem_offset_dsp_words,

Annotation

Implementation Notes