"/pl061#9030000:clocks: cell 0 is not a phandle reference" when compiling a dts file - linux-device-driver

I used "-machine dumpdtb=dtb.dtb" in qemu command to extract dtb file of the arm 'virt' machine. Then I converted the dtb file to dts file using dtc. And I tried to make that dts file backto dtb. But I'm seeing a warning message like this (only showing the first warning).
dtb.dts:284.3-21: Warning (clocks_property): /pl061#9030000:clocks: cell 0 is not a phandle reference
The warning comes from the line in the dts
pl061#9030000 {
phandle = <0x8003>;
clock-names = "apb_pclk";
clocks = <0x8000>; <==== this line
interrupts = <0x00 0x07 0x04>;
gpio-controller;
#gpio-cells = <0x02>;
compatible = "arm,pl061\0arm,primecell";
reg = <0x00 0x9030000 0x00 0x1000>;
};
I've looked at Documentation/devicetree/bindings/gpio/pl061-gpio.yaml but there is no explanation about the property clocks. I guess it's the clock frequency for the gpio but somehow the dtc program thinks it is a phandle. and I couldn't find any use of 'clocks' in the pl061 driver. Can I just safely ignore that error?

This is a phandle to the /apb-pclk node elsewhere in the dtb. The "clocks" property is part of the "arm,primecell" binding, documented here:
https://www.kernel.org/doc/Documentation/devicetree/bindings/arm/primecell.txt

Related

What's the difference between of clk_get and of_clk_get? (linux)

I ask it here to check if my guess is correct.
This page says
Currently we have devm_clk_get() which gives a managed-resource clk
(by name), or of_clk_get() which gives an unmanaged resource clk (by
id).
So I guess clk_get is selecting the clock using 'clock-names' (which is input to a clock consumer device) in the device tree, and of_clk_get is for selecting the clock using 'clock id' (which is the first number in the index-name pair of the clock input specifier.
And I see these lines in a driver drivers/tty/serial/bcm63xx_uart.c (linux 5.15.68).
clk = clk_get(&pdev->dev, "refclk"); // first try
if (IS_ERR(clk) && pdev->dev.of_node)
clk = of_clk_get(pdev->dev.of_node, 0); // second try
It looks like it first try to get the input clock from the name "refclk" and if it fails, it trys to get the clock from the clock speicifer, 0 meaning the first input clock. Is my understanding correct? Are both tries using device tree information?
I see in arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi,
clocks {
periph_clk: periph_clk {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <50000000>;
clock-output-names = "periph";
};
};
uart0: serial#640 {
compatible = "brcm,bcm6345-uart";
reg = <0x640 0x18>;
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&periph_clk>;
clock-names = "refclk";
status = "okay";
};

TypeError: 'id' argument required in Attempting to add NEO M9N to raspbery pi pico

Here is my frankensteined code, the error arises when i'm defining gps_module on line 12. I'm attaching pico pin 4 to the SDA on the GPS, pin 5 to the SCL, ground, and power
from machine import Pin, UART, I2C
#Import utime library to implement delay
import utime, time
sda_pin = machine.Pin(4)
scl_pin = machine.Pin(5)
# Create an I2C object out of our SDA and SCL pin objects
gps_module = machine.I2C(sda=sda_pin, scl=scl_pin)
print(gps_module)
#Used to Store NMEA Sentences
buff = bytearray(255)
TIMEOUT = False
#store the status of satellite is fixed or not
FIX_STATUS = False
Try 1 or 0 in the declaration
gps_module = machine.I2C(1, sda=sda_pin, scl=scl_pin)
https://docs.micropython.org/en/latest/library/machine.I2C.html#constructors
class machine.I2C(id, *, scl, sda, freq=400000)
Construct and return a new I2C object using the following parameters:
id identifies a particular I2C peripheral. Allowed values for depend
on the particular port/board
scl should be a pin object specifying the pin to use for SCL.
sda should be a pin object specifying the pin to use for SDA.
freq should be an integer which sets the maximum frequency for SCL.

Linux Device Tree to Hardware Mapping

