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.

GPMC OMAP controller of HPI

Hi, all

I already posted here before... but still got the doubts...
The OMAP 3530 and a DSP C5510, I want to write/read data in the DSP via HPI (auto-incrementing).
The OMAP is running LINUX 2.6.28.I'm using the GPMC bus in the OMAP side.
I know that I have to control the HPI transfer using two pins HCNTL0 and  HCNTL1, Changing their status I select, the DSP knows if the data I was passing was DATA, ADRESS or CONTROL.

   _____________                 _______________
  |       GPIOx|--------------->|HCNTL0         |
  |       GPIOy|--------------->|HCNTL1         |
  |        GPMC|--------------->| HPI           |
  |    OMAP    |                |      DSP      |
  |    3530    |                |     C5510A    |
  |            |                |               |
  |____________|                |_______________|

                      FIG1

So in the OMAP software I can use the linux funcition "__raw_writel(val, reg_addr)" in a loop with the "val" changing with the data I want and the interesting part, the reg-addr value set to:

      REG                           Physical Address
GPMC_NAND_DATA_i             0x6E00 0084 + (0x0000 0030 * I)
I=3 for example...
                                    "SPRUF98B–September 2008 Memory Subsystem page  1263"

to write address or data, for GPMC writing in the same register doesnt matter, software will control the pins HCNTL0 and HCNTL1, and DSP will know the address, the data and the auto-incrementing I want.


 __________________       __________________
(                  )     (                  )
(  SET HCNTL0 = 0  )---->(      WRITE       )
(  SET HCNTL1 = 0  )     (       HPIC       )
(__________________)     (__________________)
                                  

                                   |
                                   |
                                   |
 __________________       _________V________
(                  )     (                  )
(     WRITE        )<----(  SET HCNTL0 = 0  )
(     HPIA MSB     )     (  SET HCNTL1 = 1  )
(__________________)     (__________________)
        |
        |
        |
 _______V__________       __________________
(                  )     (                  )
(  SET HCNTL0 = 0  )---->(  WRITE           )
(  SET HCNTL1 = 0  )     (   HPIC           )
(__________________)     (__________________)
                                   |
                                   |
                                   |
 __________________       _________V________
(                  )     (                  )
(     WRITE        )<----(  SET HCNTL0 = 0  )
(     HPIA LSB     )     (  SET HCNTL1 = 1  )
(__________________)     (__________________)
        |
        |               .....................................
        |               :                                   :
 _______V__________     :      __________________           :                      
(                  )    :     (                  )          :
(  SET HCNTL0 = 1  )--------->(    WRITE         )-----     :
(  SET HCNTL1 = 0  )    :     (    HPID AUTO-INC )    |     :
(__________________)    :     (__________________)    |     :
                        :                ^            |     :
                        :                |   LOOP     |     :
                        :                |            |     :
                        :                --------------     :        
                        :...................................:

                      FIG. 2


So Ok this point?

Now, the hardcore part!

To save CPU, We will use the DMA (replacing the "dots square" in fig 2).
We configure the DMA mode, two channels one for WR and other for RD.
The doubt is the following, when I use the functions bellow:

        dsp_in_dmabuf = dma_map_single(lp->dev, buffer_wr, len, DMA_TO_DEVICE);
        omap_set_dma_src_adrr(*dma_ch_dsp_in, dsp_in_dmabuf);
        omap_set_dma_dest_adrr(*dma_ch_dsp_in, (physaddr + reg));
        omap_start_dma(*dma_ch_dsp_in);     
 
1) The (physaddr + reg) should be a constant address correct? (In this case I will use the same constant GPMC_NAND_DATA_i register)?

2) When DMA writes to external device, it write the address and then the data I want to write? How can I tell DMA to just send data in the GPMC lines without send address to the bus?

I hope you can help me,

