• Join
  • Sign In with my.TI Login
Texas Instruments
  • Products
  • Applications
  • Tools & Software
  • Support & Community
  • Sample & Buy
  • About TI
Sample & Purchase Cart Sample & Purchase Cart
  • Search
  • Advanced
TI E2E™ Community
  • Support Forums
  • Blogs
  • Groups
  • Videos
  • 简体中文
  • More ...
TI Home » TI E2E Community » Support Forums » Digital Signal Processors (DSP) » DaVinci™ Video Processors » DM814x and AM387x Processors Forum » DM814x: C674x access to peripherals (GPMC)
Share
DaVinci™ Video Processors
  • Forums
  • Announcements
Options
  • Subscribe via RSS

Forums

DM814x: C674x access to peripherals (GPMC)

This question is answered
Jonathan Journo
Posted by Jonathan Journo
on Oct 27 2011 04:46 AM
Intellectual475 points

Hello,

I am working on a DM814x chip and I have encounter a problem. Hopping anyone have found solutions....:-)

We need to access the GPMC bus from the C674x directly but unfortunately the GPMC memory is not mapped to the C674x core.

We could not read the data through the ARM and pass it to the DSP because of real time issues (linux latencies).

It seems I must pass through the DSP MMU that mapped L3 regions.

My 3 questions are:

1/ How can I access the GPMC memory space from the C674x without using DMA? Which MMU register should I configure.


2/ How can I access the GPMC memory space from the C674x using DMA? How to configure the DMA access.

 

3/ How does the DSP access to the DDR space? is it also from the MMU?

 

Thanks for any help

EDMA DM814x DM816x C6A816x AM389x MMU DEMMU DSP MMU GPMC DM81xx
Report Abuse
  • Reply
