SAMA5 OHCI: Use physical address and flush and/or invalidate data caches as necessary
This commit is contained in:
parent
bdbe4a4f25
commit
e32b60a78c
@ -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"
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user