Skip to content

Commit f304b5c

Browse files
kv2019iplbossart
authored andcommitted
ASoC: sof: use iopoll.h macro for polled register reads
Introduce a variant of readx_poll_timeout() macro from linux/iopoll.h to SOF and use it to replace the old snd_sof_dsp_register_poll() function. Due to indirection of register i/o in SOF, we can't directly use the iopoll.h macros. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
1 parent 1a30233 commit f304b5c

File tree

6 files changed

+111
-94
lines changed

6 files changed

+111
-94
lines changed

sound/soc/sof/intel/hda-dsp.c

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,21 @@
2727
int hda_dsp_core_reset_enter(struct snd_sof_dev *sdev, unsigned int core_mask)
2828
{
2929
u32 adspcs;
30+
u32 reset;
3031
int ret;
3132

3233
/* set reset bits for cores */
34+
reset = HDA_DSP_ADSPCS_CRST_MASK(core_mask);
3335
snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
3436
HDA_DSP_REG_ADSPCS,
35-
HDA_DSP_ADSPCS_CRST_MASK(core_mask),
36-
HDA_DSP_ADSPCS_CRST_MASK(core_mask));
37+
reset, reset),
3738

3839
/* poll with timeout to check if operation successful */
39-
ret = snd_sof_dsp_register_poll(sdev, HDA_DSP_BAR,
40-
HDA_DSP_REG_ADSPCS,
41-
HDA_DSP_ADSPCS_CRST_MASK(core_mask),
42-
HDA_DSP_ADSPCS_CRST_MASK(core_mask),
43-
HDA_DSP_RESET_TIMEOUT,
44-
HDA_DSP_REG_POLL_INTERVAL_US);
40+
ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
41+
HDA_DSP_REG_ADSPCS, adspcs,
42+
((adspcs & reset) == reset),
43+
HDA_DSP_REG_POLL_INTERVAL_US,
44+
HDA_DSP_RESET_TIMEOUT_US);
4545

4646
/* has core entered reset ? */
4747
adspcs = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
@@ -59,6 +59,7 @@ int hda_dsp_core_reset_enter(struct snd_sof_dev *sdev, unsigned int core_mask)
5959

6060
int hda_dsp_core_reset_leave(struct snd_sof_dev *sdev, unsigned int core_mask)
6161
{
62+
unsigned int crst;
6263
u32 adspcs;
6364
int ret;
6465

@@ -69,11 +70,12 @@ int hda_dsp_core_reset_leave(struct snd_sof_dev *sdev, unsigned int core_mask)
6970
0);
7071

7172
/* poll with timeout to check if operation successful */
72-
ret = snd_sof_dsp_register_poll(sdev, HDA_DSP_BAR,
73-
HDA_DSP_REG_ADSPCS,
74-
HDA_DSP_ADSPCS_CRST_MASK(core_mask), 0,
75-
HDA_DSP_RESET_TIMEOUT,
76-
HDA_DSP_REG_POLL_INTERVAL_US);
73+
crst = HDA_DSP_ADSPCS_CRST_MASK(core_mask);
74+
ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
75+
HDA_DSP_REG_ADSPCS, adspcs,
76+
!(adspcs & crst),
77+
HDA_DSP_REG_POLL_INTERVAL_US,
78+
HDA_DSP_RESET_TIMEOUT_US);
7779

7880
/* has core left reset ? */
7981
adspcs = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
@@ -133,6 +135,7 @@ int hda_dsp_core_run(struct snd_sof_dev *sdev, unsigned int core_mask)
133135

134136
int hda_dsp_core_power_up(struct snd_sof_dev *sdev, unsigned int core_mask)
135137
{
138+
unsigned int cpa;
136139
u32 adspcs;
137140
int ret;
138141

@@ -142,12 +145,12 @@ int hda_dsp_core_power_up(struct snd_sof_dev *sdev, unsigned int core_mask)
142145
HDA_DSP_ADSPCS_SPA_MASK(core_mask));
143146

144147
/* poll with timeout to check if operation successful */
145-
ret = snd_sof_dsp_register_poll(sdev, HDA_DSP_BAR,
146-
HDA_DSP_REG_ADSPCS,
147-
HDA_DSP_ADSPCS_CPA_MASK(core_mask),
148-
HDA_DSP_ADSPCS_CPA_MASK(core_mask),
149-
HDA_DSP_PU_TIMEOUT,
150-
HDA_DSP_REG_POLL_INTERVAL_US);
148+
cpa = HDA_DSP_ADSPCS_CPA_MASK(core_mask);
149+
ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
150+
HDA_DSP_REG_ADSPCS, adspcs,
151+
(adspcs & cpa) == cpa,
152+
HDA_DSP_REG_POLL_INTERVAL_US,
153+
HDA_DSP_RESET_TIMEOUT_US);
151154
if (ret < 0)
152155
dev_err(sdev->dev, "error: timeout on core powerup\n");
153156

