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 access external peripheral from C64x+ DSP

Other Parts Discussed in Thread: OMAP3530

Hello, I am newbie to the C54x+ DSP in OMAP3530.

I got Linux & DSPLink running on the ARM, and DSPBIOS Link running on the DSP.  

I have a peripheral device (let say a FPGA) connecting to the OMAP3530 data bus via GPMC_nCS4, and I want to access (read / write) the  FPGA device from the DSP-side.

How & what do I need to setup on the OMAP3530 to allow the DSP to talk to the FPGFA ?

Thanks,
/Chi.

  • You would need to have the GPMC configured properly to talk to your device.  Both the ARM and the DSP are capable of writing to the GPMC.  The DSP would need to write to the address space of CS4 in order to do the write.

    You should be aware of the fact that the DSP/IVA subsystem has an MMU on the front end.  The hardware default is that the MMU is disabled.  In this state all memory accesses simply pass through.  If software (e.g. dsplink) has turned on the MMU then you will need to add a mapping to the MMU TLB such that you can address the GPMC CS4 space.

  • I configured the GPMC for CS4 from the ARM, and is able to address the CS4 (read & write to the FPGA device) from the ARM. However, I am not able to address the CS4 from the DSP.

    The CS4 physical base address I got from the ARM (running Linux) is 0x01000000. 

    My OMAP3530 is running dsplink version 1.63.   

    Before building the dsplink package, I added the CS4 mapping to the DSPBIOS Tconf file " /dsplink/inc/DspBios/5.XX/OMAP3530/dsplink-omap3530-base.tci " as follow:

      var FPGA = prog.module("MEM").create("FPGA");
      FPGA.base         = 0x01000000;
      FPGA.len          = 0x00008000;
      FPGA.space        = "data";
      FPGA.createHeap   = false;
      FPGA.comment      = "FPGA device";

    And also added to file " /dsplink/config/all/CFG_OMAP3530_SHMEM.c " in the LINKCFG_MemEntry  LINKCFG_memTable_00 [] data structure the CS4 mapping entry, as follow:

      10,            /* ENTRY        : Entry number */
      "FPGA",        /* NAME         : Name of the memory region */
      0x01000000,    /* ADDRPHYS     : Physical address */
      0x01000000,    /* ADDRDSPVIRT  : DSP virtual address */
      (Uint32) -1,   /* ADDRGPPVIRT  : GPP virtual address (if known) */
      0x00008000,    /* SIZE         : Size of the memory region */
      FALSE,         /* SHARED       : Shared access memory? */
      FALSE          /* SYNCD        : Synchornized? */

    Can any one tell me what did I configure wrong ? Or are there other configurations I need to set ?

     
    Thanks,
    /Chi.

     

     

     

  • For your entry in CFG_OMAP3530_SHMEM.c is there another place in the file with a "number of entries" field?  I have not used the 1.6x dsplink as heavily as I did with 1.5x, but in 1.5x you needed to increment the number of entries in addition to adding the entry.

  • I have finally got it working by configuring the CS4 to a higher base address, 0x20000000.

    I sort of gotten the hint from the description in section 6.2 of DSP/BIOS Link Platform Guide (LNK 188 USR ), version 1.63. It states:

    "The DSP on the OMAP3530 has a MMU for accessing L3 interconnect address space
    (addresses above 0x11000000). DSP/BIOS™ Link automatically configures and
    enables the MMU. The translation from virtual to physical is a straight thru (i.e.
    physical address == virtual address)."

    Thanks for the help!

    /Chi.

  • Hello Chi Tran, hello TI engineer,

    Can I ask a few questions about fpga + gpmc + dsp +arm? I am not familiar with fpga and dsp, so questions maybe ......:)

    After configure fpga memory on DSPlink files: dsplink-omapXXXX-base.tci and CFG_OMAPXXXX_SHMEM.c

    how do you access fpga memory from DSP side and ARM side?

    Let's say,   FPGA.base         = 0x28000000;   FPGA.len          = 0x00100000;

    Can I directly access this memory like this in Linux device driver: *(0x28000000) |= 0x1 ?

    How about DSP side?

     

    I appreciate your help

     

     

     

     

     



  • Hi Zeng,

     

    From ARM (rather say Linux) point of view, you can directly access he FPGA as long as it is IO mapped to Linux kernel. I believe when you are assuming FPGA base address = 0x28000000, you understand the interfacing part of it.

    Thanks,

    Vaibhav

  •  

    Hello  :

    How do you configuring CS4 base address to 0x20000000?

    Directly configure GPMC_CONFIG7_4 "BASEADDRESS" fied to (100000)b?

    Does it mean that the physic address "cs_mem_base" coming from "gpmc_cs_request(4, SZ_4K, &cs_mem_base)" is useless?

    And we should use "access_addr=ioremap(0x20000000,SZ_4K)" instead of "access_addr=ioremap(cs_mem_base,SZ_4K)"?

    As my code will be like:

    if (gpmc_cs_request(MY_CS, SZ_4K, &cs_mem_base) < 0)

    {

    printk("<1>Failed to request GPMC mem for cs%d\n",MY_CS);

    return -1;

    }

     

    l=gpmc_cs_read_reg(MY_CS, GPMC_CS_CONFIG7);

    l|=(0x20);    // set A29 bit to 1

    gpmc_cs_write_reg(MY_CS, GPMC_CS_CONFIG7,l);

     

    Thank you very much !

     

  • In dsplink-omap3530-base.tci, I set:

    /*  ============================================================================

     *  MEM : MYFPGA

     *  ============================================================================

     */

    var MYFPGA = prog.module("MEM").create("MYFPGA");

    MYFPGA.base             = 0x20000000;

    MYFPGA.len              = 0x10000;

    MYFPGA.space            = "data";

    MYFPGA.comment          = "MYFPGA";

    MYFPGA.createHeap       = false;

     

    In CFG_OMAP3530_SHMEM.c, I add the entry to LINKCFG_memTable_00 [] :

        {

            10,                    /* ENTRY          : Entry number */

            "MYFPGA",              /* NAME           : Name of the memory region */

            0x20000000,            /* ADDRPHYS       : Physical address */

            0x20000000,            /* ADDRDSPVIRT    : DSP virtual address */

            (Uint32) -1u,          /* ADDRGPPVIRT    : GPP virtual address (if known) */

            0x00010000,            /* SIZE           : Size of the memory region */

            FALSE,                 /* SHARED         : Shared access memory? */

            FALSE                  /* SYNCD          : Synchornized? */

        },

    For a WRITE access:
    #define MYFPGA_FRAME_COUNT_REG        (volatile Uint16 *)(0x20000710u)
    *(MYFPGA_FRAME_COUNT_REG)= value;

  • Hello LiMing,

    On the ARM-side, I added the following to configure CS4 base address:

    #define MY_FPGA_CS  4

    //MY FPGA phys address space in CS4

    #define MY_FPGA_START  0x20000000

    static struct resource my_fpga_resources[] = {

           [0] = {

                   .start = MY_FPGA_START,

                   .end = MY_FPGA_START + SZ_64K,

                   .flags = IORESOURCE_MEM,

           },

    };

    static struct platform_device my_fpga_device = {

           .name = "my-fpga",

           .id = 0,

           .num_resources = ARRAY_SIZE(my_fpga_resources),

           .resource = my_fpga_resources,

           .dev = {

                   .platform_data = NULL,

           },

    };

    static void my_fpga_init(void)

    {

           unsigned long cs_mem_base;

           struct gpmc_timings timing;

           /* Setup FPGA chip-select */

           omap_cfg_reg(T8_GPMC_NCS4_GPIO_55);

           if (gpmc_cs_request(MY_FPGA_CS, SZ_128M, &cs_mem_base) < 0) {

                   printk(KERN_ERR "Failed to request GPMC mem for MY FPGA\n");

                   return;

           }

           my_fpga_resources[0].start= cs_mem_base;

           my_fpga_resources[0].end= cs_mem_base + SZ_128M - 1;

    ...
    ...

    Have fun!

     


     

     

  •  

    thanks Chi Tran:

    I see your point, I have done the same work to the two configuration files like this:

    ----------------------------------------------------------------------------------------------------------------------------

        /*the region bellow is added by Levin in 2011.11.11,used for communicating with GPMC*/

        {

            10,                    /* ENTRY          : Entry number */

            "FPGA",                /* NAME           : Name of the memory region */

            0x20000000,            /* ADDRPHYS       : Physical address */

            0x20000000,            /* ADDRDSPVIRT    : DSP virtual address */

            (Uint32) -1,           /* ADDRGPPVIRT    : GPP virtual address (if known) */

            0x00001000,            /* SIZE=4K           : Size of the memory region */

            FALSE,                 /* SHARED         : Shared access memory? */

            FALSE                  /* SYNCD          : Synchornized? */

        }

    ----------------------------------------------------------------------------------------------------------------------------

    /*the region bellow is added by Levin in 2011.11.11,used for communicating with GPMC*/

    /*  ============================================================================

     *  MEM : FPGA

     *  ============================================================================

     */

    var FPGA = prog.module("MEM").create("FPGA");

    FPGA.base             = 0x20000000;

    FPGA.len              = 0x00001000;

    FPGA.space            = "data";

    FPGA.createHeap       = false;

    FPGA.comment          = "SSB controller";

    -----------------------------------------------------------------------------------------------------------------------------

    what confused me is:

    How do you configuring GPMC CS4 base address to 0x20000000?

    Directly configure GPMC_CONFIG7_4 "BASEADDRESS" fied to (100000)b?

    what I mean is CS base address only determined by GPMC_CONFIG7_i "BASEADDRESS" fied?

    since I used system call "gpmc_cs_request(MY_CS, SZ_4K, &cs_mem_base)" to request the CS base address and region before. It seems to do more work than just set the CS base address.

    thanks very much.

  •  

    thanks Chi Tran:

    I see your point, I have done the same work to the two configuration files like this:

    ----------------------------------------------------------------------------------------------------------------------------

        /*the region bellow is added by Levin in 2011.11.11,used for communicating with GPMC*/

        {

            10,                    /* ENTRY          : Entry number */

            "FPGA",                /* NAME           : Name of the memory region */

            0x20000000,            /* ADDRPHYS       : Physical address */

            0x20000000,            /* ADDRDSPVIRT    : DSP virtual address */

            (Uint32) -1,           /* ADDRGPPVIRT    : GPP virtual address (if known) */

            0x00001000,            /* SIZE=4K           : Size of the memory region */

            FALSE,                 /* SHARED         : Shared access memory? */

            FALSE                  /* SYNCD          : Synchornized? */

        }

    ----------------------------------------------------------------------------------------------------------------------------

    /*the region bellow is added by Levin in 2011.11.11,used for communicating with GPMC*/

    /*  ============================================================================

     *  MEM : FPGA

     *  ============================================================================

     */

    var FPGA = prog.module("MEM").create("FPGA");

    FPGA.base             = 0x20000000;

    FPGA.len              = 0x00001000;

    FPGA.space            = "data";

    FPGA.createHeap       = false;

    FPGA.comment          = "SSB controller";

    -----------------------------------------------------------------------------------------------------------------------------

    what confused me is:

    How do you configuring GPMC CS4 base address to 0x20000000?

    Directly configure GPMC_CONFIG7_4 "BASEADDRESS" fied to (100000)b?

    what I mean is CS base address only determined by GPMC_CONFIG7_i "BASEADDRESS" fied?

    since I used system call "gpmc_cs_request(MY_CS, SZ_4K, &cs_mem_base)" to request the CS base address and region before. It seems to do more work than just set the CS base address.

    thanks very much.

  •  

    Hi Chi Tran:

    thanks  for your quick reply :)

    since you use these code:

           if (gpmc_cs_request(MY_FPGA_CS, SZ_128M, &cs_mem_base) < 0) {

                   printk(KERN_ERR "Failed to request GPMC mem for MY FPGA\n");

                   return;

           }

           my_fpga_resources[0].start= cs_mem_base;

           my_fpga_resources[0].end= cs_mem_base + SZ_128M - 1;

    Have you check that my_fpga_resources[0].start is still 0x20000000 as we wish?

  • You also have to setup the Pad Configuration Register for CS4 to Mode0. I believe the default is Mode7.

    Refer to System Control Module (SPRUFA6B) document. 

    Register Physical Address Mode0 Mode4 Mode7

    0x480020B4 gpmc_ncs4 gpio_55 safe_mode

     

  •  

    Thanks Chi Tran :-)

    It works.

    I choose CS3 。 I use these code to configure it to mode 0:

    1. l=(*(volatile int *)(ioremap(OMAP34XX_CTRL_BASE,SZ_4K)+CONTROL_PADCONF_GPMC_nCS3));

    2. l&=0xfff8fff8;//set to mode 0

    3. (*(volatile int *)(ioremap(OMAP34XX_CTRL_BASE,SZ_4K)+CONTROL_PADCONF_GPMC_nCS3))=l;

    Now I can access GPMC in ISR from DSP side. Thanks for your help :-)

    By the way I use these code to setup the timing:

    1.  

      void Levin()

       

    2.  

      {

       

    3.  

              struct gpmc_timings t;

       

    4.  

              u32 l;

       

    5.  

              memset(&t,0,sizeof(t));

       

    6.  

              t.cs_on=14;

       

    7.  

              t.adv_on=14;

       

    8.  

              t.oe_on=42;

       

    9.  

              t.access=63;

       

    10.  

              t.oe_off=70;

       

    11.  

              t.adv_rd_off=28;

       

    12.  

              t.cs_rd_off=70;

       

    13.  

              t.rd_cycle=70;

       

    14.  

              t.we_on=49;

       

    15.  

              t.we_off=112;

       

    16.  

              t.wr_access=133;

       

    17.  

              t.adv_wr_off=42;

       

    18.  

              t.cs_wr_off=133;

       

    19.  

              t.wr_cycle=133;

       

    20.  

              gpmc_cs_write_reg(MY_CS,GPMC_CS_CONFIG1,

       

    21.  

              GPMC_CONFIG1_READTYPE_SYNC

       

    22.  

              |GPMC_CONFIG1_WRITETYPE_SYNC

       

    23.  

              |GPMC_CONFIG1_CLKACTIVATIONTIME(1)

       

    24.  

              |GPMC_CONFIG1_DEVICESIZE_16

       

    25.  

              |GPMC_CONFIG1_DEVICETYPE_NOR

       

       

    26.  

              |GPMC_CONFIG1_TIME_PARA_GRAN

       

    27.  

              |GPMC_CONFIG1_FCLK_DIV4

       

      );

       

       

    28.  

              show_gpmc_clk(MY_CS,&t);

       

    29.  

              gpmc_cs_set_timings(MY_CS,&t);

       

    30.  

              l=gpmc_cs_read_reg(MY_CS,GPMC_CS_CONFIG1);

       

    31.  

              l|=GPMC_CONFIG1_FCLK_DIV4;

       

    32.  

              gpmc_cs_write_reg(MY_CS,GPMC_CS_CONFIG1,l);

       

    33.  

      }

       

     

     

    I choose these timing parameters according to my experience。

    Fortunately it works!

    But I still want to know how to set the timing exactly right.

    Would you please show how you determined that?

     

  • Hi Chi Tran,

    I know this post is 2 years old, but I hope someone will reply to my question.

    I understood the configuration changes in the tci and .c files on DSPlink  and I have made changes into the files.
    The next step Chi used is to modify the kernel of the ARM, which confused me, because in the my_fpga_init function he is re assigning my_fpga_resources[0].start to the value (address) obtained from the gpmc_cs_request call,  which is the 0x01000000.

    Can anyone explain what changes to make to the kernel so that the base address of GPMC CS4 will be 0x20000000?

    Thank you

    Muez