Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

src/platform: Add "mtk" Zephyr platform for MediaTek DSPs #9755

Merged
merged 6 commits into from
Jan 8, 2025

Conversation

andyross
Copy link
Contributor

Unify the MediaTek 8195/86/88 devices into a single Zephyr-based "mtk" platform.

  • Almost all the device config and core (interrupt, timer) drivers are in upstream Zephyr now. There's almost no per-device code left in SOF.

  • In fact it's really quite small. Just two sub-300-line C files and some mostly boilerplate headers.

  • This still builds with ZEPHYR_NATIVE_DRIVERS=n. The pre-existing dummy-dma and afe drivers are used unchanged. The former has an equivalent in upstream Zephyr. The latter will need a port.

  • The AFE driver is "half Zephyr" though. The C code remains a legacy SOF driver but all the config is source from Zephyr DTS and converted at runtime to the legacy struct.

  • It's still a IPC3 platform. Kernel support for IPC4 doesn't exist yet.

This PR depends for build and functionality on the following Zephyr PRs, don't merge until they do:

zephyrproject-rtos/zephyr#82993
zephyrproject-rtos/zephyr#83291
zephyrproject-rtos/zephyr#83292

Also open source toolchains for these platforms have been merged to Zephyr sdk-ng, but are not part of a release yet. So (other than 8195, which is already present) development is limited to Cadence tooling for the moment.

@andyross
Copy link
Contributor Author

Also full disclosure: almost all the validation on this code is happening on an unreleased platform. Support for the legacy devices is happening on a time-available basis, and I'm just one guy. :) Right now all build and run Zephyr tests. But 8195 is running a very stale kernel and I can't use factory images, I've managed to brick my 8186 (can probably get it working but have to open it and pull the battery), and 8188 is having some topology trouble even with the old binaries I need to figure out (likely missing a patch or three from a release branch?). But on the focus device it's working great and was playing bad Christmas music for me all morning.

@andyross
Copy link
Contributor Author

Oh, and the checkpatch error[1] is a false positive. It complains about the lack of a space after a comma at the end of this code generation macro. But I add it it complains about a space before a closing paren, heh. Macrobatics confuses everyone, heh.

ERROR: space required after that ',' (ctx:VxB)
#308: FILE: src/platform/mtk/dai.c:115:
+	IF_ENABLED(DT_NODE_HAS_PROP(n, prop), (.prop = DT_PROP(n, prop),))

[1] Lost in a sea of codespell warnings that "AFE" must be a misspelled "SAFE". Alas I don't get to rename the hardware.

Copy link

@eddy1021 eddy1021 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some nits

app/boards/mt8186_mt8186_adsp.conf Show resolved Hide resolved
scripts/xtensa-build-zephyr.py Show resolved Hide resolved
src/platform/mtk/dai.c Outdated Show resolved Hide resolved
src/platform/mtk/platform.c Outdated Show resolved Hide resolved
#include <stdio.h>

/* DIY assertion, an "assert()" is already defined in platform headers */
#define CHECK(expr) while (!(expr)) { \
Copy link
Collaborator

@lyakh lyakh Dec 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess if would do just as well. Usually while is used as #define x do {printf("fail");} while (0) to accept the closing semicolon without side effects, but while () {} doesn't help for that

*
* ch_num is skipped if the stored reg value is negative
* quad_ch is skipped if the mask is zero
* int_odd: <=0 reg
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, not sure, what these mean - did you mean reg <= 0?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heh. It's clearer if you read it as English and not C: "<=0" is shorthand for an adjectival phrase ("less than or equal to zero") modifying "reg". :)

Really this is just me taking notes while reverse engineering the configuration mechanisms and committing the result without editting. Swapped the order, but the text isn't a spec and the original is weird, so I doubt this will ever be obvious.


int bits = __builtin_ffs(lomask + 1) - 1;

CHECK(((lomask + 1) & lomask) == 0); /* must be power of two */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this checks, that lomask + 1 is a power of two?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Confusing comment. It's validating the the mask value is a proper right-aligned bitmask without holes, e.g. "0xff" is legal, "0xff0" is not.

type = "SRAM"
base = "0x90000000"
size = "0x00600000"
host_offset = "0x0"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in fact we can now preprocess toml with gcc, as we do for Intal ADSP platforms, so getting values from DTS might be possible?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. Though this particular block (not all the module config) is almost entirely generatable. I guess my gut says what we want is to construct and emit it ourselves from cmake (or a script invoked from there) instead of trying to do it with the preprocessor. But that takes some thought and design.

I've made the point in the past, but SOF seems to have a love affair with weak programming languages (cpp here, also m4, the topology2 changes to alsaconf, frankly alsaconf itself seems to have always been too limited pre-sof, alsabat is sort of in that list too) and then getting in trouble when the requirements expand farther than the syntax can handle. There's no shame in using python from the start. :)

// Author: Andy Ross <[email protected]>
#include <sof/lib/dai-legacy.h>
#include <ipc/dai.h>
#include <sof/drivers/afe-drv.h>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this isn't yet replacing src/platform/mt81*/lib/dai.c, right? But eventually it will?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is replacing the platform layers. It's still using the legacy driver code in src/drivers/mediatek/afe, but configuring it from DTS.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andyross but that file isn't deleted yet? Supposedly because both XTOS and Zephyr builds should now be possible