@@ -167,16 +170,18 @@ int hda_dsp_core_power_up(struct snd_sof_dev *sdev, unsigned int core_mask)
167170

168171
int hda_dsp_core_power_down(struct snd_sof_dev *sdev, unsigned int core_mask)
169172
{
173+
u32 adspcs;
174+
170175
/* update bits */
171176
snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
172177
HDA_DSP_REG_ADSPCS,
173178
HDA_DSP_ADSPCS_SPA_MASK(core_mask), 0);
174179

175-
/* poll with timeout to check if operation successful */
176-
return snd_sof_dsp_register_poll(sdev, HDA_DSP_BAR,
177-
HDA_DSP_REG_ADSPCS, HDA_DSP_ADSPCS_CPA_MASK(core_mask), 0,
178-
HDA_DSP_PD_TIMEOUT,
179-
HDA_DSP_REG_POLL_INTERVAL_US);
180+
return snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
181+
HDA_DSP_REG_ADSPCS, adspcs,
182+
!(adspcs & HDA_DSP_ADSPCS_SPA_MASK(core_mask)),
183+
HDA_DSP_REG_POLL_INTERVAL_US,
184+
HDA_DSP_PD_TIMEOUT * USEC_PER_MSEC);
180185
}
181186

182187
bool hda_dsp_core_is_enabled(struct snd_sof_dev *sdev,

sound/soc/sof/intel/hda-loader-skl.c

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ static void cl_cleanup_skl(struct snd_sof_dev *sdev)
305305

306306
static int cl_dsp_init_skl(struct snd_sof_dev *sdev)
307307
{
308+
unsigned int sts;
308309
int ret;
309310

310311
/*
@@ -353,11 +354,12 @@ static int cl_dsp_init_skl(struct snd_sof_dev *sdev)
353354
hda_dsp_ipc_int_enable(sdev);
354355

355356
/* polling the ROM init status information. */
356-
ret = snd_sof_dsp_register_poll(sdev, HDA_DSP_BAR,
357-
HDA_ADSP_FW_STATUS_SKL,
358-
HDA_DSP_ROM_STS_MASK, HDA_DSP_ROM_INIT,
359-
HDA_DSP_INIT_TIMEOUT,
360-
HDA_DSP_REG_POLL_INTERVAL_US);
357+
ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
358+
HDA_ADSP_FW_STATUS_SKL, sts,
359+
((sts & HDA_DSP_ROM_STS_MASK)
360+
== HDA_DSP_ROM_INIT),
361+
HDA_DSP_REG_POLL_INTERVAL_US,
362+
HDA_DSP_INIT_TIMEOUT_US);
361363
if (ret < 0)
362364
goto err;
363365

@@ -432,6 +434,7 @@ static int cl_copy_fw_skl(struct snd_sof_dev *sdev)
432434
struct snd_sof_pdata *plat_data = sdev->pdata;
433435
const struct firmware *fw = plat_data->fw;
434436
unsigned int bufsize = HDA_SKL_CLDMA_MAX_BUFFER_SIZE;
437+
unsigned int status;
435438
int ret = 0;
436439

437440
dev_dbg(sdev->dev, "firmware size: 0x%zx buffer size 0x%x\n", fw->size,
@@ -443,12 +446,12 @@ static int cl_copy_fw_skl(struct snd_sof_dev *sdev)
443446
return ret;
444447
}
445448

446-
ret = snd_sof_dsp_register_poll(sdev, HDA_DSP_BAR,
447-
HDA_ADSP_FW_STATUS_SKL,
448-
HDA_DSP_ROM_STS_MASK,
449-
HDA_DSP_ROM_FW_FW_LOADED,
450-
HDA_DSP_BASEFW_TIMEOUT,
451-
HDA_DSP_REG_POLL_INTERVAL_US);
449+
ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
450+
HDA_ADSP_FW_STATUS_SKL, status,
451+
((status & HDA_DSP_ROM_STS_MASK)
452+
== HDA_DSP_ROM_FW_FW_LOADED),
453+
HDA_DSP_REG_POLL_INTERVAL_US,
454+
HDA_DSP_BASEFW_TIMEOUT_US);
452455
if (ret < 0)
453456
dev_err(sdev->dev, "error: firmware transfer timeout!");
454457