I was wondering how some specific details in the device relate to the hardware and where to find this information(like schematic, datasheet etc).
An example of a usb node is given below:
In the picture above I was wondering how do you find CLK_BUS_OHCI2 or RST_BUS_EHCI2 on the hardware. If you go to the include files you get a value (CLK_BUS_OHCI2 = 39), but I am not sure how that relates to actual hardware. Like which register or which pin etc.
Nowadays I'm working with a similar platform, Allwinner A64 and I'm trying to understand how DTS, clocks, resets work. Fortunately your question came up in the search engine results. Gaurav Pathak's answer clarified most of the things for me and I want to extend a little bit from his point to help those who are trying to fill in the gap about bridging DTS and hardware.
I will refer to Linux kernel 5.7 and Allwinner A64 User Manual (v1.1).
There's a resemblance between uart4 and ehci2 in the means of node definition; for instance, we have property of clocks and resets in both of them. But ccu clock output usage were implemented different.
Let's take a closer look at uart4 node.
uart4: serial#1c29000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c29000 0x400>;
interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&ccu CLK_BUS_UART4>;
resets = <&ccu RST_BUS_UART4>;
status = "disabled";
};
Now we already know that CLK_BUS_UART4 is included from include/dt-bindings/clock/sun50i-a64-ccu.h.
<&ccu CLK_BUS_UART4>
A further search for CLK_BUS_UART4 reveals that include/dt-bindings/clock/sun50i-a64-ccu.h is also indirectly (through drivers/clk/sunxi-ng/ccu-sun50i-a64.h) included from drivers/clk/sunxi-ng/ccu-sun50i-a64.c.
Then it was possible to refer to CLK_BUS_UART4 like below (L807 # ccu-sun50i-a64.c)
[CLK_BUS_UART4] = &bus_uart4_clk.common.hw
But what is bus_uart4_clk? Let's see.
It is defined at L381 # ccu-sun50i-a64.c. This is how it looks:
static SUNXI_CCU_GATE(bus_uart4_clk, "bus-uart4", "apb2",
0x06c, BIT(20), 0);
SUNXI_CCU_GATE is a macro to manage gating register of Clock Control Unit. 4th argument, 0x06c refers to the register offset and 5th argument BIT(20) implies the Nth bit (20, in this case) at the offset of 0x06c is adjusted to drive bus_uart4_clk.
Same thing applies for the resets property. To give a specific example; just search for RST_BUS_UART4 and 0x2d8 at Linux kernel source then look at the bottom of Page 142 of the A64 User Manual.
I hope there were not too much nonsense... Please correct me if I'm wrong.
Well, as far as I know in the below structure
ehci2: usb#01c1c000 {
compatible = "allwinner,sun8i-h3-ehci", "generic-ehci";
reg = <0x01c1c000 0x100>;
interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_EHCI2>, <&ccu CLK_BUS_OHCI2>;
resets = <&ccu RST_BUS_EHCI2>, <&ccu RST_BUS_OHCI2>;
phys = <&usbphy 2>;
phy-names = "usb";
status = "disabled";
};
clocks = <&ccu CLK_BUS_EHCI2>, <&ccu CLK_BUS_OHCI2>; represents consumer clocks i.e. input clocks and is called "phandle + clock specifier pairs". As you mentioned CLK_BUS_OHCI2 has value 39, that means USB controller will take input clock from the output 39 of ccu clock source.
In the dtsi file from where you posted the above screenshot, there should be a structure that defines the ccu for example like this below:
ccu: clk#01c20060 {
#clock-cells = <1>;
compatible = "allwinner,sun7i-a20-ahb-gates-clk";
reg = <0x01c20060 0x8>;
clocks = <&ahb>;
clock-output-names = "ahb_usb0", "ahb_ehci0",
"ahb_ohci0", "ahb_ehci1", "ahb_ohci1",
"ahb_ss", "ahb_dma", "ahb_bist", "ahb_mmc0",
"ahb_mmc1", "ahb_mmc2", "ahb_mmc3", "ahb_ms",
"ahb_nand", "ahb_sdram", "ahb_ace",
"ahb_emac", "ahb_ts", "ahb_spi0", "ahb_spi1",
"ahb_spi2", "ahb_spi3", "ahb_sata",
"ahb_hstimer", "ahb_ve", "ahb_tvd", "ahb_tve0",
"ahb_tve1", "ahb_lcd0", "ahb_lcd1", "ahb_csi0",
"ahb_csi1", "ahb_hdmi1", "ahb_hdmi0",
"ahb_de_be0", "ahb_de_be1", "ahb_de_fe0",
"ahb_de_fe1", "ahb_gmac", "ahb_ehci2",
"ahb_mali";
};
In the above structure there are multiple clock source outputs, so clock source 39 should be utilised by the above USB controller for taking clock input, note that #clock-cells = <1>; represents multiple clock output and #clock-cells = <0>; is for single clock output.
The ccu structure is just an example.

How to change a mac address using the command line parameters in the linux kernel

