Skip to content

Commit f4ef514

Browse files
rfvirgilbroonie
authored andcommitted
ASoC: cs35l56: Firmware file must match the version of preloaded firmware
Check during initialization whether the firmware is already patched. If so, include the firmware version in the wm_adsp fwf_name string. If the firmware has already been patched by the BIOS the driver can only replace it if it has control of hard RESET. If the driver cannot replace the firmware, it can still load a wmfw (for ALSA control definitions) and/or a bin (for additional tunings). But these must match the version of firmware that is running on the CS35L56. The firmware is pre-patched if FIRMWARE_MISSING == 0. Including the firmware version in the fwf_name string will qualify the firmware file name: Normal (unpatched or replaceable firmware): cs35l56-rev-dsp1-misc[-system_name].[wmfw|bin] Preloaded firmware: cs35l56-rev[-s]-VVVVVV-dsp1-misc[-system_name].[wmfw|bin] Where: [-s] is an optional -s added into the name for a secured CS35L56 VVVVVV is the 24-bit firmware version in hexadecimal. Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com> Fixes: 608f1b0 ("ASoC: cs35l56: Move DSP part string generation so that it is done only once") Link: https://msgid.link/r/20240129162737.497-13-rf@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent f6c9679 commit f4ef514

File tree

3 files changed

+65
-26
lines changed

3 files changed

+65
-26
lines changed

include/sound/cs35l56.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
#define CS35L56_DSP1_AHBM_WINDOW_DEBUG_0 0x25E2040
7676
#define CS35L56_DSP1_AHBM_WINDOW_DEBUG_1 0x25E2044
7777
#define CS35L56_DSP1_XMEM_UNPACKED24_0 0x2800000
78+
#define CS35L56_DSP1_FW_VER 0x2800010
7879
#define CS35L56_DSP1_HALO_STATE_A1 0x2801E58
7980
#define CS35L56_DSP1_HALO_STATE 0x28021E0
8081
#define CS35L56_DSP1_PM_CUR_STATE_A1 0x2804000
@@ -285,6 +286,8 @@ int cs35l56_is_fw_reload_needed(struct cs35l56_base *cs35l56_base);
285286
int cs35l56_runtime_suspend_common(struct cs35l56_base *cs35l56_base);
286287
int cs35l56_runtime_resume_common(struct cs35l56_base *cs35l56_base, bool is_soundwire);
287288
void cs35l56_init_cs_dsp(struct cs35l56_base *cs35l56_base, struct cs_dsp *cs_dsp);
289+
int cs35l56_read_prot_status(struct cs35l56_base *cs35l56_base,
290+
bool *fw_missing, unsigned int *fw_version);
288291
int cs35l56_hw_init(struct cs35l56_base *cs35l56_base);
289292
int cs35l56_get_bclk_freq_id(unsigned int freq);
290293
void cs35l56_fill_supply_names(struct regulator_bulk_data *data);

sound/soc/codecs/cs35l56-shared.c

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -628,10 +628,35 @@ void cs35l56_init_cs_dsp(struct cs35l56_base *cs35l56_base, struct cs_dsp *cs_ds
628628
}
629629
EXPORT_SYMBOL_NS_GPL(cs35l56_init_cs_dsp, SND_SOC_CS35L56_SHARED);
630630

631+
int cs35l56_read_prot_status(struct cs35l56_base *cs35l56_base,
632+
bool *fw_missing, unsigned int *fw_version)
633+
{
634+
unsigned int prot_status;
635+
int ret;
636+
637+
ret = regmap_read(cs35l56_base->regmap, CS35L56_PROTECTION_STATUS, &prot_status);
638+
if (ret) {
639+
dev_err(cs35l56_base->dev, "Get PROTECTION_STATUS failed: %d\n", ret);
640+
return ret;
641+
}
642+
643+
*fw_missing = !!(prot_status & CS35L56_FIRMWARE_MISSING);
644+
645+
ret = regmap_read(cs35l56_base->regmap, CS35L56_DSP1_FW_VER, fw_version);
646+
if (ret) {
647+
dev_err(cs35l56_base->dev, "Get FW VER failed: %d\n", ret);
648+
return ret;
649+
}
650+
651+
return 0;
652+
}
653+
EXPORT_SYMBOL_NS_GPL(cs35l56_read_prot_status, SND_SOC_CS35L56_SHARED);
654+
631655
int cs35l56_hw_init(struct cs35l56_base *cs35l56_base)
632656
{
633657
int ret;
634-
unsigned int devid, revid, otpid, secured;
658+
unsigned int devid, revid, otpid, secured, fw_ver;
659+
bool fw_missing;
635660

636661
/*
637662
* When the system is not using a reset_gpio ensure the device is
@@ -690,8 +715,13 @@ int cs35l56_hw_init(struct cs35l56_base *cs35l56_base)
690715
return ret;
691716
}
692717

693-
dev_info(cs35l56_base->dev, "Cirrus Logic CS35L56%s Rev %02X OTP%d\n",
694-
cs35l56_base->secured ? "s" : "", cs35l56_base->rev, otpid);
718+
ret = cs35l56_read_prot_status(cs35l56_base, &fw_missing, &fw_ver);
719+
if (ret)
720+
return ret;
721+
722+
dev_info(cs35l56_base->dev, "Cirrus Logic CS35L56%s Rev %02X OTP%d fw:%d.%d.%d (patched=%u)\n",
723+
cs35l56_base->secured ? "s" : "", cs35l56_base->rev, otpid,
724+
fw_ver >> 16, (fw_ver >> 8) & 0xff, fw_ver & 0xff, !fw_missing);
695725

696726
/* Wake source and *_BLOCKED interrupts default to unmasked, so mask them */
697727
regmap_write(cs35l56_base->regmap, CS35L56_IRQ1_MASK_20, 0xffffffff);

sound/soc/codecs/cs35l56.c

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -804,7 +804,7 @@ static struct snd_soc_dai_driver cs35l56_dai[] = {
804804
}
805805
};
806806