You have posted to a forum that requires a moderator to approve posts before they are publicly available.
All Replies
  • Viet Dinh
    Posted by Viet Dinh
    on Oct 27 2011 11:12 AM
    Genius15290 points

    Jonathan,

    DSP has to go thru the (DE)MMU to access GPMC.

    EDMA can access GPMC directly or via (DE)MMU. 

    You will find the connectivity details in the DM814x DS (Sept. 2011) table 5-1. 

    Rgds,

    Viet

    dm8148
    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Daniel Morelli
    Posted by Daniel Morelli
    on Oct 27 2011 14:45 PM
    Prodigy80 points

    We also have the same issue.   We have the GPMC bus bridged to the NIOS Avalon bus so we can extend the SOC but we need the DSP to access the NIOS fabric as well.  Also we need to use the video port as a way to upload video data directly to the DSP.  Does the HDVPSS need to be controlled by the ARM as well.  That would also add in Linux delays.

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Jonathan Journo
    Posted by Jonathan Journo
    on Oct 31 2011 05:07 AM
    Intellectual475 points

    Hi Viet,

     

    Well, I have successfully access the GPMC bus through the EDMA via the DSP core, the EDMA accessed the GPMC directly.

     

    You wrote that each DSP and EDMA could also access the GPMC peripheral via the (DE) MMU.

     

    How can it be done?

    What do I need to configure to make it possible, may be it is the MMU_RAM register and other MMU registers?  

    If yes, is there any reference code initialization that may be shared?

    thanks, 

     

    About DSP access to the NIOS memory through PCI, It can be done via EDMA like I did for the GPMC memory.

     

     

     

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Brad Griffis
    Posted by Brad Griffis
    on Nov 01 2011 21:06 PM
    Verified Answer
    Verified by Jonathan Journo
    Guru57350 points

    Jonathan,

    All 674x cores define 0x0080_0000 as L2 RAM and similarly they define other low addresses as L1 RAM, configuration registers, etc.  That's why the 674x has trouble accessing the GPMC address range which resides at address 0x00000000 on the L3 Interconnect.  To get around this issue you configure the System MMU such that it maps some other address range (e.g. 0x1100_0000) to map to address 0x00000000.  By creating this mapping in the MMU you can perform a 674x access to 0x1100_0000 and have the MMU translate that access to 0x00000000 on the L3 interconnect.  Hopefully that makes sense at a high level.

    The actual mechanics of programming this virtual to physical address translation can be found in the Section "MMU Low-Level Programming Models" of the TRM.  For "quick and easy" programming you likely will want to simply use a static TLB programming as the complexity goes up once you enable Table Walking inside the MMU.  The details for programming a static TLB entry are documented in Table 1-49. "MMU Writing TLB Entries Statically".

    Best regards,
    Brad

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

    Please click the Verify Answer button on this post if it answers your question.
    --------------------------------------------------------------------------------------------------------- 

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Jonathan Journo
    Posted by Jonathan Journo
    on Nov 02 2011 02:33 AM
    Intellectual475 points

     

    Thanks Brad for your precious answer.

    I'll try it and report.

    If anyone has a code example of MMU configuration, I'll be happy to have a look on it.

     

     

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • David Jones
    Posted by David Jones
    on Jul 30 2012 13:18 PM
    Prodigy225 points

    Did this work and is there any code example?

    Can this be done in a GEL script (initially) ?

    We have the same issue and it seems like the remapping could be the same for everyone.

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Howard I
    Posted by Howard I
    on Aug 09 2012 05:42 AM
    Prodigy230 points

    I have same problem. I wish somebody  can give me advices how to  access the GPMC bus through the EDMA via the DSP core.

    Thanks in advanced,

     

    David

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • David Jones
    Posted by David Jones
    on Aug 09 2012 07:59 AM
    Verified Answer
    Verified by Brad Griffis
    Prodigy225 points

    Here is what I have learned, our board is now working.

    • When searching for information, there seem to be many names for the same peripheral.  These include MMU, DSP/EDMA MMU, DEMMU, IOMMU, system MMU and probably others.
    • If you map the GPMC, you must map everything.  Once you turn the MMU on, everything is blocked except what is mapped.
    • Linux (including Syslink) does not use the MMU so the DSP is free to control it.
    • The best documentation is the errata sheet, but the table "MMU entries" is not correct.  The code is a good example of setting up the TLB entries.
    • SPRA888 has good information, but not information specific to the dm8148.
    • The technical reference manual has a good description of the "system MMU".
    • The dm8148 data sheet memory map is critical.
    •  The IOMMU Linux debug driver is useful for troubleshooting.

    When the DSP tries to access any unmapped address, the core will hang.  The Linux console will produce an error message starting with "irq 122...".  If you built the IOMMU debug driver, you can install it and print out the registers ("cat regs").   The FAULT_AD register contains the address that caused the fault.  If it is an address you need to access, add it to your mapping.  The registers shown here are the same ones the DSP sees at 0x0801_0000 (when the core is not hung).

    Below is the code that got our board working.  It makes the 0x0100_0000 address appear to the DSP at 0x1100_0000.  It is based on the sequence given in the TRM.  Just call configureMmu() early in main() before starting BIOS

    /*----------------------------------------------------------------------------
    - Purpose: Writes a single TLB entry into the MMU
    -
    - Inputs: entry number
    - virtual address (as seen from DSP)
    - physical address (as seen from ARM)
    -
    - Notes: Assumes a super section 16 MB size (0x0100_0000)
    ----------------------------------------------------------------------------*/

    Void mmuWriteStaticTlb(int entry, unsigned long va, unsigned long pa)
    {
    const int MMU_BASE = 0x08010000;
    volatile int *mmu_lock = ( int *)(MMU_BASE + 0x50);
    volatile int *mmu_ld_tlb = ( int *)(MMU_BASE + 0x54);
    volatile int *mmu_cam = ( int *)(MMU_BASE + 0x58);
    volatile int *mmu_ram = ( int *)(MMU_BASE + 0x5c);

    // configure TLB virtual address , 16 MB super-section, protect, validate
    *mmu_cam = (va & 0xfff00000) | 0x0000000f;

    // load physical address of the page
    *mmu_ram = (pa & 0xfff00000);

    // lock from base value 0
    *mmu_lock = ((entry + 1) << 10) | (entry << 4);

    // load the specified entry in the TLB
    *mmu_ld_tlb = 0x00000001;
    }

    /*----------------------------------------------------------------------------
    - Purpose: Configures the MMU for all access to external memory
    -
    - Notes: Required for access to the GPMC bus
    - See spprugz8 Figure 1-22 MMU Global Initialization & table 1-50
    ----------------------------------------------------------------------------*/

    Void configureMmu()
    {
    const int MMU_BASE = 0x08010000;
    volatile int *mmu_revision = ( int *)(MMU_BASE + 0x00);
    volatile int *mmu_sysconfig = ( int *)(MMU_BASE + 0x10);
    volatile int *mmu_sysstatus = ( int *)(MMU_BASE + 0x14);
    volatile int *mmu_irqenable = ( int *)(MMU_BASE + 0x1c);
    volatile int *mmu_cntl = ( int *)(MMU_BASE + 0x44);
    int entry = 0;

    System_printf("Configuring MMU revision = 0x%08x\n", *mmu_revision); System_flush();

    // execute SW reset
    *mmu_sysconfig = 0x00000002;

    // wait for reset
    while ((*mmu_sysstatus & 0x00000001) != 0);

    // enable power save
    //*mmu_sysconfig = 0x00000001; crashes with this line

    // configure 16 16-MB segments of DDR for straight through
    for (entry = 0; entry < 16; entry++)
    {
    mmuWriteStaticTlb(entry, 0x80000000 | (entry << 24), 0x80000000 | (entry << 24));
    }

    // registers
    mmuWriteStaticTlb(entry, 0x40000000, 0x40000000);
    entry++;

    // GPMC
    mmuWriteStaticTlb(entry, 0x11000000, 0x01000000);
    entry++;

    // DDR control (cache control by syslink)
    mmuWriteStaticTlb(entry, 0x4c000000, 0x4c000000);
    entry++;


    // enable multihit fault and TLB miss
    *mmu_irqenable = 0x00000011;

    // enable memory translations (turn it on)
    *mmu_cntl = 0x00000002;

    // if this prints, at least the DDR mapping is working
    System_printf("MMU configured\n"); System_flush();
    }

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Brad Griffis
    Posted by Brad Griffis
    on Aug 10 2012 13:57 PM
    Guru57350 points

    David,

    Thanks for sharing this info with the community.  I have some follow-up info regarding the points you mentioned.

    David Jones
    When searching for information, there seem to be many names for the same peripheral.  These include MMU, DSP/EDMA MMU, DEMMU, IOMMU, system MMU and probably others.

    David Jones
    The best documentation is the errata sheet, but the table "MMU entries" is not correct.  The code is a good example of setting up the TLB entries.

    In the data manual we will replace all occurrences of "DSP/EDMA MMU" with "System MMU".  In the errata we will replace the term "DEMMU" with "System MMU" to be consistent with the TRM.  I have added a note in the PSP User's Guide and the PSP IOMMU Driver Guide stating that IOMMU is the same as System MMU.

    The MMU entries description in the errata should be as follows:

    • Entry 0: Super-section: GPMC: 0x0000 0000 - 0x00FF FFFF    //16MB
    • Entry 1: Super-section: GPMC: 0x0100 0000 - 0x01FF FFFF    //16MB
    • Entry 2: Small Page:     PAD: 0x0200 0000 - 0x0200 0FFF    //4KB
    • Entry 3: Super-section:  DDR: 0x8000 0000 - 0x80FF FFFF    //16MB
    • Entry 4: Super-section:  DDR: 0x8100 0000 - 0x81FF FFFF    //16MB
    • Entry 5: Super-section:  DDR: 0x8200 0000 - 0x82FF FFFF    //16MB
    • Entry 6: Super-section:  DDR: 0x8300 0000 - 0x83FF FFFF    //16MB
    • Entry 7: Small Page:     PAD: 0x8800 0000 - 0x8800 0FFF    //4KB

    We will update the errata accordingly.

    David Jones
    If you map the GPMC, you must map everything.  Once you turn the MMU on, everything is blocked except what is mapped.

    As a side note I want to make it clear to others that by "everything" that means "every memory block the DSP is supposed to be accessing".  So in typical scenario you would not want to map the entire DDR memory space.  Most of the DDR memory space should be exclusively used by the ARM and so by not mapping these addresses you provide an additional safety net should the DSP accidentally access a place it's not supposed to.  That way instead of crashing the ARM you end up with a System MMU fault which will effectively hang the DSP and provide information with respect to what address was improperly accessed, etc.

    Best regards,
    Brad

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

    Please click the Verify Answer button on this post if it answers your question.
    --------------------------------------------------------------------------------------------------------- 

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Jonathan Journo
    Posted by Jonathan Journo
    on Aug 30 2012 06:07 AM
    Intellectual475 points

    Hello,

    I am trying to configure the System MMU to access the DSP non-mapped memory (GPMC memory) from the DSP core.

    But when accessing the RAM from the DSP apps, the core hangs. (beacaus of a mmu exception)

     

    My DSP system memory setup is :

    MEMORY CONFIGURATION

             name            origin    length      used     unused   attr    fill

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

      SHMEM_DATA   91a00000   03f00000  028f5660  0160a9a0  RW X

      SHMEM_CFG      95900000   00100000  0000bad0  000f4530  RW X

      DDR3_DSP           95a00000   01000000  00380a3a  00c7f5c6  RW X

      SR0                       9f700000   00200000  00200000  00000000  RW X

      SR1                       9f900000   00c00000  00c00000  00000000  RW X

    All that memory is used by the DSP for code / data / syslink

    I modified the System MMU Init code, generously provided by David Jones, so I mapped the Physical memory use by my DSP apps (0x91000000 – to 0xA1000000 .  16* 16 MB).

    It seems the MMU mapping covers all the DDR memory. But when running the DSP application.

    The DSP core hangs, the ARM signals a iommu_fault exception. And reading  the MMU FAULT REGISTER tells us that the fault occurs because a read at address 0x95d3f1000 , that is the first C function called from the main program just after I have called the Init MMU function.

    I'll be pleased to know if I did something wrong in the MMU Initialization.  (for know I removed the GPMC mapping and the GPMC reads from the DSP apps)

    Thanks,

    Here is the modified Init section:

    //            System_printf("Configuring MMU revision = 0x%08x\n", *mmu_revision); System_flush();

                     // execute SW reset

                    *mmu_sysconfig = 0x00000002;

                     // wait for reset

                    while ((*mmu_sysstatus & 0x00000001) != 0);

                     // enable power save

                    //*mmu_sysconfig = 0x00000001; crashes with this line

                     // configure 16 16-MB segments of DDR for straight through

                    for (entry = 0; entry < 16; entry++)

                    {

                                    mmuWriteStaticTlb(entry, 0x91000000 | (entry << 24), 0x91000000 | (entry << 24));

                    }

     

                    // registers

                    mmuWriteStaticTlb(entry, 0x40000000, 0x40000000);

                    entry++;

     

                    // GPMC

    //            mmuWriteStaticTlb(entry, 0x11000000, 0x1f000000);

    //            entry++;

     

                    // DDR control (cache control by syslink)

                    mmuWriteStaticTlb(entry, 0x4c000000, 0x4c000000);

                    entry++;

     

                    // enable multihit fault and TLB miss

                    *mmu_irqenable = 0x00000011;

     

                    // enable memory translations (turn it on)

                    *mmu_cntl = 0x00000002;

     

                    // if this prints, at least the DDR mapping is working

    //            System_printf("MMU configured\n"); System_flush();

    GPMC System MMU
    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Brad Griffis
    Posted by Brad Griffis
    on Aug 30 2012 07:37 AM
    Verified Answer
    Verified by Jonathan Journo
    Guru57350 points

    Hi Jonathan,

    A page that might be helpful related to DSP MMU faults is this one:

    http://processors.wiki.ti.com/index.php/DSP_MMU_Faults

    It was written around Codec Engine and DSPLink, but the underlying details in terms of the root cause of various issues remains the same.

    Jonathan Journo
    The DSP core hangs, the ARM signals a iommu_fault exception. And reading  the MMU FAULT REGISTER tells us that the fault occurs because a read at address 0x95d3f1000 , that is the first C function called from the main program just after I have called the Init MMU function.

    What is the value of the MMU_IRQSTATUS register?  (This is along the lines of how we debug issues in the wiki page I referenced.)  I have a suspicion that you're running into MMU_IRQSTATUS = 0x10 (Multi-Hit Fault).

    Jonathan Journo

                    for (entry = 0; entry < 16; entry++)

                    {

                                    mmuWriteStaticTlb(entry, 0x91000000 | (entry << 24), 0x91000000 | (entry << 24));

                    }

    I think your math is incorrect.  I think you should be doing (0x91000000 | (entry << 24)) + 0x01000000. 

    entry 0x91000000 | (entry << 24)
    0 0x91000000
    1 0x91000000
    2 0x93000000
    3 0x93000000

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

    Please click the Verify Answer button on this post if it answers your question.
    --------------------------------------------------------------------------------------------------------- 

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • David Jones
    Posted by David Jones
    on Aug 30 2012 07:45 AM
    Prodigy225 points

    The iommu driver on the arm that lets you verify the TLB entries and read the registers.  On our distribution it must be built as a module or the build crashes.  An example of calling it is below. 

    // install iommu debug driver
    insmod /lib/modules/2.6.37-ts-armv7l/kernel/arch/arm/plat-omap/iommu-debug.ko
    mount -t debugfs none /sys/kernel/debug/
    cd /sys/kernel/debug/iommu/sys
    cat regs
    cat tlb

    Output:

                REVISION: 00000020
               SYSCONFIG: 00000000
               SYSSTATUS: 00000000
               IRQSTATUS: 00000001
               IRQENABLE: 00000011
              WALKING_ST: 00000000
                    CNTL: 00000002
                FAULT_AD: 50000060
                     TTB: 00000000
                    LOCK: 00005550
                  LD_TLB: 00000000
                     CAM: fff0000c
                     RAM: fff00000
                  GFLUSH: 00000000
             FLUSH_ENTRY: 00000000
                READ_CAM: 00000000
                READ_RAM: 00000000
            EMU_FAULT_AD: 00000000


        cam:     ram:
    -----------------------------------------
    1000000f 00000000 1
    1100000f 01000000 1
    0200000e 12000000 1
    4c00000e 4c000000 1
    8000000f 80000000 1
    8100000f 81000000 1
    8200000f 82000000 1
    8300000f 83000000 1
    8400000f 84000000 1
    8500000f 85000000 1
    8600000f 86000000 1
    8700000f 87000000 1
    8800000f 88000000 1
    8900000f 89000000 1
    8a00000f 8a000000 1
    8b00000f 8b000000 1
    8c00000f 8c000000 1
    8d00000f 8d000000 1
    8e00000f 8e000000 1
    8f00000f 8f000000 1
    fff0000c fff00000 1

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Jonathan Journo
    Posted by Jonathan Journo
    on Aug 30 2012 08:50 AM
    Intellectual475 points

    Thanks Brad.

    you're right, the math was a "bit" fishy. :-)

    the DSP core now uses the MMU for accessing  the RAM and also the GPMC bus.

    Thanks a lot for your support.

    Jonathan

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
TI E2E™ Community
  • Support Forums
  • Blogs
  • Videos
  • Groups
  • Site Support & Feedback
  • Settings
