This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Accessing registers

Hello,

I am about to start a custom SPI driver for OMAP4460.  I am encountering two issues at this point:

First of all I receive a "L3 custom error: MASTER:MPU TARGET:L4 PER2" exception if "omap2_mcspi_enable_clocks(...)" has not been called beforehand - while I can work with this by modifying the existing omap2 mcspi driver, is there another way to enable the clocks which does not need a reference to a omap2_mcspi struct?  The hope is that this will allow me to focus on the driver functionality rather than the Linux driver framework and will hopefully also allow me to successfully use devmem2 to validate the register values.

Secondly, I can read out MCSPI registers, but the resulting values are making no sense as they seem to change, shift, return zero or (occasionally) return what appear to be the correct values.  To do this I have tapped into the end of the "omap2_mcspi_probe" function and added the following lines:

	omap2_mcspi_enable_clocks(mcspi);
	debugTempMCSPI = spi_master_get_devdata(mcspi->master);
	while(1)
	{
		debugCounter++;
		switch (debugState++)
		{
			case 0:
				debugTempU32 = __raw_readl(debugTempMCSPI->base + 0x00);
				printk(KERN_INFO "MCSPI_HL_REV: %u.", debugTempU32);
				break;
			case 1:
				debugTempU32 = __raw_readl(debugTempMCSPI->base + 0x04);
				printk(KERN_INFO "MCSPI_HL_HWINFO: %u.", debugTempU32);
				break;
/********************************************
... other cases are copies of above/below ...
********************************************/
			case 16:
				debugTempU32 = __raw_readl(mcspi->base + 0x017C);
				printk(KERN_INFO "MCSPI_XFERLEVEL: %u.", debugTempU32);
				break;
			default:
				break;
		}
		if (debugState > 16)
			break;
		msleep (10);
	}
	omap2_mcspi_disable_clocks(mcspi);

Any advice/suggestions would be much appreciated - or, even better, a snippet of code to read and display a register correctly.

System information:

Processor: OMAP4460
Linux Version: Ubuntu 12.04.1
Kernel Version: 3.4.0

Regards,

Elliott Colley

  • Hi,
    You cannot access spi registers without enabling the spi fclk first (call to omap2_mcspi struct).
    The correct sequence to access registers in kernel is:
    1. Enable modules clocks
    2. Remap the register address (to match the kernel virtual address).
    3. Execute __raw_readl() or __raw_writel().

    For 2. & 3. I've used the following:
    static void __iomem *<pointer_to_spi_register>;
    <pointer_to_spi_register> = ioremap(<physical_address>, 32);
    unsigned long int temp = __raw_readl(<pointer_to_spi_register>);

    Hope this helps.

    Best Regards,
    Yordan
  • Thank you for your advice - this appears to have been the issue!