sound/soc/sof/intel/hda-loader.c

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, const void *fwdata,
8282
{
8383
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
8484
const struct sof_intel_dsp_desc *chip = hda->desc;
85+
unsigned int status;
8586
int ret;
8687

8788
/* step 1: power up corex */
@@ -105,11 +106,12 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, const void *fwdata,
105106
}
106107

107108
/* step 4: wait for IPC DONE bit from ROM */
108-
ret = snd_sof_dsp_register_poll(sdev, HDA_DSP_BAR,
109-
chip->ipc_ack,
110-
chip->ipc_ack_mask, chip->ipc_ack_mask,
111-
HDA_DSP_INIT_TIMEOUT,
112-
HDA_DSP_REG_POLL_INTERVAL_US);
109+
ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
110+
chip->ipc_ack, status,
111+
((status & chip->ipc_ack_mask)
112+
== chip->ipc_ack_mask),
113+
HDA_DSP_REG_POLL_INTERVAL_US,
114+
HDA_DSP_INIT_TIMEOUT_US);
113115

114116
if (ret < 0) {
115117
dev_err(sdev->dev, "error: waiting for HIPCIE done\n");
@@ -128,11 +130,13 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, const void *fwdata,
128130
hda_dsp_ipc_int_enable(sdev);
129131

130132
/* step 7: wait for ROM init */
131-
ret = snd_sof_dsp_register_poll(sdev, HDA_DSP_BAR,
132-
HDA_DSP_SRAM_REG_ROM_STATUS,
133-
HDA_DSP_ROM_STS_MASK, HDA_DSP_ROM_INIT,
134-
chip->rom_init_timeout,
135-
HDA_DSP_REG_POLL_INTERVAL_US);
133+
ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
134+
HDA_DSP_SRAM_REG_ROM_STATUS, status,
135+
((status & HDA_DSP_ROM_STS_MASK)
136+
== HDA_DSP_ROM_INIT),
137+
HDA_DSP_REG_POLL_INTERVAL_US,
138+
chip->rom_init_timeout *
139+
USEC_PER_MSEC);
136140
if (!ret)
137141
return 0;
138142

@@ -221,6 +225,7 @@ static int cl_cleanup(struct snd_sof_dev *sdev, struct snd_dma_buffer *dmab,
221225

222226
static int cl_copy_fw(struct snd_sof_dev *sdev, struct hdac_ext_stream *stream)
223227
{
228+
unsigned int reg;
224229
int ret, status;
225230

226231
ret = cl_trigger(sdev, stream, SNDRV_PCM_TRIGGER_START);
@@ -229,12 +234,12 @@ static int cl_copy_fw(struct snd_sof_dev *sdev, struct hdac_ext_stream *stream)
229234
return ret;
230235
}
231236

232-
status = snd_sof_dsp_register_poll(sdev, HDA_DSP_BAR,
233-
HDA_DSP_SRAM_REG_ROM_STATUS,
234-
HDA_DSP_ROM_STS_MASK,
235-
HDA_DSP_ROM_FW_ENTERED,
236-
HDA_DSP_BASEFW_TIMEOUT,
237-
HDA_DSP_REG_POLL_INTERVAL_US);
237+
status = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
238+
HDA_DSP_SRAM_REG_ROM_STATUS, reg,
239+
((reg & HDA_DSP_ROM_STS_MASK)
240+
== HDA_DSP_ROM_FW_ENTERED),
241+
HDA_DSP_REG_POLL_INTERVAL_US,
242+
HDA_DSP_BASEFW_TIMEOUT_US);
238243