I want to change a mac address at the u-boot level like the following.
# setenv bootargs 'console=ttyAMA0,115200n8 root=/dev/ram0 rw initrd=0x40000000 ethaddr=${ethaddr}'
# setenv ethaddr 11:22:33:44:55:66
# saveenv
And at the driver,
static unsigned char my_ethaddr[MAX_ADDR_LEN];
/* need to get the ether addr from armboot */
static int __init ethaddr_setup(char *line)
{
char *ep;
int i;
printk("command line : %s\n", line);
memset(my_ethaddr, 0, MAX_ADDR_LEN);
/* there should really be routines to do this stuff */
for (i = 0; i < 6; i++)
{
my_ethaddr[i] = line ? simple_strtoul(line, &ep, 16) : 0;
if (line)
line = (*ep) ? ep+1 : ep;
printk("mac[%d] = 0x%02Xn", i, my_ethaddr[i]);
}
return 0;
}
__setup("ethaddr=", ethaddr_setup);
When booting, the log message is like following.
[ 0.000000] Kernel command line: console=ttyAMA0,115200n8 root=/dev/ram0 rw initrd=0x40000000 ethaddr=${ethaddr}
[ 0.000000] command line : ${ethaddr}
[ 0.000000] mac[0] = 0x00, mac[1] = 0x00, mac[2] = 0x0E, mac[3] = 0x00, mac[4] = 0xDD, mac[5] = 0x00
The command line message is ${ethaddr}, is it right?
The mac address isn't correct.
How can I fix it?
You are using single quotes in:
setenv bootargs '... ethaddr=${ethaddr}'
so ${ethaddr} is not expanded and the bootargs variable contains the literal string ethaddr=${ethaddr}, which is then passed into the kernel and is what you see in your debug output. See the U-Boot documentation on How the Command Line Parsing Works for more details.
You could use double quotes, or no quotes at all, in which case ${ethaddr} would be expanded when assigning to bootargs, although you would need to set it first:
# setenv ethaddr 11:22:33:44:55:66
# setenv bootargs console=ttyAMA0,115200n8 root=/dev/ram0 rw initrd=0x40000000 ethaddr=${ethaddr}
# printenv bootargs
bootargs=console=ttyAMA0,115200n8 root=/dev/ram0 rw initrd=0x40000000 ethaddr=11:22:33:44:55:66
Note that in some systems the ethaddr variable is used by U-Boot itself to configure the MAC address of the first network device, and the Linux network driver may continue to use that address, so you don't need to explicitly pass it into the kernel. See the documentation on U-Boot Environment Variables.
In addition U-Boot may be configured to prevent modification of the ethaddr variable, although that's probably not the case here because when it is U-Boot prints the error message:
Can't overwrite "ethaddr"

Beagle Bone Black PRU Device Overlay for fast IO does not work

