Hi,
I have a devices connected to EIM_CS0, EIM_CS1 & EIM_CS2. To verify the hardware, I've been able to work with them at the u-boot level successfully; hence, I believe I understand the necessary configuration issues for the EIM bus. Now I'm trying to get portions of these interfaces running through a driver (module). Every time I try to access the EIM space from the driver the board just locks up. I've tried it using a module (using ioremap() and iowrite8()), and I've tried it using /dev/mem in user space. In both cases the board just locks up as soon as I attempt to access that memory.
I have each CS set for 32M, so CS0=0x08000000, CS1=0x0a000000, CS2=0x0c000000.
In the driver I do this (note that error checking is removed here just to simplify):
void * virt_addr;
virt_addr = ioremap_nocache(0x0a000000,0x100));
iowrite8(0x99,virt_addr); << LOCKUP
and in user space I do this (again, error checking removed for simplicity):
uint32_t mem_address, mem_size, alloc_mem_size, page_mask, page_size;
void *mem_pointer, *virt_addr;
mem_dev = open("/dev/mem", O_RDWR | O_SYNC);
mem_size = 4;
page_size = sysconf(_SC_PAGESIZE);
alloc_mem_size = (((mem_size / page_size) + 1) * page_size);
page_mask = (page_size - 1);
mem_pointer = mmap(NULL, alloc_mem_size, PROT_READ | PROT_WRITE,
MAP_SHARED, mem_dev, (mem_address & ~page_mask));
virt_addr = (mem_pointer + (mem_address & page_mask));
fprintf(stderr,"*0x%x: 0x%x'\n",mem_address,*(unsigned long*)virt_addr); <<LOCKUP
munmap(mem_pointer, alloc_mem_size);
Note that I am able to use the /dev/mem code to access other addresses within the CPU's register space, so fundamentally I know this implementation is good. It appears that the issue is that for some reason the address space becomes "unavailable" when the kernel takes over. Any thoughts on what might be the issue here?
Ok, I got it (it amazes me how often I figure something out right AFTER I post the question to this forum)...
My .dts file is very barebones because my hardware is also minimal. I had commented out the weim node...
weim: weim@021b8000 {
compatible = "fsl,imx6q-weim";
reg = <0x021b8000 0x4000>;
interrupts = <0 14 0x04>;
clocks = <&clks 196>;
};
which is what sets up (turns on) the clocks for EIM space.
With that snippet re-installed in the .dts file, things are working.
It works now using either of the above methods.
Which of the above 2 implementation is better to use?
Only userspace changes are preferred by me.
As I was typing the original question, I had a hunch...
It appears that the CCM_CCGR6 CG5 bits are cleared by the kernel.
Gotta do more investigation; however if this turns out to be the problem; how to I tell the kernel to turn this on?