Jump to content

Help me with Device Tree in H3 Mainline kernel


Recommended Posts

I'm trying to turn on the SPDIF transmitter in the H3 mainline kernel (v4.10).  To do this I'm copying sun4i_spdif.c from sunxi-next kernel (spdif marked as working starting from kernel v4.11) and make some changes in .dts files for OrangePi PC:

diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts
index 90a767f..29980a8 100644
--- a/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts
+++ b/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts
@@ -91,6 +91,24 @@
 			gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>;
 		};
 	};
+
+	sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "On-board SPDIF";
+
+		simple-audio-card,cpu {
+			sound-dai = <&spdif>;
+		};
+
+		simple-audio-card,codec {
+			sound-dai = <&spdif_out>;
+		};
+	};
+
+	spdif_out: spdif-out {
+		#sound-dai-cells = <0>;
+		compatible = "linux,spdif-dit";
+	};
 };
 
 &cpu0 {
@@ -338,3 +356,9 @@
 	allwinner,leds-active-low;
 	status = "okay";
 };
+
+&spdif {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spdif_tx_pins_a>;
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
index 21e3f42..c40d45c 100644
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
@@ -513,8 +513,8 @@
 			};
 
 			spdif_tx_pins_a: spdif@0 {
-				pins = "PA17";
-				function = "spdif";
+				allwinner,pins = "PA17";
+				allwinner,function = "spdif";
 			};
 
 			spi0_pins: spi0 {

After that, I compile Armbian, copy the image to SD, boot system on OrangePi PC board fnd see spdif presence:

root@orangepipc:~# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Codec [H3 Audio Codec], device 0: CDC PCM Codec-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: SPDIF [On-board SPDIF], device 0: spdif-dit-hifi dit-hifi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
root@orangepipc:~#

I can not test whether it works because it is very difficult to solder the input of my optical transmitter to the PA17 - it is output to miniature camera connector. But module is up and ALSA see it.

 

 

To check if it works, I did similar things for nanopi m1, but after loading the system the module did not go up and ALSA does not see the SPDIF output:

root@nanopim1:~# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Codec [H3 Audio Codec], device 0: CDC PCM Codec-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
root@nanopim1:~#

Could someone tell me what I'm doing wrong? Patches and logs in attachment.

npim1-console.txt

npim1-dmesg.txt

opipc-console.txt

opipc-dmesg.txt

spdif-001-driver-from-4.11-kernel.patch

spdif-002-nanopim1.patch

spdif-002-orangepipc.patch

Link to comment
Share on other sites

Armbian Linux community supported weekly builds download

It worked, but wrong :(

 

To make driver up,  by analogy with OrangePi PC, I enable HDMI and CODEC (patches in attachment).

As result, player (squeezelite in my case) even plays music but twice as slow as necessary - Shade sings bass :D

As I understand it - the problem is in SPDIF transmitter clocking. In the source code of the SPDIF driver there are a settings of the clock division depending on the sampling frequency of the reproduced music. But divider for 192KHz is 1 so I cah't divide it by 2 to listen 192KHz FLACs. 

I think that I need to look for where the frequency of the audio PLL is set, perhaps there is some extra divider which must be turned off.

 

 

spdif-001-driver-from-4.11-kernel.patch

spdif-002-nanopim1.patch

spdif-003-nanopim1-1.patch

Link to comment
Share on other sites

Hello!
I apologize for offtopic, but I decided not to create new theme and ask here:
Is there any way to know which .dtb file was used to configure the running kernel?
I got the impression that the system image for NanoPI M1 (mainline krnel 4.10) uses .dtb not for this board, but for OrangePi PC. 

It turned out when I tried to enable an SPDIF transmitter. When I enable SPDIF in sun8i-h3-nanopi-m1.dts, compile and boot the system for NanoPI M1, the driver was not installed and the SPDIF was not in the list of audio devices. But when I enable SPDIF in sun8i-h3-orangepi-pc.dts ( without any changes in original sun8i-h3-nanopi-m1.dts) and compile the system for NanoPI M1, the driver was installed and the SPDIF appeared in the list of audio devices. 

Tell me please, where is configured, which .dts for which board, what would I check and, if I find an error, make a patch?

Link to comment
Share on other sites

6 minutes ago, AndrewK said:

Is there any way to know which .dtb file was used to configure the running kernel?

cat /proc/device-tree/model; echo

will give you the model string which can be matched in the DT sources.

Alternatively hook up a serial console, get to the u-boot prompt and check the value of "fdtfile" environment variable - this will give you the file name.

 

11 minutes ago, AndrewK said:

I got the impression that the system image for NanoPI M1 (mainline krnel 4.10) uses .dtb not for this board, but for OrangePi PC. 

 

Mainline configuration for H3 boards is a constantly moving target and some newer boards may use configuration for other similar boards until dedicated configuration is added upstream.

Link to comment
Share on other sites

I performed the cat /proc/device-tree/model; echo and got the result Xunlong Orange Pi PС

Indeed, the Armbian for NanoPi M1 use .dtb for OrangePi PC.

Could You tell me, where in Armbian build system I can select which .dts to use? 

Judging by the contents of dts for these boards, I see difference in CPU clock speed control. I'm trying to play music through spdif and it plays twice as slow. Maybe the reason is in the wrong .dts?

 

P.S. Since this topic is about device tree overlays, as soon as I properly earn the spdif, I will create an overlay and publish a patch :)

Link to comment
Share on other sites

54 minutes ago, AndrewK said:

Could You tell me, where in Armbian build system I can select which .dts to use? 

 

You can't "select" it. It is defined by the u-boot configuration at compile time, but you can override it by setting "fdtfile" environment variable in /boot/armbianEnv.txt

Since u-boot 2017.03 doesn't have defconfig for the NanoPi M1, we are using a patch to add it and we are reusing OPi PC DT meanwhile (defined by CONFIG_DEFAULT_DEVICE_TREE)

 

54 minutes ago, AndrewK said:

P.S. Since this topic is about device tree overlays, as soon as I properly earn the spdif, I will create an overlay and publish a patch :)

