Unverified Commit d7e36da6 authored by Mark Brown's avatar Mark Brown
Browse files

firmware: cirrus: cs_dsp: Add long-offset WMDR

Merge series from Richard Fitzgerald <rf@opensource.cirrus.com>:

Version 3 of the WMDR file format introduces a new block type that has a
32-bit address offset.

The first patch of this series adds the support to the cs_dsp driver.

The rest of the series is adding KUnit tests for this.
parents 49d3bd9f 211243b6
Loading
Loading
Loading
Loading
+15 −4
Original line number Diff line number Diff line
@@ -2138,7 +2138,8 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware
	const struct cs_dsp_region *mem;
	struct cs_dsp_alg_region *alg_region;
	const char *region_name;
	int ret, pos, blocks, type, offset, reg, version;
	int ret, pos, blocks, type, version;
	unsigned int offset, reg;
	u8 *buf = NULL;
	size_t buf_len = 0;
	size_t region_len;
@@ -2163,6 +2164,7 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware
	switch (be32_to_cpu(hdr->rev) & 0xff) {
	case 1:
	case 2:
	case 3:
		break;
	default:
		cs_dsp_err(dsp, "%s: Unsupported coefficient file format %d\n",
@@ -2171,7 +2173,8 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware
		goto out_fw;
	}

	cs_dsp_info(dsp, "%s: v%d.%d.%d\n", file,
	cs_dsp_info(dsp, "%s (v%d): v%d.%d.%d\n", file,
		    be32_to_cpu(hdr->rev) & 0xff,
		    (le32_to_cpu(hdr->ver) >> 16) & 0xff,
		    (le32_to_cpu(hdr->ver) >>  8) & 0xff,
		    le32_to_cpu(hdr->ver) & 0xff);
@@ -2202,8 +2205,9 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware
			   (le32_to_cpu(blk->ver) >> 16) & 0xff,
			   (le32_to_cpu(blk->ver) >>  8) & 0xff,
			   le32_to_cpu(blk->ver) & 0xff);
		cs_dsp_dbg(dsp, "%s.%d: %d bytes at 0x%x in %x\n",
			   file, blocks, le32_to_cpu(blk->len), offset, type);
		cs_dsp_dbg(dsp, "%s.%d: %d bytes off:%#x off32:%#x in %#x\n",
			   file, blocks, le32_to_cpu(blk->len), offset,
			   le32_to_cpu(blk->offset32), type);

		reg = 0;
		region_name = "Unknown";
@@ -2236,6 +2240,13 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware
			}
			break;

		case WMFW_ADSP2_XM_LONG:
		case WMFW_ADSP2_YM_LONG:
		case WMFW_HALO_XM_PACKED_LONG:
		case WMFW_HALO_YM_PACKED_LONG:
			offset = le32_to_cpu(blk->offset32);
			type &= 0xff; /* strip extended block type flags */
			fallthrough;
		case WMFW_ADSP1_DM:
		case WMFW_ADSP1_ZM:
		case WMFW_ADSP2_XM:
+34 −4
Original line number Diff line number Diff line
@@ -56,13 +56,14 @@ EXPORT_SYMBOL_NS_GPL(cs_dsp_mock_bin_get_firmware, "FW_CS_DSP_KUNIT_TEST_UTILS")
 * @alg_id:		Algorithm ID.
 * @alg_ver:		Algorithm version.
 * @type:		Type of the block.
 * @offset:		Offset.
 * @offset:		16-bit offset.
 * @offset32:		32-bit offset (sample rate on V1 and V2 file formats).
 * @payload_data:	Pointer to buffer containing the payload data.
 * @payload_len_bytes:	Length of payload data in bytes.
 */