239244
ret = cl_trigger(sdev, stream, SNDRV_PCM_TRIGGER_STOP);
240245
if (ret < 0) {

sound/soc/sof/intel/hda.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,9 @@
195195
/* various timeout values */
196196
#define HDA_DSP_PU_TIMEOUT 50
197197
#define HDA_DSP_PD_TIMEOUT 50
198-
#define HDA_DSP_RESET_TIMEOUT 50
199-
#define HDA_DSP_BASEFW_TIMEOUT 3000
200-
#define HDA_DSP_INIT_TIMEOUT 500
198+
#define HDA_DSP_RESET_TIMEOUT_US 50000
199+
#define HDA_DSP_BASEFW_TIMEOUT_US 3000000
200+
#define HDA_DSP_INIT_TIMEOUT_US 500000
201201
#define HDA_DSP_CTRL_RESET_TIMEOUT 100
202202
#define HDA_DSP_WAIT_TIMEOUT 500 /* 500 msec */
203203
#define HDA_DSP_REG_POLL_INTERVAL_US 500 /* 0.5 msec */

sound/soc/sof/ops.c

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -142,46 +142,6 @@ void snd_sof_dsp_update_bits_forced(struct snd_sof_dev *sdev, u32 bar,
142142
}
143143
EXPORT_SYMBOL(snd_sof_dsp_update_bits_forced);
144144

145-
int snd_sof_dsp_register_poll(struct snd_sof_dev *sdev, u32 bar, u32 offset,
146-
u32 mask, u32 target, u32 timeout_ms,
147-
u32 interval_us)
148-
{
149-
u32 reg;
150-
unsigned long tout_jiff;
151-
int k = 0, s = interval_us;
152-
153-
/*
154-
* Split the loop into 2 sleep stages with varying resolution.
155-
* To do it more accurately, the range of wakeups are:
156-
* In case of interval_us = 500,
157-
* Phase 1(first 5ms): min sleep 0.5ms; max sleep 1ms.
158-
* Phase 2(beyond 5ms): min sleep 5ms; max sleep 10ms.
159-
*/
160-
161-
tout_jiff = jiffies + msecs_to_jiffies(timeout_ms);
162-
do {
163-
reg = snd_sof_dsp_read(sdev, bar, offset);
164-
if ((reg & mask) == target)
165-
break;
166-
167-
/* Phase 2 after 5ms(500us * 10) */
168-
if (++k > 10)
169-
s = interval_us * 10;
170-
171-
usleep_range(s, 2 * s);
172-
} while (time_before(jiffies, tout_jiff));
173-
174-
if ((reg & mask) == target) {
175-
dev_dbg(sdev->dev, "FW Poll Status: reg=%#x successful\n", reg);
176-
177-
return 0;
178-
}
179-
180-
dev_dbg(sdev->dev, "FW Poll Status: reg=%#x timedout\n", reg);
181-
return -ETIME;
182-
}
183-
EXPORT_SYMBOL(snd_sof_dsp_register_poll);
184-
185145
void snd_sof_dsp_panic(struct snd_sof_dev *sdev, u32 offset)
186146
{
187147
dev_err(sdev->dev, "error : DSP panic!\n");

sound/soc/sof/ops.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,50 @@ static inline const struct snd_sof_dsp_ops
376376
return NULL;
377377
}
378378

379+
/**
380+
* snd_sof_dsp_register_poll_timeout - Periodically poll an address
381+
* until a condition is met or a timeout occurs
382+
* @op: accessor function (takes @addr as its only argument)
383+
* @addr: Address to poll
384+
* @val: Variable to read the value into
385+
* @cond: Break condition (usually involving @val)
386+
* @sleep_us: Maximum time to sleep between reads in us (0
387+
* tight-loops). Should be less than ~20ms since usleep_range
388+
* is used (see Documentation/timers/timers-howto.txt).
389+
* @timeout_us: Timeout in us, 0 means never timeout
390+
*
391+
* Returns 0 on success and -ETIMEDOUT upon a timeout. In either
392+
* case, the last read value at @addr is stored in @val. Must not
393+
* be called from atomic context if sleep_us or timeout_us are used.
394+
*
395+
* This is modelled after the readx_poll_timeout macros in linux/iopoll.h.
396+
*/
397+
#define snd_sof_dsp_read_poll_timeout(sdev, bar, offset, val, cond, sleep_us, timeout_us) \
398+
({ \
399+
u64 __timeout_us = (timeout_us); \
400+
unsigned long __sleep_us = (sleep_us); \
401+
ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \
402+
might_sleep_if((__sleep_us) != 0); \
403+
for (;;) { \
404+
(val) = snd_sof_dsp_read(sdev, bar, offset); \
405+
if (cond) { \
406+
dev_dbg(sdev->dev, \
407+
"FW Poll Status: reg=%#x successful\n", (val)); \
408+
break; \
409+
} \
410+
if (__timeout_us && \
411+
ktime_compare(ktime_get(), __timeout) > 0) { \
412+
(val) = snd_sof_dsp_read(sdev, bar, offset); \
413+
dev_dbg(sdev->dev, \
414+
"FW Poll Status: reg=%#x timedout\n", (val)); \
415+
break; \
416+
} \
417+
if (__sleep_us) \
418+
usleep_range((__sleep_us >> 2) + 1, __sleep_us); \
419+
} \
420+
(cond) ? 0 : -ETIMEDOUT; \
421+
})
422+
379423
/* This is for registers bits with attribute RWC */
380424
bool snd_sof_pci_update_bits(struct snd_sof_dev *sdev, u32 offset,
381425
u32 mask, u32 value);

0 commit comments

Comments
 (0)