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.

how to write to spi device from u-boot ?

Guru 20755 points

Other Parts Discussed in Thread: SYSCONFIG

Hello,

Is it possible to set registers in some spi device connected to DM8148 ?

It seems that omap3_spi.c routines are used with ti81xx, but on trying to write bus number #3, I get the folloowing error:

SPI error: unsupported bus 3. Supported busses 0 - 3

I see in code the following:

switch (bus) {
case 0:
ds->regs = (struct mcspi *)OMAP3_MCSPI1_BASE;
break;
#ifndef CONFIG_TI81XX
case 1:
ds->regs = (struct mcspi *)OMAP3_MCSPI2_BASE;
break;
case 2:
ds->regs = (struct mcspi *)OMAP3_MCSPI3_BASE;
break;
case 3:
ds->regs = (struct mcspi *)OMAP3_MCSPI4_BASE;
break;
#endif

Does it mean that only spi bus 0 is supported ? Why ? Can we add support for spi #3 ? We need it for lcd display from u-boot. It is highly important...

Best Regards,

Ran

  • Hi Ran,

    We has something similar in the past, but for the linux kernel spi driver (not uboot):

    linux-kernel/drivers/spi/omap2_mcspi.c

    [Question]  

    If I set chip_select to 0, then I do not get the error and I see /dev/spidev4.0.

    struct spi_board_info __initdata goby_spi_slave_info[] = {

    {

    .modalias = "m25p80",

    .platform_data = &goby_avp_spi_flash,

    .irq = -1,

    .max_speed_hz = 12*1000*1000,

    //.max_speed_hz = 75*1000*1000,

    .bus_num = 2,

    .chip_select = 0,

    },

    {

    .modalias = "spidev",

    .platform_data = &ti814x_spi_usb,

    .irq = -1,

    //.max_speed_hz = 12*1000*1000, // 12mhz

    .max_speed_hz = 1*1000*1000, // 1Mhz

    .bus_num = 4,

    .chip_select = 1,

    //.mode = 0x0,

    .mode = SPI_MODE_0,

    },

    … };

    ..

    void __init ti8148_spi_init(void)

    {

    spi_register_board_info(goby_spi_slave_info,

    ARRAY_SIZE(goby_spi_slave_info));

    }

    Not that if I change the num_chipselects in omap2_mcspi.c file to 2 then do see the spidev4.1 /dev/devnode get created.

    The other SPI[3] ( or spi4 ) pins are setup in u-boot and the same as another working spi bus on the same hardware..

    [Answer]

    I agree. It seems the code in omap2_mcspi.c omap2_mcspi_probe() function is common for OMAP2, OMAP3, OMAP4 and DM814x device, but McSPI controller is different between these devices.

    The omap2_mcspi_probe function is correct for OMAP2 and OMAP3, where McSPI1 has 4 channels, McSPI2 has 2 channels, McSPI3 has 2 channels and McSPI4 has 1 channel. But this code is not correct for OMAP4 and DM814x. In OMAP4 McSPI1 has 4 channels, McSPI2 has 2 channels, McSPI3 has 1 channels and McSPI4 has 1 channels. And in DM814x McSPI1 has 4 channels, McSPI2 has 4 channels, McSPI3 has 4 channels, McSPI4 has 4 channels.

    Thus for DM814x/TI814x device, all num_chipselect should be 4, not just for McSPI1.


  • Hi Pavel,

    Thanks for the reply.

    With kernel everything just fine, the problem is that we must also configure spi device in u-boot.

    I did add some simple routine for used from the command prompt of u-boot :

    static int read_spi()

    {

           struct spi_slave *slave;

           char  *cp = 0;

           uchar tmp;

           int   j;

           int   rcode = 0;

           unsigned int    bus;

           unsigned int    cs;

           unsigned int    mode;

           int             bitlen;

           char            dout[10];

           char            din[10];

           bus = 0;

           cs = 0;

           mode = 0;

           dout[0] = 0x9f;

           slave = spi_setup_slave(bus, cs,1000000, mode);

           if (!slave) {

                   printf("Invalid device %d:%d\n", bus, cs);

                   return 1;

           }

           spi_claim_bus(slave);

           if(spi_xfer(slave, 1*8, dout,din,

                                   SPI_XFER_BEGIN | SPI_XFER_END) != 0) {

                   printf("Error during SPI transaction\n");

                   rcode = 1;

           }

           else

           {

                   printf("SPI Flash id = %d  %d  %d  %d  %d \n",din[0],din[1],din[2],din[3],din[4]);

           }

           spi_release_bus(slave);

           spi_free_slave(slave);

           return 0;

    }

    When running this routine with:

    bus 0 ,

    cs 0

    , which contain fram it does not return the correct id but at least there is no hang and no errors:

    SPI Flash id = 255  0  0  0  128

    But on changing to bus=2, cs=0, which contain lcd controller it freeze (hang) on

    on a wait loop in

    omap3_spi.c :

    spi_claim_bus -> spi_reset -> wait loop

    I also validated that the register are defind correctly (I had to add them)

    /* McSPI register */

    /* In ti814x the following address if for MCSPI0 */

    #define OMAP3_MCSPI1_BASE 0x48030000

    #define OMAP3_MCSPI2_BASE 0x481A0000

    #define OMAP3_MCSPI3_BASE 0x481A2000   <-- this is used for bus 2

    #define OMAP3_MCSPI4_BASE 0x481A4000

    I also had to make some modification in omap3_spi.c becuase it seems that it supported only bus #0 for some reason (?) 

    spi_setup_slave():

    //#ifndef CONFIG_TI81XX
    case 1:
    ds->regs = (struct mcspi *)OMAP3_MCSPI2_BASE;
    break;
    case 2:
    ds->regs = (struct mcspi *)OMAP3_MCSPI3_BASE;
    break;
    case 3:
    ds->regs = (struct mcspi *)OMAP3_MCSPI4_BASE;
    break;
    //#endif

    ...

    //#ifdef CONFIG_TI81XX
    // if ((bus == 0) && (cs > 3)) {
    //#else
    if (((bus == 0) && (cs > 3)) ||
    ((bus == 1) && (cs > 1)) ||
    ((bus == 2) && (cs > 1)) ||
    ((bus == 3) && (cs > 0))) {
    //#endif

    I also validated [inmux. pinmux are actually configured in u-boot only, so if the spi device works with kernel, it should have worked in u-boot too, Right ?

    What can be the reason for this hang ?

    Regards,

    Ran

     

  • Ran,

    The DM814x SPI modules base address is provided in:

    u-boot/drivers/spi/omap3_spi.h

    #ifdef CONFIG_TI814X
    #define OMAP3_MCSPI1_BASE (0x48030100)
    #define OMAP3_MCSPI2_BASE (0x481A0000)
    #define OMAP3_MCSPI3_BASE (0x481A2000)
    #define OMAP3_MCSPI4_BASE (0x481A4000)
    #define OMAP3_MCSPI_MAX_FREQ (125000000)

    Note that the address for McSPI1 is 0x48030100, while in DM814x datasheet is 0x48030000. This is based on the fact that offset for sysconfig is (in example) 0x10 in u-boot and 0x110 in TRM. So I would recommend you to careful check the whole address used for McSPI3 (bus 2), as it might be also set to 0x481A2100 in u-boot.

    See also if the below e2e thread will be in help:
    e2e.ti.com/.../331824

    BR
    Pavel
  • Hi Pavel,

    I tried to modify the code:
    old:
    #define OMAP3_MCSPI3_BASE (0x481A2000)
    new:
    #define OMAP3_MCSPI3_BASE (0x481A2100)
    With the new code, spi_claim_bus does not hang. I'm not sure if spi_xfer works (I haven't checked with scope), but seems that it probably solved these issue , Right ?

    Regards,
    Ran