diff --git a/arch/arm/src/sama5/Kconfig b/arch/arm/src/sama5/Kconfig index 10bf8b69d9..085d2090ad 100644 --- a/arch/arm/src/sama5/Kconfig +++ b/arch/arm/src/sama5/Kconfig @@ -348,15 +348,15 @@ config SAMA5_OHCI if SAMA5_OHCI config SAMA5_OHCI_NEDS int "Number of endpoint descriptors" - default 2 + default 6 config SAMA5_OHCI_NTDS int "Number of transfer descriptors" - default 3 + default 9 config SAMA5_OHCI_TDBUFFERS int "Number of transfer descriptor buffers" - default 2 + default 6 config SAMA5_OHCI_TDBUFSIZE int "Size of one transfer descriptor buffer" diff --git a/arch/arm/src/sama5/sam_memories.c b/arch/arm/src/sama5/sam_memories.c index 3a723f9960..9167a43239 100644 --- a/arch/arm/src/sama5/sam_memories.c +++ b/arch/arm/src/sama5/sam_memories.c @@ -58,19 +58,19 @@ * Name: peripha_physregaddr * * Description: - * Give the virtual address of a peripheral A register, return the + * Given the virtual address of a peripheral A register, return the * physical address of the register * ****************************************************************************/ -static inline uintptr_t peripha_physregaddr(uintptr_t vregaddr) +static inline uintptr_t peripha_physregaddr(uintptr_t virtregaddr) { #if SAM_PERIPHA_PSECTION != SAM_PERIPHA_VSECTION /* Get the offset into the virtual memory region section containing the * register */ - uintptr_t sectoffset = vregaddr - SAM_PERIPHA_VSECTION; + uintptr_t sectoffset = virtregaddr - SAM_PERIPHA_VSECTION; /* Add that offset to the physical base address of the memory region */ @@ -79,7 +79,7 @@ static inline uintptr_t peripha_physregaddr(uintptr_t vregaddr) #else /* 1-to-1 mapping */ - return vregaddr; + return virtregaddr; #endif } @@ -88,19 +88,19 @@ static inline uintptr_t peripha_physregaddr(uintptr_t vregaddr) * Name: periphb_physregaddr * * Description: - * Give the virtual address of a peripheral B register, return the + * Given the virtual address of a peripheral B register, return the * physical address of the register * ****************************************************************************/ -static inline uintptr_t periphb_physregaddr(uintptr_t vregaddr) +static inline uintptr_t periphb_physregaddr(uintptr_t virtregaddr) { #if SAM_PERIPHB_PSECTION != SAM_PERIPHB_VSECTION /* Get the offset into the virtual memory region section containing the * register */ - uintptr_t sectoffset = vregaddr - SAM_PERIPHB_VSECTION; + uintptr_t sectoffset = virtregaddr - SAM_PERIPHB_VSECTION; /* Add that offset to the physical base address of the memory region */ @@ -109,7 +109,7 @@ static inline uintptr_t periphb_physregaddr(uintptr_t vregaddr) #else /* 1-to-1 mapping */ - return vregaddr; + return virtregaddr; #endif } @@ -118,19 +118,19 @@ static inline uintptr_t periphb_physregaddr(uintptr_t vregaddr) * Name: sysc_physregaddr * * Description: - * Give the virtual address of a system controller register, return the + * Given the virtual address of a system controller register, return the * physical address of the register * ****************************************************************************/ -static inline uintptr_t sysc_physregaddr(uintptr_t vregaddr) +static inline uintptr_t sysc_physregaddr(uintptr_t virtregaddr) { #if SAM_SYSC_PSECTION != SAM_SYSC_VSECTION /* Get the offset into the virtual memory region section containing the * register */ - uintptr_t sectoffset = vregaddr - SAM_SYSC_VSECTION; + uintptr_t sectoffset = virtregaddr - SAM_SYSC_VSECTION; /* Add that offset to the physical base address of the memory region */ @@ -139,7 +139,7 @@ static inline uintptr_t sysc_physregaddr(uintptr_t vregaddr) #else /* 1-to-1 mapping */ - return vregaddr; + return virtregaddr; #endif } @@ -148,19 +148,19 @@ static inline uintptr_t sysc_physregaddr(uintptr_t vregaddr) * Name: isram_physramaddr * * Description: - * Give the virtual address of an internal SRAM memory location, return the + * Given the virtual address of an internal SRAM memory location, return the * physical address of that location * ****************************************************************************/ -static inline uintptr_t isram_physramaddr(uintptr_t vregaddr) +static inline uintptr_t isram_physramaddr(uintptr_t virtramaddr) { #if SAM_ISRAM_PSECTION != SAM_ISRAM_VSECTION /* Get the offset into the virtual memory region section containing the * RAM memory location. */ - uintptr_t sectoffset = vregaddr - SAM_ISRAM_VSECTION; + uintptr_t sectoffset = virtramaddr - SAM_ISRAM_VSECTION; /* Add that offset to the physical base address of the memory region */ @@ -169,7 +169,7 @@ static inline uintptr_t isram_physramaddr(uintptr_t vregaddr) #else /* 1-to-1 mapping */ - return vregaddr; + return virtramaddr; #endif } @@ -178,20 +178,20 @@ static inline uintptr_t isram_physramaddr(uintptr_t vregaddr) * Name: sdram_physramaddr * * Description: - * Give the virtual address of an external SDRAM memory location, return + * Given the virtual address of an external SDRAM memory location, return * the physical address of that location * ****************************************************************************/ #ifdef CONFIG_SAMA5_DDRCS -static inline uintptr_t sdram_physramaddr(uintptr_t vregaddr) +static inline uintptr_t sdram_physramaddr(uintptr_t virtramaddr) { #if SAM_DDRCS_PSECTION != SAM_DDRCS_VSECTION /* Get the offset into the virtual memory region section containing the * RAM memory location. */ - uintptr_t sectoffset = vregaddr - SAM_DDRCS_VSECTION; + uintptr_t sectoffset = virtramaddr - SAM_DDRCS_VSECTION; /* Add that offset to the physical base address of the memory region */ @@ -200,7 +200,7 @@ static inline uintptr_t sdram_physramaddr(uintptr_t vregaddr) #else /* 1-to-1 mapping */ - return vregaddr; + return virtramaddr; #endif } @@ -210,19 +210,19 @@ static inline uintptr_t sdram_physramaddr(uintptr_t vregaddr) * Name: nfcsram_physramaddr * * Description: - * Give the virtual address of an NFC SRAM memory location, return the + * Given the virtual address of an NFC SRAM memory location, return the * physical address of that location * ****************************************************************************/ -static inline uintptr_t nfcsram_physramaddr(uintptr_t vregaddr) +static inline uintptr_t nfcsram_physramaddr(uintptr_t virtramaddr) { #if SAM_NFCSRAM_PSECTION != SAM_NFCSRAM_VSECTION /* Get the offset into the virtual memory region section containing the * RAM memory location. */ - uintptr_t sectoffset = vregaddr - SAM_NFCSRAM_VSECTION; + uintptr_t sectoffset = virtramaddr - SAM_NFCSRAM_VSECTION; /* Add that offset to the physical base address of the memory region */ @@ -231,7 +231,7 @@ static inline uintptr_t nfcsram_physramaddr(uintptr_t vregaddr) #else /* 1-to-1 mapping */ - return vregaddr; + return virtramaddr; #endif } @@ -240,19 +240,19 @@ static inline uintptr_t nfcsram_physramaddr(uintptr_t vregaddr) * Name: udphsram_physramaddr * * Description: - * Give the virtual address of an UDPH SRAM memory location, return the + * Given the virtual address of an UDPH SRAM memory location, return the * physical address of that location * ****************************************************************************/ -static inline uintptr_t udphsram_physramaddr(uintptr_t vregaddr) +static inline uintptr_t udphsram_physramaddr(uintptr_t virtramaddr) { #if SAM_UDPHSRAM_PSECTION != SAM_UDPHSRAM_VSECTION /* Get the offset into the virtual memory region section containing the * RAM memory location. */ - uintptr_t sectoffset = vregaddr - SAM_UDPHSRAM_VSECTION; + uintptr_t sectoffset = virtramaddr - SAM_UDPHSRAM_VSECTION; /* Add that offset to the physical base address of the memory region */ @@ -261,7 +261,7 @@ static inline uintptr_t udphsram_physramaddr(uintptr_t vregaddr) #else /* 1-to-1 mapping */ - return vregaddr; + return virtramaddr; #endif } @@ -270,21 +270,21 @@ static inline uintptr_t udphsram_physramaddr(uintptr_t vregaddr) * Name: ebics0_physramaddr * * Description: - * Give the virtual address of an external CS0 SRAM memory location, + * Given the virtual address of an external CS0 SRAM memory location, * return the physical address of that location * ****************************************************************************/ #if defined(CONFIG_SAMA5_EBICS0) && (defined(CONFIG_SAMA5_EBICS0_SRAM) || \ defined(CONFIG_SAMA5_EBICS0_PSRAM)) -static inline uintptr_t ebics0_physramaddr(uintptr_t vregaddr) +static inline uintptr_t ebics0_physramaddr(uintptr_t virtramaddr) { #if SAM_EBICS0_PSECTION != SAM_EBICS0_VSECTION /* Get the offset into the virtual memory region section containing the * RAM memory location. */ - uintptr_t sectoffset = vregaddr - SAM_EBICS0_VSECTION; + uintptr_t sectoffset = virtramaddr - SAM_EBICS0_VSECTION; /* Add that offset to the physical base address of the memory region */ @@ -293,7 +293,7 @@ static inline uintptr_t ebics0_physramaddr(uintptr_t vregaddr) #else /* 1-to-1 mapping */ - return vregaddr; + return virtramaddr; #endif } @@ -303,21 +303,21 @@ static inline uintptr_t ebics0_physramaddr(uintptr_t vregaddr) * Name: ebics1_physramaddr * * Description: - * Give the virtual address of an external CS1 SRAM memory location, + * Given the virtual address of an external CS1 SRAM memory location, * return the physical address of that location * ****************************************************************************/ #if defined(CONFIG_SAMA5_EBICS1) && (defined(CONFIG_SAMA5_EBICS1_SRAM) || \ defined(CONFIG_SAMA5_EBICS1_PSRAM)) -static inline uintptr_t ebics1_physramaddr(uintptr_t vregaddr) +static inline uintptr_t ebics1_physramaddr(uintptr_t virtramaddr) { #if SAM_EBICS1_PSECTION != SAM_EBICS1_VSECTION /* Get the offset into the virtual memory region section containing the * RAM memory location. */ - uintptr_t sectoffset = vregaddr - SAM_EBICS1_VSECTION; + uintptr_t sectoffset = virtramaddr - SAM_EBICS1_VSECTION; /* Add that offset to the physical base address of the memory region */ @@ -326,7 +326,7 @@ static inline uintptr_t ebics1_physramaddr(uintptr_t vregaddr) #else /* 1-to-1 mapping */ - return vregaddr; + return virtramaddr; #endif } @@ -336,21 +336,21 @@ static inline uintptr_t ebics1_physramaddr(uintptr_t vregaddr) * Name: ebics2_physramaddr * * Description: - * Give the virtual address of an external CS2 SRAM memory location, + * Given the virtual address of an external CS2 SRAM memory location, * return the physical address of that location * ****************************************************************************/ #if defined(CONFIG_SAMA5_EBICS2) && (defined(CONFIG_SAMA5_EBICS2_SRAM) || \ defined(CONFIG_SAMA5_EBICS2_PSRAM)) -static inline uintptr_t ebics2_physramaddr(uintptr_t vregaddr) +static inline uintptr_t ebics2_physramaddr(uintptr_t virtramaddr) { #if SAM_EBICS2_PSECTION != SAM_EBICS2_VSECTION /* Get the offset into the virtual memory region section containing the * RAM memory location. */ - uintptr_t sectoffset = vregaddr - SAM_EBICS2_VSECTION; + uintptr_t sectoffset = virtramaddr - SAM_EBICS2_VSECTION; /* Add that offset to the physical base address of the memory region */ @@ -359,7 +359,7 @@ static inline uintptr_t ebics2_physramaddr(uintptr_t vregaddr) #else /* 1-to-1 mapping */ - return vregaddr; + return virtramaddr; #endif } @@ -369,21 +369,21 @@ static inline uintptr_t ebics2_physramaddr(uintptr_t vregaddr) * Name: ebics3_physramaddr * * Description: - * Give the virtual address of an external CS3 SRAM memory location, + * Given the virtual address of an external CS3 SRAM memory location, * return the physical address of that location * ****************************************************************************/ #if defined(CONFIG_SAMA5_EBICS3) && (defined(CONFIG_SAMA5_EBICS3_SRAM) || \ defined(CONFIG_SAMA5_EBICS3_PSRAM)) -static inline uintptr_t ebics3_physramaddr(uintptr_t vregaddr) +static inline uintptr_t ebics3_physramaddr(uintptr_t virtramaddr) { #if SAM_EBICS3_PSECTION != SAM_EBICS3_VSECTION /* Get the offset into the virtual memory region section containing the * RAM memory location. */ - uintptr_t sectoffset = vregaddr - SAM_EBICS3_VSECTION; + uintptr_t sectoffset = virtramaddr - SAM_EBICS3_VSECTION; /* Add that offset to the physical base address of the memory region */ @@ -392,7 +392,261 @@ static inline uintptr_t ebics3_physramaddr(uintptr_t vregaddr) #else /* 1-to-1 mapping */ - return vregaddr; + return virtramaddr; + +#endif +} +#endif + +/**************************************************************************** + * Name: isram_virtramaddr + * + * Description: + * Given the physical address of an internal SRAM memory location, return + * the virtual address of that location + * + ****************************************************************************/ + +static inline uintptr_t isram_virtramaddr(uintptr_t physramaddr) +{ +#if SAM_ISRAM_PSECTION != SAM_ISRAM_VSECTION + /* Get the offset into the virtual memory region section containing the + * RAM memory location. + */ + + uintptr_t sectoffset = physramaddr - SAM_ISRAM_PSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_ISRAM_VSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return physramaddr; + +#endif +} + +/**************************************************************************** + * Name: sdram_virtramaddr + * + * Description: + * Given the physical address of an external SDRAM memory location, return + * the virtual address of that location + * + ****************************************************************************/ + +#ifdef CONFIG_SAMA5_DDRCS +static inline uintptr_t sdram_virtramaddr(uintptr_t physramaddr) +{ +#if SAM_DDRCS_PSECTION != SAM_DDRCS_VSECTION + /* Get the offset into the virtual memory region section containing the + * RAM memory location. + */ + + uintptr_t sectoffset = physramaddr - SAM_DDRCS_PSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_DDRCS_VSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return physramaddr; + +#endif +} +#endif + +/**************************************************************************** + * Name: nfcsram_virtramaddr + * + * Description: + * Given the physical address of an NFC SRAM memory location, return the + * virtual address of that location + * + ****************************************************************************/ + +static inline uintptr_t nfcsram_virtramaddr(uintptr_t physramaddr) +{ +#if SAM_NFCSRAM_PSECTION != SAM_NFCSRAM_VSECTION + /* Get the offset into the virtual memory region section containing the + * RAM memory location. + */ + + uintptr_t sectoffset = physramaddr - SAM_NFCSRAM_PSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_NFCSRAM_VSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return physramaddr; + +#endif +} + +/**************************************************************************** + * Name: udphsram_virtramaddr + * + * Description: + * Given the physical address of an UDPH SRAM memory location, return the + * virtual address of that location + * + ****************************************************************************/ + +static inline uintptr_t udphsram_virtramaddr(uintptr_t physramaddr) +{ +#if SAM_UDPHSRAM_PSECTION != SAM_UDPHSRAM_VSECTION + /* Get the offset into the virtual memory region section containing the + * RAM memory location. + */ + + uintptr_t sectoffset = physramaddr - SAM_UDPHSRAM_PSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_UDPHSRAM_VSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return physramaddr; + +#endif +} + +/**************************************************************************** + * Name: ebics0_virtramaddr + * + * Description: + * Given the physical address of an external CS0 SRAM memory location, + * return the virtual address of that location + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_EBICS0) && (defined(CONFIG_SAMA5_EBICS0_SRAM) || \ + defined(CONFIG_SAMA5_EBICS0_PSRAM)) +static inline uintptr_t ebics0_virtramaddr(uintptr_t physramaddr) +{ +#if SAM_EBICS0_PSECTION != SAM_EBICS0_VSECTION + /* Get the offset into the virtual memory region section containing the + * RAM memory location. + */ + + uintptr_t sectoffset = physramaddr - SAM_EBICS0_PSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_EBICS0_VSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return physramaddr; + +#endif +} +#endif + +/**************************************************************************** + * Name: ebics1_virtramaddr + * + * Description: + * Given the physical address of an external CS1 SRAM memory location, + * return the virtual address of that location + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_EBICS1) && (defined(CONFIG_SAMA5_EBICS1_SRAM) || \ + defined(CONFIG_SAMA5_EBICS1_PSRAM)) +static inline uintptr_t ebics1_virtramaddr(uintptr_t physramaddr) +{ +#if SAM_EBICS1_PSECTION != SAM_EBICS1_VSECTION + /* Get the offset into the virtual memory region section containing the + * RAM memory location. + */ + + uintptr_t sectoffset = physramaddr - SAM_EBICS1_PSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_EBICS1_VSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return physramaddr; + +#endif +} +#endif + +/**************************************************************************** + * Name: ebics2_virtramaddr + * + * Description: + * Given the physical address of an external CS2 SRAM memory location, + * return the virtual address of that location + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_EBICS2) && (defined(CONFIG_SAMA5_EBICS2_SRAM) || \ + defined(CONFIG_SAMA5_EBICS2_PSRAM)) +static inline uintptr_t ebics2_virtramaddr(uintptr_t physramaddr) +{ +#if SAM_EBICS2_PSECTION != SAM_EBICS2_VSECTION + /* Get the offset into the virtual memory region section containing the + * RAM memory location. + */ + + uintptr_t sectoffset = physramaddr - SAM_EBICS2_PSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_EBICS2_VSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return physramaddr; + +#endif +} +#endif + +/**************************************************************************** + * Name: ebics3_virtramaddr + * + * Description: + * Given the physical address of an external CS3 SRAM memory location, + * return the virtual address of that location + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_EBICS3) && (defined(CONFIG_SAMA5_EBICS3_SRAM) || \ + defined(CONFIG_SAMA5_EBICS3_PSRAM)) +static inline uintptr_t ebics3_virtramaddr(uintptr_t physramaddr) +{ +#if SAM_EBICS3_PSECTION != SAM_EBICS3_VSECTION + /* Get the offset into the virtual memory region section containing the + * RAM memory location. + */ + + uintptr_t sectoffset = physramaddr - SAM_EBICS3_PSECTION; + + /* Add that offset to the physical base address of the memory region */ + + return SAM_EBICS3_VSECTION + sectoffset; + +#else + /* 1-to-1 mapping */ + + return physramaddr; #endif } @@ -406,35 +660,35 @@ static inline uintptr_t ebics3_physramaddr(uintptr_t vregaddr) * Name: sam_physregaddr * * Description: - * Give the virtual address of a register, return the physical address of + * Given the virtual address of a register, return the physical address of * the register * ****************************************************************************/ -uintptr_t sam_physregaddr(uintptr_t vregaddr) +uintptr_t sam_physregaddr(uintptr_t virtregaddr) { /* Check for a peripheral A register */ - if (vregaddr >= SAM_PERIPHA_VSECTION && - vregaddr < (SAM_PERIPHA_VSECTION + SAM_PERIPHA_SIZE)) + if (virtregaddr >= SAM_PERIPHA_VSECTION && + virtregaddr < (SAM_PERIPHA_VSECTION + SAM_PERIPHA_SIZE)) { - return peripha_physregaddr(vregaddr); + return peripha_physregaddr(virtregaddr); } /* Check for a peripheral A register */ - else if (vregaddr >= SAM_PERIPHB_VSECTION && - vregaddr < (SAM_PERIPHB_VSECTION + SAM_PERIPHB_SIZE)) + else if (virtregaddr >= SAM_PERIPHB_VSECTION && + virtregaddr < (SAM_PERIPHB_VSECTION + SAM_PERIPHB_SIZE)) { - return periphb_physregaddr(vregaddr); + return periphb_physregaddr(virtregaddr); } /* Check for a system controller register */ - else if (vregaddr >= SAM_SYSC_VSECTION && - vregaddr < (SAM_SYSC_VSECTION + SAM_SYSC_SIZE)) + else if (virtregaddr >= SAM_SYSC_VSECTION && + virtregaddr < (SAM_SYSC_VSECTION + SAM_SYSC_SIZE)) { - return sysc_physregaddr(vregaddr); + return sysc_physregaddr(virtregaddr); } /* We will not get here unless we are called with an invalid register @@ -442,64 +696,64 @@ uintptr_t sam_physregaddr(uintptr_t vregaddr) */ DEBUGPANIC(); - return vregaddr; + return virtregaddr; } /**************************************************************************** * Name: sam_physramaddr * * Description: - * Give the virtual address of a RAM memory location, return the physical + * Given the virtual address of a RAM memory location, return the physical * address of that location. * ****************************************************************************/ -uintptr_t sam_physramaddr(uintptr_t vregaddr) +uintptr_t sam_physramaddr(uintptr_t virtramaddr) { /* Check for internal SRAM. We we assume that ISRAM0 and ISRAM1 are * contiguous. */ - if (vregaddr >= SAM_ISRAM_VSECTION && - vregaddr < (SAM_ISRAM_VSECTION + SAM_ISRAM_SIZE)) + if (virtramaddr >= SAM_ISRAM_VSECTION && + virtramaddr < (SAM_ISRAM_VSECTION + SAM_ISRAM_SIZE)) { - return isram_physramaddr(vregaddr); + return isram_physramaddr(virtramaddr); } #ifdef CONFIG_SAMA5_DDRCS /* Check for external SDRAM */ - else if (vregaddr >= SAM_DDRCS_VSECTION && - vregaddr < (SAM_DDRCS_VSECTION + SAMA5_DDRCS_SIZE)) + else if (virtramaddr >= SAM_DDRCS_VSECTION && + virtramaddr < (SAM_DDRCS_VSECTION + SAMA5_DDRCS_SIZE)) { - return sdram_physramaddr(vregaddr); + return sdram_physramaddr(virtramaddr); } #endif /* Check for NFCS SRAM. */ - if (vregaddr >= SAM_NFCSRAM_VSECTION && - vregaddr < (SAM_NFCSRAM_VSECTION + SAM_NFCSRAM_SIZE)) + if (virtramaddr >= SAM_NFCSRAM_VSECTION && + virtramaddr < (SAM_NFCSRAM_VSECTION + SAM_NFCSRAM_SIZE)) { - return nfcsram_physramaddr(vregaddr); + return nfcsram_physramaddr(virtramaddr); } /* Check for UDPH SRAM. */ - if (vregaddr >= SAM_UDPHSRAM_VSECTION && - vregaddr < (SAM_UDPHSRAM_VSECTION + SAM_UDPHSRAM_SIZE)) + if (virtramaddr >= SAM_UDPHSRAM_VSECTION && + virtramaddr < (SAM_UDPHSRAM_VSECTION + SAM_UDPHSRAM_SIZE)) { - return udphsram_physramaddr(vregaddr); + return udphsram_physramaddr(virtramaddr); } #if defined(CONFIG_SAMA5_EBICS0) && (defined(CONFIG_SAMA5_EBICS0_SRAM) || \ defined(CONFIG_SAMA5_EBICS0_PSRAM)) /* Check for external SRAM or PSRAM on CS0 */ - else if (vregaddr >= SAM_EBICS0_VSECTION && - vregaddr < (SAM_EBICS0_VSECTION + SAMA5_EBICS0_SIZE)) + else if (virtramaddr >= SAM_EBICS0_VSECTION && + virtramaddr < (SAM_EBICS0_VSECTION + SAMA5_EBICS0_SIZE)) { - return ebics0_physramaddr(vregaddr); + return ebics0_physramaddr(virtramaddr); } #endif @@ -507,10 +761,10 @@ uintptr_t sam_physramaddr(uintptr_t vregaddr) defined(CONFIG_SAMA5_EBICS1_PSRAM)) /* Check for external SRAM or PSRAM on CS1 */ - else if (vregaddr >= SAM_EBICS1_VSECTION && - vregaddr < (SAM_EBICS1_VSECTION + SAMA5_EBICS1_SIZE)) + else if (virtramaddr >= SAM_EBICS1_VSECTION && + virtramaddr < (SAM_EBICS1_VSECTION + SAMA5_EBICS1_SIZE)) { - return ebics1_physramaddr(vregaddr); + return ebics1_physramaddr(virtramaddr); } #endif @@ -518,10 +772,10 @@ uintptr_t sam_physramaddr(uintptr_t vregaddr) defined(CONFIG_SAMA5_EBICS2_PSRAM)) /* Check for external SRAM or PSRAM on CS2 */ - else if (vregaddr >= SAM_EBICS2_VSECTION && - vregaddr < (SAM_EBICS2_VSECTION + SAMA5_EBICS2_SIZE)) + else if (virtramaddr >= SAM_EBICS2_VSECTION && + virtramaddr < (SAM_EBICS2_VSECTION + SAMA5_EBICS2_SIZE)) { - return ebics2_physramaddr(vregaddr); + return ebics2_physramaddr(virtramaddr); } #endif @@ -529,10 +783,10 @@ uintptr_t sam_physramaddr(uintptr_t vregaddr) defined(CONFIG_SAMA5_EBICS3_PSRAM)) /* Check for external SRAM or PSRAM on CS3 */ - else if (vregaddr >= SAM_EBICS3_VSECTION && - vregaddr < (SAM_EBICS3_VSECTION + SAMA5_EBICS3_SIZE)) + else if (virtramaddr >= SAM_EBICS3_VSECTION && + virtramaddr < (SAM_EBICS3_VSECTION + SAMA5_EBICS3_SIZE)) { - return ebics3_physramaddr(vregaddr); + return ebics3_physramaddr(virtramaddr); } #endif @@ -541,5 +795,104 @@ uintptr_t sam_physramaddr(uintptr_t vregaddr) */ DEBUGPANIC(); - return vregaddr; + return virtramaddr; +} + +/**************************************************************************** + * Name: sam_virtramaddr + * + * Description: + * Give the phsical address of a RAM memory location, return the virtual + * address of that location. + * + ****************************************************************************/ + +uintptr_t sam_virtramaddr(uintptr_t physramaddr) +{ + /* Check for internal SRAM. We we assume that ISRAM0 and ISRAM1 are + * contiguous. + */ + + if (physramaddr >= SAM_ISRAM_PSECTION && + physramaddr < (SAM_ISRAM_PSECTION + SAM_ISRAM_SIZE)) + { + return isram_virtramaddr(physramaddr); + } + +#ifdef CONFIG_SAMA5_DDRCS + /* Check for external SDRAM */ + + else if (physramaddr >= SAM_DDRCS_PSECTION && + physramaddr < (SAM_DDRCS_PSECTION + SAMA5_DDRCS_SIZE)) + { + return sdram_virtramaddr(physramaddr); + } +#endif + + /* Check for NFCS SRAM. */ + + if (physramaddr >= SAM_NFCSRAM_PSECTION && + physramaddr < (SAM_NFCSRAM_PSECTION + SAM_NFCSRAM_SIZE)) + { + return nfcsram_virtramaddr(physramaddr); + } + + /* Check for UDPH SRAM. */ + + if (physramaddr >= SAM_UDPHSRAM_PSECTION && + physramaddr < (SAM_UDPHSRAM_PSECTION + SAM_UDPHSRAM_SIZE)) + { + return udphsram_virtramaddr(physramaddr); + } + +#if defined(CONFIG_SAMA5_EBICS0) && (defined(CONFIG_SAMA5_EBICS0_SRAM) || \ + defined(CONFIG_SAMA5_EBICS0_PSRAM)) + /* Check for external SRAM or PSRAM on CS0 */ + + else if (physramaddr >= SAM_EBICS0_PSECTION && + physramaddr < (SAM_EBICS0_PSECTION + SAMA5_EBICS0_SIZE)) + { + return ebics0_virtramaddr(physramaddr); + } +#endif + +#if defined(CONFIG_SAMA5_EBICS1) && (defined(CONFIG_SAMA5_EBICS1_SRAM) || \ + defined(CONFIG_SAMA5_EBICS1_PSRAM)) + /* Check for external SRAM or PSRAM on CS1 */ + + else if (physramaddr >= SAM_EBICS1_PSECTION && + physramaddr < (SAM_EBICS1_PSECTION + SAMA5_EBICS1_SIZE)) + { + return ebics1_virtramaddr(physramaddr); + } +#endif + +#if defined(CONFIG_SAMA5_EBICS2) && (defined(CONFIG_SAMA5_EBICS2_SRAM) || \ + defined(CONFIG_SAMA5_EBICS2_PSRAM)) + /* Check for external SRAM or PSRAM on CS2 */ + + else if (physramaddr >= SAM_EBICS2_PSECTION && + physramaddr < (SAM_EBICS2_PSECTION + SAMA5_EBICS2_SIZE)) + { + return ebics2_virtramaddr(physramaddr); + } +#endif + +#if defined(CONFIG_SAMA5_EBICS3) && (defined(CONFIG_SAMA5_EBICS3_SRAM) || \ + defined(CONFIG_SAMA5_EBICS3_PSRAM)) + /* Check for external SRAM or PSRAM on CS3 */ + + else if (physramaddr >= SAM_EBICS3_PSECTION && + physramaddr < (SAM_EBICS3_PSECTION + SAMA5_EBICS3_SIZE)) + { + return ebics3_virtramaddr(physramaddr); + } +#endif + + /* We will not get here unless we are called with an invalid or + * unsupported RAM address + */ + + DEBUGPANIC(); + return physramaddr; } diff --git a/arch/arm/src/sama5/sam_memories.h b/arch/arm/src/sama5/sam_memories.h index e360759d2e..308b06c138 100644 --- a/arch/arm/src/sama5/sam_memories.h +++ b/arch/arm/src/sama5/sam_memories.h @@ -82,7 +82,7 @@ extern "C" * ****************************************************************************/ -uintptr_t sam_physregaddr(uintptr_t vregaddr); +uintptr_t sam_physregaddr(uintptr_t virtregaddr); /**************************************************************************** * Name: sam_physramaddr @@ -93,7 +93,18 @@ uintptr_t sam_physregaddr(uintptr_t vregaddr); * ****************************************************************************/ -uintptr_t sam_physramaddr(uintptr_t vregaddr); +uintptr_t sam_physramaddr(uintptr_t vramaddr); + +/**************************************************************************** + * Name: sam_virtramaddr + * + * Description: + * Give the phsical address of a RAM memory location, return the virtual + * address of that location. + * + ****************************************************************************/ + +uintptr_t sam_virtramaddr(uintptr_t physramaddr); #undef EXTERN #if defined(__cplusplus) diff --git a/arch/arm/src/sama5/sam_ohci.c b/arch/arm/src/sama5/sam_ohci.c index 0a59faf867..b7bb025e0f 100644 --- a/arch/arm/src/sama5/sam_ohci.c +++ b/arch/arm/src/sama5/sam_ohci.c @@ -61,8 +61,10 @@ #include "up_arch.h" #include "up_internal.h" +#include "cache.h" #include "chip.h" #include "sam_periphclks.h" +#include "sam_memories.h" #include "sam_usbhost.h" #include "chip/sam_pmc.h" #include "chip/sam_sfr.h" @@ -73,14 +75,6 @@ *******************************************************************************/ /* Configuration ***************************************************************/ -/* Fixed endpoint descriptor size. The actual size required by the hardware is only - * 16 bytes, however, we set aside an additional 16 bytes for for internal use by - * the OHCI host driver. 16-bytes is set aside because the EDs must still be - * aligned to 16-byte boundaries. - */ - -#define SAM_ED_SIZE 32 - /* Configurable number of user endpoint descriptors (EDs). This number excludes * the control endpoint that is always allocated. */ @@ -89,14 +83,6 @@ # define CONFIG_SAMA5_OHCI_NEDS 2 #endif -/* Fixed transfer descriptor size. The actual size required by the hardware is - * only 16 bytes, however, we set aside an additional 16 bytes for for internal - * use by the OHCI host driver. 16-bytes is set aside because the TDs must still - * be aligned to 16-byte boundaries. - */ - -#define SAM_TD_SIZE 32 - /* Configurable number of user transfer descriptors (TDs). */ #ifndef CONFIG_SAMA5_OHCI_NTDS @@ -198,7 +184,7 @@ struct sam_rhport_s struct usbhost_class_s *class; }; -/* This structure retains the state of the USB host controller */ +/* This structure retains the overall state of the USB host controller */ struct sam_ohci_s { @@ -219,27 +205,34 @@ struct sam_ohci_s }; /* The OCHI expects the size of an endpoint descriptor to be 16 bytes. - * However, the size allocated for an endpoint descriptor is 32 bytes in - * sam_ohciram.h. This extra 16-bytes is used by the OHCI host driver in - * order to maintain additional endpoint-specific data. + * However, the size allocated for an endpoint descriptor is 32 bytes. This + * extra 16-bytes is used by the OHCI host driver in order to maintain + * additional endpoint-specific data. */ +#define SAMD_ED_PADSIZE (12 - sizeof(sem_t)) + struct sam_ed_s { /* Hardware specific fields */ - struct ohci_ed_s hw; + struct ohci_ed_s hw; /* 0-15 */ /* Software specific fields */ - uint8_t xfrtype; /* Transfer type. See SB_EP_ATTR_XFER_* in usb.h */ - uint8_t interval; /* Periodic EP polling interval: 2, 4, 6, 16, or 32 */ - volatile uint8_t tdstatus; /* TD control status bits from last Writeback Done Head event */ - volatile bool wdhwait; /* TRUE: Thread is waiting for WDH interrupt */ - sem_t wdhsem; /* Semaphore used to wait for Writeback Done Head event */ - /* Unused bytes follow, depending on the size of sem_t */ + uint8_t xfrtype; /* 16: Transfer type. See SB_EP_ATTR_XFER_* in usb.h */ + uint8_t interval; /* 17: Periodic EP polling interval: 2, 4, 6, 16, or 32 */ + volatile uint8_t tdstatus; /* 18: TD control status bits from last Writeback Done Head event */ + volatile bool wdhwait; /* 19: TRUE: Thread is waiting for WDH interrupt */ + sem_t wdhsem; /* 20-23: Semaphore used to wait for Writeback Done Head event */ + + /* Padding to 32-bytes follow. The amount of padding depends on the size of sem_t */ + + uint8_t pad[SAMD_ED_PADSIZE]; }; +#define SIZEOF_SAM_ED_S 32 + /* The OCHI expects the size of an transfer descriptor to be 16 bytes. * However, the size allocated for an endpoint descriptor is 32 bytes in * RAM. This extra 16-bytes is used by the OHCI host driver in order to @@ -250,15 +243,17 @@ struct sam_gtd_s { /* Hardware specific fields */ - struct ohci_gtd_s hw; + struct ohci_gtd_s hw; /* 0-15 */ /* Software specific fields */ - struct sam_ed_s *ed; /* Pointer to parent ED */ - bool prealloc; /* Indicates a pre-allocated ED */ - uint8_t pad[11]; + struct sam_ed_s *ed; /* 16-19: Pointer to parent ED */ + bool prealloc; /* 20: Indicates a pre-allocated ED */ + uint8_t pad[11]; /* 21-31: Pad to 32 bytes */ }; +#define SIZEOF_SAM_TD_S 32 + /* The following is used to manage lists of free EDs, TDs, and TD buffers */ struct sam_list_s @@ -730,11 +725,14 @@ static inline int sam_addbulked(struct sam_ed_s *ed) { #ifndef CONFIG_USBHOST_BULK_DISABLE uint32_t regval; + uintptr_t physed; /* Add the new bulk ED to the head of the bulk list */ ed->hw.nexted = sam_getreg(SAM_USBHOST_BULKHEADED); - sam_putreg((uint32_t)ed, SAM_USBHOST_BULKHEADED); + + physed = sam_physramaddr((uintptr_t)ed); + sam_putreg((uint32_t)physed, SAM_USBHOST_BULKHEADED); /* BulkListEnable. This bit is set to enable the processing of the * Bulk list. Note: once enabled, it remains. We really should @@ -763,14 +761,15 @@ static inline int sam_rembulked(struct sam_ed_s *ed) #ifndef CONFIG_USBHOST_BULK_DISABLE struct sam_ed_s *curr; struct sam_ed_s *prev; - uint32_t regval; + uintptr_t physed; + uint32_t regval; /* Find the ED in the bulk list. NOTE: We really should never be mucking * with the bulk list while BLE is set. */ - for (curr = (struct sam_ed_s *)sam_getreg(SAM_USBHOST_BULKHEADED), - prev = NULL; + physed = sam_getreg(SAM_USBHOST_BULKHEADED); + for (curr = (struct sam_ed_s *)sam_virtramaddr(physed), prev = NULL; curr && curr != ed; prev = curr, curr = (struct sam_ed_s *)curr->hw.nexted); @@ -897,7 +896,8 @@ static inline int sam_addinted(const FAR struct usbhost_epdesc_s *epdesc, #ifndef CONFIG_USBHOST_INT_DISABLE unsigned int interval; unsigned int offset; - uint32_t head; + uintptr_t physed; + uintptr_t physhead; uint32_t regval; /* Disable periodic list processing. Does this take effect immediately? Or @@ -949,11 +949,12 @@ static inline int sam_addinted(const FAR struct usbhost_epdesc_s *epdesc, } uvdbg("min interval: %d offset: %d\n", interval, offset); - /* Get the head of the first of the duplicated entries. The first offset - * entry is always guaranteed to contain the common ED list head. + /* Get the (physical) head of the first of the duplicated entries. The + * first offset entry is always guaranteed to contain the common ED list + * head. */ - head = g_hcca.inttbl[offset]; + physhead = g_hcca.inttbl[offset]; /* Clear all current entries in the interrupt table for this direction */ @@ -964,9 +965,10 @@ static inline int sam_addinted(const FAR struct usbhost_epdesc_s *epdesc, * interrupt table. */ - ed->hw.nexted = head; - sam_setinttab((uint32_t)ed, interval, offset); - uvdbg("head: %08x next: %08x\n", ed, head); + ed->hw.nexted = physhead; + physed = sam_virtramaddr((uintptr_t)ed); + sam_setinttab((uint32_t)physed, interval, offset); + uvdbg("head: %08x next: %08x\n", physed, physhead); /* Re-enabled periodic list processing */ @@ -1005,9 +1007,10 @@ static inline int sam_reminted(struct sam_ed_s *ed) struct sam_ed_s *head; struct sam_ed_s *curr; struct sam_ed_s *prev; - unsigned int interval; - unsigned int offset; - uint32_t regval; + uintptr_t physhead; + unsigned int interval; + unsigned int offset; + uint32_t regval; /* Disable periodic list processing. Does this take effect immediately? Or * at the next SOF... need to check. @@ -1034,9 +1037,11 @@ static inline int sam_reminted(struct sam_ed_s *ed) * entry is always guaranteed to contain the common ED list head. */ - head = (struct sam_ed_s *)g_hcca.inttbl[offset]; + physhead = g_hcca.inttbl[offset]; + head = (struct sam_ed_s *)sam_virtramaddr((uintptr_t)physhead); + uvdbg("ed: %08x head: %08x next: %08x offset: %d\n", - ed, head, head ? head->hw.nexted : 0, offset); + ed, physhead, head ? head->hw.nexted : 0, offset); /* Find the ED to be removed in the ED list */ @@ -1059,7 +1064,8 @@ static inline int sam_reminted(struct sam_ed_s *ed) { /* Yes... set the head of the bulk list to skip over this ED */ - head = (struct sam_ed_s *)ed->hw.nexted; + physhead = ed->hw.nexted; + head = (struct sam_ed_s *)sam_virtramaddr((uintptr_t)physhead); } else { @@ -1069,8 +1075,9 @@ static inline int sam_reminted(struct sam_ed_s *ed) prev->hw.nexted = ed->hw.nexted; } - uvdbg("ed: %08x head: %08x next: %08x\n", - ed, head, head ? head->hw.nexted : 0); + + uvdbg("ed: %08x head: %08x next: %08x\n", + ed, physhead, head ? head->hw.nexted : 0); /* Calculate the new minimum interval for this list */ @@ -1082,6 +1089,7 @@ static inline int sam_reminted(struct sam_ed_s *ed) interval = curr->interval; } } + uvdbg("min interval: %d offset: %d\n", interval, offset); /* Save the new minimum interval */ @@ -1099,7 +1107,7 @@ static inline int sam_reminted(struct sam_ed_s *ed) * table (head might be NULL). */ - sam_setinttab((uint32_t)head, interval, offset); + sam_setinttab((uint32_t)physhead, interval, offset); } /* Re-enabled periodic list processing */ @@ -1166,6 +1174,9 @@ static int sam_enqueuetd(struct sam_rhport_s *rhport, struct sam_ed_s *ed, { struct sam_gtd_s *td; struct sam_gtd_s *tdtail; + uintptr_t phytd; + uintptr_t phytail; + uintptr_t phybuf; int ret = -ENOMEM; /* Allocate a TD from the free list */ @@ -1173,29 +1184,52 @@ static int sam_enqueuetd(struct sam_rhport_s *rhport, struct sam_ed_s *ed, td = sam_tdalloc(); if (td != NULL) { + /* Skip processing of this ED */ + + ed->hw.ctrl |= ED_CONTROL_K; + + /* Select the common tail ED for this root hub port */ + tdtail = &g_tdtail[rhport->rhpndx]; + /* Get physical addresses to support the DMA */ + + phytd = sam_physramaddr((uintptr_t)td); + phytail = sam_physramaddr((uintptr_t)tdtail); + phybuf = sam_physramaddr((uintptr_t)buffer); + /* Initialize the allocated TD and link it before the common tail TD. */ - td->hw.ctrl = (GTD_STATUS_R | dirpid | TD_DELAY(0) | toggle | GTD_STATUS_CC_MASK); + td->hw.ctrl = (GTD_STATUS_R | dirpid | TD_DELAY(0) | + toggle | GTD_STATUS_CC_MASK); tdtail->hw.ctrl = 0; - td->hw.cbp = (uint32_t)buffer; + td->hw.cbp = (uint32_t)phybuf; tdtail->hw.cbp = 0; - td->hw.nexttd = (uint32_t)tdtail; + td->hw.nexttd = (uint32_t)phytail; tdtail->hw.nexttd = 0; - td->hw.be = (uint32_t)(buffer + (buflen - 1)); + td->hw.be = (uint32_t)(phybuf + (buflen - 1)); tdtail->hw.be = 0; /* Configure driver-only fields in the extended TD structure */ - td->ed = ed; + td->ed = ed; /* Link the td to the head of the ED's TD list */ - ed->hw.headp = (uint32_t)td | ((ed->hw.headp) & ED_HEADP_C); - ed->hw.tailp = (uint32_t)tdtail; + ed->hw.headp = (uint32_t)phytd | ((ed->hw.headp) & ED_HEADP_C); + ed->hw.tailp = (uint32_t)phytail; - ret = OK; + /* Flush the buffer, the new TD, and the modified ED to RAM */ + + cp15_coherent_dcache((uintptr_t)buffer, buflen); + cp15_coherent_dcache((uintptr_t)tdtail, sizeof(struct sam_gtd_s)); + cp15_coherent_dcache((uintptr_t)td, sizeof(struct sam_gtd_s)); + + /* Resume processing of this ED */ + + ed->hw.ctrl &= ~ED_CONTROL_K; + cp15_coherent_dcache((uintptr_t)ed, sizeof(struct sam_ed_s)); + ret = OK; } return ret; @@ -1296,6 +1330,13 @@ static int sam_ctrltd(struct sam_rhport_s *rhport, uint32_t dirpid, sam_takesem(&edctrl->wdhsem); + /* Invalidate the D cache to force the control ED to be reloaded from + * RAM. + */ + + cp15_invalidate_dcache((uintptr_t)edctrl, + (uintptr_t)edctrl + sizeof(struct sam_ed_s)); + /* Check the TD completion status bits */ if (edctrl->tdstatus == TD_CC_NOERROR) @@ -1470,7 +1511,7 @@ static void sam_wdh_interrupt(void) * cleared in the interrupt status register. */ - td = (struct sam_gtd_s *)g_hcca.donehead; + td = (struct sam_gtd_s *)sam_virtramaddr(g_hcca.donehead); g_hcca.donehead = 0; /* Process each TD in the write done list */ @@ -1795,6 +1836,10 @@ static int sam_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr, /* Set the transfer type to control */ edctrl->xfrtype = USB_EP_ATTR_XFER_CONTROL; + + /* Flush the modified control ED to RAM */ + + cp15_coherent_dcache((uintptr_t)edctrl, sizeof(struct sam_ed_s)); sam_givesem(&g_ohci.exclsem); uvdbg("RHPort%d EP0 CTRL: %08x\n", rhport->rhpndx + 1, edctrl->hw.ctrl); @@ -2195,7 +2240,8 @@ static int sam_iofree(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer) * created by DRVR_ALLOC. * buffer - A buffer used for sending the request and for returning any * responses. This buffer must be large enough to hold the length value - * in the request description. buffer must have been allocated using DRVR_ALLOC + * in the request description. buffer must have been allocated using + * DRVR_ALLOC * * NOTE: On an IN transaction, req and buffer may refer to the same allocated * memory. @@ -2243,7 +2289,13 @@ static int sam_ctrlin(FAR struct usbhost_driver_s *drvr, } } + /* On an IN transaction, we need to invalidate the buffer contents to force + * it to be reloaded from RAM after the DMA. + */ + sam_givesem(&g_ohci.exclsem); + cp15_invalidate_dcache((uintptr_t)buffer, (uintptr_t)buffer + len); + return ret; } @@ -2337,6 +2389,7 @@ static int sam_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, DEBUGASSERT(rhport && ed && buffer && buflen > 0); in = (ed->hw.ctrl & ED_CONTROL_D_MASK) == ED_CONTROL_D_IN; + uvdbg("EP%d %s toggle: %d maxpacket: %d buflen: %d\n", (ed->hw.ctrl & ED_CONTROL_EN_MASK) >> ED_CONTROL_EN_SHIFT, in ? "IN" : "OUT", @@ -2391,10 +2444,25 @@ static int sam_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, sam_takesem(&ed->wdhsem); + /* Invalidate the D cache to force the ED to be reloaded from RAM */ + + cp15_invalidate_dcache((uintptr_t)ed, + (uintptr_t)ed + sizeof(struct sam_ed_s)); + /* Check the TD completion status bits */ if (ed->tdstatus == TD_CC_NOERROR) { + /* On an IN transaction, we also need to invalidate the buffer + * contents to force it to be reloaded from RAM. + */ + + if (in) + { + cp15_invalidate_dcache((uintptr_t)buffer, + (uintptr_t)buffer + buflen); + } + ret = OK; } else @@ -2467,6 +2535,8 @@ static inline void sam_ep0init(void) struct sam_ed_s *edctrl; struct sam_ed_s *preved; struct sam_gtd_s *tdtail; + uintptr_t phyctrl; + uintptr_t phytail; int rhpndx; /* Initialize the EP0 control EDs */ @@ -2475,14 +2545,16 @@ static inline void sam_ep0init(void) rhpndx < SAM_USBHOST_NRHPORT; rhpndx++, preved = edctrl) { - /* Set up some default values */ + /* Get some pointers to the EP0 control ED and to the common tail TD + * for this root hub port. + */ - (void)sam_ep0configure(&g_ohci.rhport[rhpndx].drvr, 1, 8); + tdtail = &g_tdtail[rhpndx]; + edctrl = &g_edctrl[rhpndx]; - /* Get some convenience pointers */ + /* We will also need the physical addresses for the DMA */ - tdtail = &g_tdtail[rhpndx]; - edctrl = &g_edctrl[rhpndx]; + phytail = sam_physramaddr((uintptr_t)tdtail); /* Initialize the common tail TD for this port */ @@ -2495,10 +2567,14 @@ static inline void sam_ep0init(void) memset(edctrl, 0, sizeof(struct sam_ed_s)); sem_init(&edctrl->wdhsem, 0, 0); + /* Set up some default values (like max packetsize = 8). */ + + (void)sam_ep0configure(&g_ohci.rhport[rhpndx].drvr, 0, 8); + /* Link the common tail TD to the ED's TD list */ - edctrl->hw.headp = (uint32_t)tdtail; - edctrl->hw.tailp = (uint32_t)tdtail; + edctrl->hw.headp = (uint32_t)phytail; + edctrl->hw.tailp = (uint32_t)phytail; /* If this is not the first ED in the list, then link the previous ED * to this one. Because of the memset, the last ED in the list will @@ -2507,13 +2583,22 @@ static inline void sam_ep0init(void) if (preved) { - preved->hw.nexted = (uint32_t)edctrl; + phyctrl = sam_physramaddr((uintptr_t)edctrl); + preved->hw.nexted = (uint32_t)phyctrl; } } + /* Flush all of the control EDs and tail TDs to RAM */ + + cp15_coherent_dcache((uintptr_t)g_edctrl, + SAM_USBHOST_NRHPORT * sizeof(struct sam_ed_s)); + cp15_coherent_dcache((uintptr_t)g_tdtail, + SAM_USBHOST_NRHPORT * sizeof(struct sam_gtd_s)); + /* Set the head of the control list to the EP0 ED for RHport0. */ - sam_putreg((uint32_t)&g_edctrl[0], SAM_USBHOST_CTRLHEADED); + sam_putreg((uint32_t)sam_physramaddr((uintptr_t)&g_edctrl[0]), + SAM_USBHOST_CTRLHEADED); /* ControlListEnable. This bit is set to enable the processing of the * Control list. Note: once enabled, it remains enabled and we may even @@ -2562,13 +2647,11 @@ FAR struct usbhost_connection_s *sam_ohci_initialize(int controller) irqstate_t flags; int i; - /* Sanity checks. NOTE: If certain OS features are enabled, it may be - * necessary to increase the size of SAM_ED/TD_SIZE in sam_ohciram.h - */ + /* One time sanity checks */ DEBUGASSERT(controller == 0); - DEBUGASSERT(sizeof(struct sam_ed_s) <= SAM_ED_SIZE); - DEBUGASSERT(sizeof(struct sam_gtd_s) <= SAM_TD_SIZE); + DEBUGASSERT(sizeof(struct sam_ed_s) == SIZEOF_SAM_ED_S); + DEBUGASSERT(sizeof(struct sam_gtd_s) == SIZEOF_SAM_TD_S); /* Initialize the state data structure */ @@ -2722,6 +2805,13 @@ FAR struct usbhost_connection_s *sam_ohci_initialize(int controller) return NULL; } + /* Drive Vbus +5V (the smoke test). Should be done elsewhere in OTG + * mode. + */ + + sam_usbhost_vbusdrive(SAM_OHCI_IFACE, true); + up_mdelay(50); + /* If there is a USB device in the slot at power up, then we will not * get the status change interrupt to signal us that the device is * connected. We need to set the initial connected state accordingly. @@ -2736,12 +2826,6 @@ FAR struct usbhost_connection_s *sam_ohci_initialize(int controller) i+1, g_ohci.rhport[i].connected ? "YES" : "NO"); } - /* Drive Vbus +5V (the smoke test). Should be done elsewhere in OTG - * mode. - */ - - sam_usbhost_vbusdrive(SAM_OHCI_IFACE, true); - /* Enable interrupts at the interrupt controller */ up_enable_irq(SAM_IRQ_UHPHS); /* enable USB interrupt */