I desperately try to get the PRU on my BBB working. By working I mean that I would want to use the pins P8 39-46 (GPIO2[6-13]) as a fast output controlled by the PRU.
I installed the debian for BBB (2 weeks ago, should be current) on SD.
Then I started with the following article: http://www.element14.com/community/community/designcenter/single-board-computers/next-gen_beaglebone/blog/2013/05/22/bbb--working-with-the-pru-icssprussv2
doing so, I got the PRU working with the LED example as well as with pin P8[12].
Now I try to get the other pins working. I started all over by just making a little change to the original am335x-boneblack.dtb. I just activated the PRU.
I did not change the LED heartbeat as well as pin P8.12.
Then I disabled HDMI in uEnv.txt
My "slots" look like this now:
0: 54:PF---
1: 55:PF---
2: 56:PF---
3: 57:PF---
4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
5: ff:P-O-- Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI
6: ff:P-O-- Bone-Black-HDMIN,00A0,Texas Instrument,BB-BONELT-HDMIN
I stumbled upon this post here: https://groups.google.com/forum/#!topic/beagleboard/JRG36bOURfk
EXACTLY what I would want to have, so I took the dts ( the second one) , compiled it, copied it to /lib/firmware and loaded it. "slots" says the overlay was loaded.
0: 54:PF---
1: 55:PF---
2: 56:PF---
3: 57:PF---
4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
5: ff:P-O-- Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI
6: ff:P-O-- Bone-Black-HDMIN,00A0,Texas Instrument,BB-BONELT-HDMIN
7: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-PRU-IO
BB-PRU-IO is me.
dmesg says:
... part_number 'BB-PRU-IO', version 'N/A'
... slot #7: generic override
... bone: Using override eeprom data at slot 7
... slot #7: 'Override Board Name,00A0,Override Manuf,BB-PRU-IO'
... slot #7: Requesting part number/version based 'BB-PRU-IO-00A0.dtbo
... slot #7: Requesting firmware 'BB-PRU-IO-00A0.dtbo' for board-name 'Override Board Name', version '00A0'
... slot #7: dtbo 'BB-PRU-IO-00A0.dtbo' loaded; converting to live tree
... slot #7: #2 overlays
... slot #7: Applied #2 overlays.
Looking good I would say.
The problem is the pinmux does not seam to be impressed:
cat pins | grep 8a4
=> pin 41 (44e108a4) 0000002f pinctrl-single
This is MODE 7 (GPIO Out). Not what I wanted. For all of pins I intended to switch to PRU Mode 5.
Now I tried the delivered dtbo's for the PRU 01,02 in /lib/firmware
PRU-01.dtbo seems to be a fitting example. Only the Pin is different (P9.27).
I loaded it and changed the PRU code example.
The pins did not show the expected result:
pin 105 (44e109a4) 00000027 pinctrl-single
When I run the modified testprogram from the first articel my osci shows a flatline.
I tried PRU-02.dtbo.
At least the pins showed the expected result:
pin 105 (44e109a4) 00000025 pinctrl-single
When I start my little test program I get a "bus error"
dmesg has several lines. the important ones I would say are:
[ 119.258978] WARNING: at arch/arm/mach-omap2/omap_hwmod.c:2096 _enable+0x101/0x174()
[ 119.259004] omap_hwmod: pruss: enabled state can only be entered from initialized, idle, or disabled state
[ 119.259027] Modules linked in: g_multi libcomposite btusb bluetooth rfkill uio_pruss mt7601Usta(O)
.... several trace messages
[ 119.272382] pru-rproc 4a300000.prurproc: #8 PRU interrupts registered
[ 119.272445] pru-rproc 4a300000.prurproc: Failed to read events array
[ 119.287545] pru-rproc: probe of 4a300000.prurproc failed with error -22
PRU-02 does more than PRU-01 (what I do not understand). And it does not seem to work for me.
Now I am kind of helpless.
Any ideas on that?
EDIT:
I did what you should not do. I changed the pinmux setting in the am335x-boneblack.dtb file. I just added:
0xA0 0x05
0xA4 0x05
0xA8 0x05
0xAC 0x05
0xB0 0x05
0xB4 0x05
0xB8 0x05
0xBC 0x05
to pinmux_userled_pins {
pinctrl-single,pins = <
Now it works, but I am not happy. I still would appreciate a regular overlay file.
OK I got it working:
just enable the pruss in the am335x-boneblack.dtb (convert to dts. do the changes as described in the article mentioned in the original post)
Got to the website : http://kilobaser.com/blog/2014-07-28-beaglebone-black-devicetreeoverlay-generator#dtogenerator and let the site create dts files for the various pins in my case P8 46-39. Using a single DTS(DTBO) File for each individual pin works but requires 8 dtbos loaded => I moved all of them into one DTS File.
this is it:
/dts-v1/;
/plugin/;
/{
compatible = "ti,beaglebone", "ti,beaglebone-black";
part_number = "BS_PINMODE_PRU_OUT";
exclusive-use =
"P8.46",
"P8.45",
"P8.44",
"P8.43",
"P8.42",
"P8.41",
"P8.40",
"P8.39",
"pr1_pru1_pru_r30_6",
"pr1_pru_pru1_r30_7",
"pr1_pru1_pru_r30_4",
"pr1_pru1_pru_r30_5",
"pr1_pru1_pru_r30_2",
"pr1_pru1_pru_r30_3",
"pr1_pru1_pru_r30_0",
"pr1_pru1_pru_r30_1";
fragment#0 {
target = <&am33xx_pinmux>;
__overlay__ {
bs_pinmode_pru_out: pinmux_bs_pinmode_pru_out {
pinctrl-single,pins = <0x0a4 0x5 0x0a0 0x5 0x0ac 0x5 0x0a8 0x5 0x0b4 0x5 0x0b0 0x5 0x0bc 0x5 0x0b8 0x5>;
};
};
};
fragment#1 {
target = <&ocp>;
__overlay__ {
bs_pinmode_pru_out_pinmux {
compatible = "bone-pinmux-helper";
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&bs_pinmode_pru_out>;
};
};
};
};
I named the file bspm_pru_out-00A0.dts, compiled it to bspm_pru_out-00A0.dtbo and placed it it in the /lib/firmware.
You can load it via /boot/uEnv.txt or via echo... in a rc.local file... whatever you like.