void cs_dsp_mock_bin_add_raw_block(struct cs_dsp_mock_bin_builder *builder,
				   unsigned int alg_id, unsigned int alg_ver,
				   int type, unsigned int offset,
				   int type, u16 offset, u32 offset32,
				   const void *payload_data, size_t payload_len_bytes)
{
	struct wmfw_coeff_item *item;
@@ -75,6 +76,7 @@ void cs_dsp_mock_bin_add_raw_block(struct cs_dsp_mock_bin_builder *builder,
	item = builder->write_p;

	item->offset = cpu_to_le16(offset);
	item->offset32 = cpu_to_le32(offset32);
	item->type = cpu_to_le16(type);
	item->id = cpu_to_le32(alg_id);
	item->ver = cpu_to_le32(alg_ver << 8);
@@ -104,7 +106,7 @@ static void cs_dsp_mock_bin_add_name_or_info(struct cs_dsp_mock_bin_builder *bui
		info = tmp;
	}

	cs_dsp_mock_bin_add_raw_block(builder, 0, 0, WMFW_INFO_TEXT, 0, info, info_len);
	cs_dsp_mock_bin_add_raw_block(builder, 0, 0, WMFW_INFO_TEXT, 0, 0, info, info_len);
	kunit_kfree(builder->test_priv->test, tmp);
}

@@ -156,11 +158,39 @@ void cs_dsp_mock_bin_add_patch(struct cs_dsp_mock_bin_builder *builder,
	KUNIT_ASSERT_EQ(builder->test_priv->test, payload_len_bytes % 4, 0);

	cs_dsp_mock_bin_add_raw_block(builder, alg_id, alg_ver,
				      mem_region, reg_addr_offset,
				      mem_region, (u16)reg_addr_offset, 0,
				      payload_data, payload_len_bytes);
}
EXPORT_SYMBOL_NS_GPL(cs_dsp_mock_bin_add_patch, "FW_CS_DSP_KUNIT_TEST_UTILS");

/**
 * cs_dsp_mock_bin_add_patch_off32() - Add a patch data block with 32-bit offset.
 *
 * @builder:		Pointer to struct cs_dsp_mock_bin_builder.
 * @alg_id:		Algorithm ID for the patch.
 * @alg_ver:		Algorithm version for the patch.
 * @mem_region:		Memory region for the patch.
 * @reg_addr_offset:	Offset to start of data in register addresses.
 * @payload_data:	Pointer to buffer containing the payload data.
 * @payload_len_bytes:	Length of payload data in bytes.
 */
void cs_dsp_mock_bin_add_patch_off32(struct cs_dsp_mock_bin_builder *builder,
				     unsigned int alg_id, unsigned int alg_ver,
				     int mem_region, unsigned int reg_addr_offset,
				     const void *payload_data, size_t payload_len_bytes)
{
	/* Payload length must be a multiple of 4 */
	KUNIT_ASSERT_EQ(builder->test_priv->test, payload_len_bytes % 4, 0);

	/* Mark the block as using the 32-bit offset */
	mem_region |= 0xf400;

	cs_dsp_mock_bin_add_raw_block(builder, alg_id, alg_ver,
				      mem_region, 0, reg_addr_offset,
				      payload_data, payload_len_bytes);
}
EXPORT_SYMBOL_NS_GPL(cs_dsp_mock_bin_add_patch_off32, "FW_CS_DSP_KUNIT_TEST_UTILS");

/**
 * cs_dsp_mock_bin_init() - Initialize a struct cs_dsp_mock_bin_builder.
 *
+4 −4
Original line number Diff line number Diff line
@@ -23,10 +23,10 @@ EXPORT_SYMBOL_NS_GPL(cs_dsp_mock_halo_dsp1_regions, "FW_CS_DSP_KUNIT_TEST_UTILS"
/*  List of sizes in bytes, for each entry above */
const unsigned int cs_dsp_mock_halo_dsp1_region_sizes[] = {
	0x5000,		/* PM_PACKED */
	0x6000,		/* XM_PACKED */
	0x47F4,		/* YM_PACKED */
	0x8000,		/* XM_UNPACKED_24 */
	0x5FF8,		/* YM_UNPACKED_24 */
	0x8fff4,	/* XM_PACKED */
	0x8fff4,	/* YM_PACKED */
	0xbfff8,	/* XM_UNPACKED_24 */
	0xbfff8,	/* YM_UNPACKED_24 */

	0		/* terminator */
};
+8 −8
Original line number Diff line number Diff line
@@ -157,22 +157,22 @@ static const struct reg_default halo_register_defaults[] = {
};

static const struct regmap_range halo_readable_registers[] = {
	regmap_reg_range(0x2000000, 0x2005fff), /* XM_PACKED */
	regmap_reg_range(0x2000000, 0x208fff0), /* XM_PACKED */
	regmap_reg_range(0x25e0000, 0x25e004f), /* SYSINFO */
	regmap_reg_range(0x25e2000, 0x25e2047), /* SYSINFO */
	regmap_reg_range(0x2800000, 0x2807fff), /* XM */
	regmap_reg_range(0x2800000, 0x28bfff4), /* XM */
	regmap_reg_range(0x2b80000, 0x2bc700b), /* CORE CTRL */
	regmap_reg_range(0x2c00000, 0x2c047f3), /* YM_PACKED */
	regmap_reg_range(0x3400000, 0x3405ff7), /* YM */
	regmap_reg_range(0x2c00000, 0x2c8fff0), /* YM_PACKED */
	regmap_reg_range(0x3400000, 0x34bfff4), /* YM */
	regmap_reg_range(0x3800000, 0x3804fff), /* PM_PACKED */
};

static const struct regmap_range halo_writeable_registers[] = {
	regmap_reg_range(0x2000000, 0x2005fff), /* XM_PACKED */
	regmap_reg_range(0x2800000, 0x2807fff), /* XM */
	regmap_reg_range(0x2000000, 0x208fff0), /* XM_PACKED */
	regmap_reg_range(0x2800000, 0x28bfff4), /* XM */
	regmap_reg_range(0x2b80000, 0x2bc700b), /* CORE CTRL */
	regmap_reg_range(0x2c00000, 0x2c047f3), /* YM_PACKED */
	regmap_reg_range(0x3400000, 0x3405ff7), /* YM */
	regmap_reg_range(0x2c00000, 0x2c8fff0), /* YM_PACKED */
	regmap_reg_range(0x3400000, 0x34bfff4), /* YM */
	regmap_reg_range(0x3800000, 0x3804fff), /* PM_PACKED */
};

+660 −373

File changed.

Preview size limit exceeded, changes collapsed.

Loading