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.

AM335x MCSPI Module Linux Driver

Other Parts Discussed in Thread: SYSCONFIG

I am implementing a spi slave driver for Linux kernel delivered as part of the TI-SDK-AM335x EMV. I have rebuilt the kernel without SPI support so that I can load my driver. I have written the CM_PER_SPI1_CLKCTRL register but I am not sure if there are any other registers I need to update. I can write the MCSPI_CH0CONF and MCSPI_MODULCTRL registers but anytime I touch the MCSPI_SYSSTATUS or MCSPI_SYSCONFIG register I get a external abort non-linefetch fault. I have read the spi-omap2-mcspi.c source as a reference. Is there any other power or clock modules I have to enable to be able to configure the McSPI module?

Thank You,

Paul

  As a follow on, reading the CM_PER_L4LS_CLKSTCTRL register I can see that the CLKACTIVITY_SPI_GCLK is cleared. I have tried writing the CM_PER_L4LS_CLKCTRL register to enable the L4LS domain but that does not seem to have an effect. Can someone provide any information on how to enable the CLKACTIVITY_SPI_GCLK bit.

Thank You,
Paul 

  • Hi Paul,

    Writing the value 0x2 to the CM_PER_SPI1_CLKCTRL register (or the CM_PER_SPI0_CLKCTRL register) should set the CLKACTIVITY_SPI_GCLK bit.  

    A couple questions--  

    1.  When you write to MCSPI_CH0CONF and MCSPI_MODULCTRL, can you also read back the value written?  

    2.  Do you also get the external abort non-linefetch fault when you read the register?   

    Regards,

    Melissa

  • Melissa,

    Here is an excerpt from the probe function which generates the initial fault.

    printMsg("spislave io pins reconfigured\n");
    printMsg("CM_PER_L4LS_CLKSTCTRL (00): 0x%08X\n", ioread32(clkBase));
    printMsg("CM_PER_L4LS_CLKCTRL (60): 0x%08X\n", ioread32(clkBase + 0x60));
    printMsg("CM_PER_L4FW_CLKCTRL (64): 0x%08X\n", ioread32(clkBase + 0x64));
    printMsg("CM_PER_L4HS_CLKSTCTRL (11c): 0x%08X\n", ioread32(clkBase + 0x11C));
    printMsg("CM_PER_L4HS_CLKCTRL (120): 0x%08X\n", ioread32(clkBase + 0x120));
    iowrite32(0x00000002, clkBase + 0x60);
    printMsg("SPI CLock data (50): 0x%08X\n", ioread32(clkBase + 0x50));
    iowrite32(2, clkBase + 0x50 );
    printMsg("CM_PER_L4LS_CLKCTRL (60): 0x%08X\n", ioread32(clkBase + 0x60));
    printMsg("SPI1 CLocks Enabled\n");
    printMsg("SPI CLock data (50): 0x%08X\n", ioread32(clkBase + 0x50));
    printMsg("CM_PER_L4LS_CLKSTCTRL (00): 0x%08X\n", ioread32(clkBase));
    iounmap(clkBase);
    release_mem_region(AM33XX_PRCM_BASE, 0x200);
    /*
    * Make sure all the clocks and power are enabled
    */
    printMsg("MCSPI_CH0CONF - Physical Address: 0x%08X - Virtual Address: 0x%08X\n",
    (unsigned int)&((AM33XX_SPI_Registers *)AM33XX_SPI1_BASE)->MCSPI_CH0CONF,
    (unsigned int)&(drvdata->spiRegisters->MCSPI_CH0CONF));
    printMsg("MCSPI_MODULCTRL - Physical Address: 0x%08X - Virtual Address: 0x%08X\n",
    (unsigned int)&((AM33XX_SPI_Registers *)AM33XX_SPI1_BASE)->MCSPI_MODULCTRL,
    (unsigned int)&(drvdata->spiRegisters->MCSPI_MODULCTRL));
    printMsg("MCSPI_SYSCONFIG - Physical Address: 0x%08X - Virtual Address: 0x%08X\n",
    (unsigned int)&((AM33XX_SPI_Registers *)AM33XX_SPI1_BASE)->MCSPI_SYSCONFIG,
    (unsigned int)&(drvdata->spiRegisters->MCSPI_SYSCONFIG));

    faults on the next line ->

    printMsg("MCSPI_CH0CONF - Physical Address: 0x%08X - Virtual Address: 0x%08X - Data: 0x%08X\n",
    (unsigned int)&((AM33XX_SPI_Registers *)AM33XX_SPI1_BASE)->MCSPI_CH0CONF,
    (unsigned int)&(drvdata->spiRegisters->MCSPI_CH0CONF),
    ioread32(&(drvdata->spiRegisters->MCSPI_CH0CONF)));

    and the output when I do the insmod.

    [ 64.005035] spislave io pins reconfigured
    [ 64.009216] CM_PER_L4LS_CLKSTCTRL (00): 0x18004502    <- CLKACTIVITY_SPI_GCLK 0x02000000 not set
    [ 64.014221] CM_PER_L4LS_CLKCTRL (60): 0x00000000
    [ 64.019042] CM_PER_L4FW_CLKCTRL (64): 0x00000000
    [ 64.023864] CM_PER_L4HS_CLKSTCTRL (11c): 0x00000001
    [ 64.028961] CM_PER_L4HS_CLKCTRL (120): 0x0000022A
    [ 64.033874] SPI CLock data (50): 0x00000001
    [ 64.038269] CM_PER_L4LS_CLKCTRL (60): 0x00000000
    [ 64.043060] SPI1 CLocks Enabled
    [ 64.046386] SPI CLock data (50): 0x00000002
    [ 64.050750] CM_PER_L4LS_CLKSTCTRL (00): 0x18004502    <- CLKACTIVITY_SPI_GCLK 0x02000000 still not set
    [ 64.055755] MCSPI_CH0CONF - Physical Address: 0x481A012C - Virtual Address: 0xFA1A012C
    [ 64.064025] MCSPI_MODULCTRL - Physical Address: 0x481A0128 - Virtual Address: 0xFA1A0128
    [ 64.072479] MCSPI_SYSCONFIG - Physical Address: 0x481A0110 - Virtual Address: 0xFA1A0110
    [ 64.080963] Unhandled fault: external abort on non-linefetch (0x1028) at 0xfa1a012c
    [ 64.088958] Internal error: : 1028 [#1]
    [ 64.092956] Modules linked in: spislave(O+)
    [

    Thank You for looking into this. In short, what steps and in what order do I have to perform to enable the McSPI module. 

  • Hi Paul,

    Can you try adding a while loop after writing to the CM_PER_SPI1_CLKCTRL register ("iowrite32(2, clkBase + 0x50 );" command) that waits for the L4LS_GCLK and SPI_GCLK bits in the CM_PER_L4LS_CLKSTCTRL register to be set?  

    Regards,
    Melissa

  • Melissa,

      It never breaks out of the loop, I occasionally print the value of the register while in the loop and the value never changes. 0x18004502 which indicates the L4LS clock is active but the SPI1_GCLK never is.

    Paul

     I also tried adding a write to MCSPI_SYSCONFIG to enable all clock activity and ignore idle before the loop yet it still never saw SPI1_GCLK get set. ? It seems a little strange I can write to the register yet not read it.

  • Melissa,

      I found a problem with writing to CM_PER_SPI1_CLKCTRL. I fixed that and now the loop on SPI1_GCLK completes and I am able to write to the SPI control registers. Your comment on writing to the correct addresses lead me to triple check that code and I found the problem.

    Regards,

    Paul Terricciano

  • Hi Paul,

    Thanks for the update.  Now that the SPI_GCLK bit is set, I assume you no longer see the "external abort non-linefetch fault" error.  Is that correct?

    Regards,

    Melissa

  • Melissa,

      That is correct, once the SPI_GCLK bit was set I can read write the SPI module registers.

    Thanks,

    Paul

  • Hi Paul,

                I am facing a similar issue while programming DMTimer 4 in AM335x. It would be great help if you could share solution to the problem you faced in enabling CM_PER<>CLKCTRL.

    Thanks and Regards,

    Prateek