Thanks...

  • Daniboy said:

    To save CPU, We will use the DMA (replacing the "dots square" in fig 2).
    We configure the DMA mode, two channels one for WR and other for RD.
    The doubt is the following, when I use the functions bellow:

            dsp_in_dmabuf = dma_map_single(lp->dev, buffer_wr, len, DMA_TO_DEVICE);
            omap_set_dma_src_adrr(*dma_ch_dsp_in, dsp_in_dmabuf);
            omap_set_dma_dest_adrr(*dma_ch_dsp_in, (physaddr + reg));
            omap_start_dma(*dma_ch_dsp_in);     
     
    1) The (physaddr + reg) should be a constant address correct? (In this case I will use the same constant GPMC_NAND_DATA_i register)?

    I'm not familiar with the Linux DMA driver, so this is more of a hardware answer...  You need to setup the DMA such that it writes to address in the chip select space that you have connected to the HPI.  Making that a fixed address is probably the easiest thing to do.  I'm not sure what you meant with the GPMC_NAND_DATA_i comment.  You will want to configure the GPMC as a normal async interface, not a NAND interface.

    Daniboy said:

    2) When DMA writes to external device, it write the address and then the data I want to write? How can I tell DMA to just send data in the GPMC lines without send address to the bus?

    If the address lines of the OMAP are not hooked up to the HPI of the 5510 then the address lines become a "dont care".  Said differently, you can use a fixed address in that address space and that address (as in your first question) will be placed on the address lines for every single cycle, but the 5510 will never "know" that.

    You can optimize your design a bit by actually using two of the address lines to hook up to HCNTL0 and HCNTL1 on the 5510.  Instead of having to continually change GPIO pins you can simply write to a different address to write to the various registers (HPID, HPIC, HPIA).

  • Brad Griffis said:
    You can optimize your design a bit by actually using two of the address lines to hook up to HCNTL0 and HCNTL1 on the 5510.  Instead of having to continually change GPIO pins you can simply write to a different address to write to the various registers (HPID, HPIC, HPIA).

    I agree with Brad on this, most implementations of a memory interface to a HPI utilized address lines to handle the control signals of the HPI, such that you just write to different addresses in the host to get different control combinations on the HPI. In this case you would have to have your DMA setup to write to a single address, much like Brad I am more familiar with the hardware than the Linux DMA driver, but I can say that the SDMA on the OMAP3 has a DST_AMODE bit field in the DMA4_CCRi register discussed in the SDMA chapter of the TRM which can be set to constant address mode such that it does not increment the address as values are written out.

  • Brad and Bernie,

    Thanks for the anserws. The GPMC data bus will be conected to the DSP HPI data bus and only the two GPMC address lines [2:1] will be conected to the HPI control signal. Only a single question in wich mode does I have to set my GPMC:

     

    1. Multiplexed Address Data 16-Bit Device
    2. Nonmultiplexed  Address Data 16-Bit  Device With LIMITEDADDRESS Bit Enabled
    3. 16-Bit NAND Device
    4. 8-Bit NAND Device

    I think, I must set GPMC to the option 2(Nonmultiplexed  Address Data 16-Bit  Device With LIMITEDADDRESS Bit Enabled) that is correct?

    Thanks,

  • Daniboy said:
    I think, I must set GPMC to the option 2(Nonmultiplexed  Address Data 16-Bit  Device With LIMITEDADDRESS Bit Enabled) that is correct?

    That is correct, this sets up the GPMC as a standard asynchronous parallel interface, giving you the control you would need to access the HPI through software.

  • Hi Mr. Thompson!

     

    I have a similar problem, the difference is we are using C64x family with HPI-16.

    How can I connect GPMC to indicate the first and second part of 32-bit word to HPI bus (HHWIL)?

    I think HHWIL can't be connected at GPIO because during the DMA transaction I can't control the GPIO, right?

     

    Thank you!

  • Roberto de Matos said:
    How can I connect GPMC to indicate the first and second part of 32-bit word to HPI bus (HHWIL)?

    HHWIL would be connected to the lowest address bit on the OMAP3 GPMC bus so it will change states for every 16 bits you write out, giving you effectively a 32 bit word output to the 16 bit HPI, much like you would write to a 16 bit wide SRAM. The key to using the DMA with this would be to specify a transfer size of 32 bits, so that the DMA writes out a full 32 bits into the GPMC memory space for each transfer while keeping the address of that 32 bit transfer constant. Though I have not done much work with the SDMA it looks like you would simply set DMA4_CSDPi.DATA_TYPE = 0x2 for 32 bit data, in addition to DMA4_CCRi.DST_AMODE = 0x0 for constant addressing mode.

    Roberto de Matos said:
    I think HHWIL can't be connected at GPIO because during the DMA transaction I can't control the GPIO, right?

    That is right, this would have the effect of only writing every other 16 bits of data into the HPI slave if you were to DMA, it could work if you did it very carefully with software (no DMA, or doing some crazy two step DMA for high and low half words), though in general using the lowest address bit of the 16bit GPMC should be easiest.

  •  

    Mr. Thompson,

     

    Thank you for the answers!

    Even I use DMA constant addressing mode the lowest address bit will be changed? I thought all address lines will be constant during the DMA transfer.

    While I was waiting your answer I read some parts of TRM and I thought the solution was HBE lines.

     

    From AM35xx TRM:

    Section 9.1.5.2.2 

    System requests with data width greater than the external device data bus width are split into successive accesses according to both the external device data-bus width and little-endian data organization. 

    Section 9.1.5.2.7

    The device system can issue the following requests to the GPMC:

     - Byte, Word16, Word32 requests (byte enable controlled). This is always a single request from the interconnect point of view.

     

    If the lowest address bit works I'll prefer it, because the behavior of HBE lines is very confuse.

    Thank you again!

     

  • Roberto de Matos said:
    Even I use DMA constant addressing mode the lowest address bit will be changed? I thought all address lines will be constant during the DMA transfer.

    The DMA should treat the destination as a 32 bit wide data address when moving 32 bit wide elements, so from an internal bus perspective it writes 32 bits to the same physical address (lines are constant internally) but the GPMC will end up treating it as two individual accesses externally, so the lowest address bit will toggle. This way you can access memory on external busses that differ in width from the internal bus structure of the device, the memory interface (GPMC in this case) does the adaptation for you. The only exception for the GPMC is if you use the GPMC in 8 bit mode, as it lacks an A0 pin you end up with byte alias accesses when in 8 bit.

    Roberto de Matos said:
    While I was waiting your answer I read some parts of TRM and I thought the solution was HBE lines.

    The byte enable lines are there to enable specific bytes on the bus, kind of like sub-addressing, an address under the address, so they would not be toggling the way you would need to do two individual 16 bit accesses when you have the GPMC set to 16 bit wide.

    Roberto de Matos said:

    Section 9.1.5.2.7

    The device system can issue the following requests to the GPMC:

     - Byte, Word16, Word32 requests (byte enable controlled). This is always a single request from the interconnect point of view.

    I believe what this is getting at is that the master accessors in the device (CPU, DMA, etc) can access the GPMC however they want internally, and the GPMC will manage to adapt it to the external memory. As mentioned above, the byte enables allow individual bytes to be accessed in an external memory, so the GPMC can use this to manage requests of varying widths from the master accessors.