Skip to content

Commit fecc757

Browse files
authored
Merge pull request #38 from mmaka1/smp
doc: work queue for smp architectures and cavs
2 parents 50a329b + f6e065e commit fecc757

File tree

10 files changed

+309
-0
lines changed

10 files changed

+309
-0
lines changed

developer_guides/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ Developer Guides
88

99
porting
1010
drivers/index
11+
kernel/index
1112
unit_tests
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
class "struct work" as s_work {
2+
cb
3+
cb_data
4+
timeout
5+
flags
6+
}
7+
hide s_work methods
8+
9+
enum flags {
10+
SYNC
11+
ASYNC
12+
}
13+
hide flags methods
14+
15+
class "struct work_queue_timesource" as s_wq_timesource
16+
hide s_wq_timesource methods
17+
hide s_wq_timesource attributes
18+
19+
class "work_queue" as wq {
20+
+ work_schedule()
21+
+ work_reschedule()
22+
+ work_cancel()
23+
- is_work_pending()
24+
- work_next_timeout()
25+
- run_work()
26+
- work : list
27+
}
28+
29+
class client #a1a1ca
30+
hide client methods
31+
hide client attributes
32+
33+
wq o- s_work
34+
wq <- s_wq_timesource : provides timer INT
35+
36+
s_work - flags
37+
38+
client -> s_work : (1) creates
39+
client ---> wq : (2) schedules work
40+
wq ---> client : (3) calls cb(cb_data) upon timeout
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
actor client as c
2+
3+
participant work_queue as wq
4+
participant timer as t
5+
6+
-> wq : work_new_queue
7+
wq -> t : timer_register(queue_run)
8+
<-- wq
9+
10+
c -> wq : work_schedule(&work)
11+
activate wq
12+
13+
wq -> wq : queue_reschedule()
14+
activate wq
15+
wq -> wq : queue_get_next_timeout() : timeout
16+
wq -> t : work_set_timer(timeout)
17+
deactivate wq
18+
c <-- wq
19+
deactivate wq
20+
...
21+
wq <- t : queue_run()
22+
activate wq
23+
loop is_work_pending()
24+
wq -> wq : run_work()
25+
end loop
26+
wq -> wq : queue_reschedule()

