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.

AM5728/BeagleBoard-X15: problem with activation of MCSPI (Linux SDK 02.00.01.07)

Other Parts Discussed in Thread: BEAGLEBOARD-X15, AM5728, SYSCONFIG

Hi,

I encounter troubles using a MCSPI controller on my AM5728 BeagleBoard-X15.
Let me describe my hardware and software environment and the steps I follow.

I'm trying to configure the MCSPI3 controller in slave Rx-only mode, this corresponds to the hardware layout of my upcoming proprietary board currently under design.
I'm using the TI Processor SDK v02.00.01.07 (Linux-based) as software environment and the SPI driver I work on is implemented as a Linux kernel module.
The Linux kernel version included in this SDK is the 4.1.13-RT provided by TI.

On the very first test performed I noticed that MCSPI3 registers were not accessible so that a read or write access to any of them (e.g. MCSPI_SYSCONFIG or MCSPI_SYSSTATUS) lead to a CPU exception.
Initially I thought I had a problem with I/O space mapping in the kernel module's virtual address space (usage of ioremap()) so I tried the same test in a bare-metal (no OS) software environment using U-Boot parts for the SoC setup.
In this light software environment I had the same problem related to MCSPI registers access, but I resolved it by enabling "manually" the MCSPI3 clock domain through the CM_L4PER_MCSPI_CLKCTRL register.
Setting CM_L4PER_MCSPI_CLKCTRL[MODULEMODE]=2 enables the module and as a feedback CM_L4PER_MCSPI_CLKCTRL[IDLEST] switches to 0 => module full-functional.
At this point the MCSPI3 module becomes operational and I correctly manage to interract with it.

Now I'm back on the Linux environment but the behaviour is slightly different.
When I try the same setting (CM_L4PER_MCSPI_CLKCTRL[MODULEMODE]=2) CM_L4PER_MCSPI_CLKCTRL[IDLEST] still stays =3 (this is the reset value: "Module is disabled and cannot be accessed").
It doesn't switch to 0 even after a very long wait.
It seems that something blocks the activation of the MCSPI3 clocks, for example a hardware config that prevents this request to succeed.

So when I have a look on the MCSPI3 clock dependencies I notice in ยง3.6.4.6.4 of the AM572x Technical Reference Manual (spruhz6) that MCSPI3 depends on 3 clocks:
- L4_PER_L3_GICLK (interface)
- L4_PER_L4_GICLK (interface)
- PER_48M_GFCLK (functional)

L4_PER_L3_GICLK and PER_48M_GFCLK status is readable in the CM_L4PER_CLKSTCTRL register:
- CLKACTIVITY_PER_48M_GFCL (bit 20)
- CLKACTIVITY_L4PER_L3_GICL (bit 8)
 
This register's content is different between the OK test (bare-metal) and the KO test (Linux Kernel module):
OK test: CLKACTIVITY_PER_48M_GFCL=1, CLKACTIVITY_L4PER_L3_GICL=1
KO test: CLKACTIVITY_PER_48M_GFCL=0, CLKACTIVITY_L4PER_L3_GICL=1
(0 means the corresponding clock is gated while 1 means it's running).
We can perform a forced software wakeup on the corresponding clocks through CM_L4PER_CLKSTCTRL[CLKTRCTRL] by when I try so it has no effect.

As far as I know the configuration of clock domains in this recent version of Linux is handled by:
- the Device Tree Blob and the associated OpenFirmware
- TI clock config drivers compatible with the AM5728 silicon

When I went through the DTS files (device tree sources) associated to my BeagleBoard-X15 (am57xx-beagle-x15.dts on top of them) MCSPI controllers are disabled by default.
Setting the MCSPI3 node status to "okay" only allows my kernel module's probe() service to be called but it has no hardware impact on the related clock domains activation.
The device tree sources are organized as follows in term of dependencies/inclusions:
am57xx-beagle-x15.dts <- dra74x.dtsi, am57xx-evm-cmem.dtsi
dra74x.dtsi <- dra7.dtsi, skeleton.dtsi
dra7.dtsi <- dra7xx-clocks.dtsi
dra7xx-clocks.dtsi doesn't deal with MCSPI SoC devices but other xxx-clocks.dtsi sources do so, like for example omap3xxx-clocks.dtsi, omap24xx-clocks.dtsi, am35xx-clocks.dtsi... but I don't know for sure which of these is compatible with my board.

I guess I have to merge some existing xxx-clocks.dtsi parts related to another board's DT config in mine, but I fear this won't be as easy as it seems !

=> Is someone able to tell me precisely which modifications do I have to perform on my DT source files to get a correct clock-enable config for the MCSPI3 ?
=> is there any other software impact like additional TI clock drivers I have to integrate in order to be "compatible" with required DT clock nodes ?

Lot of thanks for your help.

  • Hi,

    I will ask the software team to look at this.
  • Hi,

    A Ma said:
    Setting the MCSPI3 node status to "okay" only allows my kernel module's probe() service to be called but it has no hardware impact on the related clock domains activation.

     

    Do you get the spiX node in /dev? 

    Also try adding the spidev support (CONFIG_SPI_SPIDEV=y)  & test the interface. You can refer to this e2e thread for dts settings: 
      https://e2e.ti.com/support/arm/sitara_arm/f/791/t/496527 

    If so, linux should activate spi clk every time you open /dev/spidevX.Y, otherwise the spi interface will be idle. In short you need to open the /dev/spiX node in order to activate spi interface.

    Best Regards, 
    Yordan

  • Thank you Yordan for your feedback. It helped me a lot ... indirectly !

    Your answer is not on the right way because as I said I'm writing the driver part (kernel module) of the SPI slave Rx-only agent, without using the SPIDEV framework as userspace interface.

    As soon as my driver's probe() entry is called I need to setup the hardware according to my needs (read/write accesses on MCSPI registers).

    After reading some docs (especially "Runtime Power Management Framework for I/O Devices") and looking at kernel drivers examples I've understood that my platform device (MCSPI3) is inactive until this call: pm_runtime_get_sync().

    For the moment I don't know exactly what happens when calling this pm_runtime service (need to install a debugger to get sub-calls traces) but one thing is sure: just after that service execution all required internal MCSPI module clocks are active and the hard/soft interface is up, as opposed to the state just before.

    Additionally the thread link of your post (DTS setting) was a good example for updating my pinmux config ! Great.