TI E2E™ Community Groups
  • TI University Program
  • Make the Switch
  • Microcontroller Projects
  • Motor Drive & Control
Other Communities
  • Deyisupport
  • Designsomething.org
  • beagleboard.org
  • TI on Element 14
  • TI on TechXchangeSM
Other Technical & Support Resources
  • WEBENCH® Design Center
  • Product Information Centers
  • Technical Documents
  • TI Design Network
  • TI Technical Articles
  • TI Training

All content and materials on this site are provided "as is". TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with regard to these materials, including but not limited to all implied warranties and conditions of merchantability, fitness for a particular purpose, title and non-infringement of any third party intellectual property right. TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with respect to these materials. No license, either express or implied, by estoppel or otherwise, is granted by TI. Use of the information on this site may require a license from a third party, or a license from TI.

Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Terms of Use of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Terms of Use of this site. TI, its suppliers and providers of content reserve the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.

Follow Us Texas Instruments on Facebook Texas Instruments on Twitter Texas Instruments on LinkedIn Texas Instruments on Google+
TI Worldwide | Contact Us | my.TI Login | Site Map | Corporate Citizenship | mobile m.ti.com (Mobile Version)

TI is a global semiconductor design and manufacturing company. Innovate with 100,000+ analog ICs and
embedded processors, along with software, tools and the industry’s largest sales/support staff.

© Copyright 1995-2013 Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy Policy | Terms of Use