developer_guides/kernel/index.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.. _kernel:
2+
3+
Kernel
4+
######
5+
6+
.. toctree::
7+
:maxdepth: 1
8+
9+
work-queue
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
.. _work-queue:
2+
3+
Work Queue
4+
##########
5+
6+
Work queue service provides timer API for other FW parts. A timer API client (a
7+
component, device, ...) registers a callback and specifies when the callback
8+
should be invoked.
9+
10+
Refer to TBD for full API specification.
11+
12+
A source of time for the work queue is implemented by the specific platform
13+
and depends on the underlying architecture and the HW capabilities which
14+
determine the resolution of the timer.
15+
16+
.. uml:: images/work-queue-deps.pu
17+
:caption: Work queue dependencies
18+
19+
Basic Work Queue Flow
20+
*********************
21+
22+
.. uml:: images/work-schedule.pu
23+
:caption: Basic work queue flow
24+
25+
Extensions for SMP Architectures
26+
********************************
27+
28+
There is one instance of the work queue per CPU, created on platforms built
29+
upon SMP architectures. A client registers its callback in the queue instance
30+
that is running on the CPU the callback is supposed to run.
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
participant ipc
2+
participant "core 0" as core_0
3+
participant "core 1" as core_1
4+
participant wallclk
5+
6+
ipc -> core_0 : new pipeline 0 (@core 0)
7+
activate core_0
8+
core_0 -> wallclk : timer_register()
9+
core_0 -> core_0 : work_schedule(ppl 0 dai, +1ms)
10+
core_0 -> wallclk : work_set_timer(period = +1ms)
11+
ipc <-- core_0
12+
deactivate core_0
13+
14+
wallclk -> core_0 : cb() @ next ms
15+
activate core_0
16+
core_0 -> core_0 : ppl 0 dai cb()
17+
activate core_0
18+
core_0 -> core_0 : ppl 0 copy
19+
core_0 -> core_0 : work_schedule(ppl 0 dai, +1ms)
20+
deactivate core_0
21+
core_0 -> wallclk : work_set_timer()
22+
deactivate core_0
23+
24+
ipc -> core_0 : new pipeline 1 (@core 1)
25+
core_0 -> core_1
26+
activate core_1
27+
core_1 -> wallclk : timer_register()
28+
core_1 -> core_1 : work_schedule(ppl 1 dai)
29+
core_0 <-- core_1
30+
deactivate core_1
31+
32+
wallclk -> core_0 : cb() @ next ms
33+
activate core_0
34+
activate core_1
35+
core_0 -> core_0 : ppl 0 dai cb()
36+
activate core_0
37+
core_0 -> core_0 : ppl 0 copy
38+
core_0 -> core_0 : work_schedule(ppl 0 dai, +1ms)
39+
deactivate core_0
40+
core_1 -> core_1 : ppl 1 dai cb()
41+
activate core_1
42+
core_1 -> core_1 : ppl 1 copy
43+
core_1 -> core_1 : work_schedule(ppl 1 dai, +1ms)
44+
deactivate core_1
45+
deactivate core_1
46+
core_0 -> wallclk : work_set_timer()
47+
deactivate core_0
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
scale max 800 height
2+
3+
skinparam rectangle {
4+
backgroundColor<<dai>> #6fccdd
5+
backgroundColor<<dma>> #f6ed80
6+
backgroundColor<<stream>> #d6d6de
7+
borderColor<<stream>> #d6d6de
8+
borderColor<<ppl>> #a1a1ca
9+
10+
backgroundColor<<event>> #f05772
11+
stereotypeFontColor<<event>> #ffffff
12+
fontColor<<event>> #ffffff
13+
14+
backgroundColor<<cpu>> #f0f0f0
15+
}
16+
17+
together {
18+
' ssp dais
19+
rectangle "ssp-dai #0" as ssp_0 <<dai>>
20+
rectangle "ssp-dai #1" as ssp_1 <<dai>>
21+
' hda dais
22+
rectangle "hda-dai #0" as hda_0 <<dai>>
23+
}
24+
25+
rectangle "core #0" <<cpu>> {
26+
27+
together {
28+
rectangle "hda-dma\nhost output #0" as hda_dma_ho_0 <<dma>>
29+
rectangle "hda-dma\nhost input #0" as hda_dma_hi_0 <<dma>>
30+
}
31+
together {
32+
rectangle "dw-dma #0" as dw_dma_0 <<dma>>
33+
rectangle "dw-dma #1" as dw_dma_1 <<dma>>
34+
}
35+
36+
rectangle "playback #0" <<stream>> {
37+
38+
rectangle "ppl #0" as ppl_0 <<ppl>> {
39+
rectangle "host comp" as host_0
40+
rectangle "vol" as vol_0
41+
rectangle "mix-in" as mix_in_0
42+
43+
host_0 --> vol_0
44+
vol_0 --> mix_in_0
45+
}
46+
47+
rectangle "ppl #1" as ppl_1 <<ppl>> {
48+
rectangle "mix-out" as mix_out_1
49+
rectangle "dai comp" as dai_1
50+
51+
mix_out_1 --> dai_1
52+
}
53+
mix_in_0 --> mix_out_1
54+
}
55+
hda_dma_ho_0 --> host_0
56+
57+
dai_1 --> dw_dma_0
58+
dw_dma_0 --> ssp_0
59+
60+
rectangle "capture #0" <<stream>> {
61+
rectangle "ppl #3" as ppl_3 <<ppl>> {
62+
rectangle "host comp" as host_3
63+
rectangle "dai comp" as dai_3
64+
host_3 <-- dai_3
65+
}
66+
}
67+
hda_dma_hi_0 <-- host_3
68+
dai_3 <-- dw_dma_1
69+
dw_dma_1 <-- ssp_1
70+
71+
' now let's show who's driving
72+
rectangle "work queue #0\n@core_0" as wq_0 <<event>>
73+
wq_0 .[#green]> mix_in_0
74+
wq_0 .[#green]> dw_dma_0 : new
75+
wq_0 .[#green]> dw_dma_1 : new
76+
}
77+
78+
rectangle "core #1" <<cpu>> {
79+
80+
rectangle "hda-dma\nhost output #1" as hda_dma_ho_1 <<dma>>
81+
rectangle "hda-dma\nlink input #0" as hda_dma_li_0 <<dma>>
82+
83+
84+
rectangle "playback #1" <<stream>> {
85+
rectangle "ppl #2" as ppl_2 <<ppl>> {
86+
87+
rectangle "host comp" as host_2
88+
rectangle "dai comp" as dai_2
89+
90+
host_2 --> dai_2
91+
}
92+
}
93+
hda_dma_ho_1 --> host_2
94+
dai_2 --> hda_dma_li_0
95+
hda_dma_li_0 --> hda_0
96+
97+
rectangle "work queue #1\n@core_1" as wq_1 <<event>>
98+
wq_1 .[#green]> hda_dma_li_0
99+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.. _platforms-cavs-commons:
2+
3+
CAVS Commons
4+
############
5+
6+
.. toctree::
7+
:maxdepth: 1
8+
9+
work-queue
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
.. _platform-cavs-work-queue:
2+
3+
Work Queues
4+
###########
5+
6+
On CAVS platforms, the wallclock is used as a time source for multiple work
7+
queues (one instance of the work queue per active core).
8+
9+
Since there are not enough comparators available, all instances register to a
10+
shared interrupt (one comparator is used to wake up all). Master core is
11+
responsible for re-programming of wallclock to the next wake event. Its work
12+
queue is working in *master mode* while work queues running on other cores are
13+
attached to the shared time source (so configured to *slave mode*) on CAVS SMP
14+
platforms. On other SMP platforms, with multiple independent time sources
15+
available, all queues may be configured in *master mode*.
16+
17+
Synchronous Systick on All Cores
18+
********************************
19+
20+
Shared time source aligns scheduling of works on all the cores as they are all
21+
synchronously waken up on the same periodic event (aka *systick*).
22+
23+
Period of the systick should be configurable (by default it is 1ms). There is
24+
no better resolution of timeouts guaranteed but this should be acceptable for
25+
works that are typically scheduled on this system. Specifically low latency
26+
works are enabled and may be run on multiple cores in sync.
27+
28+
For ultra low latency configurations, the systick period may be configured to a
29+
value < 1ms.
30+
31+
HD/A DMA running in circular buffer mode (@ dai), is already registered in the
32+
work queue, specifying their period as the timeout value (1ms).
33+
34+
Other DMAs may be switched from their individual interrupt sources (buffer
35+
completion) to work queues making pipelines scheduling fully *systick aligned*.
36+
37+
In case of more complex topologies, pipelines started/terminated with a
38+
component other then dai, may be also driven by the work queues.
39+
40+
.. note:: Work queue Master/slave mode vs. independent mode configurable by
41+
CONFIG @ compile time. Work queue min tick (1ms/0.33ms/1us) configurable
42+
@ run-time. So that the current mode is still fully supported.
43+
44+
.. uml:: images/work-st.pu
45+
46+
.. uml:: images/work-smp-cavs.pu
47+
:caption: Work queue flow for CAVS SMP

platforms/intel-cavs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Intel CAVS platforms supported by the |SOF|.
1919
.. toctree::
2020
:maxdepth: 1
2121

22+
commons/index
2223
apollolake/index
2324
cannonlake/index
2425
icelake/index

0 commit comments

Comments
 (0)