cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Participant
Participant
333 Views
Registered: ‎10-17-2018

Can only access 1 out of 4 registers from Linux Kernel

Jump to solution

Hi,

I have a linux Kernel running on my Zedboard. I now want to interact with the logic fabric from a kernel module.

I created an IP with 4x32bit registers, but only seem to be able to read/write a single register. If I do:

 

	wmb();
	iowrite32(0, base_addr);
	wmb();
	iowrite32(1, base_addr+4);
	wmb();
	iowrite32(2, base_addr+8);
	wmb();
	iowrite32(3, base_addr+12);

And a little after:

 

 

 

	wmb();
	value = ioread32(base_addr);
	seq_printf(p, "0x%x\n", value);
	wmb();
	value = ioread32(base_addr+4);
	seq_printf(p, "0x%x\n", value);
	wmb();
	value = ioread32(base_addr+8);
	seq_printf(p, "0x%x\n", value);
	wmb();
	value = ioread32(base_addr+12);
	seq_printf(p, "0x%x\n", value);

All the reads return 3.

 

The IP core is still the one generated from the tool, so the fabric-side management of the registers should be working fine.

This is my device in the device tree:

mycore {
        compatible = "dglnt,mycore-1.00.a";
        reg = <0x7e410000 0x1000>;
};

The Addresses match fine (base_addr = 0x7e410000)

What could be wrong?

0 Kudos
1 Solution

Accepted Solutions
Highlighted
Participant
Participant
316 Views
Registered: ‎10-17-2018

Re: Can only access 1 out of 4 registers from Linux Kernel

Jump to solution

I solved this by calling ioremap for each register. So instead of:

base_addr = ioremap_nocache(res->start, remap_size);

I now do:

	reg0 = ioremap_nocache(res->start, 0x4);
	reg1 = ioremap_nocache(res->start+0x4, 0x4);
	reg2 = ioremap_nocache(res->start+0x8, 0x4);
	reg3 = ioremap_nocache(res->start+0xC, 0x4);

Then, instead of adding the offset in the read and writes, I write to the correct register.

View solution in original post

0 Kudos
1 Reply
Highlighted
Participant
Participant
317 Views
Registered: ‎10-17-2018

Re: Can only access 1 out of 4 registers from Linux Kernel

Jump to solution

I solved this by calling ioremap for each register. So instead of:

base_addr = ioremap_nocache(res->start, remap_size);

I now do:

	reg0 = ioremap_nocache(res->start, 0x4);
	reg1 = ioremap_nocache(res->start+0x4, 0x4);
	reg2 = ioremap_nocache(res->start+0x8, 0x4);
	reg3 = ioremap_nocache(res->start+0xC, 0x4);

Then, instead of adding the offset in the read and writes, I write to the correct register.

View solution in original post

0 Kudos