807-
static void cs35l56_secure_patch(struct cs35l56_private *cs35l56)
807+
static void cs35l56_reinit_patch(struct cs35l56_private *cs35l56)
808808
{
809809
int ret;
810810

@@ -816,19 +816,10 @@ static void cs35l56_secure_patch(struct cs35l56_private *cs35l56)
816816
cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_REINIT);
817817
}
818818

819-
static void cs35l56_patch(struct cs35l56_private *cs35l56)
819+
static void cs35l56_patch(struct cs35l56_private *cs35l56, bool firmware_missing)
820820
{
821-
unsigned int firmware_missing;
822821
int ret;
823822

824-
ret = regmap_read(cs35l56->base.regmap, CS35L56_PROTECTION_STATUS, &firmware_missing);
825-
if (ret) {
826-
dev_err(cs35l56->base.dev, "Failed to read PROTECTION_STATUS: %d\n", ret);
827-
return;
828-
}
829-
830-
firmware_missing &= CS35L56_FIRMWARE_MISSING;
831-
832823
/*
833824
* Disable SoundWire interrupts to prevent race with IRQ work.
834825
* Setting sdw_irq_no_unmask prevents the handler re-enabling
@@ -901,34 +892,49 @@ static void cs35l56_dsp_work(struct work_struct *work)
901892
struct cs35l56_private *cs35l56 = container_of(work,
902893
struct cs35l56_private,
903894
dsp_work);
895+
unsigned int firmware_version;
896+
bool firmware_missing;
897+
int ret;
904898

905899
if (!cs35l56->base.init_done)
906900
return;
907901

908902
pm_runtime_get_sync(cs35l56->base.dev);
909903

904+
ret = cs35l56_read_prot_status(&cs35l56->base, &firmware_missing, &firmware_version);
905+
if (ret)
906+
goto err;
907+
910908
/* Populate fw file qualifier with the revision and security state */
911-
if (!cs35l56->dsp.fwf_name) {
912-
cs35l56->dsp.fwf_name = kasprintf(GFP_KERNEL, "%02x%s-dsp1",
909+
kfree(cs35l56->dsp.fwf_name);
910+
if (firmware_missing) {
911+
cs35l56->dsp.fwf_name = kasprintf(GFP_KERNEL, "%02x-dsp1", cs35l56->base.rev);
912+
} else {
913+
/* Firmware files must match the running firmware version */
914+
cs35l56->dsp.fwf_name = kasprintf(GFP_KERNEL,
915+
"%02x%s-%06x-dsp1",
913916
cs35l56->base.rev,
914-
cs35l56->base.secured ? "-s" : "");
915-
if (!cs35l56->dsp.fwf_name)
916-
goto err;
917+
cs35l56->base.secured ? "-s" : "",
918+
firmware_version);
917919
}
918920

921+
if (!cs35l56->dsp.fwf_name)
922+
goto err;
923+
919924
dev_dbg(cs35l56->base.dev, "DSP fwf name: '%s' system name: '%s'\n",
920925
cs35l56->dsp.fwf_name, cs35l56->dsp.system_name);
921926

922927
/*
923-
* When the device is running in secure mode the firmware files can
924-
* only contain insecure tunings and therefore we do not need to
925-
* shutdown the firmware to apply them and can use the lower cost
926-
* reinit sequence instead.
928+
* The firmware cannot be patched if it is already running from
929+
* patch RAM. In this case the firmware files are versioned to
930+
* match the running firmware version and will only contain
931+
* tunings. We do not need to shutdown the firmware to apply
932+
* tunings so can use the lower cost reinit sequence instead.
927933
*/
928-
if (cs35l56->base.secured)
929-
cs35l56_secure_patch(cs35l56);
934+
if (!firmware_missing)
935+
cs35l56_reinit_patch(cs35l56);
930936
else
931-
cs35l56_patch(cs35l56);
937+
cs35l56_patch(cs35l56, firmware_missing);
932938

933939

934940
/*

0 commit comments

Comments
 (0)