Overlay was already added to my repo (link), I just didn't sync it to the main repo yet (especially since we are still using 4.10.x branch which doesn't have H3 SPDIF support).

 

54 minutes ago, AndrewK said:

Judging by the contents of dts for these boards, I see difference in CPU clock speed control. I'm trying to play music through spdif and it plays twice as slow. Maybe the reason is in the wrong .dts?

 

No. I would suggest waiting for the kernel 4.11 release and then reporting the issue to the driver maintainer if it would be still reproducible.

Since H3 support was added by the codekipper you may be able to catch him on the linux-sunxi IRC.

 

Edit:

Though before reporting this type of issue I would try multiple players, check and collect info from /proc or /sys - don't remember exactly, but while audio device is used you can get runtime info about sample rate, and debug info about clock rates since if it's not a userspace issue it may be a clock driver (sunxi-ng) issue.

Link to comment
Share on other sites

Ok, I tried Your spdif-out overlay. In order for .dtbo to appear in the /boot/dtb/overlay , I had to add the name of this overlay to the Makefile (see 1'st patch in attachment).

After compile image and boot system I added to /boot/armbianEnv.txt lines:

fdtfile=sun8i-h3-nanopi-m1.dtb
overlays=cir spdif-out

and after reboot see:

cat /proc/device-tree/model; echo
FriendlyArm NanoPi M1

and:

aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: SPDIF [On-board SPDIF], device 0: spdif-dit-hifi dit-hifi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0

The music over SPDIF is reproduced in the same way as before, twice as slow.

 

For the experiment, I doubled the frequencies in the source code of the SPDIF driver (see 2'nd patch in attachment), and got an wierd result: the phonograms with sampling frequencies multiples of 48KHz play correctly, and with 44.1KHz multiple is slightly faster than needed. It seems that something wrong not in SPDIF driver, but somewhere where the audio-pll is programmed (where function clk_set_rate resides). 

I'll read H3 datasheet, I'll see the source code and write here about results.

 

spdif-002-add-spdif-overlay-to-makefile.patch

spdif-003-double-mclk.patch

Link to comment
Share on other sites

14 minutes ago, AndrewK said:

For the experiment, I doubled the frequencies in the source code of the SPDIF driver (see 2'nd patch in attachment), and got an wierd result: the phonograms with sampling frequencies multiples of 48KHz play correctly, and with 44.1KHz multiple is slightly faster than needed. It seems that something wrong not in SPDIF driver, but somewhere where the audio-pll is programmed (where function clk_set_rate resides). 

If you suspect clock driver issue you should check sunxi-ng source, especially bit masks and width for audio related clocks: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/tree/drivers/clk/sunxi-ng/ccu-sun8i-h3.c?h=linux-4.10.y

Link to comment
Share on other sites

Checked bit numbers and coefficient widths in ccu-sun8i-h3.c - everything is same as in datasheet. In the driver from kernel 4.11 exactly the same. 

The only difference is the flag CLK_SET_RATE_UNGATE in audio pll structure in 4.10 and zero in 4.11 Replacing this flag with 0 as in 4.11 does not change anything.

 

I added a diagnostic message to the initialization function of the SPDIF with the actual value of the mclk after the call of the clk_set_rate. When reproducing tracks with a sampling rate of a multiple of 48 kHz, the mclk is set to 24571428 Hz instead of 24567000. When reproducing tracks with a sampling rate of a multiple of 44.1 kHz, the mclk is set to 12285714 Hz instead of 22579200. It's not even 22579200/2, but 24571428/2 !!!

It seems that the error still somewhere in clk_set_rate :(

Link to comment
Share on other sites

I found that the correct or incorrect setting of spdif mclk depends on the analog codec.

If before using of spdif I play over analog codec a phohogram with sampling frequency of 48 khz, then the spdif correctly reproduces the phonograms with a 48 khz and incorrectly with 44.1 kHz. If I play over analog codec a 44,1 khz phonogram , next the spdif correctly reproduces the 44,1 khz phonograms and 48 khz incorrectly.

Apparently, this is due to the fact that all H3 audio devices have a common clock generator and an analog codec has priority in its tuning.

Anywhere in the structures describing the analog codec driver there should be a flag that allows other audio devices to set the clock speed. I'll try to find and set it up.

Link to comment
Share on other sites

OK, I made SPDIF work in the mainline kernel (patches in the attachment). But in a way that I do not like :(

 

I had to change the settings of the "spdif" clock in linux clock tree hierarchy (see 2'nd patch). Now it works like "ac-dig" (analog codec clock) and dvider in OWA Clock register does not used during the frequency selection process.

On the good it was necessary to trace the processing of the request for changing frequency through the clock hierarchy: "spdif" -> "pll-audio" -> "pll-audio-base" -> "osc24M" and to find and eliminate the bug.  But for my level of understanding the Linux clock tree management, it is very difficult. I'm happy to return to this work if someone more experienced tells me where to look

 

Another problem is that integer audio-pll  dividers do not allow  to accurately get the requested frequencies: 24571428 instead of 24576000 and 22571428 instead of 22579200 .This is because the driver in kernel 4.10 and 4.11 does not use the PLL_AUDIO Pattern Control Register, unlike the driver in the legacy kernel.

 

spdif-001-driver-from-4.11-kernel.patch

spdif-002-change-clock-mode.patch

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
 Share

×
×
  • Create New...