Early versions of the AFE driver were published with large C struct
definitions tied to platform headers.  Zephyr strongly prefers
Devicetree for configuration and not C code.

So this is a somewhat klugey C program that builds and runs the AFE
platform code on a Linux host CPU, producing valid DTS output that can
be included in a board devicetree file in Zephyr.

Just run ./build.sh from inside this directory.  The only required
host software is a working gcc that supports the "-m32" flag.

The resulting afe-<platform>.dts files can be included directly in
Zephyr board config.

Signed-off-by: Andy Ross <[email protected]>
When building under Zephyr, you have to have a log module instantiated
(or declare someone else's) if you want to use the component logging
macros.

Signed-off-by: Andy Ross <[email protected]>
Unify the MediaTek 8195/86/88 devices into a single Zephyr-based "mtk"
platform.

+ Almost all the device config and core (interrupt, timer) drivers are
  in upstream Zephyr now.  There's almost no per-device code left in
  SOF.

+ In fact it's really quite small.  Just two sub-300-line C files and
  some mostly boilerplate headers.

+ This still builds with ZEPHYR_NATIVE_DRIVERS=n.  The pre-existing
  dummy-dma and afe drivers are used unchanged.  The former has an
  equivalent in upstream Zephyr.  The latter will need a port.

+ The AFE driver is "half Zephyr" though.  The C code remains a legacy
  SOF driver but all the config is source from Zephyr DTS and
  converted at runtime to the legacy struct.

+ It's still a IPC3 platform.  Kernel support for IPC4 doesn't exist
  yet.

Signed-off-by: Andy Ross <[email protected]>
Platform-layer support for the MT8196 Audio DSP.

Virtually all the device-dependence is now provided by Zephyr
upstream, this is just some boilerplate in a few areas, plus one
legacy/to-be-removed MMIO address which isn't captured there.

Signed-off-by: Andy Ross <[email protected]>
Add initial M4 topology for the mt8196 DSP

Originally by Darren Ye <[email protected]>

Signed-off-by: Andy Ross <[email protected]>
Simple address-space-only rimage config.  Really it would be nice to
source the data here from Zephyr DTS instead of recapitulating numbers
we already store elsewhere.

Originally by Darren Ye <[email protected]>

Signed-off-by: Andy Ross <[email protected]>
Copy link
Collaborator

@kv2019i kv2019i left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Some minor notes on possible further simplifications to platform implementation (that may not be possible yet if XTOS drivers are used)

# "MTK" is an member), it can't be selected automatically from other
# kconfigs, nor expressed as a default. Don't put anything else here.
# Board-level config goes in Zephyr (and ideally in DTS). App-level
# config goes in prj.conf.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a note it is accepted practise use to put vendor specific app settings in these board files. E.g. Intel example #9609 . I do agree anything that can be put in Zephyr board files/DTS or the app prj.conf, should not be put here.

select SCHEDULE_DMA_MULTI_CHANNEL
select HOST_PTABLE
help
Select if your target is a Mediatek DSP. Builds Zephyr firmware.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will likely conflict with #9758 . Not a big issue, just need one to go first and then rebase...

#define CLK_CPU(x) (x)

// FIXME: set correctly from mtk_adsp layer!
#define CLK_MAX_CPU_HZ CONFIG_XTENSA_CCOUNT_HZ
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some related effort to drop these definitions on SOF side #9541
This (CLK_MAX_CPU_HZ) should not be needed in generic SOF code anymore when built for Zephyr (XTOS builds may still needed if used in XTOS drivers).


struct pm_runtime_data;

static inline void platform_pm_runtime_init(struct pm_runtime_data *prd)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With #9495 , lib/pm_runtime.h is no longer needd for Zephyr SOF builds.

*/
#ifndef _SOF_PLATFORM_MTK_LIB_DAI_H
#define _SOF_PLATFORM_MTK_LIB_DAI_H

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With #9653 , this can be dropped if only supporting Zephyr builds.

// Author: Andy Ross <[email protected]>
#include <sof/lib/dai-legacy.h>
#include <ipc/dai.h>
#include <sof/drivers/afe-drv.h>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andyross but that file isn't deleted yet? Supposedly because both XTOS and Zephyr builds should now be possible

@kv2019i
Copy link
Collaborator

kv2019i commented Jan 3, 2025

@andyross let us know if you want to merge this version.

Copy link
Member

@lgirdwood lgirdwood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM @andyross

@lgirdwood
Copy link
Member

@andyross let us know if you want to merge this version.

Ack, we can take any incremental fixes as they land as we've lots of time now that stable has forked.

@andyross
Copy link
Contributor Author

andyross commented Jan 7, 2025

Yeah, let's merge this absent a -1. Note that it's still waiting on some Zephyr PRs though: zephyrproject-rtos/zephyr#83291 and zephyrproject-rtos/zephyr#83292 (though the second is non-fatal, just a performance fix), and open source builds will need to wait for the next Zephyr SDK release (or else be done with a hand-pulled pre-release of the toolchain).

@lgirdwood lgirdwood merged commit c1df459 into thesofproject:main Jan 8, 2025
45 of 51 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants