What is address-cell and size-cells in the device tree? Is reg is related to address-cell and size-cell? If yes, then how?
For example:
memory: memory#20000000 {
#address-cells = <1>;
#size-cells = <1>;
device_type = "memory";
reg = <0x20000000 0x80000000>;
};
What is 0x20000000 ? from where we can get this ?
The meaning of reg depends on the type of bus the device is connected to and is documented in the device tree binding for the bus.
Here, memory is directly mapped in the CPU address space and reg is <address size>.
So, this means that your DDR is starts at address 0x20000000 and has a size of 2GB.
This address is supposed to be documented in the SoC datasheet if you can get it, in a sections that is named memories or memory maps.
Related
In an external kernel module, using DMA Engine, when calling dma_request_chan() returns an error pointer of value -19, i.e. ENODEV or "No such device".
Now, in the active device tree, I do find a dma-names entry with what I'm trying to get a channel for, so my suspicion is that something else deeper in the forest is already not found.
How do I find out what's wrong?
Background:
I have a Zynq MP Ultrascale+ board here, with an FPGA design which uses AXI VDMA block to provide one channel of data to be received on the Cortex A's Linux, where the data is written to DDR4 by the FPGA and to be read from Linux.
I found that there is a Xilinx DMA driver included in the kernel, in the Xilinx source repo anyway, currently kernel version 5.6.0.
And that that driver has no user space interface, such that an intermediate kernel driver is needed.
This is depicted, and they have an example here: Section "4 DMA Proxy Design". I modified the code in the dma-proxy.c of the zip file linked there such that it uses only the RX channel, i.e. also only tries to request it.
The code for that is here, to not make this post huge:
Modified dma-proxy.c at onlinegdb.com
Line 407 has the function create_channel(), which used to use dma_request_slave_channel() which ditches the error code of the function it wraps, so to see the error, I am using that one instead: dma_request_chan().
The function create_channel() is called in function dma_proxy_probe() # line 470 (the occurences before that are deactivated by compile switch).
So by way of this call, dma_request_chan() will be called with the parameters:
create_channel(pdev, &channels[RX_CHANNEL], "dma_proxy_rx", DMA_DEV_TO_MEM);
The Device Tree for my board has an added node for dma-proxy driver as is shown at the top of the dma-proxy.c
dma_proxy {
compatible ="xlnx,dma_proxy";
dmas = <&axi_dma_0 0>;
dma-names = "dma_proxy_rx";
};
The name "axi_dma_0" matches with the name in the axi DMA device tree node:
axi_dma_0: dma#a0000000 {
#dma-cells = <0x1>;
clock-names = "s_axi_lite_aclk", "m_axi_s2mm_aclk";
clocks = <0x3 0x47 0x3 0x47>;
compatible = "xlnx,axi-dma-7.1", "xlnx,axi-dma-1.00.a";
interrupt-names = "s2mm_introut";
interrupt-parent = <0x1d>;
interrupts = <0x0 0x2>;
reg = <0x0 0xa0000000 0x0 0x1000>;
xlnx,addrwidth = <0x28>;
xlnx,sg-length-width = <0x1a>;
phandle = <0x1e>;
dma-channel#a0000030 {
compatible = "xlnx,axi-dma-s2mm-channel";
dma-channels = <0x1>;
interrupts = <0x0 0x2>;
xlnx,datawidth = <0x40>;
xlnx,device-id = <0x0>;
};
If I now look here:
% cat /proc/device-tree/dma_proxy/dma-names
dma_proxy_rx
Looks like my dma_proxy_rx, that I'm trying to request the channel for, is in there.
Edit:
In the boot log, I see this:
xilinx-vdma a0000000.dma: Please ensure that IP supports buffer length > 23 bits
irq: no irq domain found for interrupt-controller#a0010000 !
xilinx-vdma a0000000.dma: unable to request IRQ 0
xilinx-vdma a0000000.dma: WARN: Device release is not defined so it is not safe to unbind this driver while in use
xilinx-vdma a0000000.dma: Xilinx AXI DMA Engine Driver Probed!!
There are warnings - but in the end, the Xilinx AXI DMA Engine got "probed", meaning the lowest level driver loaded and is ready, right?
So it looks to me like there should be my device, but the kernel disagrees.
I've got the same problem with similar configuration. After digging a lot of kernel source code (especially drivers/dma/xilinx/xilinx_dma.c) I've solved this problem by changing channel number in dmas parameter from 0 to 1 in dma-proxy device tree entry like this:
dma_proxy {
compatible ="xlnx,dma_proxy";
dmas = <&axi_dma_0 1>;
dma-names = "dma_proxy_rx";
};
It seems that dma-proxy example is written for AXI DMA block with both mm2s (channel #0) and s2mm (channel #1) channels. And if we remove mm2s channel from AXI DMA block, the s2mm channel stays #1.
I am trying to get a Maxim14830 evaluation board to work with my Emcraft STM32F4 SOM. My SOM is running the Emcraft uClinux kernel 2.0.0 (Forked from Kernel 4.4) on github here (I have plans to attempt this with Kernel version 4.5 as well).
The driver is not registering the 4 ttyMAX[n] devices. Upon further inspection, none of the max310x.c driver code is actually being executed based on the printk's I've added. I would at least expect the probe function to run during boot.
The source code on github for the maxim14830 (protocol?) driver is here max310x.c
The source code on github for the spi (controller?) driver is here spi-stm32.c
I have been able to add an spidev device fine, so my belief is that this is a problem unique to the maxim14830.
I see a spi device here:
/sys/devices/platform/soc/40003800.spi/spi_master/spi1/spi1.0 # cat modalias
spi:maxim14830
I see the max310x driver here:
/sys/bus/spi/drivers/max310x
I see the following devicetree entries:
/sys/firmware/devicetree/base/soc/spi#40003800/max14830#0 # cat compatible
maxim,maxim14830
/sys/firmware/devicetree/base/clocks/osc_max14830
My devicetree looks like so:
&spi_2 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_spi_2>;
cs-gpios = <&gpiob 9 OUT>;
timeouts = <3>;
max14830: max14830#0 {
status = "okay";
compatible="maxim,maxim14830";
reg = <0>;
gpio-controller;
#gpio-cells = <2>;
spi-max-frequency = <20000000>;
interrupt-parent = <&exti>;
interrupts = <10>;
clocks = <&spi_uart_clk>;
clock-names = "xtal";
};
spidev: spidev#2 {
status = "disabled";
compatible = "linux,spidev";
spi-max-frequency = <20000000>;
reg = <0>;
};
};
I'm able to compile my device tree blob, and uboot the corresponding linux image fine. From my printk's, stm32_spi_probe is being called from the "Controller Driver," but to my knowledge no max310x.c driver code is being called after..
Where should I go to debug this further? This is my first embedded linux project and I could use some pointers..
I refer to below two links to use huge page in my linux driver:
Sequential access to hugepages in kernel driver
http://nuncaalaprimera.com/2014/using-hugepage-backed-buffers-in-linux-kernel-driver
Below is my code:
#define PAGE_SHIFT_2M 21
pages = vmalloc(nr_pages * sizeof(struct page*));
down_read(¤t->mm->mmap_sem);
get_nr_pages = get_user_pages(current, current->mm, buffer_start, nr_pages,
1 /* Write enable */, 0 /* Force */, pages, NULL);
up_read(¤t->mm->mmap_sem);
nid = page_to_nid(pages[0]); // Remap on the same NUMA node.
remapped_addr = vm_map_ram(pages, nr_pages, nid, PAGE_KERNEL);
printf("page pfn [0]=%lX, [1]=0x%lX, [2]=0x%lX\n",
page_to_pfn(pages[0]),
page_to_pfn(pages[1]),
page_to_pfn(pages[2]));
printf("page physical [0]=%lX, [1]=0x%lX, [2]=0x%lX\n",
page_to_pfn(pages[0])<<PAGE_SHIFT_2M,
page_to_pfn(pages[1])<<PAGE_SHIFT_2M,
page_to_pfn(pages[2])<<PAGE_SHIFT_2M);
printf("page logical addr [0]=%p, [1]=%p, [2]=%p\n",
__va(page_to_pfn(pages[0])<<PAGE_SHIFT_2M),
__va(page_to_pfn(pages[1])<<PAGE_SHIFT_2M),
__va(page_to_pfn(pages[2])<<PAGE_SHIFT_2M));
printf("page_address [0]=%p, [1]=%p, [2]=%p\n",
page_address(pages[0]),
page_address(pages[1]),
page_address(pages[2]));
Log print:
page pfn [0]=154A00, [1]=0x154A01, [2]=0x154A02
page physical [0]=2A940000000, [1]=0x2A940200000, [2]=0x2A940400000
page logical addr [0]=ffff8aa940000000, [1]=ffff8aa940200000, [2]=ffff8aa940400000
page_address [0]=ffff880154a00000, [1]=ffff880154a01000, [2]=ffff880154a02000
I have several questions:
1) I'm wondering whether vm_map_ram() can works with huge page. From kernel source code, I can see vm_map_ram() use PAGE_SIZE and PAGE_SHIFT, which's value should for default 4KB page size.
In my case, after write to the virtual address returned from vm_map_ram(), I encounter "BUG: unable to handle kernel paging request at XXXX" issue.
2) page_address return values for two pages are 0x1000(4KB) gap, not 2MB gap. Why is that?
3) Did I use right with "__va(page_to_pfn(pages[0])<
Thanks in advance!
I am using I2C on the Snowball board, running at 400KHz by default and would like to reduce this to 100KHz.
I use the api defined in and configure as follows
m_fd = open(m_filename.c_str(), O_RDWR);
if (ioctl(m_fd, I2C_SLAVE_FORCE, m_addr) < 0)
{
throw I2cError(DeviceConfigFail);
}
Does anyone know how I would go about changing the speed to standard mode.
Thanks
You can change the I2C SCL frequency in your driver's 'struct i2c_gpio_platform_data'.
static struct i2c_gpio_platform_data xyz_i2c_gpio_data = {
.sda_pin = GPIO_XYZ_SDA,
.scl_pin = GPIO_XYZ_SCL,
.udelay = 5, //#udelay: signal toggle delay. SCL frequency is (500 / udelay) kHz
....
};
Changing 'udelay' changes your 'xyz' i2c device's clock frequency.
You should change the I2C Frequency in driver source file of the corresponding peripheral (ie: Slave device to which you are communicating through I2C. Example: EEPROM/Camera etc.)
You may find some macro defined in that driver source code... like:
#define EEPROM_I2C_FREQ 400000 //400KHz
Change it to:
#define EEPROM_I2C_FREQ 100000 //100KHz
Only for that corresponding driver, I2C frequency/speed will be changed.
I am moving my first steps into Linux Kernel Device Driver development.
I learnt that for pci-e cards I have to call pci_register_driver providing information via an object of type pci_driver ( below an example ).
When I load my module ( via insmod ) If the information passed via .id_table is found than the .probe function is called.
As I am now I cannot see my .probe function called at all ( I added some logging via printk ) so I must assume that the information contained in pci_device_id must be wrong, right?
Is there any way to retrieve this information directly from the hardware itself?
Once I plug my PCI-E card on my Linux box, where I can find all information about it?
Maybe reading BIOS or some file in sys?
Any help is appreciated.
AFG
static struct pci_driver my_driver = {
// other here
.id_table = pci_datatable,
.probe = driver_add
//
};
static struct pci_device_id pci_datatable[] __devinitdata =
{
{ VendorID, PciExp_0041, PCI_ANY_ID, PCI_ANY_ID },
{ 0 },
};
int __devinit DmaDriverAdd(
struct pci_dev * pPciDev,
const struct pci_device_id * pPciEntry
)
{
// my stuff!
}
While the accepted answer does indeed answer the question, I want to elaborate a bit about the probe function not being called.
According to the Documentation/PCI/pci.txt (How To Write Linux PCI Drivers) the probing function is called for all existing PCI devices that are not owned by the other drivers yet. So, even if you have the correct vendor and device IDs you will not see the function being called if the device is owned by another driver.
To see which drivers own which devices run:
lspci -knn
If you temporarily change both vendor ID and device ID to PCI_ANY_ID your probe function will be called for every available (i.e. not owned) device.
The command you want is lspci.
With no arguments it will give you a list of all PCI devices, eg:
$ lspci
00:00.0 Host bridge: Intel Corporation 2nd Generation Core Processor Family DRAM Controller (rev 09)
00:02.0 VGA compatible controller: Intel Corporation 2nd Generation Core Processor Family
03:00.0 Network controller: Intel Corporation Centrino Advanced-N 6205 (rev 34)
...
Then to get the ids, use:
$ lspci -v -n -s 03:00.0
03:00.0 0280: 8086:0085 (rev 34)
Subsystem: 8086:1311
Flags: bus master, fast devsel, latency 0, IRQ 52
You can also find the same information in /sys:
$ cd /sys/bus/pci/devices/0000:03:00.0
$ cat vendor device
0x8086
0x0085
$ cat subsystem_vendor subsystem_device
0x8086
0x1311