[PATCH] DSPBRIDGE: cleanup of HW_MBOX_IsFull function
This patch does a cleanup of the HW_MBOX_IsFull function; removing some unnecessary checks and changing the returned value to bool because the status value is not needed. Signed-off-by: Fernando Guzman Lugo Reviewed-by: Felipe Contreras --- drivers/dsp/bridge/hw/hw_mbox.c| 25 - drivers/dsp/bridge/hw/hw_mbox.h| 14 -- drivers/dsp/bridge/wmd/tiomap_sm.c | 12 +++- 3 files changed, 11 insertions(+), 40 deletions(-) diff --git a/drivers/dsp/bridge/hw/hw_mbox.c b/drivers/dsp/bridge/hw/hw_mbox.c index 0c0f721..ee79032 --- a/drivers/dsp/bridge/hw/hw_mbox.c +++ b/drivers/dsp/bridge/hw/hw_mbox.c @@ -104,31 +104,6 @@ HW_STATUS HW_MBOX_MsgWrite(const void __iomem *baseAddress, return status; } -/* Reads the full status register for mailbox. */ -HW_STATUS HW_MBOX_IsFull(const void __iomem *baseAddress, - const HW_MBOX_Id_t mailBoxId, u32 *const pIsFull) -{ - HW_STATUS status = RET_OK; - u32 fullStatus; - - /* Check input parameters */ - CHECK_INPUT_PARAM(baseAddress, 0, RET_BAD_NULL_PARAM, RES_MBOX_BASE + - RES_INVALID_INPUT_PARAM); - CHECK_INPUT_PARAM(pIsFull, NULL, RET_BAD_NULL_PARAM, RES_MBOX_BASE + - RES_INVALID_INPUT_PARAM); - CHECK_INPUT_RANGE_MIN0(mailBoxId, HW_MBOX_ID_MAX, RET_INVALID_ID, - RES_MBOX_BASE + RES_INVALID_INPUT_PARAM); - - /* read the is full status parameter for Mailbox */ - fullStatus = MLBMAILBOX_FIFOSTATUS___0_15FifoFullMBmRead32(baseAddress, - (u32)mailBoxId); - - /* fill in return parameter */ - *pIsFull = (fullStatus & 0xFF); - - return status; -} - /* Gets number of messages in a specified mailbox. */ HW_STATUS HW_MBOX_NumMsgGet(const void __iomem *baseAddress, const HW_MBOX_Id_t mailBoxId, u32 *const pNumMsg) diff --git a/drivers/dsp/bridge/hw/hw_mbox.h b/drivers/dsp/bridge/hw/hw_mbox.h index 5d3d18f..341b58a --- a/drivers/dsp/bridge/hw/hw_mbox.h +++ b/drivers/dsp/bridge/hw/hw_mbox.h @@ -26,6 +26,8 @@ #ifndef __MBOX_H #define __MBOX_H +#include "MLBRegAcM.h" + /* Bitmasks for Mailbox interrupt sources */ #define HW_MBOX_INT_NEW_MSG0x1 #define HW_MBOX_INT_NOT_FULL 0x2 @@ -158,12 +160,12 @@ extern HW_STATUS HW_MBOX_MsgWrite( * * PURPOSE: : this function reads the full status register for mailbox. */ -extern HW_STATUS HW_MBOX_IsFull( - const void __iomem *baseAddress, - const HW_MBOX_Id_t mailBoxId, - u32 *constpIsFull - ); - +static inline bool HW_MBOX_IsFull(const void __iomem *baseAddress, + const HW_MBOX_Id_t mailBoxId) +{ + return MLBMAILBOX_FIFOSTATUS___0_15FifoFullMBmRead32(baseAddress, + (u32)mailBoxId); +} /* * FUNCTION : HW_MBOX_NumMsgGet * diff --git a/drivers/dsp/bridge/wmd/tiomap_sm.c b/drivers/dsp/bridge/wmd/tiomap_sm.c index edc3bcf..f8496cf --- a/drivers/dsp/bridge/wmd/tiomap_sm.c +++ b/drivers/dsp/bridge/wmd/tiomap_sm.c @@ -178,7 +178,6 @@ DSP_STATUS CHNLSM_InterruptDSP(struct WMD_DEV_CONTEXT *hDevContext) #endif #endif HW_STATUS hwStatus; - u32 mbxFull; struct CFG_HOSTRES resources; u16 cnt = 10; u32 temp; @@ -241,14 +240,9 @@ DSP_STATUS CHNLSM_InterruptDSP(struct WMD_DEV_CONTEXT *hDevContext) pDevContext->dwBrdState = BRD_RUNNING; } - while (--cnt) { - hwStatus = HW_MBOX_IsFull(resources.dwMboxBase, - MBOX_ARM2DSP, &mbxFull); - if (mbxFull) - UTIL_Wait(1000);/* wait for 1 ms) */ - else - break; - } + while (--cnt && HW_MBOX_IsFull(resources.dwMboxBase, MBOX_ARM2DSP)) + mdelay(1); + if (!cnt) { DBG_Trace(DBG_LEVEL7, "Timed out waiting for DSP mailbox \n"); status = WMD_E_TIMEOUT; -- 1.5.6.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] DSPBRIDGE: wait less and check the mailbox more.
Performance is increased if we wait less and check the mailbox more when it's full. Signed-off-by: Felipe Contreras Signed-off-by: Fernando Guzman Lugo --- drivers/dsp/bridge/wmd/tiomap_sm.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/dsp/bridge/wmd/tiomap_sm.c b/drivers/dsp/bridge/wmd/tiomap_sm.c index f8496cf..2843788 --- a/drivers/dsp/bridge/wmd/tiomap_sm.c +++ b/drivers/dsp/bridge/wmd/tiomap_sm.c @@ -179,7 +179,7 @@ DSP_STATUS CHNLSM_InterruptDSP(struct WMD_DEV_CONTEXT *hDevContext) #endif HW_STATUS hwStatus; struct CFG_HOSTRES resources; - u16 cnt = 10; + u16 cnt = 1000; u32 temp; /* We are waiting indefinitely here. This needs to be fixed in the * second phase */ @@ -241,7 +241,7 @@ DSP_STATUS CHNLSM_InterruptDSP(struct WMD_DEV_CONTEXT *hDevContext) pDevContext->dwBrdState = BRD_RUNNING; } while (--cnt && HW_MBOX_IsFull(resources.dwMboxBase, MBOX_ARM2DSP)) - mdelay(1); + udelay(1); if (!cnt) { DBG_Trace(DBG_LEVEL7, "Timed out waiting for DSP mailbox \n"); -- 1.5.6.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] DSPBRIDGE: Change address resources to void __iomem *
This patch changes address resources to void __iomem * Signed-off-by: Guzman Lugo Fernando --- arch/arm/plat-omap/include/dspbridge/cfgdefs.h | 16 drivers/dsp/bridge/hw/hw_dspssC64P.c |2 +- drivers/dsp/bridge/hw/hw_dspssC64P.h |2 +- drivers/dsp/bridge/hw/hw_mbox.c| 30 +++-- drivers/dsp/bridge/hw/hw_mbox.h| 18 drivers/dsp/bridge/hw/hw_mmu.c | 43 ++-- drivers/dsp/bridge/hw/hw_mmu.h | 30 +++--- drivers/dsp/bridge/hw/hw_prcm.c| 26 ++-- drivers/dsp/bridge/hw/hw_prcm.h| 17 drivers/dsp/bridge/rmgr/drv.c | 52 drivers/dsp/bridge/rmgr/node.c |2 +- drivers/dsp/bridge/wmd/_tiomap.h |2 +- drivers/dsp/bridge/wmd/tiomap3430.c| 47 ++--- 13 files changed, 145 insertions(+), 142 deletions(-) diff --git a/arch/arm/plat-omap/include/dspbridge/cfgdefs.h b/arch/arm/plat-omap/include/dspbridge/cfgdefs.h index ca96b3c..e7633b5 --- a/arch/arm/plat-omap/include/dspbridge/cfgdefs.h +++ b/arch/arm/plat-omap/include/dspbridge/cfgdefs.h @@ -96,14 +96,14 @@ u32 dwChnlOffset; u32 dwChnlBufSize; u32 dwNumChnls; - u32 dwPrmBase; - u32 dwCmBase; - u32 dwPerBase; - u32 dwWdTimerDspBase; - u32 dwMboxBase; - u32 dwDmmuBase; - u32 dwDipiBase; - u32 dwSysCtrlBase; + void __iomem *dwPrmBase; + void __iomem *dwCmBase; + void __iomem *dwPerBase; + void __iomem *dwWdTimerDspBase; + void __iomem *dwMboxBase; + void __iomem *dwDmmuBase; + u32 *dwDipiBase; + void __iomem *dwSysCtrlBase; } ; struct CFG_DSPMEMDESC { diff --git a/drivers/dsp/bridge/hw/hw_dspssC64P.c b/drivers/dsp/bridge/hw/hw_dspssC64P.c index 0d0d45c..6aac57d --- a/drivers/dsp/bridge/hw/hw_dspssC64P.c +++ b/drivers/dsp/bridge/hw/hw_dspssC64P.c @@ -34,7 +34,7 @@ #include /* HW FUNCTIONS */ -HW_STATUS HW_DSPSS_BootModeSet(const u32 baseAddress, +HW_STATUS HW_DSPSS_BootModeSet(const void __iomem *baseAddress, enum HW_DSPSYSC_BootMode_t bootMode, const u32 bootAddress) { diff --git a/drivers/dsp/bridge/hw/hw_dspssC64P.h b/drivers/dsp/bridge/hw/hw_dspssC64P.h index 493effd..50f9af4 --- a/drivers/dsp/bridge/hw/hw_dspssC64P.h +++ b/drivers/dsp/bridge/hw/hw_dspssC64P.h @@ -41,7 +41,7 @@ #define HW_DSP_IDLEBOOT_ADDR 0x007E - extern HW_STATUS HW_DSPSS_BootModeSet(const u32 baseAddress, + extern HW_STATUS HW_DSPSS_BootModeSet(const void __iomem *baseAddress, enum HW_DSPSYSC_BootMode_t bootMode, const u32 bootAddress); diff --git a/drivers/dsp/bridge/hw/hw_mbox.c b/drivers/dsp/bridge/hw/hw_mbox.c index bc61d64..93fa51e --- a/drivers/dsp/bridge/hw/hw_mbox.c +++ b/drivers/dsp/bridge/hw/hw_mbox.c @@ -36,7 +37,7 @@ struct MAILBOX_CONTEXT mboxsetting = {0x4, 0x1, 0x1}; /* Saves the mailbox context */ -HW_STATUS HW_MBOX_saveSettings(u32 baseAddress) +HW_STATUS HW_MBOX_saveSettings(void __iomem *baseAddress) { HW_STATUS status = RET_OK; @@ -50,7 +51,7 @@ HW_STATUS HW_MBOX_saveSettings(u32 baseAddress) } /* Restores the mailbox context */ -HW_STATUS HW_MBOX_restoreSettings(u32 baseAddress) +HW_STATUS HW_MBOX_restoreSettings(void __iomem *baseAddress) { HW_STATUS status = RET_OK; /* Restor IRQ enable status */ @@ -65,8 +66,8 @@ HW_STATUS HW_MBOX_restoreSettings(u32 baseAddress) /* Reads a u32 from the sub module message box Specified. if there are no * messages in the mailbox then and error is returned. */ -HW_STATUS HW_MBOX_MsgRead(const u32 baseAddress, const HW_MBOX_Id_t mailBoxId, - u32 *const pReadValue) +HW_STATUS HW_MBOX_MsgRead(const void __iomem *baseAddress, + const HW_MBOX_Id_t mailBoxId, u32 *const pReadValue) { HW_STATUS status = RET_OK; @@ -86,8 +87,8 @@ HW_STATUS HW_MBOX_MsgRead(const u32 baseAddress, const HW_MBOX_Id_t mailBoxId, } /* Writes a u32 from the sub module message box Specified. */ -HW_STATUS HW_MBOX_MsgWrite(const u32 baseAddress, const HW_MBOX_Id_t mailBoxId, - const u32 writeValue) +HW_STATUS HW_MBOX_MsgWrite(const void __iomem *baseAddress, + const HW_MBOX_Id_t mailBoxId, const u32 writeValue) { HW_STATUS status = RET_OK; @@ -105,8 +106,8 @@ HW_STATUS HW_MBOX_MsgWrite(const u32 baseAddress, const HW_MBOX_Id_t mailBoxId, } /* Reads the full status register for mailbox. */ -HW_STATUS HW_MBOX_IsFull(const u32 baseAddress, const HW_MBOX_Id_t mailBoxId, - u32
[PATCH] DSPBRIDGE: Remove variables not used in cfgdefs.h
This patch removes some variable that are not used. Signed-off-by: Guzman Lugo Fernando --- arch/arm/plat-omap/include/dspbridge/cfgdefs.h | 10 -- drivers/dsp/bridge/rmgr/drv.c |2 -- 2 files changed, 0 insertions(+), 12 deletions(-) diff --git a/arch/arm/plat-omap/include/dspbridge/cfgdefs.h b/arch/arm/plat-omap/include/dspbridge/cfgdefs.h index e7633b5..34a28f8 --- a/arch/arm/plat-omap/include/dspbridge/cfgdefs.h +++ b/arch/arm/plat-omap/include/dspbridge/cfgdefs.h @@ -77,15 +77,6 @@ u8 bIRQAttrib; /* IRQ Attribute */ u32 dwOffsetForMonitor; /* The Shared memory starts from * dwMemBase + this offset */ - u32 dwBusType; /* Bus type for this device */ - u32 dwProgBase; /* DSP ProgBase */ - u32 dwProgLength; /* DSP ProgBase Length */ - u32 dwRegBase; /* DSP memory mapped register base */ - u32 dwRegLength;/* DSP Register Base Length */ - u32 ClientHandle; /* Client Handle */ - u32 SocketHandle; /* Socket and Function Pair */ - u32 CardInfo; /* This will be used as a context data in -* in the CardRequestIRQ */ /* * Info needed by NODE for allocating channels to communicate with RMS: * dwChnlOffset: Offset of RMS channels. Lower channels are @@ -102,7 +93,6 @@ void __iomem *dwWdTimerDspBase; void __iomem *dwMboxBase; void __iomem *dwDmmuBase; - u32 *dwDipiBase; void __iomem *dwSysCtrlBase; } ; diff --git a/drivers/dsp/bridge/rmgr/drv.c b/drivers/dsp/bridge/rmgr/drv.c index 2241f48..160d730 --- a/drivers/dsp/bridge/rmgr/drv.c +++ b/drivers/dsp/bridge/rmgr/drv.c @@ -1733,7 +1733,6 @@ static DSP_STATUS RequestBridgeResources(u32 dwContext, s32 bRequest) /* Second window is for DSP external memory shared with MPU */ if (DSP_SUCCEEDED(status)) { /* for Linux, these are hard-coded values */ - pResources->dwBusType = 0; pResources->bIRQRegisters = 0; pResources->bIRQAttrib = 0; pResources->dwOffsetForMonitor = 0; @@ -1856,7 +1855,6 @@ static DSP_STATUS RequestBridgeResourcesDSP(u32 dwContext, s32 bRequest) } if (DSP_SUCCEEDED(status)) { /* for Linux, these are hard-coded values */ - pResources->dwBusType = 0; pResources->bIRQRegisters = 0; pResources->bIRQAttrib = 0; pResources->dwOffsetForMonitor = 0; -- 1.5.6.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] DSPBRIDGE: Removes wrappers funtions of readl and writel
This patch change the call to RD_MEM_32_VOLATILE and WR_MEM_32_VOLATILE with __raw_readl and __raw_writel Signed-off-by: Guzman Lugo Fernando --- drivers/dsp/bridge/hw/MLBRegAcM.h| 41 drivers/dsp/bridge/hw/MMURegAcM.h| 66 ++-- drivers/dsp/bridge/hw/PRCMRegAcM.h | 181 +- drivers/dsp/bridge/hw/hw_dspssC64P.c |5 +- 4 files changed, 148 insertions(+), 145 deletions(-) diff --git a/drivers/dsp/bridge/hw/MLBRegAcM.h b/drivers/dsp/bridge/hw/MLBRegAcM.h index 747a2e1..d215ec5 --- a/drivers/dsp/bridge/hw/MLBRegAcM.h +++ b/drivers/dsp/bridge/hw/MLBRegAcM.h @@ -18,6 +18,7 @@ #define _MLB_REG_ACM_H #include +#include #include #include "MLBAccInt.h" @@ -25,7 +26,7 @@ #define MLBMAILBOX_SYSCONFIGReadRegister32(baseAddress)\ (_DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_SYSCONFIGReadRegister32),\ - RD_MEM_32_VOLATILE(((u32)(baseAddress))+ \ + __raw_readl(((baseAddress))+ \ MLB_MAILBOX_SYSCONFIG_OFFSET)) @@ -34,13 +35,13 @@ const u32 offset = MLB_MAILBOX_SYSCONFIG_OFFSET;\ register u32 newValue = ((u32)(value));\ _DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_SYSCONFIGWriteRegister32);\ -WR_MEM_32_VOLATILE(((u32)(baseAddress))+offset, newValue);\ +__raw_writel(newValue, ((baseAddress))+offset);\ } #define MLBMAILBOX_SYSCONFIGSIdleModeRead32(baseAddress)\ (_DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_SYSCONFIGSIdleModeRead32),\ - (((RD_MEM_32_VOLATILEu32)(baseAddress))+\ + (((__raw_readlu32)(baseAddress))+\ (MLB_MAILBOX_SYSCONFIG_OFFSET &\ MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK) >>\ MLB_MAILBOX_SYSCONFIG_SIdleMode_OFFSET)) @@ -49,7 +50,7 @@ #define MLBMAILBOX_SYSCONFIGSIdleModeWrite32(baseAddress, value)\ {\ const u32 offset = MLB_MAILBOX_SYSCONFIG_OFFSET;\ -register u32 data = RD_MEM_32_VOLATILE(((u32)(baseAddress)) +\ +register u32 data = __raw_readl(((u32)(baseAddress)) +\ offset);\ register u32 newValue = ((u32)(value));\ _DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_SYSCONFIGSIdleModeWrite32);\ @@ -57,7 +58,7 @@ newValue <<= MLB_MAILBOX_SYSCONFIG_SIdleMode_OFFSET;\ newValue &= MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK;\ newValue |= data;\ -WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, newValue);\ +__raw_writel(newValue, (u32)(baseAddress)+offset);\ } @@ -65,20 +66,20 @@ {\ const u32 offset = MLB_MAILBOX_SYSCONFIG_OFFSET;\ register u32 data =\ -RD_MEM_32_VOLATILE(((u32)(baseAddress))+offset);\ +__raw_readl(((u32)(baseAddress))+offset);\ register u32 newValue = ((u32)(value));\ _DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_SYSCONFIGSoftResetWrite32);\ data &= ~(MLB_MAILBOX_SYSCONFIG_SoftReset_MASK);\ newValue <<= MLB_MAILBOX_SYSCONFIG_SoftReset_OFFSET;\ newValue &= MLB_MAILBOX_SYSCONFIG_SoftReset_MASK;\ newValue |= data;\ -WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, newValue);\ +__raw_writel(newValue, (u32)(baseAddress)+offset);\ } #define MLBMAILBOX_SYSCONFIGAutoIdleRead32(baseAddress)\ (_DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_SYSCONFIGAutoIdleRead32),\ - (((RD_MEM_32_VOLATILEu32)(baseAddress))+\ + (((__raw_readlu32)(baseAddress))+\ (MLB_MAILBOX_SYSCONFIG_OFFSET &\ MLB_MAILBOX_SYSCONFIG_AutoIdle_MASK) >>\ MLB_MAILBOX_SYSCONFIG_AutoIdle_OFFSET)) @@ -88,20 +89,20 @@ {\ const u32 offset = MLB_MAILBOX_SYSCONFIG_OFFSET;\ register u32 data =\ -RD_MEM_32_VOLATILE(((u32)(baseAddress))+offset);\ +__raw_readl(((u32)(baseAddress))+offset);\ register u32 newValue = ((u32)(value));\ _DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_SYSCONFIGAutoIdleWrite32);\ data &= ~(MLB_MAILBOX_SYSCONFIG_AutoIdle_MASK);\ newValue <<= MLB_MAILBOX_SYSCONFIG_AutoIdle_OFFSET;\ newValue &= MLB_MAILBOX_SYSCONFIG_AutoIdle_MASK;\ newValue |= data;\ -WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, newValue);\ +__raw_writel(newValue, (u32)(baseAddress)+offset);\ } #define MLBMAILBOX_SYSSTATUSResetDoneRead32(baseAddress)\ (_DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_SYSSTATUSResetDoneRead32),\ - (((RD_MEM_32_VOLATILEu32)(baseAddress))+\ + (((__raw_readlu32)(baseAddress))+\ (MLB_MAILBOX_SYSSTATUS_OFFSET &\ MLB_MAILBOX_SYSSTATUS_ResetDone_MASK) >>\ MLB_MAILBOX_SYSSTATUS_ResetDone_OFFSET)) @@ -109,7 +110,7 @@ #define MLBMAILBOX_MESSAGE___0_15ReadRegister32(baseAddress, bank)\ (_DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_MESSAGE___0_15ReadRegister32),\ - RD_MEM_32_VOLATILE(((u32)(baseAddress))+\ + __raw_readl(((baseAddress))+\ (MLB_MAILBOX_MESSAGE___REGSET_0_15_OFFSET +\ MLB_MAILBOX_MESSAGE___0_15_OFFSET+(\ (bank)*MLB_MAILBOX_MESSAGE___REGSET_0_15_STEP @@ -122,14 +123,14 @@ ((bank)*MLB_MAILBOX_MESSAGE___REGSET_0_15_STEP);\ register u32 newValue = ((u32)(value));\ _DEBUG_LEVEL_1_EASI(EASI
[PATCH] DSPBRIDGE: Remove SEEK_* redefinitions
This patch removes the SEEK_* redefinitions in host_os.h Signed-off-by: Guzman Lugo Fernando --- arch/arm/plat-omap/include/dspbridge/host_os.h |6 -- 1 files changed, 0 insertions(+), 6 deletions(-) diff --git a/arch/arm/plat-omap/include/dspbridge/host_os.h b/arch/arm/plat-omap/include/dspbridge/host_os.h index ff49e0d..9245eea --- a/arch/arm/plat-omap/include/dspbridge/host_os.h +++ b/arch/arm/plat-omap/include/dspbridge/host_os.h @@ -60,12 +60,6 @@ #include #include -/* --- Macros */ - -#define SEEK_SET0 /* Seek from beginning of file. */ -#define SEEK_CUR1 /* Seek from current position. */ -#define SEEK_END2 /* Seek from end of file. */ - /* TODO -- Remove, once BP defines them */ #define INT_MAIL_MPU_IRQ26 #define INT_DSP_MMU_IRQ28 -- 1.5.6.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv4 2/4] iovmm: add superpages support to fixed da address
This patch adds superpages support to fixed ad address inside iommu_kmap function. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/iovmm.c | 62 +-- 1 files changed, 36 insertions(+), 26 deletions(-) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 34f0012..93a34d9 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -87,35 +87,43 @@ static size_t sgtable_len(const struct sg_table *sgt) } #define sgtable_ok(x) (!!sgtable_len(x)) +static unsigned max_alignment(u32 addr) +{ + int i; + unsigned pagesize[] = { SZ_16M, SZ_1M, SZ_64K, SZ_4K, }; + for (i = 0; i < ARRAY_SIZE(pagesize) && addr & (pagesize[i] - 1); i++) + ; + return (i < ARRAY_SIZE(pagesize)) ? pagesize[i] : 0; +} + /* * calculate the optimal number sg elements from total bytes based on * iommu superpages */ -static unsigned int sgtable_nents(size_t bytes) +static unsigned sgtable_nents(size_t bytes, u32 da, u32 pa) { - int i; - unsigned int nr_entries; - const unsigned long pagesize[] = { SZ_16M, SZ_1M, SZ_64K, SZ_4K, }; + unsigned nr_entries = 0, ent_sz; if (!IS_ALIGNED(bytes, PAGE_SIZE)) { pr_err("%s: wrong size %08x\n", __func__, bytes); return 0; } - nr_entries = 0; - for (i = 0; i < ARRAY_SIZE(pagesize); i++) { - if (bytes >= pagesize[i]) { - nr_entries += (bytes / pagesize[i]); - bytes %= pagesize[i]; - } + while (bytes) { + ent_sz = max_alignment(da | pa); + ent_sz = min_t(unsigned, ent_sz, iopgsz_max(bytes)); + nr_entries++; + da += ent_sz; + pa += ent_sz; + bytes -= ent_sz; } - BUG_ON(bytes); return nr_entries; } /* allocate and initialize sg_table header(a kind of 'superblock') */ -static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags) +static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags, + u32 da, u32 pa) { unsigned int nr_entries; int err; @@ -127,9 +135,8 @@ static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags) if (!IS_ALIGNED(bytes, PAGE_SIZE)) return ERR_PTR(-EINVAL); - /* FIXME: IOVMF_DA_FIXED should support 'superpages' */ - if ((flags & IOVMF_LINEAR) && (flags & IOVMF_DA_ANON)) { - nr_entries = sgtable_nents(bytes); + if (flags & IOVMF_LINEAR) { + nr_entries = sgtable_nents(bytes, da, pa); if (!nr_entries) return ERR_PTR(-EINVAL); } else @@ -409,7 +416,8 @@ static inline void sgtable_drain_vmalloc(struct sg_table *sgt) BUG_ON(!sgt); } -static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) +static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, u32 da, + size_t len) { unsigned int i; struct scatterlist *sg; @@ -418,9 +426,10 @@ static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) va = phys_to_virt(pa); for_each_sg(sgt->sgl, sg, sgt->nents, i) { - size_t bytes; + unsigned bytes; - bytes = iopgsz_max(len); + bytes = max_alignment(da | pa); + bytes = min_t(unsigned, bytes, iopgsz_max(len)); BUG_ON(!iopgsz_ok(bytes)); @@ -429,6 +438,7 @@ static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) * 'pa' is cotinuous(linear). */ pa += bytes; + da += bytes; len -= bytes; } BUG_ON(len); @@ -695,18 +705,18 @@ u32 iommu_vmalloc(struct iommu *obj, u32 da, size_t bytes, u32 flags) if (!va) return -ENOMEM; - sgt = sgtable_alloc(bytes, flags); + flags &= IOVMF_HW_MASK; + flags |= IOVMF_DISCONT; + flags |= IOVMF_ALLOC; + flags |= (da ? IOVMF_DA_FIXED : IOVMF_DA_ANON); + + sgt = sgtable_alloc(bytes, flags, da, 0); if (IS_ERR(sgt)) { da = PTR_ERR(sgt); goto err_sgt_alloc; } sgtable_fill_vmalloc(sgt, va); - flags &= IOVMF_HW_MASK; - flags |= IOVMF_DISCONT; - flags |= IOVMF_ALLOC; - flags |= (da ? IOVMF_DA_FIXED : IOVMF_DA_ANON); - da = __iommu_vmap(obj, da, sgt, va, bytes, flags); if (IS_ERR_VALUE(da)) goto err_iommu_vmap; @@ -746,11 +756,11 @@ static u32 __iommu_kmap(struct iommu *obj, u32 da, u32 pa, void *va, { struct sg_table *sgt; -
[PATCHv4 4/4] iommu: create new api to set valid da range
Some IOMMUs cannot use the whole 0x0 - 0x range. With this new API the valid range can be set. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/include/plat/iommu.h |3 +++ arch/arm/plat-omap/iommu.c | 29 + arch/arm/plat-omap/iovmm.c | 15 --- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h index 33c7d41..aea01b1 100644 --- a/arch/arm/plat-omap/include/plat/iommu.h +++ b/arch/arm/plat-omap/include/plat/iommu.h @@ -46,6 +46,8 @@ struct iommu { struct list_headmmap; struct mutexmmap_lock; /* protect mmap */ + u32 da_start; + u32 da_end; int (*isr)(struct iommu *obj); @@ -152,6 +154,7 @@ extern void flush_iotlb_all(struct iommu *obj); extern int iopgtable_store_entry(struct iommu *obj, struct iotlb_entry *e); extern size_t iopgtable_clear_entry(struct iommu *obj, u32 iova); +extern int iommu_set_da_range(struct iommu *obj, u32 start, u32 end); extern struct iommu *iommu_get(const char *name); extern void iommu_put(struct iommu *obj); diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index 6cd151b..e70e76b 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c @@ -25,6 +25,12 @@ #include "iopgtable.h" +/* Reserve the first page for NULL */ +#define IOMMU_DEFAULT_DA_START PAGE_SIZE +/* 0x not allowed because it is not page aligned */ +#define IOMMU_DEFAULT_DA_END 0xF000; + + #define for_each_iotlb_cr(obj, n, __i, cr) \ for (__i = 0; \ (__i < (n)) && (cr = __iotlb_read_cr((obj), __i), true); \ @@ -830,6 +836,27 @@ static int device_match_by_alias(struct device *dev, void *data) } /** + * iommu_set_da_range - Set a valid device address range + * @obj: target iommu + * @start Start of valid range + * @endEnd of valid range + **/ +int iommu_set_da_range(struct iommu *obj, u32 start, u32 end) +{ + if (!obj) + return -EFAULT; + + if (end < start || !PAGE_ALIGN(start | end)) + return -EINVAL; + + obj->da_start = start; + obj->da_end = end; + + return 0; +} +EXPORT_SYMBOL_GPL(iommu_set_da_range); + +/** * iommu_get - Get iommu handler * @name: target iommu name **/ @@ -853,6 +880,8 @@ struct iommu *iommu_get(const char *name) if (err) goto err_enable; flush_iotlb_all(obj); + obj->da_start = IOMMU_DEFAULT_DA_START; + obj->da_end = IOMMU_DEFAULT_DA_END; } if (!try_module_get(obj->owner)) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 5489ca9..cff382f 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -280,13 +280,14 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, alignement = PAGE_SIZE; if (flags & IOVMF_DA_ANON) { - /* -* Reserve the first page for NULL -*/ - start = PAGE_SIZE; + start = obj->da_start; + if (flags & IOVMF_LINEAR) alignement = iopgsz_max(bytes); start = roundup(start, alignement); + } else if (start < obj->da_start || start > obj->da_end || + obj->da_end - start < bytes) { + return ERR_PTR(-EINVAL); } tmp = NULL; @@ -299,16 +300,16 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, if (prev_end > start) break; - if (start + bytes <= tmp->da_start) + if (tmp->da_start > start && (tmp->da_start - start) >= bytes) goto found; - if (flags & IOVMF_DA_ANON) + if (tmp->da_end >= start && flags & IOVMF_DA_ANON) start = roundup(tmp->da_end + 1, alignement); prev_end = tmp->da_end; } - if ((start >= prev_end) && (ULONG_MAX - start + 1 >= bytes)) + if ((start >= prev_end) && (obj->da_end - start >= bytes)) goto found; dev_dbg(obj->dev, "%s: no space to fit %08x(%x) flags: %08x\n", -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv4 1/4] iovmm: no gap checking for fixed address
If some fixed da address is wanted to be mapped and the page is freed but it is used as gap, the mapping will fail. This patch is fixing that and olny keeps the gap for not fixed address. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/iovmm.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 24ca9c4..34f0012 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -289,7 +289,7 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, prev_end = 0; list_for_each_entry(tmp, &obj->mmap, list) { - if (prev_end >= start) + if (prev_end > start) break; if (start + bytes <= tmp->da_start) @@ -301,7 +301,7 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, prev_end = tmp->da_end; } - if ((start > prev_end) && (ULONG_MAX - start >= bytes)) + if ((start >= prev_end) && (ULONG_MAX - start + 1 >= bytes)) goto found; dev_dbg(obj->dev, "%s: no space to fit %08x(%x) flags: %08x\n", -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv4 3/4] iovmm: replace __iounmap with omap_iounmap
Omap platform is omap_iounmap function. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/iovmm.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 93a34d9..5489ca9 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -821,7 +821,7 @@ void iommu_kunmap(struct iommu *obj, u32 da) struct sg_table *sgt; typedef void (*func_t)(const void *); - sgt = unmap_vm_area(obj, da, (func_t)__iounmap, + sgt = unmap_vm_area(obj, da, (func_t)omap_iounmap, IOVMF_LINEAR | IOVMF_MMIO); if (!sgt) dev_dbg(obj->dev, "%s: No sgt\n", __func__); -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv4 0/4] iovmm: fixes for iovmm module
Version 4: * Changes in "iommu: create new api to set valid da range" - Validate range for fixed address. - Change way of change boundaries to avoid possible overflow instead of style : start + bytes >= end which start + end can overflow use style: end - start < bytes Version 3: * change patch 2 base on Felipe Contreras' comments, now it uses min_t and I deleted some blank lines. * patch "create new api to set valid da range" is base on "iovmm: IVA2 MMU range is from 0x1100 to 0x" patch and on Hiroshi's comments and now it is added to this set. Version 2: * Removed "iovmm: fixes for iovmm module" that patch was already sent. * Modified "iovmm: fix roundup for next area and end check for the last area" patch, base on Davin Cohen's comments and rename it to a proper name that describes what it is doing now. Fernando Guzman Lugo (4): iovmm: no gap checking for fixed address iovmm: add superpages support to fixed da address iovmm: replace __iounmap with omap_iounmap iommu: create new api to set valid da range arch/arm/plat-omap/include/plat/iommu.h |3 + arch/arm/plat-omap/iommu.c | 29 +++ arch/arm/plat-omap/iovmm.c | 81 +- 3 files changed, 78 insertions(+), 35 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] omap: mailbox - fix missing mbox owner assignment when creating queue
mbox field of omap_mbox_queue structure is never assigned to the mailbox owner. Causing kernel panic when dereference it. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/mailbox.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index c59c9c3..b1e0e8f 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -217,6 +217,7 @@ static struct omap_mbox_queue *mbox_queue_alloc(struct omap_mbox *mbox, return NULL; spin_lock_init(&mq->lock); + mq->mbox = mbox; if (kfifo_alloc(&mq->fifo, mbox_kfifo_size, GFP_KERNEL)) goto error; -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv5 3/4] iovmm: replace __iounmap with omap_iounmap
Omap platform is omap_iounmap function. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/iovmm.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 93a34d9..5489ca9 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -821,7 +821,7 @@ void iommu_kunmap(struct iommu *obj, u32 da) struct sg_table *sgt; typedef void (*func_t)(const void *); - sgt = unmap_vm_area(obj, da, (func_t)__iounmap, + sgt = unmap_vm_area(obj, da, (func_t)omap_iounmap, IOVMF_LINEAR | IOVMF_MMIO); if (!sgt) dev_dbg(obj->dev, "%s: No sgt\n", __func__); -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv5 2/4] iovmm: add superpages support to fixed da address
This patch adds superpages support to fixed ad address inside iommu_kmap function. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/iovmm.c | 62 +-- 1 files changed, 36 insertions(+), 26 deletions(-) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 34f0012..93a34d9 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -87,35 +87,43 @@ static size_t sgtable_len(const struct sg_table *sgt) } #define sgtable_ok(x) (!!sgtable_len(x)) +static unsigned max_alignment(u32 addr) +{ + int i; + unsigned pagesize[] = { SZ_16M, SZ_1M, SZ_64K, SZ_4K, }; + for (i = 0; i < ARRAY_SIZE(pagesize) && addr & (pagesize[i] - 1); i++) + ; + return (i < ARRAY_SIZE(pagesize)) ? pagesize[i] : 0; +} + /* * calculate the optimal number sg elements from total bytes based on * iommu superpages */ -static unsigned int sgtable_nents(size_t bytes) +static unsigned sgtable_nents(size_t bytes, u32 da, u32 pa) { - int i; - unsigned int nr_entries; - const unsigned long pagesize[] = { SZ_16M, SZ_1M, SZ_64K, SZ_4K, }; + unsigned nr_entries = 0, ent_sz; if (!IS_ALIGNED(bytes, PAGE_SIZE)) { pr_err("%s: wrong size %08x\n", __func__, bytes); return 0; } - nr_entries = 0; - for (i = 0; i < ARRAY_SIZE(pagesize); i++) { - if (bytes >= pagesize[i]) { - nr_entries += (bytes / pagesize[i]); - bytes %= pagesize[i]; - } + while (bytes) { + ent_sz = max_alignment(da | pa); + ent_sz = min_t(unsigned, ent_sz, iopgsz_max(bytes)); + nr_entries++; + da += ent_sz; + pa += ent_sz; + bytes -= ent_sz; } - BUG_ON(bytes); return nr_entries; } /* allocate and initialize sg_table header(a kind of 'superblock') */ -static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags) +static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags, + u32 da, u32 pa) { unsigned int nr_entries; int err; @@ -127,9 +135,8 @@ static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags) if (!IS_ALIGNED(bytes, PAGE_SIZE)) return ERR_PTR(-EINVAL); - /* FIXME: IOVMF_DA_FIXED should support 'superpages' */ - if ((flags & IOVMF_LINEAR) && (flags & IOVMF_DA_ANON)) { - nr_entries = sgtable_nents(bytes); + if (flags & IOVMF_LINEAR) { + nr_entries = sgtable_nents(bytes, da, pa); if (!nr_entries) return ERR_PTR(-EINVAL); } else @@ -409,7 +416,8 @@ static inline void sgtable_drain_vmalloc(struct sg_table *sgt) BUG_ON(!sgt); } -static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) +static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, u32 da, + size_t len) { unsigned int i; struct scatterlist *sg; @@ -418,9 +426,10 @@ static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) va = phys_to_virt(pa); for_each_sg(sgt->sgl, sg, sgt->nents, i) { - size_t bytes; + unsigned bytes; - bytes = iopgsz_max(len); + bytes = max_alignment(da | pa); + bytes = min_t(unsigned, bytes, iopgsz_max(len)); BUG_ON(!iopgsz_ok(bytes)); @@ -429,6 +438,7 @@ static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) * 'pa' is cotinuous(linear). */ pa += bytes; + da += bytes; len -= bytes; } BUG_ON(len); @@ -695,18 +705,18 @@ u32 iommu_vmalloc(struct iommu *obj, u32 da, size_t bytes, u32 flags) if (!va) return -ENOMEM; - sgt = sgtable_alloc(bytes, flags); + flags &= IOVMF_HW_MASK; + flags |= IOVMF_DISCONT; + flags |= IOVMF_ALLOC; + flags |= (da ? IOVMF_DA_FIXED : IOVMF_DA_ANON); + + sgt = sgtable_alloc(bytes, flags, da, 0); if (IS_ERR(sgt)) { da = PTR_ERR(sgt); goto err_sgt_alloc; } sgtable_fill_vmalloc(sgt, va); - flags &= IOVMF_HW_MASK; - flags |= IOVMF_DISCONT; - flags |= IOVMF_ALLOC; - flags |= (da ? IOVMF_DA_FIXED : IOVMF_DA_ANON); - da = __iommu_vmap(obj, da, sgt, va, bytes, flags); if (IS_ERR_VALUE(da)) goto err_iommu_vmap; @@ -746,11 +756,11 @@ static u32 __iommu_kmap(struct iommu *obj, u32 da, u32 pa, void *va, { struct sg_table *sgt; -
[PATCHv5 4/4] iommu: create new api to set valid da range
Some IOMMUs cannot use the whole 0x0 - 0x rage. With this new API the valid range can be set. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/include/plat/iommu.h |3 ++ arch/arm/plat-omap/iommu.c | 33 +++ arch/arm/plat-omap/iovmm.c | 18 ++-- 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h index 33c7d41..2ea8ea3 100644 --- a/arch/arm/plat-omap/include/plat/iommu.h +++ b/arch/arm/plat-omap/include/plat/iommu.h @@ -103,6 +103,8 @@ struct iommu_platform_data { const char *name; const char *clk_name; const int nr_tlb_entries; + u32 da_start; + u32 da_end; }; #if defined(CONFIG_ARCH_OMAP1) @@ -152,6 +154,7 @@ extern void flush_iotlb_all(struct iommu *obj); extern int iopgtable_store_entry(struct iommu *obj, struct iotlb_entry *e); extern size_t iopgtable_clear_entry(struct iommu *obj, u32 iova); +extern int iommu_set_da_range(struct iommu *obj, u32 start, u32 end); extern struct iommu *iommu_get(const char *name); extern void iommu_put(struct iommu *obj); diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index 6cd151b..b3846bd 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c @@ -25,6 +25,12 @@ #include "iopgtable.h" +/* Reserve the first page for NULL */ +#define IOMMU_DEFAULT_DA_START PAGE_SIZE +/* 0x not allowed because it is not page aligned */ +#define IOMMU_DEFAULT_DA_END 0xF000 + + #define for_each_iotlb_cr(obj, n, __i, cr) \ for (__i = 0; \ (__i < (n)) && (cr = __iotlb_read_cr((obj), __i), true); \ @@ -830,6 +836,31 @@ static int device_match_by_alias(struct device *dev, void *data) } /** + * iommu_set_da_range - Set a valid device address range + * @obj: target iommu + * @start Start of valid range + * @endEnd of valid range + **/ +int iommu_set_da_range(struct iommu *obj, u32 start, u32 end) +{ + struct iommu_platform_data *pdata; + + if (!obj) + return -EFAULT; + + if (end < start || !PAGE_ALIGN(start | end)) + return -EINVAL; + + pdata = obj->dev->platform_data; + + pdata->da_start = start; + pdata->da_end = end; + + return 0; +} +EXPORT_SYMBOL_GPL(iommu_set_da_range); + +/** * iommu_get - Get iommu handler * @name: target iommu name **/ @@ -853,6 +884,8 @@ struct iommu *iommu_get(const char *name) if (err) goto err_enable; flush_iotlb_all(obj); + iommu_set_da_range(obj, IOMMU_DEFAULT_DA_START, + IOMMU_DEFAULT_DA_END); } if (!try_module_get(obj->owner)) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 5489ca9..3809add 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -272,21 +272,25 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, { struct iovm_struct *new, *tmp; u32 start, prev_end, alignement; + struct iommu_platform_data *pdata; if (!obj || !bytes) return ERR_PTR(-EINVAL); + pdata = obj->dev->platform_data; + start = da; alignement = PAGE_SIZE; if (flags & IOVMF_DA_ANON) { - /* -* Reserve the first page for NULL -*/ - start = PAGE_SIZE; + start = pdata->da_start; + if (flags & IOVMF_LINEAR) alignement = iopgsz_max(bytes); start = roundup(start, alignement); + } else if (start < pdata->da_start || start > pdata->da_end || + pdata->da_end - start < bytes) { + return ERR_PTR(-EINVAL); } tmp = NULL; @@ -299,16 +303,16 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, if (prev_end > start) break; - if (start + bytes <= tmp->da_start) + if (tmp->da_start > start && (tmp->da_start - start) >= bytes) goto found; - if (flags & IOVMF_DA_ANON) + if (tmp->da_end >= start && flags & IOVMF_DA_ANON) start = roundup(tmp->da_end + 1, alignement); prev_end = tmp->da_end; } - if ((start >= prev_end) && (ULONG_MAX - start + 1 >= bytes)) + if ((start >= prev_end) && (pdata->da_end - start >= bytes)) goto found;
[PATCHv5 0/4] iovmm: fixes for iovmm module
Version 5: * Changes in "iommu: create new api to set valid da range" - Change range variables to platform data structure. Version 4: * Changes in "iommu: create new api to set valid da range" - Validate range for fixed address. - Change way of change boundaries to avoid possible overflow instead of style : start + bytes >= end which start + end can overflow use style: end - start < bytes Version 3: * change patch 2 base on Felipe Contreras' comments, now it uses min_t and I deleted some blank lines. * patch "create new api to set valid da range" is base on "iovmm: IVA2 MMU range is from 0x1100 to 0x" patch and on Hiroshi's comments and now it is added to this set. Version 2: * Removed "iovmm: fixes for iovmm module" that patch was already sent. * Modified "iovmm: fix roundup for next area and end check for the last area" patch, base on Davin Cohen's comments and rename it to a proper name that describes what it is doing now. *** BLURB HERE *** Fernando Guzman Lugo (4): iovmm: no gap checking for fixed address iovmm: add superpages support to fixed da address iovmm: replace __iounmap with omap_iounmap iommu: create new api to set valid da range arch/arm/plat-omap/include/plat/iommu.h |3 + arch/arm/plat-omap/iommu.c | 33 arch/arm/plat-omap/iovmm.c | 84 ++- 3 files changed, 85 insertions(+), 35 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv5 1/4] iovmm: no gap checking for fixed address
If some fixed da address is wanted to be mapped and the page is freed but it is used as gap, the mapping will fail. This patch is fixing that and olny keeps the gap for not fixed address. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/iovmm.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 24ca9c4..34f0012 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -289,7 +289,7 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, prev_end = 0; list_for_each_entry(tmp, &obj->mmap, list) { - if (prev_end >= start) + if (prev_end > start) break; if (start + bytes <= tmp->da_start) @@ -301,7 +301,7 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, prev_end = tmp->da_end; } - if ((start > prev_end) && (ULONG_MAX - start >= bytes)) + if ((start >= prev_end) && (ULONG_MAX - start + 1 >= bytes)) goto found; dev_dbg(obj->dev, "%s: no space to fit %08x(%x) flags: %08x\n", -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv5 0/4] omap: iovmm - fixes for iovmm module
Version 5: * Changes in "iommu: create new api to set valid da range" - Change range variables to platform data structure. Version 4: * Changes in "iommu: create new api to set valid da range" - Validate range for fixed address. - Change way of change boundaries to avoid possible overflow instead of style : start + bytes >= end which start + end can overflow use style: end - start < bytes Version 3: * change patch 2 base on Felipe Contreras' comments, now it uses min_t and I deleted some blank lines. * patch "create new api to set valid da range" is base on "iovmm: IVA2 MMU range is from 0x1100 to 0x" patch and on Hiroshi's comments and now it is added to this set. Version 2: * Removed "iovmm: fixes for iovmm module" that patch was already sent. * Modified "iovmm: fix roundup for next area and end check for the last area" patch, base on Davin Cohen's comments and rename it to a proper name that describes what it is doing now. *** BLURB HERE *** Fernando Guzman Lugo (4): iovmm: no gap checking for fixed address iovmm: add superpages support to fixed da address iovmm: replace __iounmap with omap_iounmap iommu: create new api to set valid da range arch/arm/plat-omap/include/plat/iommu.h |3 + arch/arm/plat-omap/iommu.c | 33 arch/arm/plat-omap/iovmm.c | 84 ++- 3 files changed, 85 insertions(+), 35 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv5 2/4] omap: iovmm - add superpages support to fixed da address
This patch adds superpages support to fixed ad address inside iommu_kmap function. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/iovmm.c | 62 +-- 1 files changed, 36 insertions(+), 26 deletions(-) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 34f0012..93a34d9 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -87,35 +87,43 @@ static size_t sgtable_len(const struct sg_table *sgt) } #define sgtable_ok(x) (!!sgtable_len(x)) +static unsigned max_alignment(u32 addr) +{ + int i; + unsigned pagesize[] = { SZ_16M, SZ_1M, SZ_64K, SZ_4K, }; + for (i = 0; i < ARRAY_SIZE(pagesize) && addr & (pagesize[i] - 1); i++) + ; + return (i < ARRAY_SIZE(pagesize)) ? pagesize[i] : 0; +} + /* * calculate the optimal number sg elements from total bytes based on * iommu superpages */ -static unsigned int sgtable_nents(size_t bytes) +static unsigned sgtable_nents(size_t bytes, u32 da, u32 pa) { - int i; - unsigned int nr_entries; - const unsigned long pagesize[] = { SZ_16M, SZ_1M, SZ_64K, SZ_4K, }; + unsigned nr_entries = 0, ent_sz; if (!IS_ALIGNED(bytes, PAGE_SIZE)) { pr_err("%s: wrong size %08x\n", __func__, bytes); return 0; } - nr_entries = 0; - for (i = 0; i < ARRAY_SIZE(pagesize); i++) { - if (bytes >= pagesize[i]) { - nr_entries += (bytes / pagesize[i]); - bytes %= pagesize[i]; - } + while (bytes) { + ent_sz = max_alignment(da | pa); + ent_sz = min_t(unsigned, ent_sz, iopgsz_max(bytes)); + nr_entries++; + da += ent_sz; + pa += ent_sz; + bytes -= ent_sz; } - BUG_ON(bytes); return nr_entries; } /* allocate and initialize sg_table header(a kind of 'superblock') */ -static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags) +static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags, + u32 da, u32 pa) { unsigned int nr_entries; int err; @@ -127,9 +135,8 @@ static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags) if (!IS_ALIGNED(bytes, PAGE_SIZE)) return ERR_PTR(-EINVAL); - /* FIXME: IOVMF_DA_FIXED should support 'superpages' */ - if ((flags & IOVMF_LINEAR) && (flags & IOVMF_DA_ANON)) { - nr_entries = sgtable_nents(bytes); + if (flags & IOVMF_LINEAR) { + nr_entries = sgtable_nents(bytes, da, pa); if (!nr_entries) return ERR_PTR(-EINVAL); } else @@ -409,7 +416,8 @@ static inline void sgtable_drain_vmalloc(struct sg_table *sgt) BUG_ON(!sgt); } -static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) +static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, u32 da, + size_t len) { unsigned int i; struct scatterlist *sg; @@ -418,9 +426,10 @@ static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) va = phys_to_virt(pa); for_each_sg(sgt->sgl, sg, sgt->nents, i) { - size_t bytes; + unsigned bytes; - bytes = iopgsz_max(len); + bytes = max_alignment(da | pa); + bytes = min_t(unsigned, bytes, iopgsz_max(len)); BUG_ON(!iopgsz_ok(bytes)); @@ -429,6 +438,7 @@ static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) * 'pa' is cotinuous(linear). */ pa += bytes; + da += bytes; len -= bytes; } BUG_ON(len); @@ -695,18 +705,18 @@ u32 iommu_vmalloc(struct iommu *obj, u32 da, size_t bytes, u32 flags) if (!va) return -ENOMEM; - sgt = sgtable_alloc(bytes, flags); + flags &= IOVMF_HW_MASK; + flags |= IOVMF_DISCONT; + flags |= IOVMF_ALLOC; + flags |= (da ? IOVMF_DA_FIXED : IOVMF_DA_ANON); + + sgt = sgtable_alloc(bytes, flags, da, 0); if (IS_ERR(sgt)) { da = PTR_ERR(sgt); goto err_sgt_alloc; } sgtable_fill_vmalloc(sgt, va); - flags &= IOVMF_HW_MASK; - flags |= IOVMF_DISCONT; - flags |= IOVMF_ALLOC; - flags |= (da ? IOVMF_DA_FIXED : IOVMF_DA_ANON); - da = __iommu_vmap(obj, da, sgt, va, bytes, flags); if (IS_ERR_VALUE(da)) goto err_iommu_vmap; @@ -746,11 +756,11 @@ static u32 __iommu_kmap(struct iommu *obj, u32 da, u32 pa, void *va, { struct sg_table *sgt; -
[PATCHv5 3/4] omap: iovmm - replace __iounmap with omap_iounmap
Omap platform is omap_iounmap function. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/iovmm.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 93a34d9..5489ca9 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -821,7 +821,7 @@ void iommu_kunmap(struct iommu *obj, u32 da) struct sg_table *sgt; typedef void (*func_t)(const void *); - sgt = unmap_vm_area(obj, da, (func_t)__iounmap, + sgt = unmap_vm_area(obj, da, (func_t)omap_iounmap, IOVMF_LINEAR | IOVMF_MMIO); if (!sgt) dev_dbg(obj->dev, "%s: No sgt\n", __func__); -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv5 4/4] omap: iommu - create new api to set valid da range
Some IOMMUs cannot use the whole 0x0 - 0x rage. With this new API the valid range can be set. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/include/plat/iommu.h |3 ++ arch/arm/plat-omap/iommu.c | 33 +++ arch/arm/plat-omap/iovmm.c | 18 ++-- 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h index 33c7d41..2ea8ea3 100644 --- a/arch/arm/plat-omap/include/plat/iommu.h +++ b/arch/arm/plat-omap/include/plat/iommu.h @@ -103,6 +103,8 @@ struct iommu_platform_data { const char *name; const char *clk_name; const int nr_tlb_entries; + u32 da_start; + u32 da_end; }; #if defined(CONFIG_ARCH_OMAP1) @@ -152,6 +154,7 @@ extern void flush_iotlb_all(struct iommu *obj); extern int iopgtable_store_entry(struct iommu *obj, struct iotlb_entry *e); extern size_t iopgtable_clear_entry(struct iommu *obj, u32 iova); +extern int iommu_set_da_range(struct iommu *obj, u32 start, u32 end); extern struct iommu *iommu_get(const char *name); extern void iommu_put(struct iommu *obj); diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index 6cd151b..b3846bd 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c @@ -25,6 +25,12 @@ #include "iopgtable.h" +/* Reserve the first page for NULL */ +#define IOMMU_DEFAULT_DA_START PAGE_SIZE +/* 0x not allowed because it is not page aligned */ +#define IOMMU_DEFAULT_DA_END 0xF000 + + #define for_each_iotlb_cr(obj, n, __i, cr) \ for (__i = 0; \ (__i < (n)) && (cr = __iotlb_read_cr((obj), __i), true); \ @@ -830,6 +836,31 @@ static int device_match_by_alias(struct device *dev, void *data) } /** + * iommu_set_da_range - Set a valid device address range + * @obj: target iommu + * @start Start of valid range + * @endEnd of valid range + **/ +int iommu_set_da_range(struct iommu *obj, u32 start, u32 end) +{ + struct iommu_platform_data *pdata; + + if (!obj) + return -EFAULT; + + if (end < start || !PAGE_ALIGN(start | end)) + return -EINVAL; + + pdata = obj->dev->platform_data; + + pdata->da_start = start; + pdata->da_end = end; + + return 0; +} +EXPORT_SYMBOL_GPL(iommu_set_da_range); + +/** * iommu_get - Get iommu handler * @name: target iommu name **/ @@ -853,6 +884,8 @@ struct iommu *iommu_get(const char *name) if (err) goto err_enable; flush_iotlb_all(obj); + iommu_set_da_range(obj, IOMMU_DEFAULT_DA_START, + IOMMU_DEFAULT_DA_END); } if (!try_module_get(obj->owner)) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 5489ca9..3809add 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -272,21 +272,25 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, { struct iovm_struct *new, *tmp; u32 start, prev_end, alignement; + struct iommu_platform_data *pdata; if (!obj || !bytes) return ERR_PTR(-EINVAL); + pdata = obj->dev->platform_data; + start = da; alignement = PAGE_SIZE; if (flags & IOVMF_DA_ANON) { - /* -* Reserve the first page for NULL -*/ - start = PAGE_SIZE; + start = pdata->da_start; + if (flags & IOVMF_LINEAR) alignement = iopgsz_max(bytes); start = roundup(start, alignement); + } else if (start < pdata->da_start || start > pdata->da_end || + pdata->da_end - start < bytes) { + return ERR_PTR(-EINVAL); } tmp = NULL; @@ -299,16 +303,16 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, if (prev_end > start) break; - if (start + bytes <= tmp->da_start) + if (tmp->da_start > start && (tmp->da_start - start) >= bytes) goto found; - if (flags & IOVMF_DA_ANON) + if (tmp->da_end >= start && flags & IOVMF_DA_ANON) start = roundup(tmp->da_end + 1, alignement); prev_end = tmp->da_end; } - if ((start >= prev_end) && (ULONG_MAX - start + 1 >= bytes)) + if ((start >= prev_end) && (pdata->da_end - start >= bytes)) goto found;
[PATCHv5 1/4] omap: iovmm - no gap checking for fixed address
If some fixed da address is wanted to be mapped and the page is freed but it is used as gap, the mapping will fail. This patch is fixing that and olny keeps the gap for not fixed address. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/iovmm.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 24ca9c4..34f0012 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -289,7 +289,7 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, prev_end = 0; list_for_each_entry(tmp, &obj->mmap, list) { - if (prev_end >= start) + if (prev_end > start) break; if (start + bytes <= tmp->da_start) @@ -301,7 +301,7 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, prev_end = tmp->da_end; } - if ((start > prev_end) && (ULONG_MAX - start >= bytes)) + if ((start >= prev_end) && (ULONG_MAX - start + 1 >= bytes)) goto found; dev_dbg(obj->dev, "%s: no space to fit %08x(%x) flags: %08x\n", -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 7/8] staging: tidspbridge - fix some issues after iommu patches
This patch fixes: * In delete_node() we need to check for udsp_heap_addr in order to unmap the head instead of udsp_heap_res_addr which used to be the reserved memory a not valid anymore. * Fix in get_io_pages() as pointed by Felipe Contreras in this mail: http://marc.info/?l=linux-kernel&m=128735502205183&w=2 Signed-off-by: Fernando Guzman Lugo --- drivers/staging/tidspbridge/core/dsp-mmu.c |2 +- drivers/staging/tidspbridge/rmgr/node.c|2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/tidspbridge/core/dsp-mmu.c b/drivers/staging/tidspbridge/core/dsp-mmu.c index 3a00087..54f3ba4 100644 --- a/drivers/staging/tidspbridge/core/dsp-mmu.c +++ b/drivers/staging/tidspbridge/core/dsp-mmu.c @@ -196,7 +196,7 @@ static int get_io_pages(struct mm_struct *mm, u32 uva, unsigned pages, int i; struct page *pg; - for (i = 0; i < pages; i++) { + for (i = 0; i < pages; i++, uva += PAGE_SIZE) { pa = user_va2_pa(mm, uva); if (!pfn_valid(__phys_to_pfn(pa))) diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c index 3f5abcf..f7fe6c0 100644 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ b/drivers/staging/tidspbridge/rmgr/node.c @@ -2541,7 +2541,7 @@ static void delete_node(struct node_object *hnode, kfree(task_arg_obj.strm_out_def); task_arg_obj.strm_out_def = NULL; } - if (task_arg_obj.udsp_heap_res_addr) { + if (task_arg_obj.udsp_heap_addr) { status = proc_un_map(hnode->hprocessor, (void *) task_arg_obj.udsp_heap_addr, pr_ctxt); -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/8] staging: tidspbridge - misc fixes
This set of patches fix some issues found in lastest tree. Fernando Guzman Lugo (8): staging: tidspbridge - remove req_addr from proc_map staging: tidspbridge - add kconfig parameter for DMM size staging: tidspbridge - change mmufault tasklet to a workqueue staging: tidspbridge - fix timeout in dsp_gpt_wait_overflow staging: tidspbridge - use GTP7 for DSP stack dump staging: tidspbridge - remove disabling twl when printing DSP stack staging: tidspbridge - fix some issues after iommu patches staging: tidspbridge - make sync_wait_on_event interruptible drivers/staging/tidspbridge/Kconfig|8 +++ drivers/staging/tidspbridge/core/dsp-clock.c | 13 +++-- drivers/staging/tidspbridge/core/dsp-mmu.c | 55 +++- drivers/staging/tidspbridge/core/tiomap3430.c | 20 ++- .../staging/tidspbridge/include/dspbridge/clk.h|4 +- .../tidspbridge/include/dspbridge/dsp-mmu.h|3 + .../tidspbridge/include/dspbridge/dspapi-ioctl.h |1 - .../staging/tidspbridge/include/dspbridge/proc.h |3 - .../staging/tidspbridge/include/dspbridge/sync.h | 13 - drivers/staging/tidspbridge/pmgr/dspapi.c |2 +- drivers/staging/tidspbridge/rmgr/node.c|4 +- drivers/staging/tidspbridge/rmgr/proc.c| 25 - 12 files changed, 95 insertions(+), 56 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/8] staging: tidspbridge - fix timeout in dsp_gpt_wait_overflow
Timeout was not being initialized correctly and should use time_is-before_jiffies, also make it a parameter Signed-off-by: Fernando Guzman Lugo --- drivers/staging/tidspbridge/core/dsp-clock.c | 13 +++-- drivers/staging/tidspbridge/core/dsp-mmu.c |5 - .../staging/tidspbridge/include/dspbridge/clk.h|4 +++- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/staging/tidspbridge/core/dsp-clock.c b/drivers/staging/tidspbridge/core/dsp-clock.c index 46d17c7..8106d1e 100644 --- a/drivers/staging/tidspbridge/core/dsp-clock.c +++ b/drivers/staging/tidspbridge/core/dsp-clock.c @@ -202,13 +202,13 @@ static void mcbsp_clk_prepare(bool flag, u8 id) * Sets an overflow interrupt for the desired GPT waiting for a timeout * of 5 msecs for the interrupt to occur. */ -void dsp_gpt_wait_overflow(short int clk_id, unsigned int load) +int dsp_gpt_wait_overflow(short int clk_id, unsigned int load, + unsigned long timeout) { struct omap_dm_timer *gpt = timer[clk_id - 1]; - unsigned long timeout; if (!gpt) - return; + return -EINVAL; /* Enable overflow interrupt */ omap_dm_timer_set_int_enable(gpt, OMAP_TIMER_INT_OVERFLOW); @@ -222,14 +222,15 @@ void dsp_gpt_wait_overflow(short int clk_id, unsigned int load) /* Wait 80us for timer to overflow */ udelay(80); - timeout = msecs_to_jiffies(5); + timeout = jiffies + msecs_to_jiffies(timeout); /* Check interrupt status and wait for interrupt */ while (!(omap_dm_timer_read_status(gpt) & OMAP_TIMER_INT_OVERFLOW)) { - if (time_is_after_jiffies(timeout)) { + if (time_is_before_jiffies(timeout)) { pr_err("%s: GPTimer interrupt failed\n", __func__); - break; + return -ETIME; } } + return 0; } /* diff --git a/drivers/staging/tidspbridge/core/dsp-mmu.c b/drivers/staging/tidspbridge/core/dsp-mmu.c index 6d7501a..2d4e897 100644 --- a/drivers/staging/tidspbridge/core/dsp-mmu.c +++ b/drivers/staging/tidspbridge/core/dsp-mmu.c @@ -65,7 +65,10 @@ static void mmu_fault_print_stack(struct bridge_dev_context *dev_context) dsp_clk_enable(DSP_CLK_GPT8); - dsp_gpt_wait_overflow(DSP_CLK_GPT8, 0xfffe); + if (dsp_gpt_wait_overflow(DSP_CLK_GPT8, 0xfffe, 10)) { + pr_err("%s: error sending interrupt to DSP\n", __func__); + return; + } /* Clear MMU interrupt */ tmp = iommu_read_reg(mmu, MMU_IRQSTATUS); diff --git a/drivers/staging/tidspbridge/include/dspbridge/clk.h b/drivers/staging/tidspbridge/include/dspbridge/clk.h index b239503..6fe1ff2 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/clk.h +++ b/drivers/staging/tidspbridge/include/dspbridge/clk.h @@ -62,7 +62,9 @@ extern void dsp_clk_exit(void); */ extern void dsp_clk_init(void); -void dsp_gpt_wait_overflow(short int clk_id, unsigned int load); +int dsp_gpt_wait_overflow(short int clk_id, unsigned int load, + unsigned long timeout); + /* * dsp_clk_enable -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/8] staging: tidspbridge - remove disabling twl when printing DSP stack
Now the SHM segments are not in lock tlbs, instead they are in translation tables. So we cannot disable twl in order to get the DSP stack dump. Signed-off-by: Fernando Guzman Lugo --- drivers/staging/tidspbridge/core/dsp-mmu.c |8 1 files changed, 0 insertions(+), 8 deletions(-) diff --git a/drivers/staging/tidspbridge/core/dsp-mmu.c b/drivers/staging/tidspbridge/core/dsp-mmu.c index 157b743..3a00087 100644 --- a/drivers/staging/tidspbridge/core/dsp-mmu.c +++ b/drivers/staging/tidspbridge/core/dsp-mmu.c @@ -43,14 +43,6 @@ static void mmu_fault_print_stack(struct bridge_dev_context *dev_context) if (!dummy_addr) return; - /* -* Before acking the MMU fault, let's make sure MMU can only -* access entry #0. Then add a new entry so that the DSP OS -* can continue in order to dump the stack. -*/ - tmp = iommu_read_reg(mmu, MMU_CNTL); - tmp &= ~MMU_CNTL_TWL_EN; - iommu_write_reg(mmu, tmp, MMU_CNTL); fa = iommu_read_reg(mmu, MMU_FAULT_AD); e.da = fa & PAGE_MASK; e.pa = virt_to_phys(dummy_addr); -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/8] staging: tidspbridge - change mmufault tasklet to a workqueue
We don't need to manage the mmufault inside a tasklet it is safer using a workqueue. Signed-off-by: Fernando Guzman Lugo --- drivers/staging/tidspbridge/core/dsp-mmu.c | 34 ++-- 1 files changed, 22 insertions(+), 12 deletions(-) diff --git a/drivers/staging/tidspbridge/core/dsp-mmu.c b/drivers/staging/tidspbridge/core/dsp-mmu.c index 983c95a..6d7501a 100644 --- a/drivers/staging/tidspbridge/core/dsp-mmu.c +++ b/drivers/staging/tidspbridge/core/dsp-mmu.c @@ -28,7 +28,8 @@ #define MMU_CNTL_TWL_EN(1 << 2) -static struct tasklet_struct mmu_tasklet; +static struct workqueue_struct *mmu_wq; +static struct work_struct fault_work; #ifdef CONFIG_TIDSPBRIDGE_BACKTRACE static void mmu_fault_print_stack(struct bridge_dev_context *dev_context) @@ -37,7 +38,10 @@ static void mmu_fault_print_stack(struct bridge_dev_context *dev_context) u32 fa, tmp; struct iotlb_entry e; struct iommu *mmu = dev_context->dsp_mmu; - dummy_addr = (void *)__get_free_page(GFP_ATOMIC); + + dummy_addr = (void *)__get_free_page(GFP_KERNEL); + if (!dummy_addr) + return; /* * Before acking the MMU fault, let's make sure MMU can only @@ -76,19 +80,19 @@ static void mmu_fault_print_stack(struct bridge_dev_context *dev_context) #endif -static void fault_tasklet(unsigned long data) +static void mmu_fault_work(struct work_struct *work) { - struct iommu *mmu = (struct iommu *)data; struct bridge_dev_context *dev_ctx; struct deh_mgr *dm; u32 fa; + dev_get_deh_mgr(dev_get_first(), &dm); dev_get_bridge_context(dev_get_first(), &dev_ctx); if (!dm || !dev_ctx) return; - fa = iommu_read_reg(mmu, MMU_FAULT_AD); + fa = iommu_read_reg(dev_ctx->dsp_mmu, MMU_FAULT_AD); #ifdef CONFIG_TIDSPBRIDGE_BACKTRACE print_dsp_trace_buffer(dev_ctx); @@ -109,7 +113,8 @@ static int mmu_fault_callback(struct iommu *mmu) return -EPERM; iommu_write_reg(mmu, 0, MMU_IRQENABLE); - tasklet_schedule(&mmu_tasklet); + queue_work(mmu_wq, &fault_work); + return 0; } @@ -126,10 +131,16 @@ struct iommu *dsp_mmu_init() mmu = iommu_get("iva2"); - if (!IS_ERR(mmu)) { - tasklet_init(&mmu_tasklet, fault_tasklet, (unsigned long)mmu); - mmu->isr = mmu_fault_callback; + if (IS_ERR(mmu)) + return mmu; + + mmu->isr = mmu_fault_callback; + mmu_wq = create_workqueue("dsp-mmu_wq"); + if (!mmu_wq) { + iommu_put(mmu); + return ERR_PTR(-ENOMEM); } + INIT_WORK(&fault_work, mmu_fault_work); return mmu; } @@ -143,9 +154,8 @@ struct iommu *dsp_mmu_init() */ void dsp_mmu_exit(struct iommu *mmu) { - if (mmu) - iommu_put(mmu); - tasklet_kill(&mmu_tasklet); + iommu_put(mmu); + destroy_workqueue(mmu_wq); } /** -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/8] staging: tidspbridge - use GTP7 for DSP stack dump
DSP stack dump is changed to GTP7 due to GPT8 is used by DSP side apps Signed-off-by: Fernando Guzman Lugo --- drivers/staging/tidspbridge/core/dsp-mmu.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/tidspbridge/core/dsp-mmu.c b/drivers/staging/tidspbridge/core/dsp-mmu.c index 2d4e897..157b743 100644 --- a/drivers/staging/tidspbridge/core/dsp-mmu.c +++ b/drivers/staging/tidspbridge/core/dsp-mmu.c @@ -63,9 +63,9 @@ static void mmu_fault_print_stack(struct bridge_dev_context *dev_context) load_iotlb_entry(mmu, &e); - dsp_clk_enable(DSP_CLK_GPT8); + dsp_clk_enable(DSP_CLK_GPT7); - if (dsp_gpt_wait_overflow(DSP_CLK_GPT8, 0xfffe, 10)) { + if (dsp_gpt_wait_overflow(DSP_CLK_GPT7, 0xfffe, 10)) { pr_err("%s: error sending interrupt to DSP\n", __func__); return; } @@ -75,7 +75,7 @@ static void mmu_fault_print_stack(struct bridge_dev_context *dev_context) iommu_write_reg(mmu, tmp, MMU_IRQSTATUS); dump_dsp_stack(dev_context); - dsp_clk_disable(DSP_CLK_GPT8); + dsp_clk_disable(DSP_CLK_GPT7); iopgtable_clear_entry(mmu, fa); free_page((unsigned long)dummy_addr); -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/8] staging: tidspbridge - remove req_addr from proc_map
The device address is assigned by tidspbridge no need for that parameter anymore. Signed-off-by: Fernando Guzman Lugo --- .../tidspbridge/include/dspbridge/dspapi-ioctl.h |1 - .../staging/tidspbridge/include/dspbridge/proc.h |3 -- drivers/staging/tidspbridge/pmgr/dspapi.c |2 +- drivers/staging/tidspbridge/rmgr/node.c|2 +- drivers/staging/tidspbridge/rmgr/proc.c| 25 +-- 5 files changed, 14 insertions(+), 19 deletions(-) diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h b/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h index 8da5bd8..db06468 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h @@ -138,7 +138,6 @@ union trapped_args { void *hprocessor; void *pmpu_addr; u32 ul_size; - void *req_addr; void *__user *pp_map_addr; u32 ul_map_attr; } args_proc_mapmem; diff --git a/drivers/staging/tidspbridge/include/dspbridge/proc.h b/drivers/staging/tidspbridge/include/dspbridge/proc.h index 2d12aab..74344bd 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/proc.h +++ b/drivers/staging/tidspbridge/include/dspbridge/proc.h @@ -524,8 +524,6 @@ extern int proc_invalidate_memory(void *hprocessor, * hprocessor : The processor handle. * pmpu_addr : Starting address of the memory region to map. * ul_size : Size of the memory region to map. - * req_addr : Requested DSP start address. Offset-adjusted actual - * mapped address is in the last argument. * pp_map_addr : Ptr to DSP side mapped u8 address. * ul_map_attr : Optional endianness attributes, virt to phys flag. * Returns: @@ -546,7 +544,6 @@ extern int proc_invalidate_memory(void *hprocessor, extern int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size, - void *req_addr, void **pp_map_addr, u32 ul_map_attr, struct process_context *pr_ctxt); diff --git a/drivers/staging/tidspbridge/pmgr/dspapi.c b/drivers/staging/tidspbridge/pmgr/dspapi.c index 0187c47..d1e1185 100644 --- a/drivers/staging/tidspbridge/pmgr/dspapi.c +++ b/drivers/staging/tidspbridge/pmgr/dspapi.c @@ -952,7 +952,7 @@ u32 procwrap_map(union trapped_args *args, void *pr_ctxt) status = proc_map(args->args_proc_mapmem.hprocessor, args->args_proc_mapmem.pmpu_addr, args->args_proc_mapmem.ul_size, - args->args_proc_mapmem.req_addr, &map_addr, + &map_addr, args->args_proc_mapmem.ul_map_attr, pr_ctxt); if (!status) { if (put_user(map_addr, args->args_proc_mapmem.pp_map_addr)) { diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c index a660247..3f5abcf 100644 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ b/drivers/staging/tidspbridge/rmgr/node.c @@ -430,7 +430,7 @@ int node_allocate(struct proc_object *hprocessor, map_attrs |= DSP_MAPVIRTUALADDR; status = proc_map(hprocessor, (void *)attr_in->pgpp_virt_addr, pnode->create_args.asa.task_arg_obj.heap_size, - NULL, (void **)&mapped_addr, map_attrs, + (void **)&mapped_addr, map_attrs, pr_ctxt); if (status) pr_err("%s: Failed to map memory for Heap: 0x%x\n", diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c index 7a15a02..5e5eb75 100644 --- a/drivers/staging/tidspbridge/rmgr/proc.c +++ b/drivers/staging/tidspbridge/rmgr/proc.c @@ -1314,10 +1314,10 @@ func_end: * Maps a MPU buffer to DSP address space. */ int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size, - void *req_addr, void **pp_map_addr, u32 ul_map_attr, + void **pp_map_addr, u32 ul_map_attr, struct process_context *pr_ctxt) { - u32 va_align; + u32 da; u32 pa_align; u32 size_align; int status = 0; @@ -1336,7 +1336,6 @@ int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size, #endif /* Calculate the page-aligned PA, VA and size */ - va_align = PG_ALIGN_LOW((u32) req_addr, PG_SIZE4K); pa_align = PG_ALIGN_LOW((u32) pmpu_addr, PG_SIZE4K); size_align = PG_ALIGN_HIGH(ul_size + (u32) pmpu_addr - pa_align, PG_SIZE4K); @@ -1351,26 +1350,26 @@ int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size, /* Add
[PATCH 2/8] staging: tidspbridge - add kconfig parameter for DMM size
A new kconfig parameter for DMM size is added. Also DMM is allocated after the end of SHM area. So that the checks on DSP are still valid and we avoid using areas between SHM which are not mapped reducing the probability of shared memory corruption. NOTE: This patch has a dependency on this patch: "omap: iommu - create new api to set valid da range" Signed-off-by: Fernando Guzman Lugo --- drivers/staging/tidspbridge/Kconfig|8 drivers/staging/tidspbridge/core/tiomap3430.c | 20 ++-- .../tidspbridge/include/dspbridge/dsp-mmu.h|3 +++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/drivers/staging/tidspbridge/Kconfig b/drivers/staging/tidspbridge/Kconfig index 672008f..37e47f5 100644 --- a/drivers/staging/tidspbridge/Kconfig +++ b/drivers/staging/tidspbridge/Kconfig @@ -42,6 +42,14 @@ config TIDSPBRIDGE_MEMPOOL_SIZE Allocate specified size of memory at booting time to avoid allocation failure under heavy memory fragmentation after some use time. +config TIDSPBRIDGE_DMM_SIZE + hex "DMM capable memory size (Byte)" + depends on TIDSPBRIDGE + default "0x1000" + help + Memory size of DSP virtual address for Dynamic Memory Mapping. + Please make sure the size is 4K aligned. + config TIDSPBRIDGE_DEBUG bool "Debug Support" depends on TIDSPBRIDGE diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index c28dcf1..88c8c71 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -345,7 +345,6 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, OMAP343X_CONTROL_IVA2_BOOTMOD)); } } - if (!status) { (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK, 0, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); @@ -362,6 +361,11 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, if (!status) { dev_context->dsp_mmu = mmu; sm_sg = &dev_context->sh_s; + /* Set valid range to map shared memory */ + status = iommu_set_da_range(mmu, sm_sg->seg0_da, + sm_sg->seg1_da + sm_sg->seg1_size); + } + if (!status) { sg0_da = iommu_kmap(mmu, sm_sg->seg0_da, sm_sg->seg0_pa, sm_sg->seg0_size, IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32); if (IS_ERR_VALUE(sg0_da)) { @@ -411,7 +415,19 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, l4_i++; } } - + if (!status) { + /* Set valid range for DMM mappings */ + if (MAX_DSP_MMU_DA - CONFIG_TIDSPBRIDGE_DMM_SIZE < + sm_sg->seg1_da + sm_sg->seg1_size) { + dev_err(bridge, "DMM size too big!\n"); + status = -ENOMEM; + } else { + status = iommu_set_da_range(mmu, + sm_sg->seg1_da + sm_sg->seg1_size, + sm_sg->seg1_da + sm_sg->seg1_size + + CONFIG_TIDSPBRIDGE_DMM_SIZE); + } + } /* Lock the above TLB entries and get the BIOS and load monitor timer * information */ if (!status) { diff --git a/drivers/staging/tidspbridge/include/dspbridge/dsp-mmu.h b/drivers/staging/tidspbridge/include/dspbridge/dsp-mmu.h index cb38d4c..bbbe9e6 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dsp-mmu.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dsp-mmu.h @@ -22,6 +22,9 @@ #include #include +/* Last patch is not mapped to detect buffer overflow in DSP side */ +#define MAX_DSP_MMU_DA 0xF000 + /** * dsp_mmu_init() - initialize dsp_mmu module and returns a handle * -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 8/8] staging: tidspbridge - make sync_wait_on_event interruptible
So that avoid non-killable process. Signed-off-by: Fernando Guzman Lugo --- .../staging/tidspbridge/include/dspbridge/sync.h | 13 +++-- 1 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/staging/tidspbridge/include/dspbridge/sync.h b/drivers/staging/tidspbridge/include/dspbridge/sync.h index e2651e7..df05b8f 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/sync.h +++ b/drivers/staging/tidspbridge/include/dspbridge/sync.h @@ -80,13 +80,22 @@ void sync_set_event(struct sync_object *event); * This functios will wait until @event is set or until timeout. In case of * success the function will return 0 and * in case of timeout the function will return -ETIME + * in case of signal the function will return -ERESTARTSYS */ static inline int sync_wait_on_event(struct sync_object *event, unsigned timeout) { - return wait_for_completion_timeout(&event->comp, - msecs_to_jiffies(timeout)) ? 0 : -ETIME; + int res; + + res = wait_for_completion_interruptible_timeout(&event->comp, + msecs_to_jiffies(timeout)); + if (!res) + res = -ETIME; + else if (res > 0) + res = 0; + + return res; } /** -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/4] omap: iovmm - fixes for iovmm module
Version 6: * Rebase on Russell King branch. - for details see: http://marc.info/?l=linux-omap&m=129228495723001&w=2 Version 5: * Changes in "iommu: create new api to set valid da range" - Change range variables to platform data structure. Version 4: * Changes in "iommu: create new api to set valid da range" - Validate range for fixed address. - Change way of change boundaries to avoid possible overflow instead of style : start + bytes >= end which start + end can overflow use style: end - start < bytes Version 3: * change patch 2 base on Felipe Contreras' comments, now it uses min_t and I deleted some blank lines. * patch "create new api to set valid da range" is base on "iovmm: IVA2 MMU range is from 0x1100 to 0x" patch and on Hiroshi's comments and now it is added to this set. Version 2: * Removed "iovmm: fixes for iovmm module" that patch was already sent. * Modified "iovmm: fix roundup for next area and end check for the last area" patch, base on Davin Cohen's comments and rename it to a proper name that describes what it is doing now. Guzman Lugo, Fernando (4): omap: iovmm - no gap checking for fixed address omap: iovmm - add superpages support to fixed da address omap: iovmm - replace __iounmap with iounmap omap: iommu - create new api to set valid da range arch/arm/plat-omap/include/plat/iommu.h |3 + arch/arm/plat-omap/iommu.c | 33 arch/arm/plat-omap/iovmm.c | 84 ++- 3 files changed, 85 insertions(+), 35 deletions(-) -- 1.7.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv6 1/4] omap: iovmm - no gap checking for fixed address
From: Guzman Lugo, Fernando If some fixed da address is wanted to be mapped and the page is freed but it is used as gap, the mapping will fail. This patch is fixing that and olny keeps the gap for not fixed address. Signed-off-by: Fernando Guzman Lugo Acked-by: Hiroshi DOYU --- arch/arm/plat-omap/iovmm.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 8ce0de2..34f0012 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -289,10 +289,10 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, prev_end = 0; list_for_each_entry(tmp, &obj->mmap, list) { - if (prev_end >= start) + if (prev_end > start) break; - if (start + bytes < tmp->da_start) + if (start + bytes <= tmp->da_start) goto found; if (flags & IOVMF_DA_ANON) @@ -301,7 +301,7 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, prev_end = tmp->da_end; } - if ((start > prev_end) && (ULONG_MAX - start >= bytes)) + if ((start >= prev_end) && (ULONG_MAX - start + 1 >= bytes)) goto found; dev_dbg(obj->dev, "%s: no space to fit %08x(%x) flags: %08x\n", -- 1.7.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv6 2/4] omap: iovmm - add superpages support to fixed da address
From: Guzman Lugo, Fernando This patch adds superpages support to fixed ad address inside iommu_kmap function. Signed-off-by: Fernando Guzman Lugo Acked-by: Hiroshi DOYU --- arch/arm/plat-omap/iovmm.c | 62 +-- 1 files changed, 36 insertions(+), 26 deletions(-) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 34f0012..93a34d9 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -87,35 +87,43 @@ static size_t sgtable_len(const struct sg_table *sgt) } #define sgtable_ok(x) (!!sgtable_len(x)) +static unsigned max_alignment(u32 addr) +{ + int i; + unsigned pagesize[] = { SZ_16M, SZ_1M, SZ_64K, SZ_4K, }; + for (i = 0; i < ARRAY_SIZE(pagesize) && addr & (pagesize[i] - 1); i++) + ; + return (i < ARRAY_SIZE(pagesize)) ? pagesize[i] : 0; +} + /* * calculate the optimal number sg elements from total bytes based on * iommu superpages */ -static unsigned int sgtable_nents(size_t bytes) +static unsigned sgtable_nents(size_t bytes, u32 da, u32 pa) { - int i; - unsigned int nr_entries; - const unsigned long pagesize[] = { SZ_16M, SZ_1M, SZ_64K, SZ_4K, }; + unsigned nr_entries = 0, ent_sz; if (!IS_ALIGNED(bytes, PAGE_SIZE)) { pr_err("%s: wrong size %08x\n", __func__, bytes); return 0; } - nr_entries = 0; - for (i = 0; i < ARRAY_SIZE(pagesize); i++) { - if (bytes >= pagesize[i]) { - nr_entries += (bytes / pagesize[i]); - bytes %= pagesize[i]; - } + while (bytes) { + ent_sz = max_alignment(da | pa); + ent_sz = min_t(unsigned, ent_sz, iopgsz_max(bytes)); + nr_entries++; + da += ent_sz; + pa += ent_sz; + bytes -= ent_sz; } - BUG_ON(bytes); return nr_entries; } /* allocate and initialize sg_table header(a kind of 'superblock') */ -static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags) +static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags, + u32 da, u32 pa) { unsigned int nr_entries; int err; @@ -127,9 +135,8 @@ static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags) if (!IS_ALIGNED(bytes, PAGE_SIZE)) return ERR_PTR(-EINVAL); - /* FIXME: IOVMF_DA_FIXED should support 'superpages' */ - if ((flags & IOVMF_LINEAR) && (flags & IOVMF_DA_ANON)) { - nr_entries = sgtable_nents(bytes); + if (flags & IOVMF_LINEAR) { + nr_entries = sgtable_nents(bytes, da, pa); if (!nr_entries) return ERR_PTR(-EINVAL); } else @@ -409,7 +416,8 @@ static inline void sgtable_drain_vmalloc(struct sg_table *sgt) BUG_ON(!sgt); } -static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) +static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, u32 da, + size_t len) { unsigned int i; struct scatterlist *sg; @@ -418,9 +426,10 @@ static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) va = phys_to_virt(pa); for_each_sg(sgt->sgl, sg, sgt->nents, i) { - size_t bytes; + unsigned bytes; - bytes = iopgsz_max(len); + bytes = max_alignment(da | pa); + bytes = min_t(unsigned, bytes, iopgsz_max(len)); BUG_ON(!iopgsz_ok(bytes)); @@ -429,6 +438,7 @@ static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) * 'pa' is cotinuous(linear). */ pa += bytes; + da += bytes; len -= bytes; } BUG_ON(len); @@ -695,18 +705,18 @@ u32 iommu_vmalloc(struct iommu *obj, u32 da, size_t bytes, u32 flags) if (!va) return -ENOMEM; - sgt = sgtable_alloc(bytes, flags); + flags &= IOVMF_HW_MASK; + flags |= IOVMF_DISCONT; + flags |= IOVMF_ALLOC; + flags |= (da ? IOVMF_DA_FIXED : IOVMF_DA_ANON); + + sgt = sgtable_alloc(bytes, flags, da, 0); if (IS_ERR(sgt)) { da = PTR_ERR(sgt); goto err_sgt_alloc; } sgtable_fill_vmalloc(sgt, va); - flags &= IOVMF_HW_MASK; - flags |= IOVMF_DISCONT; - flags |= IOVMF_ALLOC; - flags |= (da ? IOVMF_DA_FIXED : IOVMF_DA_ANON); - da = __iommu_vmap(obj, da, sgt, va, bytes, flags); if (IS_ERR_VALUE(da)) goto err_iommu_vmap; @@ -746,11 +756,11 @@ static u32 __iommu_kmap(struct iommu *obj, u32 da, u32 pa, v
[PATCHv6 3/4] omap: iovmm - replace __iounmap with iounmap
From: Guzman Lugo, Fernando __iounmap function is wrong for OMAP architecture, instead use iounmap which will call to the correct function. Signed-off-by: Fernando Guzman Lugo Acked-by: Hiroshi DOYU --- arch/arm/plat-omap/iovmm.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 93a34d9..fa6e643 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -821,7 +821,7 @@ void iommu_kunmap(struct iommu *obj, u32 da) struct sg_table *sgt; typedef void (*func_t)(const void *); - sgt = unmap_vm_area(obj, da, (func_t)__iounmap, + sgt = unmap_vm_area(obj, da, (func_t)iounmap, IOVMF_LINEAR | IOVMF_MMIO); if (!sgt) dev_dbg(obj->dev, "%s: No sgt\n", __func__); -- 1.7.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv6 4/4] omap: iommu - create new api to set valid da range
From: Guzman Lugo, Fernando Some IOMMUs cannot use the whole 0x0 - 0x rage. With this new API the valid range can be set. Signed-off-by: Fernando Guzman Lugo Acked-by: Hiroshi DOYU --- arch/arm/plat-omap/include/plat/iommu.h |3 ++ arch/arm/plat-omap/iommu.c | 33 +++ arch/arm/plat-omap/iovmm.c | 18 ++-- 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h index 33c7d41..2ea8ea3 100644 --- a/arch/arm/plat-omap/include/plat/iommu.h +++ b/arch/arm/plat-omap/include/plat/iommu.h @@ -103,6 +103,8 @@ struct iommu_platform_data { const char *name; const char *clk_name; const int nr_tlb_entries; + u32 da_start; + u32 da_end; }; #if defined(CONFIG_ARCH_OMAP1) @@ -152,6 +154,7 @@ extern void flush_iotlb_all(struct iommu *obj); extern int iopgtable_store_entry(struct iommu *obj, struct iotlb_entry *e); extern size_t iopgtable_clear_entry(struct iommu *obj, u32 iova); +extern int iommu_set_da_range(struct iommu *obj, u32 start, u32 end); extern struct iommu *iommu_get(const char *name); extern void iommu_put(struct iommu *obj); diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index 6cd151b..b3846bd 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c @@ -25,6 +25,12 @@ #include "iopgtable.h" +/* Reserve the first page for NULL */ +#define IOMMU_DEFAULT_DA_START PAGE_SIZE +/* 0x not allowed because it is not page aligned */ +#define IOMMU_DEFAULT_DA_END 0xF000 + + #define for_each_iotlb_cr(obj, n, __i, cr) \ for (__i = 0; \ (__i < (n)) && (cr = __iotlb_read_cr((obj), __i), true); \ @@ -830,6 +836,31 @@ static int device_match_by_alias(struct device *dev, void *data) } /** + * iommu_set_da_range - Set a valid device address range + * @obj: target iommu + * @start Start of valid range + * @endEnd of valid range + **/ +int iommu_set_da_range(struct iommu *obj, u32 start, u32 end) +{ + struct iommu_platform_data *pdata; + + if (!obj) + return -EFAULT; + + if (end < start || !PAGE_ALIGN(start | end)) + return -EINVAL; + + pdata = obj->dev->platform_data; + + pdata->da_start = start; + pdata->da_end = end; + + return 0; +} +EXPORT_SYMBOL_GPL(iommu_set_da_range); + +/** * iommu_get - Get iommu handler * @name: target iommu name **/ @@ -853,6 +884,8 @@ struct iommu *iommu_get(const char *name) if (err) goto err_enable; flush_iotlb_all(obj); + iommu_set_da_range(obj, IOMMU_DEFAULT_DA_START, + IOMMU_DEFAULT_DA_END); } if (!try_module_get(obj->owner)) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index fa6e643..ee3ca20 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -272,21 +272,25 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, { struct iovm_struct *new, *tmp; u32 start, prev_end, alignement; + struct iommu_platform_data *pdata; if (!obj || !bytes) return ERR_PTR(-EINVAL); + pdata = obj->dev->platform_data; + start = da; alignement = PAGE_SIZE; if (flags & IOVMF_DA_ANON) { - /* -* Reserve the first page for NULL -*/ - start = PAGE_SIZE; + start = pdata->da_start; + if (flags & IOVMF_LINEAR) alignement = iopgsz_max(bytes); start = roundup(start, alignement); + } else if (start < pdata->da_start || start > pdata->da_end || + pdata->da_end - start < bytes) { + return ERR_PTR(-EINVAL); } tmp = NULL; @@ -299,16 +303,16 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, if (prev_end > start) break; - if (start + bytes <= tmp->da_start) + if (tmp->da_start > start && (tmp->da_start - start) >= bytes) goto found; - if (flags & IOVMF_DA_ANON) + if (tmp->da_end >= start && flags & IOVMF_DA_ANON) start = roundup(tmp->da_end + 1, alignement); prev_end = tmp->da_end; } - if ((start >= prev_end) && (ULONG_MAX - start + 1 >= bytes)) + if ((start >= prev_end) && (pdata->da_e
[PATCHv7 0/4] omap: iovmm - fixes for iovmm module
Misc fixes found while working with iovmm module. They are needed in order to tidspbridge can work properly along with iovmm module. Version 7: * Change 4/4 patch base on Felipe Contreras comments about having start/end in platform data and struct iommu. Version 6: * Rebase on Russell King branch. - for details see: http://marc.info/?l=linux-omap&m=129228495723001&w=2 Version 5: * Changes in "iommu: create new api to set valid da range" - Change range variables to platform data structure. Version 4: * Changes in "iommu: create new api to set valid da range" - Validate range for fixed address. - Change way of change boundaries to avoid possible overflow instead of style : start + bytes >= end which start + end can overflow use style: end - start < bytes Version 3: * change patch 2 base on Felipe Contreras' comments, now it uses min_t and I deleted some blank lines. * patch "create new api to set valid da range" is base on "iovmm: IVA2 MMU range is from 0x1100 to 0x" patch and on Hiroshi's comments and now it is added to this set. Version 2: * Removed "iovmm: fixes for iovmm module" that patch was already sent. * Modified "iovmm: fix roundup for next area and end check for the last area" patch, base on Davin Cohen's comments and rename it to a proper name that describes what it is doing now. Guzman Lugo, Fernando (4): omap: iovmm - no gap checking for fixed address omap: iovmm - add superpages support to fixed da address omap: iovmm - replace __iounmap with iounmap omap: iommu - create new api to set valid da range arch/arm/mach-omap2/omap-iommu.c|8 +++ arch/arm/plat-omap/include/plat/iommu.h |5 ++ arch/arm/plat-omap/iommu.c | 24 + arch/arm/plat-omap/iovmm.c | 81 +- 4 files changed, 83 insertions(+), 35 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv7 2/4] omap: iovmm - add superpages support to fixed da address
From: Guzman Lugo, Fernando This patch adds superpages support to fixed ad address inside iommu_kmap function. Signed-off-by: Fernando Guzman Lugo Acked-by: Hiroshi DOYU --- arch/arm/plat-omap/iovmm.c | 62 +-- 1 files changed, 36 insertions(+), 26 deletions(-) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 34f0012..93a34d9 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -87,35 +87,43 @@ static size_t sgtable_len(const struct sg_table *sgt) } #define sgtable_ok(x) (!!sgtable_len(x)) +static unsigned max_alignment(u32 addr) +{ + int i; + unsigned pagesize[] = { SZ_16M, SZ_1M, SZ_64K, SZ_4K, }; + for (i = 0; i < ARRAY_SIZE(pagesize) && addr & (pagesize[i] - 1); i++) + ; + return (i < ARRAY_SIZE(pagesize)) ? pagesize[i] : 0; +} + /* * calculate the optimal number sg elements from total bytes based on * iommu superpages */ -static unsigned int sgtable_nents(size_t bytes) +static unsigned sgtable_nents(size_t bytes, u32 da, u32 pa) { - int i; - unsigned int nr_entries; - const unsigned long pagesize[] = { SZ_16M, SZ_1M, SZ_64K, SZ_4K, }; + unsigned nr_entries = 0, ent_sz; if (!IS_ALIGNED(bytes, PAGE_SIZE)) { pr_err("%s: wrong size %08x\n", __func__, bytes); return 0; } - nr_entries = 0; - for (i = 0; i < ARRAY_SIZE(pagesize); i++) { - if (bytes >= pagesize[i]) { - nr_entries += (bytes / pagesize[i]); - bytes %= pagesize[i]; - } + while (bytes) { + ent_sz = max_alignment(da | pa); + ent_sz = min_t(unsigned, ent_sz, iopgsz_max(bytes)); + nr_entries++; + da += ent_sz; + pa += ent_sz; + bytes -= ent_sz; } - BUG_ON(bytes); return nr_entries; } /* allocate and initialize sg_table header(a kind of 'superblock') */ -static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags) +static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags, + u32 da, u32 pa) { unsigned int nr_entries; int err; @@ -127,9 +135,8 @@ static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags) if (!IS_ALIGNED(bytes, PAGE_SIZE)) return ERR_PTR(-EINVAL); - /* FIXME: IOVMF_DA_FIXED should support 'superpages' */ - if ((flags & IOVMF_LINEAR) && (flags & IOVMF_DA_ANON)) { - nr_entries = sgtable_nents(bytes); + if (flags & IOVMF_LINEAR) { + nr_entries = sgtable_nents(bytes, da, pa); if (!nr_entries) return ERR_PTR(-EINVAL); } else @@ -409,7 +416,8 @@ static inline void sgtable_drain_vmalloc(struct sg_table *sgt) BUG_ON(!sgt); } -static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) +static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, u32 da, + size_t len) { unsigned int i; struct scatterlist *sg; @@ -418,9 +426,10 @@ static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) va = phys_to_virt(pa); for_each_sg(sgt->sgl, sg, sgt->nents, i) { - size_t bytes; + unsigned bytes; - bytes = iopgsz_max(len); + bytes = max_alignment(da | pa); + bytes = min_t(unsigned, bytes, iopgsz_max(len)); BUG_ON(!iopgsz_ok(bytes)); @@ -429,6 +438,7 @@ static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) * 'pa' is cotinuous(linear). */ pa += bytes; + da += bytes; len -= bytes; } BUG_ON(len); @@ -695,18 +705,18 @@ u32 iommu_vmalloc(struct iommu *obj, u32 da, size_t bytes, u32 flags) if (!va) return -ENOMEM; - sgt = sgtable_alloc(bytes, flags); + flags &= IOVMF_HW_MASK; + flags |= IOVMF_DISCONT; + flags |= IOVMF_ALLOC; + flags |= (da ? IOVMF_DA_FIXED : IOVMF_DA_ANON); + + sgt = sgtable_alloc(bytes, flags, da, 0); if (IS_ERR(sgt)) { da = PTR_ERR(sgt); goto err_sgt_alloc; } sgtable_fill_vmalloc(sgt, va); - flags &= IOVMF_HW_MASK; - flags |= IOVMF_DISCONT; - flags |= IOVMF_ALLOC; - flags |= (da ? IOVMF_DA_FIXED : IOVMF_DA_ANON); - da = __iommu_vmap(obj, da, sgt, va, bytes, flags); if (IS_ERR_VALUE(da)) goto err_iommu_vmap; @@ -746,11 +756,11 @@ static u32 __iommu_kmap(struct iommu *obj, u32 da, u32 pa, v
[PATCHv7 4/4] omap: iommu - create new api to set valid da range
From: Guzman Lugo, Fernando Some IOMMUs cannot use the whole 0x0 - 0x range. With this new API the valid range can be set. Signed-off-by: Fernando Guzman Lugo Acked-by: Hiroshi DOYU --- arch/arm/mach-omap2/omap-iommu.c|8 arch/arm/plat-omap/include/plat/iommu.h |5 + arch/arm/plat-omap/iommu.c | 24 arch/arm/plat-omap/iovmm.c | 15 --- 4 files changed, 45 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c index f5a1aad..6be548c 100644 --- a/arch/arm/mach-omap2/omap-iommu.c +++ b/arch/arm/mach-omap2/omap-iommu.c @@ -33,6 +33,8 @@ static struct iommu_device omap3_devices[] = { .name = "isp", .nr_tlb_entries = 8, .clk_name = "cam_ick", + .da_start = 0x0, + .da_end = 0xF000, }, }, #if defined(CONFIG_MPU_BRIDGE_IOMMU) @@ -43,6 +45,8 @@ static struct iommu_device omap3_devices[] = { .name = "iva2", .nr_tlb_entries = 32, .clk_name = "iva2_ck", + .da_start = 0x1100, + .da_end = 0xF000, }, }, #endif @@ -64,6 +68,8 @@ static struct iommu_device omap4_devices[] = { .name = "ducati", .nr_tlb_entries = 32, .clk_name = "ducati_ick", + .da_start = 0x0, + .da_end = 0xF000, }, }, #if defined(CONFIG_MPU_TESLA_IOMMU) @@ -74,6 +80,8 @@ static struct iommu_device omap4_devices[] = { .name = "tesla", .nr_tlb_entries = 32, .clk_name = "tesla_ick", + .da_start = 0x0, + .da_end = 0xF000, }, }, #endif diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h index 33c7d41..69230d6 100644 --- a/arch/arm/plat-omap/include/plat/iommu.h +++ b/arch/arm/plat-omap/include/plat/iommu.h @@ -50,6 +50,8 @@ struct iommu { int (*isr)(struct iommu *obj); void *ctx; /* iommu context: registres saved area */ + u32 da_start; + u32 da_end; }; struct cr_regs { @@ -103,6 +105,8 @@ struct iommu_platform_data { const char *name; const char *clk_name; const int nr_tlb_entries; + u32 da_start; + u32 da_end; }; #if defined(CONFIG_ARCH_OMAP1) @@ -152,6 +156,7 @@ extern void flush_iotlb_all(struct iommu *obj); extern int iopgtable_store_entry(struct iommu *obj, struct iotlb_entry *e); extern size_t iopgtable_clear_entry(struct iommu *obj, u32 iova); +extern int iommu_set_da_range(struct iommu *obj, u32 start, u32 end); extern struct iommu *iommu_get(const char *name); extern void iommu_put(struct iommu *obj); diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index 6cd151b..b1107c0 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c @@ -830,6 +830,28 @@ static int device_match_by_alias(struct device *dev, void *data) } /** + * iommu_set_da_range - Set a valid device address range + * @obj: target iommu + * @start Start of valid range + * @endEnd of valid range + **/ +int iommu_set_da_range(struct iommu *obj, u32 start, u32 end) +{ + + if (!obj) + return -EFAULT; + + if (end < start || !PAGE_ALIGN(start | end)) + return -EINVAL; + + obj->da_start = start; + obj->da_end = end; + + return 0; +} +EXPORT_SYMBOL_GPL(iommu_set_da_range); + +/** * iommu_get - Get iommu handler * @name: target iommu name **/ @@ -922,6 +944,8 @@ static int __devinit omap_iommu_probe(struct platform_device *pdev) obj->name = pdata->name; obj->dev = &pdev->dev; obj->ctx = (void *)obj + sizeof(*obj); + obj->da_start = pdata->da_start; + obj->da_end = pdata->da_end; mutex_init(&obj->iommu_lock); mutex_init(&obj->mmap_lock); diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index fa6e643..6dc1296 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -280,13 +280,14 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, alignement = PAGE_SIZE; if (flags & IOVMF_DA_ANON) { - /* -* Reserve the first page for NULL -*/ - start = PAGE_SIZE; + start = obj->da_start; + if (flags & IOVMF_LINEAR)
[PATCHv7 3/4] omap: iovmm - replace __iounmap with iounmap
From: Guzman Lugo, Fernando __iounmap function is wrong for OMAP architecture, instead use iounmap which will call to the correct function. Signed-off-by: Fernando Guzman Lugo Acked-by: Hiroshi DOYU --- arch/arm/plat-omap/iovmm.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 93a34d9..fa6e643 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -821,7 +821,7 @@ void iommu_kunmap(struct iommu *obj, u32 da) struct sg_table *sgt; typedef void (*func_t)(const void *); - sgt = unmap_vm_area(obj, da, (func_t)__iounmap, + sgt = unmap_vm_area(obj, da, (func_t)iounmap, IOVMF_LINEAR | IOVMF_MMIO); if (!sgt) dev_dbg(obj->dev, "%s: No sgt\n", __func__); -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv7 1/4] omap: iovmm - no gap checking for fixed address
From: Guzman Lugo, Fernando If some fixed da address is wanted to be mapped and the page is freed but it is used as gap, the mapping will fail. This patch is fixing that and olny keeps the gap for not fixed address. Signed-off-by: Fernando Guzman Lugo Acked-by: Hiroshi DOYU --- arch/arm/plat-omap/iovmm.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 8ce0de2..34f0012 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -289,10 +289,10 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, prev_end = 0; list_for_each_entry(tmp, &obj->mmap, list) { - if (prev_end >= start) + if (prev_end > start) break; - if (start + bytes < tmp->da_start) + if (start + bytes <= tmp->da_start) goto found; if (flags & IOVMF_DA_ANON) @@ -301,7 +301,7 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, prev_end = tmp->da_end; } - if ((start > prev_end) && (ULONG_MAX - start >= bytes)) + if ((start >= prev_end) && (ULONG_MAX - start + 1 >= bytes)) goto found; dev_dbg(obj->dev, "%s: no space to fit %08x(%x) flags: %08x\n", -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 03/11] staging: tidspbridge - rename bridge_brd_mem_map/unmap to a proper name
Now these functions only map user space addresses to dsp virtual addresses, so now the functions have a more meaningful name. Also now user_to_dsp_map returns the mapped address. Signed-off-by: Fernando Guzman Lugo --- drivers/staging/tidspbridge/core/_tiomap.h | 24 +++ drivers/staging/tidspbridge/core/tiomap3430.c | 153 ++-- .../tidspbridge/include/dspbridge/dspdefs.h| 44 -- drivers/staging/tidspbridge/pmgr/dev.c |2 - drivers/staging/tidspbridge/rmgr/proc.c| 34 +++-- 5 files changed, 116 insertions(+), 141 deletions(-) diff --git a/drivers/staging/tidspbridge/core/_tiomap.h b/drivers/staging/tidspbridge/core/_tiomap.h index c1bf95d..8777492 100644 --- a/drivers/staging/tidspbridge/core/_tiomap.h +++ b/drivers/staging/tidspbridge/core/_tiomap.h @@ -383,4 +383,28 @@ extern s32 dsp_debug; */ int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val); +/** + * user_to_dsp_map() - maps user to dsp virtual address + * @mmu: Pointer to iommu handle. + * @uva: Virtual user space address. + * @da DSP address + * @size Buffer size to map. + * @usr_pgsstruct page array pointer where the user pages will be stored + * + * This function maps a user space buffer into DSP virtual address. + * + */ +u32 user_to_dsp_map(struct iommu *mmu, u32 uva, u32 da, u32 size, + struct page **usr_pgs); + +/** + * user_to_dsp_unmap() - unmaps DSP virtual buffer. + * @mmu: Pointer to iommu handle. + * @da DSP address + * + * This function unmaps a user space buffer into DSP virtual address. + * + */ +int user_to_dsp_unmap(struct iommu *mmu, u32 da); + #endif /* _TIOMAP_ */ diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index 721116b..8825700 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -95,12 +95,6 @@ static int bridge_brd_mem_copy(struct bridge_dev_context *dev_ctxt, static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt, u8 *host_buff, u32 dsp_addr, u32 ul_num_bytes, u32 mem_type); -static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctxt, - u32 ul_mpu_addr, u32 virt_addr, - u32 ul_num_bytes, u32 ul_map_attr, - struct page **mapped_pages); -static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctxt, -u32 da); static int bridge_dev_create(struct bridge_dev_context **dev_cntxt, struct dev_object *hdev_obj, @@ -108,9 +102,6 @@ static int bridge_dev_create(struct bridge_dev_context static int bridge_dev_ctrl(struct bridge_dev_context *dev_context, u32 dw_cmd, void *pargs); static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt); -static int get_io_pages(struct mm_struct *mm, u32 uva, unsigned pages, - struct page **usr_pgs); -static u32 user_va2_pa(struct mm_struct *mm, u32 address); static int pte_update(struct bridge_dev_context *dev_ctxt, u32 pa, u32 va, u32 size, struct hw_mmu_map_attrs_t *map_attrs); @@ -180,8 +171,6 @@ static struct bridge_drv_interface drv_interface_fxns = { bridge_brd_set_state, bridge_brd_mem_copy, bridge_brd_mem_write, - bridge_brd_mem_map, - bridge_brd_mem_un_map, /* The following CHNL functions are provided by chnl_io.lib: */ bridge_chnl_create, bridge_chnl_destroy, @@ -1151,22 +1140,77 @@ static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt, } /* - * bridge_brd_mem_map - * This function maps MPU buffer to the DSP address space. It performs - * linear to physical address translation if required. It translates each - * page since linear addresses can be physically non-contiguous - * All address & size arguments are assumed to be page aligned (in proc.c) + * user_va2_pa + * Purpose: + * This function walks through the page tables to convert a userland + * virtual address to physical address + */ +static u32 user_va2_pa(struct mm_struct *mm, u32 address) +{ + pgd_t *pgd; + pmd_t *pmd; + pte_t *ptep, pte; + + pgd = pgd_offset(mm, address); + if (!(pgd_none(*pgd) || pgd_bad(*pgd))) { + pmd = pmd_offset(pgd, address); + if (!(pmd_none(*pmd) || pmd_bad(*pmd))) { + ptep = pte_offset_map(pmd, address); + if (ptep) { + pte = *
[PATCHv2 09/11] staging: tidspbridge - remove reserved memory clean up
Now iommv module keeps track of iommu memory used, we do not need resource cleanup for reserved memories anymore. Signed-off-by: Fernando Guzman Lugo --- .../staging/tidspbridge/include/dspbridge/drv.h|4 -- drivers/staging/tidspbridge/rmgr/drv.c | 11 -- drivers/staging/tidspbridge/rmgr/drv_interface.c |2 - drivers/staging/tidspbridge/rmgr/proc.c| 36 4 files changed, 0 insertions(+), 53 deletions(-) diff --git a/drivers/staging/tidspbridge/include/dspbridge/drv.h b/drivers/staging/tidspbridge/include/dspbridge/drv.h index c1f363e..427f38b 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/drv.h +++ b/drivers/staging/tidspbridge/include/dspbridge/drv.h @@ -165,10 +165,6 @@ struct process_context { struct list_head dmm_map_list; spinlock_t dmm_map_lock; - /* DMM reserved memory resources */ - struct list_head dmm_rsv_list; - spinlock_t dmm_rsv_lock; - /* DSP Heap resources */ struct dspheap_res_object *pdspheap_list; diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c index 0c857b9..91cc168 100644 --- a/drivers/staging/tidspbridge/rmgr/drv.c +++ b/drivers/staging/tidspbridge/rmgr/drv.c @@ -146,7 +146,6 @@ int drv_remove_all_dmm_res_elements(void *process_ctxt) struct process_context *ctxt = (struct process_context *)process_ctxt; int status = 0; struct dmm_map_object *temp_map, *map_obj; - struct dmm_rsv_object *temp_rsv, *rsv_obj; /* Free DMM mapped memory resources */ list_for_each_entry_safe(map_obj, temp_map, &ctxt->dmm_map_list, link) { @@ -156,16 +155,6 @@ int drv_remove_all_dmm_res_elements(void *process_ctxt) pr_err("%s: proc_un_map failed!" " status = 0x%xn", __func__, status); } - - /* Free DMM reserved memory resources */ - list_for_each_entry_safe(rsv_obj, temp_rsv, &ctxt->dmm_rsv_list, link) { - status = proc_un_reserve_memory(ctxt->hprocessor, (void *) - rsv_obj->dsp_reserved_addr, - ctxt); - if (status) - pr_err("%s: proc_un_reserve_memory failed!" - " status = 0x%xn", __func__, status); - } return status; } diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c index 4c0b9ee..f9a1e0b 100644 --- a/drivers/staging/tidspbridge/rmgr/drv_interface.c +++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c @@ -507,8 +507,6 @@ static int bridge_open(struct inode *ip, struct file *filp) pr_ctxt->res_state = PROC_RES_ALLOCATED; spin_lock_init(&pr_ctxt->dmm_map_lock); INIT_LIST_HEAD(&pr_ctxt->dmm_map_list); - spin_lock_init(&pr_ctxt->dmm_rsv_lock); - INIT_LIST_HEAD(&pr_ctxt->dmm_rsv_list); pr_ctxt->node_id = kzalloc(sizeof(struct idr), GFP_KERNEL); if (pr_ctxt->node_id) { diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c index 59c946b..e5fec57 100644 --- a/drivers/staging/tidspbridge/rmgr/proc.c +++ b/drivers/staging/tidspbridge/rmgr/proc.c @@ -1515,7 +1515,6 @@ int proc_reserve_memory(void *hprocessor, u32 ul_size, struct dmm_object *dmm_mgr; int status = 0; struct proc_object *p_proc_object = (struct proc_object *)hprocessor; - struct dmm_rsv_object *rsv_obj; if (!p_proc_object) { status = -EFAULT; @@ -1529,22 +1528,6 @@ int proc_reserve_memory(void *hprocessor, u32 ul_size, } status = dmm_reserve_memory(dmm_mgr, ul_size, (u32 *) pp_rsv_addr); - if (status != 0) - goto func_end; - - /* -* A successful reserve should be followed by insertion of rsv_obj -* into dmm_rsv_list, so that reserved memory resource tracking -* remains uptodate -*/ - rsv_obj = kmalloc(sizeof(struct dmm_rsv_object), GFP_KERNEL); - if (rsv_obj) { - rsv_obj->dsp_reserved_addr = (u32) *pp_rsv_addr; - spin_lock(&pr_ctxt->dmm_rsv_lock); - list_add(&rsv_obj->link, &pr_ctxt->dmm_rsv_list); - spin_unlock(&pr_ctxt->dmm_rsv_lock); - } - func_end: dev_dbg(bridge, "%s: hprocessor: 0x%p ul_size: 0x%x pp_rsv_addr: 0x%p " "status 0x%x\n", __func__, hprocessor, @@ -1756,7 +1739,6 @@ int proc_un_reserve_memory(void *hprocessor, void *prsv_addr, struct dmm_object *dmm_mgr; int status = 0; struct proc_object *p_proc_object = (struct proc_objec
[PATCHv2 08/11] staging: tidspbridge: remove dw_dmmu_base from cfg_hostres struct
We don't need to map iva2 iommu register base address anymore. Signed-off-by: Fernando Guzman Lugo --- drivers/staging/tidspbridge/core/tiomap3430.c |3 --- drivers/staging/tidspbridge/core/tiomap_io.c |3 +-- .../tidspbridge/include/dspbridge/cfgdefs.h|1 - drivers/staging/tidspbridge/rmgr/drv.c |4 4 files changed, 1 insertions(+), 10 deletions(-) diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index 789cc5e..f890a0e 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -830,8 +830,6 @@ static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt) iounmap((void *)host_res->dw_mem_base[3]); if (host_res->dw_mem_base[4]) iounmap((void *)host_res->dw_mem_base[4]); - if (host_res->dw_dmmu_base) - iounmap(host_res->dw_dmmu_base); if (host_res->dw_per_base) iounmap(host_res->dw_per_base); if (host_res->dw_per_pm_base) @@ -845,7 +843,6 @@ static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt) host_res->dw_mem_base[2] = (u32) NULL; host_res->dw_mem_base[3] = (u32) NULL; host_res->dw_mem_base[4] = (u32) NULL; - host_res->dw_dmmu_base = NULL; host_res->dw_sys_ctrl_base = NULL; kfree(host_res); diff --git a/drivers/staging/tidspbridge/core/tiomap_io.c b/drivers/staging/tidspbridge/core/tiomap_io.c index 63d46bc..81a5401 100644 --- a/drivers/staging/tidspbridge/core/tiomap_io.c +++ b/drivers/staging/tidspbridge/core/tiomap_io.c @@ -391,7 +391,6 @@ int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val) omap_dspbridge_dev->dev.platform_data; struct cfg_hostres *resources = dev_context->resources; int status = 0; - u32 temp; if (!dev_context->mbox) return 0; @@ -435,7 +434,7 @@ int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val) omap_mbox_restore_ctx(dev_context->mbox); /* Access MMU SYS CONFIG register to generate a short wakeup */ - temp = readl(resources->dw_dmmu_base + 0x10); + iommu_read_reg(dev_context->dsp_mmu, MMU_SYSCONFIG); dev_context->dw_brd_state = BRD_RUNNING; } else if (dev_context->dw_brd_state == BRD_RETENTION) { diff --git a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h b/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h index 38122db..dfb55cc 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h @@ -68,7 +68,6 @@ struct cfg_hostres { void __iomem *dw_per_base; u32 dw_per_pm_base; u32 dw_core_pm_base; - void __iomem *dw_dmmu_base; void __iomem *dw_sys_ctrl_base; }; diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c index 81b1b90..0c857b9 100644 --- a/drivers/staging/tidspbridge/rmgr/drv.c +++ b/drivers/staging/tidspbridge/rmgr/drv.c @@ -743,7 +743,6 @@ static int request_bridge_resources(struct cfg_hostres *res) host_res->dw_sys_ctrl_base = ioremap(OMAP_SYSC_BASE, OMAP_SYSC_SIZE); dev_dbg(bridge, "dw_mem_base[0] 0x%x\n", host_res->dw_mem_base[0]); dev_dbg(bridge, "dw_mem_base[3] 0x%x\n", host_res->dw_mem_base[3]); - dev_dbg(bridge, "dw_dmmu_base %p\n", host_res->dw_dmmu_base); /* for 24xx base port is not mapping the mamory for DSP * internal memory TODO Do a ioremap here */ @@ -797,8 +796,6 @@ int drv_request_bridge_res_dsp(void **phost_resources) OMAP_PER_PRM_SIZE); host_res->dw_core_pm_base = (u32) ioremap(OMAP_CORE_PRM_BASE, OMAP_CORE_PRM_SIZE); - host_res->dw_dmmu_base = ioremap(OMAP_DMMU_BASE, -OMAP_DMMU_SIZE); dev_dbg(bridge, "dw_mem_base[0] 0x%x\n", host_res->dw_mem_base[0]); @@ -810,7 +807,6 @@ int drv_request_bridge_res_dsp(void **phost_resources) host_res->dw_mem_base[3]); dev_dbg(bridge, "dw_mem_base[4] 0x%x\n", host_res->dw_mem_base[4]); - dev_dbg(bridge, "dw_dmmu_base %p\n", host_res->dw_dmmu_base); shm_size = drv_datap->shm_size; if (shm_size >= 0x1) { -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 00/11] staging tidspbridge: iommu migration
This set of patches remove the dspbridge custom mmu implementation and use iommu module instead. Version2: - Comments from FUJITA Tomonori and previous patch "tidspbridge: add map support for big buffers" was removed and instead a patch to define ARCH_HAS_SG_CHAIN in arm architecture will be sent. - Rebase to the latest tidspbridge. Fernando Guzman Lugo (11): staging: tidspbridge: replace iommu custom for opensource implementation staging: tidspbridge - move shared memory iommu maps to tiomap3430.c staging: tidspbridge - rename bridge_brd_mem_map/unmap to a proper name staging: tidspbridge - remove custom mmu code from tiomap3430.c staging: tidspbridge - fix mmufault support staging: tidspbrge - remove hw directory staging: tidspbridge - move all iommu related code to a new file staging: tidspbridge: remove dw_dmmu_base from cfg_hostres struct staging: tidspbridge - remove reserved memory clean up staging: tidspbridge - deprecate reserve/unreserve_memory funtions staging: tidspbridge - remove dmm custom module drivers/staging/tidspbridge/Makefile |7 +- drivers/staging/tidspbridge/core/_deh.h|5 +- drivers/staging/tidspbridge/core/_tiomap.h | 19 +- drivers/staging/tidspbridge/core/dsp-mmu.c | 316 ++ drivers/staging/tidspbridge/core/io_sm.c | 180 +--- drivers/staging/tidspbridge/core/tiomap3430.c | 1070 ++-- drivers/staging/tidspbridge/core/tiomap3430_pwr.c |4 - drivers/staging/tidspbridge/core/tiomap_io.c | 17 +- drivers/staging/tidspbridge/core/ue_deh.c | 115 +--- drivers/staging/tidspbridge/hw/EasiGlobal.h| 41 - drivers/staging/tidspbridge/hw/MMUAccInt.h | 76 -- drivers/staging/tidspbridge/hw/MMURegAcM.h | 225 drivers/staging/tidspbridge/hw/hw_defs.h | 58 -- drivers/staging/tidspbridge/hw/hw_mmu.c| 562 -- drivers/staging/tidspbridge/hw/hw_mmu.h| 163 --- .../tidspbridge/include/dspbridge/cfgdefs.h|1 - .../staging/tidspbridge/include/dspbridge/dev.h| 24 - .../staging/tidspbridge/include/dspbridge/dmm.h| 75 -- .../staging/tidspbridge/include/dspbridge/drv.h| 10 - .../tidspbridge/include/dspbridge/dsp-mmu.h| 67 ++ .../tidspbridge/include/dspbridge/dspdefs.h| 44 - .../tidspbridge/include/dspbridge/dspioctl.h |7 - .../staging/tidspbridge/include/dspbridge/proc.h | 46 - drivers/staging/tidspbridge/pmgr/dev.c | 63 +-- drivers/staging/tidspbridge/pmgr/dmm.c | 533 -- drivers/staging/tidspbridge/pmgr/dspapi.c | 34 +- drivers/staging/tidspbridge/rmgr/drv.c | 15 - drivers/staging/tidspbridge/rmgr/drv_interface.c |2 - drivers/staging/tidspbridge/rmgr/node.c| 48 +- drivers/staging/tidspbridge/rmgr/proc.c| 197 + 30 files changed, 568 insertions(+), 3456 deletions(-) create mode 100644 drivers/staging/tidspbridge/core/dsp-mmu.c delete mode 100644 drivers/staging/tidspbridge/hw/EasiGlobal.h delete mode 100644 drivers/staging/tidspbridge/hw/MMUAccInt.h delete mode 100644 drivers/staging/tidspbridge/hw/MMURegAcM.h delete mode 100644 drivers/staging/tidspbridge/hw/hw_defs.h delete mode 100644 drivers/staging/tidspbridge/hw/hw_mmu.c delete mode 100644 drivers/staging/tidspbridge/hw/hw_mmu.h delete mode 100644 drivers/staging/tidspbridge/include/dspbridge/dmm.h create mode 100644 drivers/staging/tidspbridge/include/dspbridge/dsp-mmu.h delete mode 100644 drivers/staging/tidspbridge/pmgr/dmm.c -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 06/11] staging: tidspbrge - remove hw directory
hw directory was only being used for custom iommu implementation APIs, so after the iommu module migration this directory is not needed anymore. Signed-off-by: Fernando Guzman Lugo --- drivers/staging/tidspbridge/Makefile |3 +- drivers/staging/tidspbridge/core/_tiomap.h |1 - drivers/staging/tidspbridge/core/io_sm.c |4 - drivers/staging/tidspbridge/core/tiomap3430.c |4 - drivers/staging/tidspbridge/core/tiomap3430_pwr.c |4 - drivers/staging/tidspbridge/core/tiomap_io.c |2 +- drivers/staging/tidspbridge/hw/EasiGlobal.h| 41 -- drivers/staging/tidspbridge/hw/MMUAccInt.h | 76 --- drivers/staging/tidspbridge/hw/MMURegAcM.h | 225 drivers/staging/tidspbridge/hw/hw_defs.h | 58 -- drivers/staging/tidspbridge/hw/hw_mmu.c| 562 drivers/staging/tidspbridge/hw/hw_mmu.h| 163 -- .../tidspbridge/include/dspbridge/dspioctl.h |7 - 13 files changed, 2 insertions(+), 1148 deletions(-) delete mode 100644 drivers/staging/tidspbridge/hw/EasiGlobal.h delete mode 100644 drivers/staging/tidspbridge/hw/MMUAccInt.h delete mode 100644 drivers/staging/tidspbridge/hw/MMURegAcM.h delete mode 100644 drivers/staging/tidspbridge/hw/hw_defs.h delete mode 100644 drivers/staging/tidspbridge/hw/hw_mmu.c delete mode 100644 drivers/staging/tidspbridge/hw/hw_mmu.h diff --git a/drivers/staging/tidspbridge/Makefile b/drivers/staging/tidspbridge/Makefile index 8082d5c..e09547d 100644 --- a/drivers/staging/tidspbridge/Makefile +++ b/drivers/staging/tidspbridge/Makefile @@ -11,10 +11,9 @@ librmgr = rmgr/dbdcd.o rmgr/disp.o rmgr/drv.o rmgr/mgr.o rmgr/node.o \ rmgr/nldr.o rmgr/drv_interface.o libdload = dynload/cload.o dynload/getsection.o dynload/reloc.o \ dynload/tramp.o -libhw = hw/hw_mmu.o bridgedriver-objs = $(libgen) $(libservices) $(libcore) $(libpmgr) $(librmgr) \ - $(libdload) $(libhw) + $(libdload) #Machine dependent ccflags-y += -D_TI_ -D_DB_TIOMAP -DTMS32060 \ diff --git a/drivers/staging/tidspbridge/core/_tiomap.h b/drivers/staging/tidspbridge/core/_tiomap.h index 394a64a..cd7ff88 100644 --- a/drivers/staging/tidspbridge/core/_tiomap.h +++ b/drivers/staging/tidspbridge/core/_tiomap.h @@ -26,7 +26,6 @@ #include #include #include -#include #include /* for bridge_ioctl_extproc defn */ #include #include diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index 56856ad..194bada 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -39,10 +39,6 @@ #include #include -/* Hardware Abstraction Layer */ -#include -#include - /* Bridge Driver */ #include #include diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index 55ea265..58118aa 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -33,10 +33,6 @@ #include #include -/* Hardware Abstraction Layer */ -#include -#include - /* --- Link Driver */ #include #include diff --git a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c index b9d0753..e29b969 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c +++ b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c @@ -29,10 +29,6 @@ #include #include -/* Hardware Abstraction Layer */ -#include -#include - #include /* --- Bridge Driver */ diff --git a/drivers/staging/tidspbridge/core/tiomap_io.c b/drivers/staging/tidspbridge/core/tiomap_io.c index 1300bd3..63d46bc 100644 --- a/drivers/staging/tidspbridge/core/tiomap_io.c +++ b/drivers/staging/tidspbridge/core/tiomap_io.c @@ -141,7 +141,7 @@ int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt, ul_shm_base_virt - ul_tlb_base_virt; ul_shm_offset_virt += PG_ALIGN_HIGH(ul_ext_end - ul_dyn_ext_base + - 1, HW_PAGE_SIZE64KB); + 1, PAGE_SIZE * 16); dw_ext_prog_virt_mem -= ul_shm_offset_virt; dw_ext_prog_virt_mem += (ul_ext_base - ul_dyn_ext_base); diff --git a/drivers/staging/tidspbridge/hw/EasiGlobal.h b/drivers/staging/tidspbridge/hw/EasiGlobal.h deleted file mode 100644 index e48d7f6..000 --- a/drivers/staging/tidspbridge/hw/EasiGlobal.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * EasiGlobal.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors
[PATCHv2 10/11] staging: tidspbridge - deprecate reserve/unreserve_memory funtions
Now what iommu memory usage is kept track by iommu module the functions reserve/unreserve_memory are not needed anymore. Signed-off-by: Fernando Guzman Lugo --- .../staging/tidspbridge/include/dspbridge/proc.h | 46 drivers/staging/tidspbridge/pmgr/dspapi.c | 34 +- drivers/staging/tidspbridge/rmgr/node.c| 20 + drivers/staging/tidspbridge/rmgr/proc.c| 114 ++-- 4 files changed, 17 insertions(+), 197 deletions(-) diff --git a/drivers/staging/tidspbridge/include/dspbridge/proc.h b/drivers/staging/tidspbridge/include/dspbridge/proc.h index 5e09fd1..2d12aab 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/proc.h +++ b/drivers/staging/tidspbridge/include/dspbridge/proc.h @@ -551,29 +551,6 @@ extern int proc_map(void *hprocessor, struct process_context *pr_ctxt); /* - * proc_reserve_memory - * Purpose: - * Reserve a virtually contiguous region of DSP address space. - * Parameters: - * hprocessor : The processor handle. - * ul_size : Size of the address space to reserve. - * pp_rsv_addr : Ptr to DSP side reserved u8 address. - * Returns: - * 0 : Success. - * -EFAULT : Invalid processor handle. - * -EPERM : General failure. - * -ENOMEM : Cannot reserve chunk of this size. - * Requires: - * pp_rsv_addr is not NULL - * PROC Initialized. - * Ensures: - * Details: - */ -extern int proc_reserve_memory(void *hprocessor, - u32 ul_size, void **pp_rsv_addr, - struct process_context *pr_ctxt); - -/* * proc_un_map * Purpose: * Removes a MPU buffer mapping from the DSP address space. @@ -595,27 +572,4 @@ extern int proc_reserve_memory(void *hprocessor, extern int proc_un_map(void *hprocessor, void *map_addr, struct process_context *pr_ctxt); -/* - * proc_un_reserve_memory - * Purpose: - * Frees a previously reserved region of DSP address space. - * Parameters: - * hprocessor : The processor handle. - * prsv_addr : Ptr to DSP side reservedBYTE address. - * Returns: - * 0 : Success. - * -EFAULT : Invalid processor handle. - * -EPERM : General failure. - * -ENOENT : Cannot find a reserved region starting with this - * : address. - * Requires: - * prsv_addr is not NULL - * PROC Initialized. - * Ensures: - * Details: - */ -extern int proc_un_reserve_memory(void *hprocessor, -void *prsv_addr, -struct process_context *pr_ctxt); - #endif /* PROC_ */ diff --git a/drivers/staging/tidspbridge/pmgr/dspapi.c b/drivers/staging/tidspbridge/pmgr/dspapi.c index faf8304..0187c47 100644 --- a/drivers/staging/tidspbridge/pmgr/dspapi.c +++ b/drivers/staging/tidspbridge/pmgr/dspapi.c @@ -989,27 +989,10 @@ u32 procwrap_register_notify(union trapped_args *args, void *pr_ctxt) /* * procwrap_reserve_memory */ -u32 procwrap_reserve_memory(union trapped_args *args, void *pr_ctxt) +u32 __deprecated procwrap_reserve_memory(union trapped_args *args, + void *pr_ctxt) { - int status; - void *prsv_addr; - void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor; - - if ((args->args_proc_rsvmem.ul_size <= 0) || - (args->args_proc_rsvmem.ul_size & (PG_SIZE4K - 1)) != 0) - return -EINVAL; - - status = proc_reserve_memory(hprocessor, -args->args_proc_rsvmem.ul_size, &prsv_addr, -pr_ctxt); - if (!status) { - if (put_user(prsv_addr, args->args_proc_rsvmem.pp_rsv_addr)) { - status = -EINVAL; - proc_un_reserve_memory(args->args_proc_rsvmem. - hprocessor, prsv_addr, pr_ctxt); - } - } - return status; + return 0; } /* @@ -1038,15 +1021,10 @@ u32 procwrap_un_map(union trapped_args *args, void *pr_ctxt) /* * procwrap_un_reserve_memory */ -u32 procwrap_un_reserve_memory(union trapped_args *args, void *pr_ctxt) +u32 __deprecated procwrap_un_reserve_memory(union trapped_args *args, + void *pr_ctxt) { - int status; - void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor; - - status = proc_un_reserve_memory(hprocessor, - args->args_proc_unrsvmem.prsv_addr, - pr_ctxt); - return status; + return 0; }
[PATCHv2 05/11] staging: tidspbridge - fix mmufault support
With changes for iommu migration mmufault report and dsp track dump is broken, this patch fixes that. Signed-off-by: Fernando Guzman Lugo --- drivers/staging/tidspbridge/core/_deh.h |2 + drivers/staging/tidspbridge/core/tiomap3430.c |2 + drivers/staging/tidspbridge/core/ue_deh.c | 93 ++--- 3 files changed, 40 insertions(+), 57 deletions(-) diff --git a/drivers/staging/tidspbridge/core/_deh.h b/drivers/staging/tidspbridge/core/_deh.h index 16723cd..f1254f0 100644 --- a/drivers/staging/tidspbridge/core/_deh.h +++ b/drivers/staging/tidspbridge/core/_deh.h @@ -32,4 +32,6 @@ struct deh_mgr { struct tasklet_struct dpc_tasklet; }; +int mmu_fault_isr(struct iommu *mmu); + #endif /* _DEH_ */ diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index f99cc24..55ea265 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -56,6 +56,7 @@ #include "_tiomap.h" #include "_tiomap_pwr.h" #include "tiomap_io.h" +#include "_deh.h" /* Offset in shared mem to write to in order to synchronize start with DSP */ #define SHMSYNCOFFSET 4/* GPP byte offset */ @@ -365,6 +366,7 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, } if (!status) { dev_context->dsp_mmu = mmu; + mmu->isr = mmu_fault_isr; sm_sg = &dev_context->sh_s; sg0_da = iommu_kmap(mmu, sm_sg->seg0_da, sm_sg->seg0_pa, sm_sg->seg0_size, IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32); diff --git a/drivers/staging/tidspbridge/core/ue_deh.c b/drivers/staging/tidspbridge/core/ue_deh.c index 14f3191..2e1ac89 100644 --- a/drivers/staging/tidspbridge/core/ue_deh.c +++ b/drivers/staging/tidspbridge/core/ue_deh.c @@ -31,7 +31,7 @@ #include #include -static u32 fault_addr; +#define MMU_CNTL_TWL_EN(1 << 2) static void mmu_fault_dpc(unsigned long data) { @@ -43,43 +43,18 @@ static void mmu_fault_dpc(unsigned long data) bridge_deh_notify(deh, DSP_MMUFAULT, 0); } -static irqreturn_t mmu_fault_isr(int irq, void *data) +int mmu_fault_isr(struct iommu *mmu) { - struct deh_mgr *deh = data; - struct cfg_hostres *resources; - u32 event; + struct deh_mgr *dm; - if (!deh) - return IRQ_HANDLED; + dev_get_deh_mgr(dev_get_first(), &dm); - resources = deh->hbridge_context->resources; - if (!resources) { - dev_dbg(bridge, "%s: Failed to get Host Resources\n", - __func__); - return IRQ_HANDLED; - } + if (!dm) + return -EPERM; - hw_mmu_event_status(resources->dw_dmmu_base, &event); - if (event == HW_MMU_TRANSLATION_FAULT) { - hw_mmu_fault_addr_read(resources->dw_dmmu_base, &fault_addr); - dev_dbg(bridge, "%s: event=0x%x, fault_addr=0x%x\n", __func__, - event, fault_addr); - /* -* Schedule a DPC directly. In the future, it may be -* necessary to check if DSP MMU fault is intended for -* Bridge. -*/ - tasklet_schedule(&deh->dpc_tasklet); - - /* Disable the MMU events, else once we clear it will -* start to raise INTs again */ - hw_mmu_event_disable(resources->dw_dmmu_base, - HW_MMU_TRANSLATION_FAULT); - } else { - hw_mmu_event_disable(resources->dw_dmmu_base, - HW_MMU_ALL_INTERRUPTS); - } - return IRQ_HANDLED; + iommu_write_reg(mmu, 0, MMU_IRQENABLE); + tasklet_schedule(&dm->dpc_tasklet); + return 0; } int bridge_deh_create(struct deh_mgr **ret_deh, @@ -161,42 +136,45 @@ int bridge_deh_register_notify(struct deh_mgr *deh, u32 event_mask, #ifdef CONFIG_TIDSPBRIDGE_BACKTRACE static void mmu_fault_print_stack(struct bridge_dev_context *dev_context) { - struct cfg_hostres *resources; - struct hw_mmu_map_attrs_t map_attrs = { - .endianism = HW_LITTLE_ENDIAN, - .element_size = HW_ELEM_SIZE16BIT, - .mixed_size = HW_MMU_CPUES, - }; - void *dummy_va_addr; - - resources = dev_context->resources; - dummy_va_addr = (void*)__get_free_page(GFP_ATOMIC); + void *dummy_addr; + u32 fa, tmp; + struct iotlb_entry e; + struct iommu *mmu = dev_context->dsp_mmu; + dummy_addr = (void *)__get_free_page(GFP_ATOMIC); /* * Before acking the MMU fault, let's make sure MMU can only * access entry #0. Then add a new entry so that the DSP OS
[PATCHv2 07/11] staging: tidspbridge - move all iommu related code to a new file
Create dsp-mmu module and moves all the iommu code related to this module. Signed-off-by: Fernando Guzman Lugo --- drivers/staging/tidspbridge/Makefile |2 +- drivers/staging/tidspbridge/core/_deh.h|3 - drivers/staging/tidspbridge/core/_tiomap.h | 27 +-- drivers/staging/tidspbridge/core/dsp-mmu.c | 316 drivers/staging/tidspbridge/core/tiomap3430.c | 178 +--- drivers/staging/tidspbridge/core/ue_deh.c | 86 +-- .../tidspbridge/include/dspbridge/dsp-mmu.h| 67 7 files changed, 390 insertions(+), 289 deletions(-) create mode 100644 drivers/staging/tidspbridge/core/dsp-mmu.c create mode 100644 drivers/staging/tidspbridge/include/dspbridge/dsp-mmu.h diff --git a/drivers/staging/tidspbridge/Makefile b/drivers/staging/tidspbridge/Makefile index e09547d..bd36651 100644 --- a/drivers/staging/tidspbridge/Makefile +++ b/drivers/staging/tidspbridge/Makefile @@ -2,7 +2,7 @@ obj-$(CONFIG_TIDSPBRIDGE) += bridgedriver.o libgen = gen/gb.o gen/gs.o gen/gh.o gen/uuidutil.o libcore = core/chnl_sm.o core/msg_sm.o core/io_sm.o core/tiomap3430.o \ - core/tiomap3430_pwr.o core/tiomap_io.o \ + core/tiomap3430_pwr.o core/tiomap_io.o core/dsp-mmu.o \ core/ue_deh.o core/wdt.o core/dsp-clock.o core/sync.o libpmgr = pmgr/chnl.o pmgr/io.o pmgr/msg.o pmgr/cod.o pmgr/dev.o pmgr/dspapi.o \ pmgr/dmm.o pmgr/cmm.o pmgr/dbll.o diff --git a/drivers/staging/tidspbridge/core/_deh.h b/drivers/staging/tidspbridge/core/_deh.h index f1254f0..8ae2633 100644 --- a/drivers/staging/tidspbridge/core/_deh.h +++ b/drivers/staging/tidspbridge/core/_deh.h @@ -27,9 +27,6 @@ struct deh_mgr { struct bridge_dev_context *hbridge_context; /* Bridge context. */ struct ntfy_object *ntfy_obj; /* NTFY object */ - - /* MMU Fault DPC */ - struct tasklet_struct dpc_tasklet; }; int mmu_fault_isr(struct iommu *mmu); diff --git a/drivers/staging/tidspbridge/core/_tiomap.h b/drivers/staging/tidspbridge/core/_tiomap.h index cd7ff88..e0a801c 100644 --- a/drivers/staging/tidspbridge/core/_tiomap.h +++ b/drivers/staging/tidspbridge/core/_tiomap.h @@ -23,8 +23,7 @@ #include #include #include -#include -#include +#include #include #include /* for bridge_ioctl_extproc defn */ #include @@ -380,28 +379,4 @@ extern s32 dsp_debug; */ int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val); -/** - * user_to_dsp_map() - maps user to dsp virtual address - * @mmu: Pointer to iommu handle. - * @uva: Virtual user space address. - * @da DSP address - * @size Buffer size to map. - * @usr_pgsstruct page array pointer where the user pages will be stored - * - * This function maps a user space buffer into DSP virtual address. - * - */ -u32 user_to_dsp_map(struct iommu *mmu, u32 uva, u32 da, u32 size, - struct page **usr_pgs); - -/** - * user_to_dsp_unmap() - unmaps DSP virtual buffer. - * @mmu: Pointer to iommu handle. - * @da DSP address - * - * This function unmaps a user space buffer into DSP virtual address. - * - */ -int user_to_dsp_unmap(struct iommu *mmu, u32 da); - #endif /* _TIOMAP_ */ diff --git a/drivers/staging/tidspbridge/core/dsp-mmu.c b/drivers/staging/tidspbridge/core/dsp-mmu.c new file mode 100644 index 000..3c978f9 --- /dev/null +++ b/drivers/staging/tidspbridge/core/dsp-mmu.c @@ -0,0 +1,316 @@ +/* + * dsp-mmu.c + * + * DSP-BIOS Bridge driver support functions for TI OMAP processors. + * + * DSP iommu. + * + * Copyright (C) 2010 Texas Instruments, Inc. + * + * This package is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include +#include +#include +#include +#include +#include +#include "_tiomap.h" + +#include + +#define MMU_CNTL_TWL_EN(1 << 2) + +static struct tasklet_struct mmu_tasklet; + +#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE +static void mmu_fault_print_stack(struct bridge_dev_context *dev_context) +{ + void *dummy_addr; + u32 fa, tmp; + struct iotlb_entry e; + struct iommu *mmu = dev_context->dsp_mmu; + dummy_addr = (void *)__get_free_page(GFP_ATOMIC); + + /* +* Before acking the MMU fault, let's make sure MMU can only +* access entry #0. Then add a new entry so that the DSP OS +* can continue in order to dump the stack. +*/ + tmp = iommu_read_reg(mmu, MMU_CNTL); + tmp &= ~MMU_CNTL_TWL_EN; + iommu_wri
[PATCHv2 02/11] staging: tidspbridge - move shared memory iommu maps to tiomap3430.c
Now iommu maps of shared memory segments are done in bridge_brd_start and unmaped in bridge_brd_stop. Signed-off-by: Fernando Guzman Lugo --- drivers/staging/tidspbridge/core/_tiomap.h| 13 +++ drivers/staging/tidspbridge/core/io_sm.c | 125 +++ drivers/staging/tidspbridge/core/tiomap3430.c | 136 +++- drivers/staging/tidspbridge/core/tiomap_io.c | 12 +- 4 files changed, 139 insertions(+), 147 deletions(-) diff --git a/drivers/staging/tidspbridge/core/_tiomap.h b/drivers/staging/tidspbridge/core/_tiomap.h index a42c393..c1bf95d 100644 --- a/drivers/staging/tidspbridge/core/_tiomap.h +++ b/drivers/staging/tidspbridge/core/_tiomap.h @@ -308,6 +308,18 @@ static const struct bpwr_clk_t bpwr_clks[] = { #define CLEAR_BIT_INDEX(reg, index) (reg &= ~(1 << (index))) +struct shm_segs { + u32 seg0_da; + u32 seg0_pa; + u32 seg0_va; + u32 seg0_size; + u32 seg1_da; + u32 seg1_pa; + u32 seg1_va; + u32 seg1_size; +}; + + /* This Bridge driver's device context: */ struct bridge_dev_context { struct dev_object *hdev_obj;/* Handle to Bridge device object. */ @@ -331,6 +343,7 @@ struct bridge_dev_context { struct omap_mbox *mbox; /* Mail box handle */ struct iommu *dsp_mmu; /* iommu for iva2 handler */ + struct shm_segs sh_s; struct cfg_hostres *resources; /* Host Resources */ /* diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index 842b8db..56856ad 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -291,7 +291,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) struct cod_manager *cod_man; struct chnl_mgr *hchnl_mgr; struct msg_mgr *hmsg_mgr; - struct iommu *mmu; + struct shm_segs *sm_sg; u32 ul_shm_base; u32 ul_shm_base_offset; u32 ul_shm_limit; @@ -317,14 +317,6 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) u32 shm0_end; u32 ul_dyn_ext_base; u32 ul_seg1_size = 0; - u32 pa_curr = 0; - u32 va_curr = 0; - u32 gpp_va_curr = 0; - u32 num_bytes = 0; - u32 all_bits = 0; - u32 page_size[] = { HW_PAGE_SIZE16MB, HW_PAGE_SIZE1MB, - HW_PAGE_SIZE64KB, HW_PAGE_SIZE4KB - }; status = dev_get_bridge_context(hio_mgr->hdev_obj, &pbridge_context); if (!pbridge_context) { @@ -337,19 +329,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) status = -EFAULT; goto func_end; } - mmu = pbridge_context->dsp_mmu; - - if (mmu) - iommu_put(mmu); - mmu = iommu_get("iva2"); - - if (IS_ERR_OR_NULL(mmu)) { - dev_err(bridge, "iommu_get failed!\n"); - pbridge_context->dsp_mmu = NULL; - status = -EFAULT; - goto func_end; - } - pbridge_context->dsp_mmu = mmu; + sm_sg = &pbridge_context->sh_s; status = dev_get_cod_mgr(hio_mgr->hdev_obj, &cod_man); if (!cod_man) { @@ -485,74 +465,14 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) if (status) goto func_end; - pa_curr = ul_gpp_pa; - va_curr = ul_dyn_ext_base * hio_mgr->word_size; - gpp_va_curr = ul_gpp_va; - num_bytes = ul_seg1_size; - - va_curr = iommu_kmap(mmu, va_curr, pa_curr, num_bytes, - IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32); - if (IS_ERR_VALUE(va_curr)) { - status = (int)va_curr; - goto func_end; - } - - pa_curr += ul_pad_size + num_bytes; - va_curr += ul_pad_size + num_bytes; - gpp_va_curr += ul_pad_size + num_bytes; - - /* Configure the TLB entries for the next cacheable segment */ - num_bytes = ul_seg_size; - va_curr = ul_dsp_va * hio_mgr->word_size; - while (num_bytes) { - /* -* To find the max. page size with which both PA & VA are -* aligned. -*/ - all_bits = pa_curr | va_curr; - dev_dbg(bridge, "all_bits for Seg1 %x, pa_curr %x, " - "va_curr %x, num_bytes %x\n", all_bits, pa_curr, - va_curr, num_bytes); - for (i = 0; i < 4; i++) { - if (!(num_bytes >= page_size[i]) || - !((all_bits & (page_size[i] - 1)) == 0)) - continue; - if (ndx < MAX_LOCK_TLB_ENTRIES) { - /* -* This is the physical address written to -* D
[PATCHv2 01/11] staging: tidspbridge: replace iommu custom for opensource implementation
Now the tidspbridge uses the API's from iovmm module. Signed-off-by: Fernando Guzman Lugo --- drivers/staging/tidspbridge/core/_tiomap.h |4 +- drivers/staging/tidspbridge/core/io_sm.c | 121 ++ drivers/staging/tidspbridge/core/tiomap3430.c | 522 drivers/staging/tidspbridge/core/ue_deh.c |8 - .../tidspbridge/include/dspbridge/dspdefs.h|2 +- drivers/staging/tidspbridge/rmgr/proc.c|2 +- 6 files changed, 138 insertions(+), 521 deletions(-) diff --git a/drivers/staging/tidspbridge/core/_tiomap.h b/drivers/staging/tidspbridge/core/_tiomap.h index 1c1f157..a42c393 100644 --- a/drivers/staging/tidspbridge/core/_tiomap.h +++ b/drivers/staging/tidspbridge/core/_tiomap.h @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include #include /* for bridge_ioctl_extproc defn */ @@ -328,7 +330,7 @@ struct bridge_dev_context { u32 dw_internal_size; /* Internal memory size */ struct omap_mbox *mbox; /* Mail box handle */ - + struct iommu *dsp_mmu; /* iommu for iva2 handler */ struct cfg_hostres *resources; /* Host Resources */ /* diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index 5718645..842b8db 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -291,6 +291,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) struct cod_manager *cod_man; struct chnl_mgr *hchnl_mgr; struct msg_mgr *hmsg_mgr; + struct iommu *mmu; u32 ul_shm_base; u32 ul_shm_base_offset; u32 ul_shm_limit; @@ -313,7 +314,6 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) struct bridge_ioctl_extproc ae_proc[BRDIOCTL_NUMOFMMUTLB]; struct cfg_hostres *host_res; struct bridge_dev_context *pbridge_context; - u32 map_attrs; u32 shm0_end; u32 ul_dyn_ext_base; u32 ul_seg1_size = 0; @@ -337,6 +337,20 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) status = -EFAULT; goto func_end; } + mmu = pbridge_context->dsp_mmu; + + if (mmu) + iommu_put(mmu); + mmu = iommu_get("iva2"); + + if (IS_ERR_OR_NULL(mmu)) { + dev_err(bridge, "iommu_get failed!\n"); + pbridge_context->dsp_mmu = NULL; + status = -EFAULT; + goto func_end; + } + pbridge_context->dsp_mmu = mmu; + status = dev_get_cod_mgr(hio_mgr->hdev_obj, &cod_man); if (!cod_man) { status = -EFAULT; @@ -476,55 +490,16 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) gpp_va_curr = ul_gpp_va; num_bytes = ul_seg1_size; - /* -* Try to fit into TLB entries. If not possible, push them to page -* tables. It is quite possible that if sections are not on -* bigger page boundary, we may end up making several small pages. -* So, push them onto page tables, if that is the case. -*/ - map_attrs = 0x; - map_attrs = DSP_MAPLITTLEENDIAN; - map_attrs |= DSP_MAPPHYSICALADDR; - map_attrs |= DSP_MAPELEMSIZE32; - map_attrs |= DSP_MAPDONOTLOCK; - - while (num_bytes) { - /* -* To find the max. page size with which both PA & VA are -* aligned. -*/ - all_bits = pa_curr | va_curr; - dev_dbg(bridge, "all_bits %x, pa_curr %x, va_curr %x, " - "num_bytes %x\n", all_bits, pa_curr, va_curr, - num_bytes); - for (i = 0; i < 4; i++) { - if ((num_bytes >= page_size[i]) && ((all_bits & -(page_size[i] - - 1)) == 0)) { - status = - hio_mgr->intf_fxns-> - pfn_brd_mem_map(hio_mgr->hbridge_context, - pa_curr, va_curr, - page_size[i], map_attrs, - NULL); - if (status) - goto func_end; - pa_curr += page_size[i]; - va_curr += page_size[i]; - gpp_va_curr += page_size[i]; - num_bytes -= page_size[i]; - /* -* Don't try smaller sizes. Hopefully we have -
[PATCHv2 04/11] staging: tidspbridge - remove custom mmu code from tiomap3430.c
This patch removes all the custom mmu code remaining in tiomap3430.c which is not needed anymore. Signed-off-by: Fernando Guzman Lugo --- drivers/staging/tidspbridge/core/_tiomap.h|2 - drivers/staging/tidspbridge/core/tiomap3430.c | 425 - 2 files changed, 0 insertions(+), 427 deletions(-) diff --git a/drivers/staging/tidspbridge/core/_tiomap.h b/drivers/staging/tidspbridge/core/_tiomap.h index 8777492..394a64a 100644 --- a/drivers/staging/tidspbridge/core/_tiomap.h +++ b/drivers/staging/tidspbridge/core/_tiomap.h @@ -330,7 +330,6 @@ struct bridge_dev_context { */ u32 dw_dsp_ext_base_addr; /* See the comment above */ u32 dw_api_reg_base;/* API mem map'd registers */ - void __iomem *dw_dsp_mmu_base; /* DSP MMU Mapped registers */ u32 dw_api_clk_base;/* CLK Registers */ u32 dw_dsp_clk_m2_base; /* DSP Clock Module m2 */ u32 dw_public_rhea; /* Pub Rhea */ @@ -356,7 +355,6 @@ struct bridge_dev_context { /* TC Settings */ bool tc_word_swap_on; /* Traffic Controller Word Swap */ - struct pg_table_attrs *pt_attrs; u32 dsp_per_clks; }; diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index 8825700..f99cc24 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -102,56 +102,8 @@ static int bridge_dev_create(struct bridge_dev_context static int bridge_dev_ctrl(struct bridge_dev_context *dev_context, u32 dw_cmd, void *pargs); static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt); -static int pte_update(struct bridge_dev_context *dev_ctxt, u32 pa, -u32 va, u32 size, -struct hw_mmu_map_attrs_t *map_attrs); -static int pte_set(struct pg_table_attrs *pt, u32 pa, u32 va, - u32 size, struct hw_mmu_map_attrs_t *attrs); -static int mem_map_vmalloc(struct bridge_dev_context *dev_context, - u32 ul_mpu_addr, u32 virt_addr, - u32 ul_num_bytes, - struct hw_mmu_map_attrs_t *hw_attrs); - bool wait_for_start(struct bridge_dev_context *dev_context, u32 dw_sync_addr); -/* --- Globals */ - -/* Attributes of L2 page tables for DSP MMU */ -struct page_info { - u32 num_entries;/* Number of valid PTEs in the L2 PT */ -}; - -/* Attributes used to manage the DSP MMU page tables */ -struct pg_table_attrs { - spinlock_t pg_lock; /* Critical section object handle */ - - u32 l1_base_pa; /* Physical address of the L1 PT */ - u32 l1_base_va; /* Virtual address of the L1 PT */ - u32 l1_size;/* Size of the L1 PT */ - u32 l1_tbl_alloc_pa; - /* Physical address of Allocated mem for L1 table. May not be aligned */ - u32 l1_tbl_alloc_va; - /* Virtual address of Allocated mem for L1 table. May not be aligned */ - u32 l1_tbl_alloc_sz; - /* Size of consistent memory allocated for L1 table. -* May not be aligned */ - - u32 l2_base_pa; /* Physical address of the L2 PT */ - u32 l2_base_va; /* Virtual address of the L2 PT */ - u32 l2_size;/* Size of the L2 PT */ - u32 l2_tbl_alloc_pa; - /* Physical address of Allocated mem for L2 table. May not be aligned */ - u32 l2_tbl_alloc_va; - /* Virtual address of Allocated mem for L2 table. May not be aligned */ - u32 l2_tbl_alloc_sz; - /* Size of consistent memory allocated for L2 table. -* May not be aligned */ - - u32 l2_num_pages; /* Number of allocated L2 PT */ - /* Array [l2_num_pages] of L2 PT info structs */ - struct page_info *pg_info; -}; - /* * This Bridge driver's function interface table. */ @@ -200,27 +152,6 @@ static struct bridge_drv_interface drv_interface_fxns = { bridge_msg_set_queue_id, }; -static inline void flush_all(struct bridge_dev_context *dev_context) -{ - if (dev_context->dw_brd_state == BRD_DSP_HIBERNATION || - dev_context->dw_brd_state == BRD_HIBERNATION) - wake_dsp(dev_context, NULL); - - hw_mmu_tlb_flush_all(dev_context->dw_dsp_mmu_base); -} - -static void bad_page_dump(u32 pa, struct page *pg) -{ - pr_emerg("DSPBRIDGE: MAP function: COUNT 0 FOR PA 0x%x\n", pa); - pr_emerg("Bad page state in process '%s'\n" -"page:%p flags:0x%0*lx mapping:%p mapcount:%d count:%d\n" -"Backtrace:\n", -current->comm, pg, (int)(2 * sizeof(unsigned long)), -(unsigned long)pg->flags, pg->mapping, -page_mapcount(pg), page_count(pg)); -
[PATCHv2 11/11] staging: tidspbridge - remove dmm custom module
Dmm custom module is not needed anymore. Signed-off-by: Fernando Guzman Lugo --- drivers/staging/tidspbridge/Makefile |2 +- drivers/staging/tidspbridge/core/tiomap3430.c |1 - .../staging/tidspbridge/include/dspbridge/dev.h| 24 - .../staging/tidspbridge/include/dspbridge/dmm.h| 75 --- .../staging/tidspbridge/include/dspbridge/drv.h|6 - drivers/staging/tidspbridge/pmgr/dev.c | 61 +--- drivers/staging/tidspbridge/pmgr/dmm.c | 533 drivers/staging/tidspbridge/rmgr/node.c| 28 +- drivers/staging/tidspbridge/rmgr/proc.c| 23 - 9 files changed, 6 insertions(+), 747 deletions(-) delete mode 100644 drivers/staging/tidspbridge/include/dspbridge/dmm.h delete mode 100644 drivers/staging/tidspbridge/pmgr/dmm.c diff --git a/drivers/staging/tidspbridge/Makefile b/drivers/staging/tidspbridge/Makefile index bd36651..7c122fa 100644 --- a/drivers/staging/tidspbridge/Makefile +++ b/drivers/staging/tidspbridge/Makefile @@ -5,7 +5,7 @@ libcore = core/chnl_sm.o core/msg_sm.o core/io_sm.o core/tiomap3430.o \ core/tiomap3430_pwr.o core/tiomap_io.o core/dsp-mmu.o \ core/ue_deh.o core/wdt.o core/dsp-clock.o core/sync.o libpmgr = pmgr/chnl.o pmgr/io.o pmgr/msg.o pmgr/cod.o pmgr/dev.o pmgr/dspapi.o \ - pmgr/dmm.o pmgr/cmm.o pmgr/dbll.o + pmgr/cmm.o pmgr/dbll.o librmgr = rmgr/dbdcd.o rmgr/disp.o rmgr/drv.o rmgr/mgr.o rmgr/node.o \ rmgr/proc.o rmgr/pwr.o rmgr/rmm.o rmgr/strm.o rmgr/dspdrv.o \ rmgr/nldr.o rmgr/drv_interface.o diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index f890a0e..0e3558a 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -45,7 +45,6 @@ /* --- Platform Manager */ #include #include -#include #include /* --- Local */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dev.h b/drivers/staging/tidspbridge/include/dspbridge/dev.h index 357458f..9bdd48f 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dev.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dev.h @@ -27,7 +27,6 @@ #include #include #include -#include #include /* --- This */ @@ -234,29 +233,6 @@ extern int dev_get_cmm_mgr(struct dev_object *hdev_obj, struct cmm_object **mgr); /* - * dev_get_dmm_mgr - * Purpose: - * Retrieve the handle to the dynamic memory manager created for this - * device. - * Parameters: - * hdev_obj: Handle to device object created with - * dev_create_device(). - * *mgr: Ptr to location to store handle. - * Returns: - * 0:Success. - * -EFAULT:Invalid hdev_obj. - * Requires: - * mgr != NULL. - * DEV Initialized. - * Ensures: - * 0:*mgr contains a handle to a channel manager object, - * or NULL. - * else: *mgr is NULL. - */ -extern int dev_get_dmm_mgr(struct dev_object *hdev_obj, - struct dmm_object **mgr); - -/* * dev_get_cod_mgr * Purpose: * Retrieve the COD manager create for this device. diff --git a/drivers/staging/tidspbridge/include/dspbridge/dmm.h b/drivers/staging/tidspbridge/include/dspbridge/dmm.h deleted file mode 100644 index 6c58335..000 --- a/drivers/staging/tidspbridge/include/dspbridge/dmm.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * dmm.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * The Dynamic Memory Mapping(DMM) module manages the DSP Virtual address - * space that can be directly mapped to any MPU buffer or memory region. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef DMM_ -#define DMM_ - -#include - -struct dmm_object; - -/* DMM attributes used in dmm_create() */ -struct dmm_mgrattrs { - u32 reserved; -}; - -#define DMMPOOLSIZE 0x400 - -/* - * dmm_get_handle - * Purpose: - * Return the dynamic memory manager object for this device. - * This is typically called from the client process. - */ - -extern int dmm_get_handle(void *hprocessor, -struct dmm_object **dmm_manager); - -extern int dmm_reserve_memory(struct dmm_objec
[PATCH 2/4] iovmm: fix roundup for next area and end check for the last area
As da_end does not belongs to the area the roundup should be done to da_end and not to da_end + 1. Also the end check for the last area should be ULONG_MAX - start + 1 >= bytes. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/iovmm.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 24ca9c4..fc6b109 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -289,19 +289,19 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, prev_end = 0; list_for_each_entry(tmp, &obj->mmap, list) { - if (prev_end >= start) + if (prev_end > start) break; if (start + bytes <= tmp->da_start) goto found; if (flags & IOVMF_DA_ANON) - start = roundup(tmp->da_end + 1, alignement); + start = roundup(tmp->da_end, alignement); prev_end = tmp->da_end; } - if ((start > prev_end) && (ULONG_MAX - start >= bytes)) + if ((start >= prev_end) && (ULONG_MAX - start + 1 >= bytes)) goto found; dev_dbg(obj->dev, "%s: no space to fit %08x(%x) flags: %08x\n", -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/4] iovmm: add superpages support to fixed da address
This patch adds superpages support to fixed ad address inside iommu_kmap function. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/iovmm.c | 61 ++- 1 files changed, 37 insertions(+), 24 deletions(-) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index fc6b109..e7ffec8 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -87,27 +87,37 @@ static size_t sgtable_len(const struct sg_table *sgt) } #define sgtable_ok(x) (!!sgtable_len(x)) + +static unsigned max_alignment(u32 addr) +{ + int i; + unsigned pagesize[] = { SZ_16M, SZ_1M, SZ_64K, SZ_4K, }; + for (i = 0; i < ARRAY_SIZE(pagesize) && addr & (pagesize[i] - 1); i++) + ; + return (i < ARRAY_SIZE(pagesize)) ? pagesize[i] : 0; +} + + /* * calculate the optimal number sg elements from total bytes based on * iommu superpages */ -static unsigned int sgtable_nents(size_t bytes) +static unsigned int sgtable_nents(size_t bytes, u32 da, u32 pa) { - int i; - unsigned int nr_entries; - const unsigned long pagesize[] = { SZ_16M, SZ_1M, SZ_64K, SZ_4K, }; + unsigned int nr_entries = 0, ent_sz; if (!IS_ALIGNED(bytes, PAGE_SIZE)) { pr_err("%s: wrong size %08x\n", __func__, bytes); return 0; } - nr_entries = 0; - for (i = 0; i < ARRAY_SIZE(pagesize); i++) { - if (bytes >= pagesize[i]) { - nr_entries += (bytes / pagesize[i]); - bytes %= pagesize[i]; - } + while (bytes) { + ent_sz = max_alignment(da | pa); + ent_sz = min(ent_sz, (unsigned)iopgsz_max(bytes)); + nr_entries++; + da += ent_sz; + pa += ent_sz; + bytes -= ent_sz; } BUG_ON(bytes); @@ -115,7 +125,8 @@ static unsigned int sgtable_nents(size_t bytes) } /* allocate and initialize sg_table header(a kind of 'superblock') */ -static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags) +static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags, + u32 da, u32 pa) { unsigned int nr_entries; int err; @@ -127,9 +138,8 @@ static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags) if (!IS_ALIGNED(bytes, PAGE_SIZE)) return ERR_PTR(-EINVAL); - /* FIXME: IOVMF_DA_FIXED should support 'superpages' */ - if ((flags & IOVMF_LINEAR) && (flags & IOVMF_DA_ANON)) { - nr_entries = sgtable_nents(bytes); + if (flags & IOVMF_LINEAR) { + nr_entries = sgtable_nents(bytes, da, pa); if (!nr_entries) return ERR_PTR(-EINVAL); } else @@ -409,7 +419,8 @@ static inline void sgtable_drain_vmalloc(struct sg_table *sgt) BUG_ON(!sgt); } -static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) +static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, u32 da, + size_t len) { unsigned int i; struct scatterlist *sg; @@ -420,7 +431,8 @@ static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) for_each_sg(sgt->sgl, sg, sgt->nents, i) { size_t bytes; - bytes = iopgsz_max(len); + bytes = max_alignment(da | pa); + bytes = min(bytes, (size_t)iopgsz_max(len)); BUG_ON(!iopgsz_ok(bytes)); @@ -429,6 +441,7 @@ static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) * 'pa' is cotinuous(linear). */ pa += bytes; + da += bytes; len -= bytes; } BUG_ON(len); @@ -695,18 +708,18 @@ u32 iommu_vmalloc(struct iommu *obj, u32 da, size_t bytes, u32 flags) if (!va) return -ENOMEM; - sgt = sgtable_alloc(bytes, flags); + flags &= IOVMF_HW_MASK; + flags |= IOVMF_DISCONT; + flags |= IOVMF_ALLOC; + flags |= (da ? IOVMF_DA_FIXED : IOVMF_DA_ANON); + + sgt = sgtable_alloc(bytes, flags, da, 0); if (IS_ERR(sgt)) { da = PTR_ERR(sgt); goto err_sgt_alloc; } sgtable_fill_vmalloc(sgt, va); - flags &= IOVMF_HW_MASK; - flags |= IOVMF_DISCONT; - flags |= IOVMF_ALLOC; - flags |= (da ? IOVMF_DA_FIXED : IOVMF_DA_ANON); - da = __iommu_vmap(obj, da, sgt, va, bytes, flags); if (IS_ERR_VALUE(da)) goto err_iommu_vmap; @@ -746,11 +759,11 @@ static u32 __iommu_kmap(struct iommu *obj, u32 da, u32 pa, void *va, { struct sg_table *sgt; - sgt = sgta
[PATCH 1/4] iommu: remove CONFIG_MPU_BRIDGE_IOMMU
remove CONFIG_MPU_BRIDGE_IOMMU in order to create iommu_device for iva2. Signed-off-by: Fernando Guzman Lugo --- arch/arm/mach-omap2/omap-iommu.c |2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c index f5a1aad..bb8c01d 100644 --- a/arch/arm/mach-omap2/omap-iommu.c +++ b/arch/arm/mach-omap2/omap-iommu.c @@ -35,7 +35,6 @@ static struct iommu_device omap3_devices[] = { .clk_name = "cam_ick", }, }, -#if defined(CONFIG_MPU_BRIDGE_IOMMU) { .base = 0x5d00, .irq = 28, @@ -45,7 +44,6 @@ static struct iommu_device omap3_devices[] = { .clk_name = "iva2_ck", }, }, -#endif }; #define NR_OMAP3_IOMMU_DEVICES ARRAY_SIZE(omap3_devices) static struct platform_device *omap3_iommu_pdev[NR_OMAP3_IOMMU_DEVICES]; -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/4] iovmm: replace __iounmap with omap_iounmap
Omap platform is omap_iounmap function. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/iovmm.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) mode change 100644 => 100755 arch/arm/plat-omap/iovmm.c diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c old mode 100644 new mode 100755 index e7ffec8..326776d --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -824,7 +824,7 @@ void iommu_kunmap(struct iommu *obj, u32 da) struct sg_table *sgt; typedef void (*func_t)(const void *); - sgt = unmap_vm_area(obj, da, (func_t)__iounmap, + sgt = unmap_vm_area(obj, da, (func_t)omap_iounmap, IOVMF_LINEAR | IOVMF_MMIO); if (!sgt) dev_dbg(obj->dev, "%s: No sgt\n", __func__); -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/4] iovmm: fixes for iovmm module
This patches are needed in order to tidspbridge can use iovmm with no issues. Fernando Guzman Lugo (4): iommu: remove CONFIG_MPU_BRIDGE_IOMMU iovmm: fix roundup for next area and end check for the last area iovmm: add superpages support to fixed da address iovmm: replace __iounmap with omap_iounmap arch/arm/mach-omap2/omap-iommu.c |2 - arch/arm/plat-omap/iovmm.c | 69 ++--- 2 files changed, 41 insertions(+), 30 deletions(-) mode change 100644 => 100755 arch/arm/plat-omap/iovmm.c -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] scatterlist: define SG chain for arm architecture
Define SG chain for ARM architecture in order to work with big buffers. This patch is needed in order to iovmm users can pass a big buffer to map it and ARM architecture has not issues using SG chain. This change was suggested by FUJITA Tomonori. Signed-off-by: Fernando Guzman Lugo --- arch/arm/include/asm/scatterlist.h |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/arch/arm/include/asm/scatterlist.h b/arch/arm/include/asm/scatterlist.h index 2f87870..3de0a0b 100644 --- a/arch/arm/include/asm/scatterlist.h +++ b/arch/arm/include/asm/scatterlist.h @@ -5,4 +5,6 @@ #include #include +#define ARCH_HAS_SG_CHAIN + #endif /* _ASMARM_SCATTERLIST_H */ -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 2/3] iovmm: add superpages support to fixed da address
This patch adds superpages support to fixed ad address inside iommu_kmap function. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/iovmm.c | 61 ++- 1 files changed, 37 insertions(+), 24 deletions(-) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 34f0012..8006a19 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -87,27 +87,37 @@ static size_t sgtable_len(const struct sg_table *sgt) } #define sgtable_ok(x) (!!sgtable_len(x)) + +static unsigned max_alignment(u32 addr) +{ + int i; + unsigned pagesize[] = { SZ_16M, SZ_1M, SZ_64K, SZ_4K, }; + for (i = 0; i < ARRAY_SIZE(pagesize) && addr & (pagesize[i] - 1); i++) + ; + return (i < ARRAY_SIZE(pagesize)) ? pagesize[i] : 0; +} + + /* * calculate the optimal number sg elements from total bytes based on * iommu superpages */ -static unsigned int sgtable_nents(size_t bytes) +static unsigned int sgtable_nents(size_t bytes, u32 da, u32 pa) { - int i; - unsigned int nr_entries; - const unsigned long pagesize[] = { SZ_16M, SZ_1M, SZ_64K, SZ_4K, }; + unsigned int nr_entries = 0, ent_sz; if (!IS_ALIGNED(bytes, PAGE_SIZE)) { pr_err("%s: wrong size %08x\n", __func__, bytes); return 0; } - nr_entries = 0; - for (i = 0; i < ARRAY_SIZE(pagesize); i++) { - if (bytes >= pagesize[i]) { - nr_entries += (bytes / pagesize[i]); - bytes %= pagesize[i]; - } + while (bytes) { + ent_sz = max_alignment(da | pa); + ent_sz = min(ent_sz, (unsigned)iopgsz_max(bytes)); + nr_entries++; + da += ent_sz; + pa += ent_sz; + bytes -= ent_sz; } BUG_ON(bytes); @@ -115,7 +125,8 @@ static unsigned int sgtable_nents(size_t bytes) } /* allocate and initialize sg_table header(a kind of 'superblock') */ -static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags) +static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags, + u32 da, u32 pa) { unsigned int nr_entries; int err; @@ -127,9 +138,8 @@ static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags) if (!IS_ALIGNED(bytes, PAGE_SIZE)) return ERR_PTR(-EINVAL); - /* FIXME: IOVMF_DA_FIXED should support 'superpages' */ - if ((flags & IOVMF_LINEAR) && (flags & IOVMF_DA_ANON)) { - nr_entries = sgtable_nents(bytes); + if (flags & IOVMF_LINEAR) { + nr_entries = sgtable_nents(bytes, da, pa); if (!nr_entries) return ERR_PTR(-EINVAL); } else @@ -409,7 +419,8 @@ static inline void sgtable_drain_vmalloc(struct sg_table *sgt) BUG_ON(!sgt); } -static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) +static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, u32 da, + size_t len) { unsigned int i; struct scatterlist *sg; @@ -420,7 +431,8 @@ static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) for_each_sg(sgt->sgl, sg, sgt->nents, i) { size_t bytes; - bytes = iopgsz_max(len); + bytes = max_alignment(da | pa); + bytes = min(bytes, (size_t)iopgsz_max(len)); BUG_ON(!iopgsz_ok(bytes)); @@ -429,6 +441,7 @@ static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) * 'pa' is cotinuous(linear). */ pa += bytes; + da += bytes; len -= bytes; } BUG_ON(len); @@ -695,18 +708,18 @@ u32 iommu_vmalloc(struct iommu *obj, u32 da, size_t bytes, u32 flags) if (!va) return -ENOMEM; - sgt = sgtable_alloc(bytes, flags); + flags &= IOVMF_HW_MASK; + flags |= IOVMF_DISCONT; + flags |= IOVMF_ALLOC; + flags |= (da ? IOVMF_DA_FIXED : IOVMF_DA_ANON); + + sgt = sgtable_alloc(bytes, flags, da, 0); if (IS_ERR(sgt)) { da = PTR_ERR(sgt); goto err_sgt_alloc; } sgtable_fill_vmalloc(sgt, va); - flags &= IOVMF_HW_MASK; - flags |= IOVMF_DISCONT; - flags |= IOVMF_ALLOC; - flags |= (da ? IOVMF_DA_FIXED : IOVMF_DA_ANON); - da = __iommu_vmap(obj, da, sgt, va, bytes, flags); if (IS_ERR_VALUE(da)) goto err_iommu_vmap; @@ -746,11 +759,11 @@ static u32 __iommu_kmap(struct iommu *obj, u32 da, u32 pa, void *va, { struct sg_table *sgt; - sgt = sgta
[PATCHv2 1/3] iovmm: no gap checking for fixed address
If some fixed da address is wanted to be mapped and the page is freed but it is used as gap, the mapping will fail. This patch is fixing that and olny keeps the gap for not fixed address. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/iovmm.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 24ca9c4..34f0012 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -289,7 +289,7 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, prev_end = 0; list_for_each_entry(tmp, &obj->mmap, list) { - if (prev_end >= start) + if (prev_end > start) break; if (start + bytes <= tmp->da_start) @@ -301,7 +301,7 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, prev_end = tmp->da_end; } - if ((start > prev_end) && (ULONG_MAX - start >= bytes)) + if ((start >= prev_end) && (ULONG_MAX - start + 1 >= bytes)) goto found; dev_dbg(obj->dev, "%s: no space to fit %08x(%x) flags: %08x\n", -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 0/3] iovmm: fixes for iovmm module
iovmm: fixes for iovmm module Version 2: * Removed "iovmm: fixes for iovmm module" that patch was already sent. * Modified "iovmm: fix roundup for next area and end check for the last area" patch, base on Davin Cohen's comments and rename it to a proper name that describes what it is doing now. Fernando Guzman Lugo (3): iovmm: no gap checking for fixed address iovmm: add superpages support to fixed da address iovmm: replace __iounmap with omap_iounmap arch/arm/plat-omap/iovmm.c | 67 ++- 1 files changed, 40 insertions(+), 27 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 3/3] iovmm: replace __iounmap with omap_iounmap
Omap platform is omap_iounmap function. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/iovmm.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 8006a19..75965a1 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -824,7 +824,7 @@ void iommu_kunmap(struct iommu *obj, u32 da) struct sg_table *sgt; typedef void (*func_t)(const void *); - sgt = unmap_vm_area(obj, da, (func_t)__iounmap, + sgt = unmap_vm_area(obj, da, (func_t)omap_iounmap, IOVMF_LINEAR | IOVMF_MMIO); if (!sgt) dev_dbg(obj->dev, "%s: No sgt\n", __func__); -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv3 03/11] staging: tidspbridge - rename bridge_brd_mem_map/unmap to a proper name
Now these functions only map user space addresses to dsp virtual addresses, so now the functions have a more meaningful name. Also now user_to_dsp_map returns the mapped address. Signed-off-by: Fernando Guzman Lugo --- drivers/staging/tidspbridge/core/_tiomap.h | 24 +++ drivers/staging/tidspbridge/core/tiomap3430.c | 153 ++-- .../tidspbridge/include/dspbridge/dspdefs.h| 44 -- drivers/staging/tidspbridge/pmgr/dev.c |2 - drivers/staging/tidspbridge/rmgr/proc.c| 34 +++-- 5 files changed, 116 insertions(+), 141 deletions(-) diff --git a/drivers/staging/tidspbridge/core/_tiomap.h b/drivers/staging/tidspbridge/core/_tiomap.h index c1bf95d..8777492 100644 --- a/drivers/staging/tidspbridge/core/_tiomap.h +++ b/drivers/staging/tidspbridge/core/_tiomap.h @@ -383,4 +383,28 @@ extern s32 dsp_debug; */ int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val); +/** + * user_to_dsp_map() - maps user to dsp virtual address + * @mmu: Pointer to iommu handle. + * @uva: Virtual user space address. + * @da DSP address + * @size Buffer size to map. + * @usr_pgsstruct page array pointer where the user pages will be stored + * + * This function maps a user space buffer into DSP virtual address. + * + */ +u32 user_to_dsp_map(struct iommu *mmu, u32 uva, u32 da, u32 size, + struct page **usr_pgs); + +/** + * user_to_dsp_unmap() - unmaps DSP virtual buffer. + * @mmu: Pointer to iommu handle. + * @da DSP address + * + * This function unmaps a user space buffer into DSP virtual address. + * + */ +int user_to_dsp_unmap(struct iommu *mmu, u32 da); + #endif /* _TIOMAP_ */ diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index 3749cd5..0e5b805 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -97,12 +97,6 @@ static int bridge_brd_mem_copy(struct bridge_dev_context *dev_ctxt, static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt, u8 *host_buff, u32 dsp_addr, u32 ul_num_bytes, u32 mem_type); -static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctxt, - u32 ul_mpu_addr, u32 virt_addr, - u32 ul_num_bytes, u32 ul_map_attr, - struct page **mapped_pages); -static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctxt, -u32 da); static int bridge_dev_create(struct bridge_dev_context **dev_cntxt, struct dev_object *hdev_obj, @@ -110,9 +104,6 @@ static int bridge_dev_create(struct bridge_dev_context static int bridge_dev_ctrl(struct bridge_dev_context *dev_context, u32 dw_cmd, void *pargs); static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt); -static int get_io_pages(struct mm_struct *mm, u32 uva, unsigned pages, - struct page **usr_pgs); -static u32 user_va2_pa(struct mm_struct *mm, u32 address); static int pte_update(struct bridge_dev_context *dev_ctxt, u32 pa, u32 va, u32 size, struct hw_mmu_map_attrs_t *map_attrs); @@ -182,8 +173,6 @@ static struct bridge_drv_interface drv_interface_fxns = { bridge_brd_set_state, bridge_brd_mem_copy, bridge_brd_mem_write, - bridge_brd_mem_map, - bridge_brd_mem_un_map, /* The following CHNL functions are provided by chnl_io.lib: */ bridge_chnl_create, bridge_chnl_destroy, @@ -1154,22 +1143,77 @@ static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt, } /* - * bridge_brd_mem_map - * This function maps MPU buffer to the DSP address space. It performs - * linear to physical address translation if required. It translates each - * page since linear addresses can be physically non-contiguous - * All address & size arguments are assumed to be page aligned (in proc.c) + * user_va2_pa + * Purpose: + * This function walks through the page tables to convert a userland + * virtual address to physical address + */ +static u32 user_va2_pa(struct mm_struct *mm, u32 address) +{ + pgd_t *pgd; + pmd_t *pmd; + pte_t *ptep, pte; + + pgd = pgd_offset(mm, address); + if (!(pgd_none(*pgd) || pgd_bad(*pgd))) { + pmd = pmd_offset(pgd, address); + if (!(pmd_none(*pmd) || pmd_bad(*pmd))) { + ptep = pte_offset_map(pmd, address); + if (ptep) { + pte = *
[PATCHv3 08/11] staging: tidspbridge: remove dw_dmmu_base from cfg_hostres struct
We don't need to map iva2 iommu register base address anymore. Signed-off-by: Fernando Guzman Lugo --- drivers/staging/tidspbridge/core/tiomap3430.c |3 --- drivers/staging/tidspbridge/core/tiomap_io.c |3 +-- .../tidspbridge/include/dspbridge/cfgdefs.h|1 - drivers/staging/tidspbridge/rmgr/drv.c |4 4 files changed, 1 insertions(+), 10 deletions(-) diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index 4927ec3..a95ff2f 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -833,8 +833,6 @@ static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt) iounmap((void *)host_res->dw_mem_base[3]); if (host_res->dw_mem_base[4]) iounmap((void *)host_res->dw_mem_base[4]); - if (host_res->dw_dmmu_base) - iounmap(host_res->dw_dmmu_base); if (host_res->dw_per_base) iounmap(host_res->dw_per_base); if (host_res->dw_per_pm_base) @@ -848,7 +846,6 @@ static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt) host_res->dw_mem_base[2] = (u32) NULL; host_res->dw_mem_base[3] = (u32) NULL; host_res->dw_mem_base[4] = (u32) NULL; - host_res->dw_dmmu_base = NULL; host_res->dw_sys_ctrl_base = NULL; kfree(host_res); diff --git a/drivers/staging/tidspbridge/core/tiomap_io.c b/drivers/staging/tidspbridge/core/tiomap_io.c index b526532..66dbf02 100644 --- a/drivers/staging/tidspbridge/core/tiomap_io.c +++ b/drivers/staging/tidspbridge/core/tiomap_io.c @@ -393,7 +393,6 @@ int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val) omap_dspbridge_dev->dev.platform_data; struct cfg_hostres *resources = dev_context->resources; int status = 0; - u32 temp; if (!dev_context->mbox) return 0; @@ -437,7 +436,7 @@ int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val) omap_mbox_restore_ctx(dev_context->mbox); /* Access MMU SYS CONFIG register to generate a short wakeup */ - temp = readl(resources->dw_dmmu_base + 0x10); + iommu_read_reg(dev_context->dsp_mmu, MMU_SYSCONFIG); dev_context->dw_brd_state = BRD_RUNNING; } else if (dev_context->dw_brd_state == BRD_RETENTION) { diff --git a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h b/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h index 38122db..dfb55cc 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h @@ -68,7 +68,6 @@ struct cfg_hostres { void __iomem *dw_per_base; u32 dw_per_pm_base; u32 dw_core_pm_base; - void __iomem *dw_dmmu_base; void __iomem *dw_sys_ctrl_base; }; diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c index 81b1b90..0c857b9 100644 --- a/drivers/staging/tidspbridge/rmgr/drv.c +++ b/drivers/staging/tidspbridge/rmgr/drv.c @@ -743,7 +743,6 @@ static int request_bridge_resources(struct cfg_hostres *res) host_res->dw_sys_ctrl_base = ioremap(OMAP_SYSC_BASE, OMAP_SYSC_SIZE); dev_dbg(bridge, "dw_mem_base[0] 0x%x\n", host_res->dw_mem_base[0]); dev_dbg(bridge, "dw_mem_base[3] 0x%x\n", host_res->dw_mem_base[3]); - dev_dbg(bridge, "dw_dmmu_base %p\n", host_res->dw_dmmu_base); /* for 24xx base port is not mapping the mamory for DSP * internal memory TODO Do a ioremap here */ @@ -797,8 +796,6 @@ int drv_request_bridge_res_dsp(void **phost_resources) OMAP_PER_PRM_SIZE); host_res->dw_core_pm_base = (u32) ioremap(OMAP_CORE_PRM_BASE, OMAP_CORE_PRM_SIZE); - host_res->dw_dmmu_base = ioremap(OMAP_DMMU_BASE, -OMAP_DMMU_SIZE); dev_dbg(bridge, "dw_mem_base[0] 0x%x\n", host_res->dw_mem_base[0]); @@ -810,7 +807,6 @@ int drv_request_bridge_res_dsp(void **phost_resources) host_res->dw_mem_base[3]); dev_dbg(bridge, "dw_mem_base[4] 0x%x\n", host_res->dw_mem_base[4]); - dev_dbg(bridge, "dw_dmmu_base %p\n", host_res->dw_dmmu_base); shm_size = drv_datap->shm_size; if (shm_size >= 0x1) { -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv3 10/11] staging: tidspbridge - deprecate reserve/unreserve_memory funtions
Now what iommu memory usage is kept track by iommu module the functions reserve/unreserve_memory are not needed anymore. Signed-off-by: Fernando Guzman Lugo --- .../staging/tidspbridge/include/dspbridge/proc.h | 46 drivers/staging/tidspbridge/pmgr/dspapi.c | 34 +- drivers/staging/tidspbridge/rmgr/node.c| 20 + drivers/staging/tidspbridge/rmgr/proc.c| 114 ++-- 4 files changed, 17 insertions(+), 197 deletions(-) diff --git a/drivers/staging/tidspbridge/include/dspbridge/proc.h b/drivers/staging/tidspbridge/include/dspbridge/proc.h index 5e09fd1..2d12aab 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/proc.h +++ b/drivers/staging/tidspbridge/include/dspbridge/proc.h @@ -551,29 +551,6 @@ extern int proc_map(void *hprocessor, struct process_context *pr_ctxt); /* - * proc_reserve_memory - * Purpose: - * Reserve a virtually contiguous region of DSP address space. - * Parameters: - * hprocessor : The processor handle. - * ul_size : Size of the address space to reserve. - * pp_rsv_addr : Ptr to DSP side reserved u8 address. - * Returns: - * 0 : Success. - * -EFAULT : Invalid processor handle. - * -EPERM : General failure. - * -ENOMEM : Cannot reserve chunk of this size. - * Requires: - * pp_rsv_addr is not NULL - * PROC Initialized. - * Ensures: - * Details: - */ -extern int proc_reserve_memory(void *hprocessor, - u32 ul_size, void **pp_rsv_addr, - struct process_context *pr_ctxt); - -/* * proc_un_map * Purpose: * Removes a MPU buffer mapping from the DSP address space. @@ -595,27 +572,4 @@ extern int proc_reserve_memory(void *hprocessor, extern int proc_un_map(void *hprocessor, void *map_addr, struct process_context *pr_ctxt); -/* - * proc_un_reserve_memory - * Purpose: - * Frees a previously reserved region of DSP address space. - * Parameters: - * hprocessor : The processor handle. - * prsv_addr : Ptr to DSP side reservedBYTE address. - * Returns: - * 0 : Success. - * -EFAULT : Invalid processor handle. - * -EPERM : General failure. - * -ENOENT : Cannot find a reserved region starting with this - * : address. - * Requires: - * prsv_addr is not NULL - * PROC Initialized. - * Ensures: - * Details: - */ -extern int proc_un_reserve_memory(void *hprocessor, -void *prsv_addr, -struct process_context *pr_ctxt); - #endif /* PROC_ */ diff --git a/drivers/staging/tidspbridge/pmgr/dspapi.c b/drivers/staging/tidspbridge/pmgr/dspapi.c index faf8304..0187c47 100644 --- a/drivers/staging/tidspbridge/pmgr/dspapi.c +++ b/drivers/staging/tidspbridge/pmgr/dspapi.c @@ -989,27 +989,10 @@ u32 procwrap_register_notify(union trapped_args *args, void *pr_ctxt) /* * procwrap_reserve_memory */ -u32 procwrap_reserve_memory(union trapped_args *args, void *pr_ctxt) +u32 __deprecated procwrap_reserve_memory(union trapped_args *args, + void *pr_ctxt) { - int status; - void *prsv_addr; - void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor; - - if ((args->args_proc_rsvmem.ul_size <= 0) || - (args->args_proc_rsvmem.ul_size & (PG_SIZE4K - 1)) != 0) - return -EINVAL; - - status = proc_reserve_memory(hprocessor, -args->args_proc_rsvmem.ul_size, &prsv_addr, -pr_ctxt); - if (!status) { - if (put_user(prsv_addr, args->args_proc_rsvmem.pp_rsv_addr)) { - status = -EINVAL; - proc_un_reserve_memory(args->args_proc_rsvmem. - hprocessor, prsv_addr, pr_ctxt); - } - } - return status; + return 0; } /* @@ -1038,15 +1021,10 @@ u32 procwrap_un_map(union trapped_args *args, void *pr_ctxt) /* * procwrap_un_reserve_memory */ -u32 procwrap_un_reserve_memory(union trapped_args *args, void *pr_ctxt) +u32 __deprecated procwrap_un_reserve_memory(union trapped_args *args, + void *pr_ctxt) { - int status; - void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor; - - status = proc_un_reserve_memory(hprocessor, - args->args_proc_unrsvmem.prsv_addr, - pr_ctxt); - return status; + return 0; }
[PATCHv3 11/11] staging: tidspbridge - remove dmm custom module
Dmm custom module is not needed anymore. Signed-off-by: Fernando Guzman Lugo --- drivers/staging/tidspbridge/Makefile |2 +- drivers/staging/tidspbridge/core/tiomap3430.c |1 - .../staging/tidspbridge/include/dspbridge/dev.h| 24 - .../staging/tidspbridge/include/dspbridge/dmm.h| 75 --- .../staging/tidspbridge/include/dspbridge/drv.h|6 - drivers/staging/tidspbridge/pmgr/dev.c | 61 +--- drivers/staging/tidspbridge/pmgr/dmm.c | 533 drivers/staging/tidspbridge/rmgr/node.c| 28 +- drivers/staging/tidspbridge/rmgr/proc.c| 23 - 9 files changed, 6 insertions(+), 747 deletions(-) delete mode 100644 drivers/staging/tidspbridge/include/dspbridge/dmm.h delete mode 100644 drivers/staging/tidspbridge/pmgr/dmm.c diff --git a/drivers/staging/tidspbridge/Makefile b/drivers/staging/tidspbridge/Makefile index bd36651..7c122fa 100644 --- a/drivers/staging/tidspbridge/Makefile +++ b/drivers/staging/tidspbridge/Makefile @@ -5,7 +5,7 @@ libcore = core/chnl_sm.o core/msg_sm.o core/io_sm.o core/tiomap3430.o \ core/tiomap3430_pwr.o core/tiomap_io.o core/dsp-mmu.o \ core/ue_deh.o core/wdt.o core/dsp-clock.o core/sync.o libpmgr = pmgr/chnl.o pmgr/io.o pmgr/msg.o pmgr/cod.o pmgr/dev.o pmgr/dspapi.o \ - pmgr/dmm.o pmgr/cmm.o pmgr/dbll.o + pmgr/cmm.o pmgr/dbll.o librmgr = rmgr/dbdcd.o rmgr/disp.o rmgr/drv.o rmgr/mgr.o rmgr/node.o \ rmgr/proc.o rmgr/pwr.o rmgr/rmm.o rmgr/strm.o rmgr/dspdrv.o \ rmgr/nldr.o rmgr/drv_interface.o diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index a95ff2f..f22bc12 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -47,7 +47,6 @@ /* --- Platform Manager */ #include #include -#include #include /* --- Local */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dev.h b/drivers/staging/tidspbridge/include/dspbridge/dev.h index 357458f..9bdd48f 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dev.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dev.h @@ -27,7 +27,6 @@ #include #include #include -#include #include /* --- This */ @@ -234,29 +233,6 @@ extern int dev_get_cmm_mgr(struct dev_object *hdev_obj, struct cmm_object **mgr); /* - * dev_get_dmm_mgr - * Purpose: - * Retrieve the handle to the dynamic memory manager created for this - * device. - * Parameters: - * hdev_obj: Handle to device object created with - * dev_create_device(). - * *mgr: Ptr to location to store handle. - * Returns: - * 0:Success. - * -EFAULT:Invalid hdev_obj. - * Requires: - * mgr != NULL. - * DEV Initialized. - * Ensures: - * 0:*mgr contains a handle to a channel manager object, - * or NULL. - * else: *mgr is NULL. - */ -extern int dev_get_dmm_mgr(struct dev_object *hdev_obj, - struct dmm_object **mgr); - -/* * dev_get_cod_mgr * Purpose: * Retrieve the COD manager create for this device. diff --git a/drivers/staging/tidspbridge/include/dspbridge/dmm.h b/drivers/staging/tidspbridge/include/dspbridge/dmm.h deleted file mode 100644 index 6c58335..000 --- a/drivers/staging/tidspbridge/include/dspbridge/dmm.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * dmm.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * The Dynamic Memory Mapping(DMM) module manages the DSP Virtual address - * space that can be directly mapped to any MPU buffer or memory region. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef DMM_ -#define DMM_ - -#include - -struct dmm_object; - -/* DMM attributes used in dmm_create() */ -struct dmm_mgrattrs { - u32 reserved; -}; - -#define DMMPOOLSIZE 0x400 - -/* - * dmm_get_handle - * Purpose: - * Return the dynamic memory manager object for this device. - * This is typically called from the client process. - */ - -extern int dmm_get_handle(void *hprocessor, -struct dmm_object **dmm_manager); - -extern int dmm_reserve_memory(struct dmm_objec
[PATCHv3 06/11] staging: tidspbridge - remove hw directory
hw directory was only being used for custom iommu implementation APIs, so after the iommu module migration this directory is not needed anymore. Signed-off-by: Fernando Guzman Lugo --- drivers/staging/tidspbridge/Makefile |3 +- drivers/staging/tidspbridge/core/_tiomap.h |1 - drivers/staging/tidspbridge/core/io_sm.c |4 - drivers/staging/tidspbridge/core/tiomap3430.c |4 - drivers/staging/tidspbridge/core/tiomap3430_pwr.c |4 - drivers/staging/tidspbridge/core/tiomap_io.c |2 +- drivers/staging/tidspbridge/hw/EasiGlobal.h| 41 -- drivers/staging/tidspbridge/hw/MMUAccInt.h | 76 --- drivers/staging/tidspbridge/hw/MMURegAcM.h | 225 drivers/staging/tidspbridge/hw/hw_defs.h | 58 -- drivers/staging/tidspbridge/hw/hw_mmu.c| 562 drivers/staging/tidspbridge/hw/hw_mmu.h| 163 -- .../tidspbridge/include/dspbridge/dspioctl.h |7 - 13 files changed, 2 insertions(+), 1148 deletions(-) delete mode 100644 drivers/staging/tidspbridge/hw/EasiGlobal.h delete mode 100644 drivers/staging/tidspbridge/hw/MMUAccInt.h delete mode 100644 drivers/staging/tidspbridge/hw/MMURegAcM.h delete mode 100644 drivers/staging/tidspbridge/hw/hw_defs.h delete mode 100644 drivers/staging/tidspbridge/hw/hw_mmu.c delete mode 100644 drivers/staging/tidspbridge/hw/hw_mmu.h diff --git a/drivers/staging/tidspbridge/Makefile b/drivers/staging/tidspbridge/Makefile index 8082d5c..e09547d 100644 --- a/drivers/staging/tidspbridge/Makefile +++ b/drivers/staging/tidspbridge/Makefile @@ -11,10 +11,9 @@ librmgr = rmgr/dbdcd.o rmgr/disp.o rmgr/drv.o rmgr/mgr.o rmgr/node.o \ rmgr/nldr.o rmgr/drv_interface.o libdload = dynload/cload.o dynload/getsection.o dynload/reloc.o \ dynload/tramp.o -libhw = hw/hw_mmu.o bridgedriver-objs = $(libgen) $(libservices) $(libcore) $(libpmgr) $(librmgr) \ - $(libdload) $(libhw) + $(libdload) #Machine dependent ccflags-y += -D_TI_ -D_DB_TIOMAP -DTMS32060 \ diff --git a/drivers/staging/tidspbridge/core/_tiomap.h b/drivers/staging/tidspbridge/core/_tiomap.h index 394a64a..cd7ff88 100644 --- a/drivers/staging/tidspbridge/core/_tiomap.h +++ b/drivers/staging/tidspbridge/core/_tiomap.h @@ -26,7 +26,6 @@ #include #include #include -#include #include /* for bridge_ioctl_extproc defn */ #include #include diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index 56856ad..194bada 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -39,10 +39,6 @@ #include #include -/* Hardware Abstraction Layer */ -#include -#include - /* Bridge Driver */ #include #include diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index 86f..8496c83 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -35,10 +35,6 @@ #include #include -/* Hardware Abstraction Layer */ -#include -#include - /* --- Link Driver */ #include #include diff --git a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c index fb9026e..b57a9fd 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c +++ b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c @@ -31,10 +31,6 @@ #include #include -/* Hardware Abstraction Layer */ -#include -#include - #include /* --- Bridge Driver */ diff --git a/drivers/staging/tidspbridge/core/tiomap_io.c b/drivers/staging/tidspbridge/core/tiomap_io.c index 5ba6795..b526532 100644 --- a/drivers/staging/tidspbridge/core/tiomap_io.c +++ b/drivers/staging/tidspbridge/core/tiomap_io.c @@ -143,7 +143,7 @@ int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt, ul_shm_base_virt - ul_tlb_base_virt; ul_shm_offset_virt += PG_ALIGN_HIGH(ul_ext_end - ul_dyn_ext_base + - 1, HW_PAGE_SIZE64KB); + 1, PAGE_SIZE * 16); dw_ext_prog_virt_mem -= ul_shm_offset_virt; dw_ext_prog_virt_mem += (ul_ext_base - ul_dyn_ext_base); diff --git a/drivers/staging/tidspbridge/hw/EasiGlobal.h b/drivers/staging/tidspbridge/hw/EasiGlobal.h deleted file mode 100644 index e48d7f6..000 --- a/drivers/staging/tidspbridge/hw/EasiGlobal.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * EasiGlobal.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors
[PATCHv3 09/11] staging: tidspbridge - remove reserved memory clean up
Now iommv module keeps track of iommu memory used, we do not need resource cleanup for reserved memories anymore. Signed-off-by: Fernando Guzman Lugo --- .../staging/tidspbridge/include/dspbridge/drv.h|4 -- drivers/staging/tidspbridge/rmgr/drv.c | 11 -- drivers/staging/tidspbridge/rmgr/drv_interface.c |2 - drivers/staging/tidspbridge/rmgr/proc.c| 36 4 files changed, 0 insertions(+), 53 deletions(-) diff --git a/drivers/staging/tidspbridge/include/dspbridge/drv.h b/drivers/staging/tidspbridge/include/dspbridge/drv.h index c1f363e..427f38b 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/drv.h +++ b/drivers/staging/tidspbridge/include/dspbridge/drv.h @@ -165,10 +165,6 @@ struct process_context { struct list_head dmm_map_list; spinlock_t dmm_map_lock; - /* DMM reserved memory resources */ - struct list_head dmm_rsv_list; - spinlock_t dmm_rsv_lock; - /* DSP Heap resources */ struct dspheap_res_object *pdspheap_list; diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c index 0c857b9..91cc168 100644 --- a/drivers/staging/tidspbridge/rmgr/drv.c +++ b/drivers/staging/tidspbridge/rmgr/drv.c @@ -146,7 +146,6 @@ int drv_remove_all_dmm_res_elements(void *process_ctxt) struct process_context *ctxt = (struct process_context *)process_ctxt; int status = 0; struct dmm_map_object *temp_map, *map_obj; - struct dmm_rsv_object *temp_rsv, *rsv_obj; /* Free DMM mapped memory resources */ list_for_each_entry_safe(map_obj, temp_map, &ctxt->dmm_map_list, link) { @@ -156,16 +155,6 @@ int drv_remove_all_dmm_res_elements(void *process_ctxt) pr_err("%s: proc_un_map failed!" " status = 0x%xn", __func__, status); } - - /* Free DMM reserved memory resources */ - list_for_each_entry_safe(rsv_obj, temp_rsv, &ctxt->dmm_rsv_list, link) { - status = proc_un_reserve_memory(ctxt->hprocessor, (void *) - rsv_obj->dsp_reserved_addr, - ctxt); - if (status) - pr_err("%s: proc_un_reserve_memory failed!" - " status = 0x%xn", __func__, status); - } return status; } diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c index 5d0670c..63052b0 100644 --- a/drivers/staging/tidspbridge/rmgr/drv_interface.c +++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c @@ -509,8 +509,6 @@ static int bridge_open(struct inode *ip, struct file *filp) pr_ctxt->res_state = PROC_RES_ALLOCATED; spin_lock_init(&pr_ctxt->dmm_map_lock); INIT_LIST_HEAD(&pr_ctxt->dmm_map_list); - spin_lock_init(&pr_ctxt->dmm_rsv_lock); - INIT_LIST_HEAD(&pr_ctxt->dmm_rsv_list); pr_ctxt->node_id = kzalloc(sizeof(struct idr), GFP_KERNEL); if (pr_ctxt->node_id) { diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c index 59c946b..e5fec57 100644 --- a/drivers/staging/tidspbridge/rmgr/proc.c +++ b/drivers/staging/tidspbridge/rmgr/proc.c @@ -1515,7 +1515,6 @@ int proc_reserve_memory(void *hprocessor, u32 ul_size, struct dmm_object *dmm_mgr; int status = 0; struct proc_object *p_proc_object = (struct proc_object *)hprocessor; - struct dmm_rsv_object *rsv_obj; if (!p_proc_object) { status = -EFAULT; @@ -1529,22 +1528,6 @@ int proc_reserve_memory(void *hprocessor, u32 ul_size, } status = dmm_reserve_memory(dmm_mgr, ul_size, (u32 *) pp_rsv_addr); - if (status != 0) - goto func_end; - - /* -* A successful reserve should be followed by insertion of rsv_obj -* into dmm_rsv_list, so that reserved memory resource tracking -* remains uptodate -*/ - rsv_obj = kmalloc(sizeof(struct dmm_rsv_object), GFP_KERNEL); - if (rsv_obj) { - rsv_obj->dsp_reserved_addr = (u32) *pp_rsv_addr; - spin_lock(&pr_ctxt->dmm_rsv_lock); - list_add(&rsv_obj->link, &pr_ctxt->dmm_rsv_list); - spin_unlock(&pr_ctxt->dmm_rsv_lock); - } - func_end: dev_dbg(bridge, "%s: hprocessor: 0x%p ul_size: 0x%x pp_rsv_addr: 0x%p " "status 0x%x\n", __func__, hprocessor, @@ -1756,7 +1739,6 @@ int proc_un_reserve_memory(void *hprocessor, void *prsv_addr, struct dmm_object *dmm_mgr; int status = 0; struct proc_object *p_proc_object = (struct proc_objec
[PATCHv3 01/11] staging: tidspbridge: replace iommu custom for opensource implementation
Now the tidspbridge uses the API's from iovmm module. Signed-off-by: Fernando Guzman Lugo --- drivers/staging/tidspbridge/core/_tiomap.h |4 +- drivers/staging/tidspbridge/core/io_sm.c | 121 ++ drivers/staging/tidspbridge/core/tiomap3430.c | 522 drivers/staging/tidspbridge/core/ue_deh.c |8 - .../tidspbridge/include/dspbridge/dspdefs.h|2 +- drivers/staging/tidspbridge/rmgr/proc.c|2 +- 6 files changed, 138 insertions(+), 521 deletions(-) diff --git a/drivers/staging/tidspbridge/core/_tiomap.h b/drivers/staging/tidspbridge/core/_tiomap.h index 1c1f157..a42c393 100644 --- a/drivers/staging/tidspbridge/core/_tiomap.h +++ b/drivers/staging/tidspbridge/core/_tiomap.h @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include #include /* for bridge_ioctl_extproc defn */ @@ -328,7 +330,7 @@ struct bridge_dev_context { u32 dw_internal_size; /* Internal memory size */ struct omap_mbox *mbox; /* Mail box handle */ - + struct iommu *dsp_mmu; /* iommu for iva2 handler */ struct cfg_hostres *resources; /* Host Resources */ /* diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index 5718645..842b8db 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -291,6 +291,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) struct cod_manager *cod_man; struct chnl_mgr *hchnl_mgr; struct msg_mgr *hmsg_mgr; + struct iommu *mmu; u32 ul_shm_base; u32 ul_shm_base_offset; u32 ul_shm_limit; @@ -313,7 +314,6 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) struct bridge_ioctl_extproc ae_proc[BRDIOCTL_NUMOFMMUTLB]; struct cfg_hostres *host_res; struct bridge_dev_context *pbridge_context; - u32 map_attrs; u32 shm0_end; u32 ul_dyn_ext_base; u32 ul_seg1_size = 0; @@ -337,6 +337,20 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) status = -EFAULT; goto func_end; } + mmu = pbridge_context->dsp_mmu; + + if (mmu) + iommu_put(mmu); + mmu = iommu_get("iva2"); + + if (IS_ERR_OR_NULL(mmu)) { + dev_err(bridge, "iommu_get failed!\n"); + pbridge_context->dsp_mmu = NULL; + status = -EFAULT; + goto func_end; + } + pbridge_context->dsp_mmu = mmu; + status = dev_get_cod_mgr(hio_mgr->hdev_obj, &cod_man); if (!cod_man) { status = -EFAULT; @@ -476,55 +490,16 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) gpp_va_curr = ul_gpp_va; num_bytes = ul_seg1_size; - /* -* Try to fit into TLB entries. If not possible, push them to page -* tables. It is quite possible that if sections are not on -* bigger page boundary, we may end up making several small pages. -* So, push them onto page tables, if that is the case. -*/ - map_attrs = 0x; - map_attrs = DSP_MAPLITTLEENDIAN; - map_attrs |= DSP_MAPPHYSICALADDR; - map_attrs |= DSP_MAPELEMSIZE32; - map_attrs |= DSP_MAPDONOTLOCK; - - while (num_bytes) { - /* -* To find the max. page size with which both PA & VA are -* aligned. -*/ - all_bits = pa_curr | va_curr; - dev_dbg(bridge, "all_bits %x, pa_curr %x, va_curr %x, " - "num_bytes %x\n", all_bits, pa_curr, va_curr, - num_bytes); - for (i = 0; i < 4; i++) { - if ((num_bytes >= page_size[i]) && ((all_bits & -(page_size[i] - - 1)) == 0)) { - status = - hio_mgr->intf_fxns-> - pfn_brd_mem_map(hio_mgr->hbridge_context, - pa_curr, va_curr, - page_size[i], map_attrs, - NULL); - if (status) - goto func_end; - pa_curr += page_size[i]; - va_curr += page_size[i]; - gpp_va_curr += page_size[i]; - num_bytes -= page_size[i]; - /* -* Don't try smaller sizes. Hopefully we have -
[PATCHv3 04/11] staging: tidspbridge - remove custom mmu code from tiomap3430.c
This patch removes all the custom mmu code remaining in tiomap3430.c which is not needed anymore. Signed-off-by: Fernando Guzman Lugo --- drivers/staging/tidspbridge/core/_tiomap.h|2 - drivers/staging/tidspbridge/core/tiomap3430.c | 425 - 2 files changed, 0 insertions(+), 427 deletions(-) diff --git a/drivers/staging/tidspbridge/core/_tiomap.h b/drivers/staging/tidspbridge/core/_tiomap.h index 8777492..394a64a 100644 --- a/drivers/staging/tidspbridge/core/_tiomap.h +++ b/drivers/staging/tidspbridge/core/_tiomap.h @@ -330,7 +330,6 @@ struct bridge_dev_context { */ u32 dw_dsp_ext_base_addr; /* See the comment above */ u32 dw_api_reg_base;/* API mem map'd registers */ - void __iomem *dw_dsp_mmu_base; /* DSP MMU Mapped registers */ u32 dw_api_clk_base;/* CLK Registers */ u32 dw_dsp_clk_m2_base; /* DSP Clock Module m2 */ u32 dw_public_rhea; /* Pub Rhea */ @@ -356,7 +355,6 @@ struct bridge_dev_context { /* TC Settings */ bool tc_word_swap_on; /* Traffic Controller Word Swap */ - struct pg_table_attrs *pt_attrs; u32 dsp_per_clks; }; diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index 0e5b805..e5f67be 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -104,56 +104,8 @@ static int bridge_dev_create(struct bridge_dev_context static int bridge_dev_ctrl(struct bridge_dev_context *dev_context, u32 dw_cmd, void *pargs); static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt); -static int pte_update(struct bridge_dev_context *dev_ctxt, u32 pa, -u32 va, u32 size, -struct hw_mmu_map_attrs_t *map_attrs); -static int pte_set(struct pg_table_attrs *pt, u32 pa, u32 va, - u32 size, struct hw_mmu_map_attrs_t *attrs); -static int mem_map_vmalloc(struct bridge_dev_context *dev_context, - u32 ul_mpu_addr, u32 virt_addr, - u32 ul_num_bytes, - struct hw_mmu_map_attrs_t *hw_attrs); - bool wait_for_start(struct bridge_dev_context *dev_context, u32 dw_sync_addr); -/* --- Globals */ - -/* Attributes of L2 page tables for DSP MMU */ -struct page_info { - u32 num_entries;/* Number of valid PTEs in the L2 PT */ -}; - -/* Attributes used to manage the DSP MMU page tables */ -struct pg_table_attrs { - spinlock_t pg_lock; /* Critical section object handle */ - - u32 l1_base_pa; /* Physical address of the L1 PT */ - u32 l1_base_va; /* Virtual address of the L1 PT */ - u32 l1_size;/* Size of the L1 PT */ - u32 l1_tbl_alloc_pa; - /* Physical address of Allocated mem for L1 table. May not be aligned */ - u32 l1_tbl_alloc_va; - /* Virtual address of Allocated mem for L1 table. May not be aligned */ - u32 l1_tbl_alloc_sz; - /* Size of consistent memory allocated for L1 table. -* May not be aligned */ - - u32 l2_base_pa; /* Physical address of the L2 PT */ - u32 l2_base_va; /* Virtual address of the L2 PT */ - u32 l2_size;/* Size of the L2 PT */ - u32 l2_tbl_alloc_pa; - /* Physical address of Allocated mem for L2 table. May not be aligned */ - u32 l2_tbl_alloc_va; - /* Virtual address of Allocated mem for L2 table. May not be aligned */ - u32 l2_tbl_alloc_sz; - /* Size of consistent memory allocated for L2 table. -* May not be aligned */ - - u32 l2_num_pages; /* Number of allocated L2 PT */ - /* Array [l2_num_pages] of L2 PT info structs */ - struct page_info *pg_info; -}; - /* * This Bridge driver's function interface table. */ @@ -202,27 +154,6 @@ static struct bridge_drv_interface drv_interface_fxns = { bridge_msg_set_queue_id, }; -static inline void flush_all(struct bridge_dev_context *dev_context) -{ - if (dev_context->dw_brd_state == BRD_DSP_HIBERNATION || - dev_context->dw_brd_state == BRD_HIBERNATION) - wake_dsp(dev_context, NULL); - - hw_mmu_tlb_flush_all(dev_context->dw_dsp_mmu_base); -} - -static void bad_page_dump(u32 pa, struct page *pg) -{ - pr_emerg("DSPBRIDGE: MAP function: COUNT 0 FOR PA 0x%x\n", pa); - pr_emerg("Bad page state in process '%s'\n" -"page:%p flags:0x%0*lx mapping:%p mapcount:%d count:%d\n" -"Backtrace:\n", -current->comm, pg, (int)(2 * sizeof(unsigned long)), -(unsigned long)pg->flags, pg->mapping, -page_mapcount(pg), page_count(pg)); -
[PATCHv3 07/11] staging: tidspbridge - move all iommu related code to a new file
Create dsp-mmu module and moves all the iommu code related to this module. Signed-off-by: Fernando Guzman Lugo --- drivers/staging/tidspbridge/Makefile |2 +- drivers/staging/tidspbridge/core/_deh.h|3 - drivers/staging/tidspbridge/core/_tiomap.h | 27 +-- drivers/staging/tidspbridge/core/dsp-mmu.c | 316 drivers/staging/tidspbridge/core/tiomap3430.c | 178 +--- drivers/staging/tidspbridge/core/ue_deh.c | 86 +-- .../tidspbridge/include/dspbridge/dsp-mmu.h| 67 7 files changed, 390 insertions(+), 289 deletions(-) create mode 100644 drivers/staging/tidspbridge/core/dsp-mmu.c create mode 100644 drivers/staging/tidspbridge/include/dspbridge/dsp-mmu.h diff --git a/drivers/staging/tidspbridge/Makefile b/drivers/staging/tidspbridge/Makefile index e09547d..bd36651 100644 --- a/drivers/staging/tidspbridge/Makefile +++ b/drivers/staging/tidspbridge/Makefile @@ -2,7 +2,7 @@ obj-$(CONFIG_TIDSPBRIDGE) += bridgedriver.o libgen = gen/gb.o gen/gs.o gen/gh.o gen/uuidutil.o libcore = core/chnl_sm.o core/msg_sm.o core/io_sm.o core/tiomap3430.o \ - core/tiomap3430_pwr.o core/tiomap_io.o \ + core/tiomap3430_pwr.o core/tiomap_io.o core/dsp-mmu.o \ core/ue_deh.o core/wdt.o core/dsp-clock.o core/sync.o libpmgr = pmgr/chnl.o pmgr/io.o pmgr/msg.o pmgr/cod.o pmgr/dev.o pmgr/dspapi.o \ pmgr/dmm.o pmgr/cmm.o pmgr/dbll.o diff --git a/drivers/staging/tidspbridge/core/_deh.h b/drivers/staging/tidspbridge/core/_deh.h index f1254f0..8ae2633 100644 --- a/drivers/staging/tidspbridge/core/_deh.h +++ b/drivers/staging/tidspbridge/core/_deh.h @@ -27,9 +27,6 @@ struct deh_mgr { struct bridge_dev_context *hbridge_context; /* Bridge context. */ struct ntfy_object *ntfy_obj; /* NTFY object */ - - /* MMU Fault DPC */ - struct tasklet_struct dpc_tasklet; }; int mmu_fault_isr(struct iommu *mmu); diff --git a/drivers/staging/tidspbridge/core/_tiomap.h b/drivers/staging/tidspbridge/core/_tiomap.h index cd7ff88..e0a801c 100644 --- a/drivers/staging/tidspbridge/core/_tiomap.h +++ b/drivers/staging/tidspbridge/core/_tiomap.h @@ -23,8 +23,7 @@ #include #include #include -#include -#include +#include #include #include /* for bridge_ioctl_extproc defn */ #include @@ -380,28 +379,4 @@ extern s32 dsp_debug; */ int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val); -/** - * user_to_dsp_map() - maps user to dsp virtual address - * @mmu: Pointer to iommu handle. - * @uva: Virtual user space address. - * @da DSP address - * @size Buffer size to map. - * @usr_pgsstruct page array pointer where the user pages will be stored - * - * This function maps a user space buffer into DSP virtual address. - * - */ -u32 user_to_dsp_map(struct iommu *mmu, u32 uva, u32 da, u32 size, - struct page **usr_pgs); - -/** - * user_to_dsp_unmap() - unmaps DSP virtual buffer. - * @mmu: Pointer to iommu handle. - * @da DSP address - * - * This function unmaps a user space buffer into DSP virtual address. - * - */ -int user_to_dsp_unmap(struct iommu *mmu, u32 da); - #endif /* _TIOMAP_ */ diff --git a/drivers/staging/tidspbridge/core/dsp-mmu.c b/drivers/staging/tidspbridge/core/dsp-mmu.c new file mode 100644 index 000..3c978f9 --- /dev/null +++ b/drivers/staging/tidspbridge/core/dsp-mmu.c @@ -0,0 +1,316 @@ +/* + * dsp-mmu.c + * + * DSP-BIOS Bridge driver support functions for TI OMAP processors. + * + * DSP iommu. + * + * Copyright (C) 2010 Texas Instruments, Inc. + * + * This package is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include +#include +#include +#include +#include +#include +#include "_tiomap.h" + +#include + +#define MMU_CNTL_TWL_EN(1 << 2) + +static struct tasklet_struct mmu_tasklet; + +#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE +static void mmu_fault_print_stack(struct bridge_dev_context *dev_context) +{ + void *dummy_addr; + u32 fa, tmp; + struct iotlb_entry e; + struct iommu *mmu = dev_context->dsp_mmu; + dummy_addr = (void *)__get_free_page(GFP_ATOMIC); + + /* +* Before acking the MMU fault, let's make sure MMU can only +* access entry #0. Then add a new entry so that the DSP OS +* can continue in order to dump the stack. +*/ + tmp = iommu_read_reg(mmu, MMU_CNTL); + tmp &= ~MMU_CNTL_TWL_EN; + iommu_wri
[PATCHv3 05/11] staging: tidspbridge - fix mmufault support
With changes for iommu migration mmufault report and dsp track dump is broken, this patch fixes that. Signed-off-by: Fernando Guzman Lugo --- drivers/staging/tidspbridge/core/_deh.h |2 + drivers/staging/tidspbridge/core/tiomap3430.c |2 + drivers/staging/tidspbridge/core/ue_deh.c | 93 ++--- 3 files changed, 40 insertions(+), 57 deletions(-) diff --git a/drivers/staging/tidspbridge/core/_deh.h b/drivers/staging/tidspbridge/core/_deh.h index 16723cd..f1254f0 100644 --- a/drivers/staging/tidspbridge/core/_deh.h +++ b/drivers/staging/tidspbridge/core/_deh.h @@ -32,4 +32,6 @@ struct deh_mgr { struct tasklet_struct dpc_tasklet; }; +int mmu_fault_isr(struct iommu *mmu); + #endif /* _DEH_ */ diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index e5f67be..86f 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -58,6 +58,7 @@ #include "_tiomap.h" #include "_tiomap_pwr.h" #include "tiomap_io.h" +#include "_deh.h" /* Offset in shared mem to write to in order to synchronize start with DSP */ #define SHMSYNCOFFSET 4/* GPP byte offset */ @@ -367,6 +368,7 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, } if (!status) { dev_context->dsp_mmu = mmu; + mmu->isr = mmu_fault_isr; sm_sg = &dev_context->sh_s; sg0_da = iommu_kmap(mmu, sm_sg->seg0_da, sm_sg->seg0_pa, sm_sg->seg0_size, IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32); diff --git a/drivers/staging/tidspbridge/core/ue_deh.c b/drivers/staging/tidspbridge/core/ue_deh.c index 14f3191..2e1ac89 100644 --- a/drivers/staging/tidspbridge/core/ue_deh.c +++ b/drivers/staging/tidspbridge/core/ue_deh.c @@ -31,7 +31,7 @@ #include #include -static u32 fault_addr; +#define MMU_CNTL_TWL_EN(1 << 2) static void mmu_fault_dpc(unsigned long data) { @@ -43,43 +43,18 @@ static void mmu_fault_dpc(unsigned long data) bridge_deh_notify(deh, DSP_MMUFAULT, 0); } -static irqreturn_t mmu_fault_isr(int irq, void *data) +int mmu_fault_isr(struct iommu *mmu) { - struct deh_mgr *deh = data; - struct cfg_hostres *resources; - u32 event; + struct deh_mgr *dm; - if (!deh) - return IRQ_HANDLED; + dev_get_deh_mgr(dev_get_first(), &dm); - resources = deh->hbridge_context->resources; - if (!resources) { - dev_dbg(bridge, "%s: Failed to get Host Resources\n", - __func__); - return IRQ_HANDLED; - } + if (!dm) + return -EPERM; - hw_mmu_event_status(resources->dw_dmmu_base, &event); - if (event == HW_MMU_TRANSLATION_FAULT) { - hw_mmu_fault_addr_read(resources->dw_dmmu_base, &fault_addr); - dev_dbg(bridge, "%s: event=0x%x, fault_addr=0x%x\n", __func__, - event, fault_addr); - /* -* Schedule a DPC directly. In the future, it may be -* necessary to check if DSP MMU fault is intended for -* Bridge. -*/ - tasklet_schedule(&deh->dpc_tasklet); - - /* Disable the MMU events, else once we clear it will -* start to raise INTs again */ - hw_mmu_event_disable(resources->dw_dmmu_base, - HW_MMU_TRANSLATION_FAULT); - } else { - hw_mmu_event_disable(resources->dw_dmmu_base, - HW_MMU_ALL_INTERRUPTS); - } - return IRQ_HANDLED; + iommu_write_reg(mmu, 0, MMU_IRQENABLE); + tasklet_schedule(&dm->dpc_tasklet); + return 0; } int bridge_deh_create(struct deh_mgr **ret_deh, @@ -161,42 +136,45 @@ int bridge_deh_register_notify(struct deh_mgr *deh, u32 event_mask, #ifdef CONFIG_TIDSPBRIDGE_BACKTRACE static void mmu_fault_print_stack(struct bridge_dev_context *dev_context) { - struct cfg_hostres *resources; - struct hw_mmu_map_attrs_t map_attrs = { - .endianism = HW_LITTLE_ENDIAN, - .element_size = HW_ELEM_SIZE16BIT, - .mixed_size = HW_MMU_CPUES, - }; - void *dummy_va_addr; - - resources = dev_context->resources; - dummy_va_addr = (void*)__get_free_page(GFP_ATOMIC); + void *dummy_addr; + u32 fa, tmp; + struct iotlb_entry e; + struct iommu *mmu = dev_context->dsp_mmu; + dummy_addr = (void *)__get_free_page(GFP_ATOMIC); /* * Before acking the MMU fault, let's make sure MMU can only * access entry #0. Then add a new entry so that the DSP OS
[PATCHv3 00/11] staging tidspbridge: iommu migration
This set of patches remove the dspbridge custom mmu implementation and use iommu module instead. Version2: - Comments from FUJITA Tomonori and previous patch "tidspbridge: add map support for big buffers" was removed and instead a patch to define ARCH_HAS_SG_CHAIN in arm architecture will be sent. - Rebase to the latest tidspbridge. Version2 - Rebase to the latest staging-next tree commit: a747d4b817daf95c64ac6396e27fddc66c83a811 Fernando Guzman Lugo (11): staging: tidspbridge: replace iommu custom for opensource implementation staging: tidspbridge - move shared memory iommu maps to tiomap3430.c staging: tidspbridge - rename bridge_brd_mem_map/unmap to a proper name staging: tidspbridge - remove custom mmu code from tiomap3430.c staging: tidspbridge - fix mmufault support staging: tidspbrge - remove hw directory staging: tidspbridge - move all iommu related code to a new file staging: tidspbridge: remove dw_dmmu_base from cfg_hostres struct staging: tidspbridge - remove reserved memory clean up staging: tidspbridge - deprecate reserve/unreserve_memory funtions staging: tidspbridge - remove dmm custom module drivers/staging/tidspbridge/Makefile |7 +- drivers/staging/tidspbridge/core/_deh.h|5 +- drivers/staging/tidspbridge/core/_tiomap.h | 19 +- drivers/staging/tidspbridge/core/dsp-mmu.c | 316 ++ drivers/staging/tidspbridge/core/io_sm.c | 180 +--- drivers/staging/tidspbridge/core/tiomap3430.c | 1070 ++-- drivers/staging/tidspbridge/core/tiomap3430_pwr.c |4 - drivers/staging/tidspbridge/core/tiomap_io.c | 17 +- drivers/staging/tidspbridge/core/ue_deh.c | 115 +--- drivers/staging/tidspbridge/hw/EasiGlobal.h| 41 - drivers/staging/tidspbridge/hw/MMUAccInt.h | 76 -- drivers/staging/tidspbridge/hw/MMURegAcM.h | 225 drivers/staging/tidspbridge/hw/hw_defs.h | 58 -- drivers/staging/tidspbridge/hw/hw_mmu.c| 562 -- drivers/staging/tidspbridge/hw/hw_mmu.h| 163 --- .../tidspbridge/include/dspbridge/cfgdefs.h|1 - .../staging/tidspbridge/include/dspbridge/dev.h| 24 - .../staging/tidspbridge/include/dspbridge/dmm.h| 75 -- .../staging/tidspbridge/include/dspbridge/drv.h| 10 - .../tidspbridge/include/dspbridge/dsp-mmu.h| 67 ++ .../tidspbridge/include/dspbridge/dspdefs.h| 44 - .../tidspbridge/include/dspbridge/dspioctl.h |7 - .../staging/tidspbridge/include/dspbridge/proc.h | 46 - drivers/staging/tidspbridge/pmgr/dev.c | 63 +-- drivers/staging/tidspbridge/pmgr/dmm.c | 533 -- drivers/staging/tidspbridge/pmgr/dspapi.c | 34 +- drivers/staging/tidspbridge/rmgr/drv.c | 15 - drivers/staging/tidspbridge/rmgr/drv_interface.c |2 - drivers/staging/tidspbridge/rmgr/node.c| 48 +- drivers/staging/tidspbridge/rmgr/proc.c| 197 + 30 files changed, 568 insertions(+), 3456 deletions(-) create mode 100644 drivers/staging/tidspbridge/core/dsp-mmu.c delete mode 100644 drivers/staging/tidspbridge/hw/EasiGlobal.h delete mode 100644 drivers/staging/tidspbridge/hw/MMUAccInt.h delete mode 100644 drivers/staging/tidspbridge/hw/MMURegAcM.h delete mode 100644 drivers/staging/tidspbridge/hw/hw_defs.h delete mode 100644 drivers/staging/tidspbridge/hw/hw_mmu.c delete mode 100644 drivers/staging/tidspbridge/hw/hw_mmu.h delete mode 100644 drivers/staging/tidspbridge/include/dspbridge/dmm.h create mode 100644 drivers/staging/tidspbridge/include/dspbridge/dsp-mmu.h delete mode 100644 drivers/staging/tidspbridge/pmgr/dmm.c -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv3 02/11] staging: tidspbridge - move shared memory iommu maps to tiomap3430.c
Now iommu maps of shared memory segments are done in bridge_brd_start and unmaped in bridge_brd_stop. Signed-off-by: Fernando Guzman Lugo --- drivers/staging/tidspbridge/core/_tiomap.h| 13 +++ drivers/staging/tidspbridge/core/io_sm.c | 125 +++ drivers/staging/tidspbridge/core/tiomap3430.c | 135 +++- drivers/staging/tidspbridge/core/tiomap_io.c | 12 +- 4 files changed, 139 insertions(+), 146 deletions(-) diff --git a/drivers/staging/tidspbridge/core/_tiomap.h b/drivers/staging/tidspbridge/core/_tiomap.h index a42c393..c1bf95d 100644 --- a/drivers/staging/tidspbridge/core/_tiomap.h +++ b/drivers/staging/tidspbridge/core/_tiomap.h @@ -308,6 +308,18 @@ static const struct bpwr_clk_t bpwr_clks[] = { #define CLEAR_BIT_INDEX(reg, index) (reg &= ~(1 << (index))) +struct shm_segs { + u32 seg0_da; + u32 seg0_pa; + u32 seg0_va; + u32 seg0_size; + u32 seg1_da; + u32 seg1_pa; + u32 seg1_va; + u32 seg1_size; +}; + + /* This Bridge driver's device context: */ struct bridge_dev_context { struct dev_object *hdev_obj;/* Handle to Bridge device object. */ @@ -331,6 +343,7 @@ struct bridge_dev_context { struct omap_mbox *mbox; /* Mail box handle */ struct iommu *dsp_mmu; /* iommu for iva2 handler */ + struct shm_segs sh_s; struct cfg_hostres *resources; /* Host Resources */ /* diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index 842b8db..56856ad 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -291,7 +291,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) struct cod_manager *cod_man; struct chnl_mgr *hchnl_mgr; struct msg_mgr *hmsg_mgr; - struct iommu *mmu; + struct shm_segs *sm_sg; u32 ul_shm_base; u32 ul_shm_base_offset; u32 ul_shm_limit; @@ -317,14 +317,6 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) u32 shm0_end; u32 ul_dyn_ext_base; u32 ul_seg1_size = 0; - u32 pa_curr = 0; - u32 va_curr = 0; - u32 gpp_va_curr = 0; - u32 num_bytes = 0; - u32 all_bits = 0; - u32 page_size[] = { HW_PAGE_SIZE16MB, HW_PAGE_SIZE1MB, - HW_PAGE_SIZE64KB, HW_PAGE_SIZE4KB - }; status = dev_get_bridge_context(hio_mgr->hdev_obj, &pbridge_context); if (!pbridge_context) { @@ -337,19 +329,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) status = -EFAULT; goto func_end; } - mmu = pbridge_context->dsp_mmu; - - if (mmu) - iommu_put(mmu); - mmu = iommu_get("iva2"); - - if (IS_ERR_OR_NULL(mmu)) { - dev_err(bridge, "iommu_get failed!\n"); - pbridge_context->dsp_mmu = NULL; - status = -EFAULT; - goto func_end; - } - pbridge_context->dsp_mmu = mmu; + sm_sg = &pbridge_context->sh_s; status = dev_get_cod_mgr(hio_mgr->hdev_obj, &cod_man); if (!cod_man) { @@ -485,74 +465,14 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) if (status) goto func_end; - pa_curr = ul_gpp_pa; - va_curr = ul_dyn_ext_base * hio_mgr->word_size; - gpp_va_curr = ul_gpp_va; - num_bytes = ul_seg1_size; - - va_curr = iommu_kmap(mmu, va_curr, pa_curr, num_bytes, - IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32); - if (IS_ERR_VALUE(va_curr)) { - status = (int)va_curr; - goto func_end; - } - - pa_curr += ul_pad_size + num_bytes; - va_curr += ul_pad_size + num_bytes; - gpp_va_curr += ul_pad_size + num_bytes; - - /* Configure the TLB entries for the next cacheable segment */ - num_bytes = ul_seg_size; - va_curr = ul_dsp_va * hio_mgr->word_size; - while (num_bytes) { - /* -* To find the max. page size with which both PA & VA are -* aligned. -*/ - all_bits = pa_curr | va_curr; - dev_dbg(bridge, "all_bits for Seg1 %x, pa_curr %x, " - "va_curr %x, num_bytes %x\n", all_bits, pa_curr, - va_curr, num_bytes); - for (i = 0; i < 4; i++) { - if (!(num_bytes >= page_size[i]) || - !((all_bits & (page_size[i] - 1)) == 0)) - continue; - if (ndx < MAX_LOCK_TLB_ENTRIES) { - /* -* This is the physical address written to -* D
[PATCH] staging: tidspbridge - update Kconfig to select IOMMU module
IOMMU module most be selected when using tidspbridge, because now tidsbridge depends on iommu module. Signed-off-by: Fernando Guzman Lugo --- drivers/staging/tidspbridge/Kconfig |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/drivers/staging/tidspbridge/Kconfig b/drivers/staging/tidspbridge/Kconfig index 93de4f2..ff64d46 100644 --- a/drivers/staging/tidspbridge/Kconfig +++ b/drivers/staging/tidspbridge/Kconfig @@ -6,6 +6,7 @@ menuconfig TIDSPBRIDGE tristate "DSP Bridge driver" depends on ARCH_OMAP3 select OMAP_MBOX_FWK + select OMAP_IOMMU help DSP/BIOS Bridge is designed for platforms that contain a GPP and one or more attached DSPs. The GPP is considered the master or -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] iovmm: IVA2 MMU range is from 0x11000000 to 0xFFFFFFFF
IV2 MMU capable addresses start from 0x1100 Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/iovmm.c |7 ++- 1 files changed, 6 insertions(+), 1 deletions(-) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 75965a1..c0344f4 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -286,7 +286,12 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, /* * Reserve the first page for NULL */ - start = PAGE_SIZE; + if (!strcmp(obj->name, "iva2")) + /* IVA2 MMU control starts from 0x1100 */ + start = 0x1100; + else + start = PAGE_SIZE; + if (flags & IOVMF_LINEAR) alignement = iopgsz_max(bytes); start = roundup(start, alignement); -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/4] iovmm: no gap checking for fixed address
If some fixed da address is wanted to be mapped and the page is freed but it is used as gap, the mapping will fail. This patch is fixing that and olny keeps the gap for not fixed address. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/iovmm.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 24ca9c4..34f0012 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -289,7 +289,7 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, prev_end = 0; list_for_each_entry(tmp, &obj->mmap, list) { - if (prev_end >= start) + if (prev_end > start) break; if (start + bytes <= tmp->da_start) @@ -301,7 +301,7 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, prev_end = tmp->da_end; } - if ((start > prev_end) && (ULONG_MAX - start >= bytes)) + if ((start >= prev_end) && (ULONG_MAX - start + 1 >= bytes)) goto found; dev_dbg(obj->dev, "%s: no space to fit %08x(%x) flags: %08x\n", -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv3 0/4] iovmm: fixes for iovmm module
Version 3: * change patch 2 base on Felipe Contreras' comments, now it uses min_t and I deleted some blank lines. * patch "create new api to set valid da range" is base on "iovmm: IVA2 MMU range is from 0x1100 to 0x" patch and on Hiroshi's comments and now it is added to this set. Version 2: * Removed "iovmm: fixes for iovmm module" that patch was already sent. * Modified "iovmm: fix roundup for next area and end check for the last area" patch, base on Davin Cohen's comments and rename it to a proper name that describes what it is doing now. Fernando Guzman Lugo (4): iovmm: no gap checking for fixed address iovmm: add superpages support to fixed da address iovmm: replace __iounmap with omap_iounmap iommu: create new api to set valid da range arch/arm/plat-omap/include/plat/iommu.h |3 + arch/arm/plat-omap/iommu.c | 29 arch/arm/plat-omap/iovmm.c | 74 +-- 3 files changed, 73 insertions(+), 33 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/4] iovmm: add superpages support to fixed da address
This patch adds superpages support to fixed ad address inside iommu_kmap function. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/iovmm.c | 62 +-- 1 files changed, 36 insertions(+), 26 deletions(-) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 34f0012..93a34d9 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -87,35 +87,43 @@ static size_t sgtable_len(const struct sg_table *sgt) } #define sgtable_ok(x) (!!sgtable_len(x)) +static unsigned max_alignment(u32 addr) +{ + int i; + unsigned pagesize[] = { SZ_16M, SZ_1M, SZ_64K, SZ_4K, }; + for (i = 0; i < ARRAY_SIZE(pagesize) && addr & (pagesize[i] - 1); i++) + ; + return (i < ARRAY_SIZE(pagesize)) ? pagesize[i] : 0; +} + /* * calculate the optimal number sg elements from total bytes based on * iommu superpages */ -static unsigned int sgtable_nents(size_t bytes) +static unsigned sgtable_nents(size_t bytes, u32 da, u32 pa) { - int i; - unsigned int nr_entries; - const unsigned long pagesize[] = { SZ_16M, SZ_1M, SZ_64K, SZ_4K, }; + unsigned nr_entries = 0, ent_sz; if (!IS_ALIGNED(bytes, PAGE_SIZE)) { pr_err("%s: wrong size %08x\n", __func__, bytes); return 0; } - nr_entries = 0; - for (i = 0; i < ARRAY_SIZE(pagesize); i++) { - if (bytes >= pagesize[i]) { - nr_entries += (bytes / pagesize[i]); - bytes %= pagesize[i]; - } + while (bytes) { + ent_sz = max_alignment(da | pa); + ent_sz = min_t(unsigned, ent_sz, iopgsz_max(bytes)); + nr_entries++; + da += ent_sz; + pa += ent_sz; + bytes -= ent_sz; } - BUG_ON(bytes); return nr_entries; } /* allocate and initialize sg_table header(a kind of 'superblock') */ -static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags) +static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags, + u32 da, u32 pa) { unsigned int nr_entries; int err; @@ -127,9 +135,8 @@ static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags) if (!IS_ALIGNED(bytes, PAGE_SIZE)) return ERR_PTR(-EINVAL); - /* FIXME: IOVMF_DA_FIXED should support 'superpages' */ - if ((flags & IOVMF_LINEAR) && (flags & IOVMF_DA_ANON)) { - nr_entries = sgtable_nents(bytes); + if (flags & IOVMF_LINEAR) { + nr_entries = sgtable_nents(bytes, da, pa); if (!nr_entries) return ERR_PTR(-EINVAL); } else @@ -409,7 +416,8 @@ static inline void sgtable_drain_vmalloc(struct sg_table *sgt) BUG_ON(!sgt); } -static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) +static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, u32 da, + size_t len) { unsigned int i; struct scatterlist *sg; @@ -418,9 +426,10 @@ static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) va = phys_to_virt(pa); for_each_sg(sgt->sgl, sg, sgt->nents, i) { - size_t bytes; + unsigned bytes; - bytes = iopgsz_max(len); + bytes = max_alignment(da | pa); + bytes = min_t(unsigned, bytes, iopgsz_max(len)); BUG_ON(!iopgsz_ok(bytes)); @@ -429,6 +438,7 @@ static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) * 'pa' is cotinuous(linear). */ pa += bytes; + da += bytes; len -= bytes; } BUG_ON(len); @@ -695,18 +705,18 @@ u32 iommu_vmalloc(struct iommu *obj, u32 da, size_t bytes, u32 flags) if (!va) return -ENOMEM; - sgt = sgtable_alloc(bytes, flags); + flags &= IOVMF_HW_MASK; + flags |= IOVMF_DISCONT; + flags |= IOVMF_ALLOC; + flags |= (da ? IOVMF_DA_FIXED : IOVMF_DA_ANON); + + sgt = sgtable_alloc(bytes, flags, da, 0); if (IS_ERR(sgt)) { da = PTR_ERR(sgt); goto err_sgt_alloc; } sgtable_fill_vmalloc(sgt, va); - flags &= IOVMF_HW_MASK; - flags |= IOVMF_DISCONT; - flags |= IOVMF_ALLOC; - flags |= (da ? IOVMF_DA_FIXED : IOVMF_DA_ANON); - da = __iommu_vmap(obj, da, sgt, va, bytes, flags); if (IS_ERR_VALUE(da)) goto err_iommu_vmap; @@ -746,11 +756,11 @@ static u32 __iommu_kmap(struct iommu *obj, u32 da, u32 pa, void *va, { struct sg_table *sgt; -
[PATCH 3/4] iovmm: replace __iounmap with omap_iounmap
Omap platform is omap_iounmap function. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/iovmm.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 93a34d9..5489ca9 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -821,7 +821,7 @@ void iommu_kunmap(struct iommu *obj, u32 da) struct sg_table *sgt; typedef void (*func_t)(const void *); - sgt = unmap_vm_area(obj, da, (func_t)__iounmap, + sgt = unmap_vm_area(obj, da, (func_t)omap_iounmap, IOVMF_LINEAR | IOVMF_MMIO); if (!sgt) dev_dbg(obj->dev, "%s: No sgt\n", __func__); -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/4] iommu: create new api to set valid da range
Some IOMMUs cannot use the whole 0x0 - 0x rage. With this new API the valid range can be set. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/include/plat/iommu.h |3 +++ arch/arm/plat-omap/iommu.c | 29 + arch/arm/plat-omap/iovmm.c |8 +++- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h index 33c7d41..aea01b1 100644 --- a/arch/arm/plat-omap/include/plat/iommu.h +++ b/arch/arm/plat-omap/include/plat/iommu.h @@ -46,6 +46,8 @@ struct iommu { struct list_headmmap; struct mutexmmap_lock; /* protect mmap */ + u32 da_start; + u32 da_end; int (*isr)(struct iommu *obj); @@ -152,6 +154,7 @@ extern void flush_iotlb_all(struct iommu *obj); extern int iopgtable_store_entry(struct iommu *obj, struct iotlb_entry *e); extern size_t iopgtable_clear_entry(struct iommu *obj, u32 iova); +extern int iommu_set_da_range(struct iommu *obj, u32 start, u32 end); extern struct iommu *iommu_get(const char *name); extern void iommu_put(struct iommu *obj); diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index 6cd151b..e70e76b 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c @@ -25,6 +25,12 @@ #include "iopgtable.h" +/* Reserve the first page for NULL */ +#define IOMMU_DEFAULT_DA_START PAGE_SIZE +/* 0x not allowed because it is not page aligned */ +#define IOMMU_DEFAULT_DA_END 0xF000; + + #define for_each_iotlb_cr(obj, n, __i, cr) \ for (__i = 0; \ (__i < (n)) && (cr = __iotlb_read_cr((obj), __i), true); \ @@ -830,6 +836,27 @@ static int device_match_by_alias(struct device *dev, void *data) } /** + * iommu_set_da_range - Set a valid device address range + * @obj: target iommu + * @start Start of valid range + * @endEnd of valid range + **/ +int iommu_set_da_range(struct iommu *obj, u32 start, u32 end) +{ + if (!obj) + return -EFAULT; + + if (end < start || !PAGE_ALIGN(start | end)) + return -EINVAL; + + obj->da_start = start; + obj->da_end = end; + + return 0; +} +EXPORT_SYMBOL_GPL(iommu_set_da_range); + +/** * iommu_get - Get iommu handler * @name: target iommu name **/ @@ -853,6 +880,8 @@ struct iommu *iommu_get(const char *name) if (err) goto err_enable; flush_iotlb_all(obj); + obj->da_start = IOMMU_DEFAULT_DA_START; + obj->da_end = IOMMU_DEFAULT_DA_END; } if (!try_module_get(obj->owner)) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 5489ca9..bb45780 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -280,10 +280,8 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, alignement = PAGE_SIZE; if (flags & IOVMF_DA_ANON) { - /* -* Reserve the first page for NULL -*/ - start = PAGE_SIZE; + start = obj->da_start; + if (flags & IOVMF_LINEAR) alignement = iopgsz_max(bytes); start = roundup(start, alignement); @@ -308,7 +306,7 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da, prev_end = tmp->da_end; } - if ((start >= prev_end) && (ULONG_MAX - start + 1 >= bytes)) + if ((start >= prev_end) && (obj->da_end - start >= bytes)) goto found; dev_dbg(obj->dev, "%s: no space to fit %08x(%x) flags: %08x\n", -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] staging: tidspbridge - configure full L1 MMU range
Otherwise a virtual address beyond of the L1 size is used, the MMU hardware will look into a memory that does not belong to L1 translation tables. IOW; the MMU would allow to access any memory, configured or not. Reported-by: Felipe Contreras Signed-off-by: Fernando Guzman Lugo Signed-off-by: Felipe Contreras --- drivers/staging/tidspbridge/core/tiomap3430.c |6 ++ 1 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index 1be081f..ec96d1e 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -70,6 +70,7 @@ #define MMU_LARGE_PAGE_MASK 0x #define MMU_SMALL_PAGE_MASK 0xF000 #define OMAP3_IVA2_BOOTADDR_MASK 0xFC00 +#define MMU_L1_SIZE 0x4000 #define PAGES_II_LVL_TABLE 512 #define PHYS_TO_PAGE(phys) pfn_to_page((phys) >> PAGE_SHIFT) @@ -786,10 +787,7 @@ static int bridge_dev_create(struct bridge_dev_context pt_attrs = kzalloc(sizeof(struct pg_table_attrs), GFP_KERNEL); if (pt_attrs != NULL) { - /* Assuming that we use only DSP's memory map -* until 0x4000: , we would need only 1024 -* L1 enties i.e L1 size = 4K */ - pt_attrs->l1_size = 0x1000; + pt_attrs->l1_size = MMU_L1_SIZE; align_size = pt_attrs->l1_size; /* Align sizes are expected to be power of 2 */ /* we like to get aligned on L1 table size */ -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2] staging: tidspbridge: configure full L1 MMU range
From: Guzman Lugo, Fernando IVA MMU can manage up to 4GB of address space through its page tables, given that it's L1 is divided into 1MB sections it requires at least 16KB for its table which represents 4096 entries of 32 bits each. Previously, only 1GB was being handled by setting the page table size to 4KB, any virtual address beyond of the L1 size used, would fall into memory that does not belong to L1 translation tables, leading to unpredictable results. So, set the L1 table size to cover the entire MMU range (4GB) whether is meant to be used or not. Reported-by: Felipe Contreras Signed-off-by: Fernando Guzman Lugo Signed-off-by: Felipe Contreras --- drivers/staging/tidspbridge/core/tiomap3430.c |5 + 1 files changed, 1 insertions(+), 4 deletions(-) diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index cacd30e..7608822 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -784,10 +784,7 @@ static int bridge_dev_create(struct bridge_dev_context pt_attrs = kzalloc(sizeof(struct pg_table_attrs), GFP_KERNEL); if (pt_attrs != NULL) { - /* Assuming that we use only DSP's memory map -* until 0x4000: , we would need only 1024 -* L1 enties i.e L1 size = 4K */ - pt_attrs->l1_size = 0x1000; + pt_attrs->l1_size = SZ_16K; /* 4096 entries of 32 bits */ align_size = pt_attrs->l1_size; /* Align sizes are expected to be power of 2 */ /* we like to get aligned on L1 table size */ -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] mailbox: change full flag per mailbox queue instead of global
As pointer by Ben Ohand, the variable rq_full flag is a global variable, so if there are multiple mailbox user there will be conflics. Now there is a full flag per mailbox queue. Reported-by: Ohad Ben-Cohen Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/include/plat/mailbox.h |1 + arch/arm/plat-omap/mailbox.c |7 +++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h index 729166b..a6144b8 100644 --- a/arch/arm/plat-omap/include/plat/mailbox.h +++ b/arch/arm/plat-omap/include/plat/mailbox.h @@ -47,6 +47,7 @@ struct omap_mbox_queue { struct tasklet_struct tasklet; int (*callback)(void *); struct omap_mbox*mbox; + boolfull; }; struct omap_mbox { diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 8d86b0b..a1e274e 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -30,7 +30,6 @@ static struct omap_mbox *mboxes; static DEFINE_RWLOCK(mboxes_lock); -static bool rq_full; static int mbox_configured; static DEFINE_MUTEX(mbox_configured_lock); @@ -140,9 +139,9 @@ static void mbox_rx_work(struct work_struct *work) while (1) { spin_lock_irqsave(q->queue_lock, flags); rq = blk_fetch_request(q); - if (rq_full) { + if (mbox->rxq->full) { omap_mbox_enable_irq(mbox, IRQ_RX); - rq_full = false; + mbox->rxq->full = false; } spin_unlock_irqrestore(q->queue_lock, flags); if (!rq) @@ -183,7 +182,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) rq = blk_get_request(q, WRITE, GFP_ATOMIC); if (unlikely(!rq)) { omap_mbox_disable_irq(mbox, IRQ_RX); - rq_full = true; + mbox->rxq->full = true; goto nomem; } -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] mailbox: change full flag per mailbox queue instead of global
As pointed by Ben Ohand, the variable rq_full flag is a global variable, so if there are multiple mailbox users there will be conflics. Now there is a full flag per mailbox queue. Reported-by: Ohad Ben-Cohen Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/include/plat/mailbox.h |1 + arch/arm/plat-omap/mailbox.c |7 +++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h index 729166b..a6144b8 100644 --- a/arch/arm/plat-omap/include/plat/mailbox.h +++ b/arch/arm/plat-omap/include/plat/mailbox.h @@ -47,6 +47,7 @@ struct omap_mbox_queue { struct tasklet_struct tasklet; int (*callback)(void *); struct omap_mbox*mbox; + boolfull; }; struct omap_mbox { diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 8d86b0b..a1e274e 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -30,7 +30,6 @@ static struct omap_mbox *mboxes; static DEFINE_RWLOCK(mboxes_lock); -static bool rq_full; static int mbox_configured; static DEFINE_MUTEX(mbox_configured_lock); @@ -140,9 +139,9 @@ static void mbox_rx_work(struct work_struct *work) while (1) { spin_lock_irqsave(q->queue_lock, flags); rq = blk_fetch_request(q); - if (rq_full) { + if (mbox->rxq->full) { omap_mbox_enable_irq(mbox, IRQ_RX); - rq_full = false; + mbox->rxq->full = false; } spin_unlock_irqrestore(q->queue_lock, flags); if (!rq) @@ -183,7 +182,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) rq = blk_get_request(q, WRITE, GFP_ATOMIC); if (unlikely(!rq)) { omap_mbox_disable_irq(mbox, IRQ_RX); - rq_full = true; + mbox->rxq->full = true; goto nomem; } -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv3 1/9] dspbridge: replace iommu custom for opensource implementation
This patch replace the call to custom dsp mmu implemenation for the once on iommu module. Signed-off-by: Fernando Guzman Lugo --- drivers/dsp/bridge/core/_tiomap.h| 16 + drivers/dsp/bridge/core/io_sm.c | 114 ++-- drivers/dsp/bridge/core/tiomap3430.c | 501 +- drivers/dsp/bridge/core/ue_deh.c | 10 - 4 files changed, 118 insertions(+), 523 deletions(-) diff --git a/drivers/dsp/bridge/core/_tiomap.h b/drivers/dsp/bridge/core/_tiomap.h index bf0164e..d13677a 100644 --- a/drivers/dsp/bridge/core/_tiomap.h +++ b/drivers/dsp/bridge/core/_tiomap.h @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include #include /* for bridge_ioctl_extproc defn */ @@ -330,6 +332,7 @@ struct bridge_dev_context { u32 dw_internal_size; /* Internal memory size */ struct omap_mbox *mbox; /* Mail box handle */ + struct iommu *dsp_mmu; /* iommu for iva2 handler */ struct cfg_hostres *resources; /* Host Resources */ @@ -374,4 +377,17 @@ extern s32 dsp_debug; */ int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val); +static inline void dsp_iotlb_init(struct iotlb_entry *e, u32 da, u32 pa, + u32 pgsz) +{ + e->da = da; + e->pa = pa; + e->valid = 1; + e->prsvd = 1; + e->pgsz = pgsz & MMU_CAM_PGSZ_MASK; + e->endian = MMU_RAM_ENDIAN_LITTLE; + e->elsz = MMU_RAM_ELSZ_32; + e->mixed = 0; +} + #endif /* _TIOMAP_ */ diff --git a/drivers/dsp/bridge/core/io_sm.c b/drivers/dsp/bridge/core/io_sm.c index 7fb840d..1f47f8b 100644 --- a/drivers/dsp/bridge/core/io_sm.c +++ b/drivers/dsp/bridge/core/io_sm.c @@ -290,6 +290,8 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) struct cod_manager *cod_man; struct chnl_mgr *hchnl_mgr; struct msg_mgr *hmsg_mgr; + struct iommu *mmu; + struct iotlb_entry e; u32 ul_shm_base; u32 ul_shm_base_offset; u32 ul_shm_limit; @@ -312,7 +314,6 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) struct bridge_ioctl_extproc ae_proc[BRDIOCTL_NUMOFMMUTLB]; struct cfg_hostres *host_res; struct bridge_dev_context *pbridge_context; - u32 map_attrs; u32 shm0_end; u32 ul_dyn_ext_base; u32 ul_seg1_size = 0; @@ -336,6 +337,21 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) status = -EFAULT; goto func_end; } + + mmu = pbridge_context->dsp_mmu; + + if (mmu) + iommu_put(mmu); + mmu = iommu_get("iva2"); + + if (IS_ERR_OR_NULL(mmu)) { + pr_err("Error in iommu_get\n"); + pbridge_context->dsp_mmu = NULL; + status = -EFAULT; + goto func_end; + } + pbridge_context->dsp_mmu = mmu; + status = dev_get_cod_mgr(hio_mgr->hdev_obj, &cod_man); if (!cod_man) { status = -EFAULT; @@ -477,55 +493,16 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) gpp_va_curr = ul_gpp_va; num_bytes = ul_seg1_size; - /* -* Try to fit into TLB entries. If not possible, push them to page -* tables. It is quite possible that if sections are not on -* bigger page boundary, we may end up making several small pages. -* So, push them onto page tables, if that is the case. -*/ - map_attrs = 0x; - map_attrs = DSP_MAPLITTLEENDIAN; - map_attrs |= DSP_MAPPHYSICALADDR; - map_attrs |= DSP_MAPELEMSIZE32; - map_attrs |= DSP_MAPDONOTLOCK; - - while (num_bytes) { - /* -* To find the max. page size with which both PA & VA are -* aligned. -*/ - all_bits = pa_curr | va_curr; - dev_dbg(bridge, "all_bits %x, pa_curr %x, va_curr %x, " - "num_bytes %x\n", all_bits, pa_curr, va_curr, - num_bytes); - for (i = 0; i < 4; i++) { - if ((num_bytes >= page_size[i]) && ((all_bits & -(page_size[i] - - 1)) == 0)) { - status = - hio_mgr->intf_fxns-> - pfn_brd_mem_map(hio_mgr->hbridge_context, - pa_curr, va_curr, - page_size[i], map_attrs, - NULL); - if (DSP_FAILED(status)) - goto func_e
[PATCHv3 3/9] dspbridge: rename bridge_brd_mem_map/unmap to a proper name
Now these functions only map user space addresses to dsp virtual addresses, so now the functions have a more meaningful name Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/include/dspbridge/dspdefs.h | 44 drivers/dsp/bridge/core/_tiomap.h | 25 +++ drivers/dsp/bridge/core/tiomap3430.c | 52 ++-- drivers/dsp/bridge/pmgr/dev.c |2 - drivers/dsp/bridge/rmgr/proc.c | 12 +++-- 5 files changed, 53 insertions(+), 82 deletions(-) diff --git a/arch/arm/plat-omap/include/dspbridge/dspdefs.h b/arch/arm/plat-omap/include/dspbridge/dspdefs.h index 493f62e..4f56ae6 100644 --- a/arch/arm/plat-omap/include/dspbridge/dspdefs.h +++ b/arch/arm/plat-omap/include/dspbridge/dspdefs.h @@ -162,48 +162,6 @@ typedef int(*fxn_brd_memwrite) (struct bridge_dev_context u32 ulMemType); /* - * bridge_brd_mem_map - * Purpose: - * Map a MPU memory region to a DSP/IVA memory space - * Parameters: - * hDevContext:Handle to Bridge driver defined device info. - * ul_mpu_addr: MPU memory region start address. - * ulVirtAddr: DSP/IVA memory region u8 address. - * ul_num_bytes: Number of bytes to map. - * map_attrs: Mapping attributes (e.g. endianness). - * Returns: - * 0:Success. - * -EPERM: Other, unspecified error. - * Requires: - * hDevContext != NULL; - * Ensures: - */ -typedef int(*fxn_brd_memmap) (struct bridge_dev_context -* hDevContext, u32 ul_mpu_addr, -u32 ulVirtAddr, u32 ul_num_bytes, -u32 ulMapAttrs, -struct page **mapped_pages); - -/* - * bridge_brd_mem_un_map - * Purpose: - * UnMap an MPU memory region from DSP/IVA memory space - * Parameters: - * hDevContext:Handle to Bridge driver defined device info. - * ulVirtAddr: DSP/IVA memory region u8 address. - * ul_num_bytes: Number of bytes to unmap. - * Returns: - * 0:Success. - * -EPERM: Other, unspecified error. - * Requires: - * hDevContext != NULL; - * Ensures: - */ -typedef int(*fxn_brd_memunmap) (struct bridge_dev_context - * hDevContext, - u32 ulVirtAddr, u32 ul_num_bytes); - -/* * bridge_brd_stop * Purpose: * Bring board to the BRD_STOPPED state. @@ -1061,8 +1019,6 @@ struct bridge_drv_interface { fxn_brd_setstate pfn_brd_set_state; /* Sets the Board State */ fxn_brd_memcopy pfn_brd_mem_copy; /* Copies DSP Memory */ fxn_brd_memwrite pfn_brd_mem_write; /* Write DSP Memory w/o halt */ - fxn_brd_memmap pfn_brd_mem_map; /* Maps MPU mem to DSP mem */ - fxn_brd_memunmap pfn_brd_mem_un_map;/* Unmaps MPU mem to DSP mem */ fxn_chnl_create pfn_chnl_create;/* Create channel manager. */ fxn_chnl_destroy pfn_chnl_destroy; /* Destroy channel manager. */ fxn_chnl_open pfn_chnl_open;/* Create a new channel. */ diff --git a/drivers/dsp/bridge/core/_tiomap.h b/drivers/dsp/bridge/core/_tiomap.h index 6a822c6..4aa2358 100644 --- a/drivers/dsp/bridge/core/_tiomap.h +++ b/drivers/dsp/bridge/core/_tiomap.h @@ -396,4 +396,29 @@ static inline void dsp_iotlb_init(struct iotlb_entry *e, u32 da, u32 pa, e->mixed = 0; } +/** + * user_to_dsp_map() - maps user to dsp virtual address + * @mmu: Pointer to iommu handle. + * @uva: Virtual user space address. + * @da DSP address + * @size Buffer size to map. + * @usr_pgsstruct page array pointer where the user pages will be stored + * + * This function maps a user space buffer into DSP virtual address. + * + */ + +int user_to_dsp_map(struct iommu *mmu, u32 uva, u32 da, u32 size, + struct page **usr_pgs); + +/** + * user_to_dsp_unmap() - unmaps DSP virtual buffer. + * @mmu: Pointer to iommu handle. + * @da DSP address + * + * This function unmaps a user space buffer into DSP virtual address. + * + */ +int user_to_dsp_unmap(struct iommu *mmu, u32 da); + #endif /* _TIOMAP_ */ diff --git a/drivers/dsp/bridge/core/tiomap3430.c b/drivers/dsp/bridge/core/tiomap3430.c index 89d4936..88f5167 100644 --- a/drivers/dsp/bridge/core/tiomap3430.c +++ b/drivers/dsp/bridge/core/tiomap3430.c @@ -98,12 +98,6 @@ static int bridge_brd_mem_copy(struct bridge_dev_context *hDevContext, static int bridge_brd_mem_write(struct bridge_dev_context *dev_context, IN u8 *pbHostBuf, u32 dwDSPAddr, u32 ul_num_bytes, u32 ulMemType); -static int bridge_brd_mem_map(struct bridge_dev_context *hDevCont
[PATCHv3 0/9] dspbridge: iommu migration
This set of patches remove the dspbridge custom mmu implementation and use iommu module instead. NOTE: in order to dspbridge can work properly the patch "0001-iovmm-add-superpages-support-to-fixed-da-address.patch" is needed (specifically iommu_kmap calls need this patch). Fernando Guzman Lugo (9): dspbridge: replace iommu custom for opensource implementation dspbridge: move shared memory iommu maps to tiomap3430.c dspbridge: rename bridge_brd_mem_map/unmap to a proper name dspbridge: remove custom mmu code from tiomap3430.c dspbridge: add mmufault support dspbridge: remove hw directory dspbridge: move all iommu related code to a new file dspbridge: add map support for big buffers dspbridge: cleanup bridge_dev_context and cfg_hostres structures arch/arm/plat-omap/include/dspbridge/cfgdefs.h |1 - arch/arm/plat-omap/include/dspbridge/dsp-mmu.h | 90 ++ arch/arm/plat-omap/include/dspbridge/dspdefs.h | 44 - arch/arm/plat-omap/include/dspbridge/dspdeh.h |1 - arch/arm/plat-omap/include/dspbridge/dspioctl.h |7 - drivers/dsp/bridge/Makefile |5 +- drivers/dsp/bridge/core/_deh.h |3 - drivers/dsp/bridge/core/_tiomap.h | 15 +- drivers/dsp/bridge/core/dsp-mmu.c | 229 drivers/dsp/bridge/core/io_sm.c | 185 +--- drivers/dsp/bridge/core/mmu_fault.c | 139 --- drivers/dsp/bridge/core/mmu_fault.h | 36 - drivers/dsp/bridge/core/tiomap3430.c| 1297 --- drivers/dsp/bridge/core/tiomap3430_pwr.c| 183 +--- drivers/dsp/bridge/core/tiomap_io.c | 16 +- drivers/dsp/bridge/core/ue_deh.c| 87 +-- drivers/dsp/bridge/hw/EasiGlobal.h | 41 - drivers/dsp/bridge/hw/GlobalTypes.h | 308 -- drivers/dsp/bridge/hw/MMUAccInt.h | 76 -- drivers/dsp/bridge/hw/MMURegAcM.h | 226 drivers/dsp/bridge/hw/hw_defs.h | 60 -- drivers/dsp/bridge/hw/hw_mmu.c | 587 -- drivers/dsp/bridge/hw/hw_mmu.h | 161 --- drivers/dsp/bridge/pmgr/dev.c |2 - drivers/dsp/bridge/rmgr/drv.c |4 - drivers/dsp/bridge/rmgr/node.c |4 +- drivers/dsp/bridge/rmgr/proc.c | 19 +- 27 files changed, 599 insertions(+), 3227 deletions(-) create mode 100644 arch/arm/plat-omap/include/dspbridge/dsp-mmu.h create mode 100644 drivers/dsp/bridge/core/dsp-mmu.c delete mode 100644 drivers/dsp/bridge/core/mmu_fault.c delete mode 100644 drivers/dsp/bridge/core/mmu_fault.h delete mode 100644 drivers/dsp/bridge/hw/EasiGlobal.h delete mode 100644 drivers/dsp/bridge/hw/GlobalTypes.h delete mode 100644 drivers/dsp/bridge/hw/MMUAccInt.h delete mode 100644 drivers/dsp/bridge/hw/MMURegAcM.h delete mode 100644 drivers/dsp/bridge/hw/hw_defs.h delete mode 100644 drivers/dsp/bridge/hw/hw_mmu.c delete mode 100644 drivers/dsp/bridge/hw/hw_mmu.h -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv3 7/9] dspbridge: move all iommu related code to a new file
This patch moves all the code related to iommu in the dsp-mmu.c file Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/include/dspbridge/dsp-mmu.h | 90 ++ arch/arm/plat-omap/include/dspbridge/dspdeh.h |1 - drivers/dsp/bridge/Makefile|2 +- drivers/dsp/bridge/core/_deh.h |3 - drivers/dsp/bridge/core/_tiomap.h | 41 +- drivers/dsp/bridge/core/dsp-mmu.c | 218 drivers/dsp/bridge/core/mmu_fault.c| 76 drivers/dsp/bridge/core/mmu_fault.h| 35 drivers/dsp/bridge/core/tiomap3430.c | 111 + drivers/dsp/bridge/core/ue_deh.c | 68 +--- drivers/dsp/bridge/rmgr/proc.c |6 +- 11 files changed, 318 insertions(+), 333 deletions(-) create mode 100644 arch/arm/plat-omap/include/dspbridge/dsp-mmu.h create mode 100644 drivers/dsp/bridge/core/dsp-mmu.c delete mode 100644 drivers/dsp/bridge/core/mmu_fault.c delete mode 100644 drivers/dsp/bridge/core/mmu_fault.h diff --git a/arch/arm/plat-omap/include/dspbridge/dsp-mmu.h b/arch/arm/plat-omap/include/dspbridge/dsp-mmu.h new file mode 100644 index 000..266f38b --- /dev/null +++ b/arch/arm/plat-omap/include/dspbridge/dsp-mmu.h @@ -0,0 +1,90 @@ +/* + * dsp-mmu.h + * + * DSP-BIOS Bridge driver support functions for TI OMAP processors. + * + * DSP iommu. + * + * Copyright (C) 2005-2010 Texas Instruments, Inc. + * + * This package is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef _DSP_MMU_ +#define _DSP_MMU_ + +#include +#include + +/** + * dsp_iotlb_init() - initialize dsp mmu entry + * @e: Pointer tbl entry. + * @da DSP address + * @pa:physical address. + * @pgsz page size to map. + * + * This function initializes a dsp mmu entry in order to be used with + * iommu functions. + */ +static inline void dsp_iotlb_init(struct iotlb_entry *e, u32 da, u32 pa, + u32 pgsz) +{ + e->da = da; + e->pa = pa; + e->valid = 1; + e->prsvd = 1; + e->pgsz = pgsz & MMU_CAM_PGSZ_MASK; + e->endian = MMU_RAM_ENDIAN_LITTLE; + e->elsz = MMU_RAM_ELSZ_32; + e->mixed = 0; +} + +/** + * dsp_mmu_init() - initialize dsp_mmu module and returns a handle + * + * This function initialize dsp mmu module and returns a struct iommu + * handle to use it for dsp maps. + * + */ +struct iommu *dsp_mmu_init(void); + +/** + * dsp_mmu_exit() - destroy dsp mmu module + * @mmu: Pointer to iommu handle. + * + * This function destroys dsp mmu module. + * + */ +void dsp_mmu_exit(struct iommu *mmu); + +/** + * user_to_dsp_map() - maps user to dsp virtual address + * @mmu: Pointer to iommu handle. + * @uva: Virtual user space address. + * @da DSP address + * @size Buffer size to map. + * @usr_pgsstruct page array pointer where the user pages will be stored + * + * This function maps a user space buffer into DSP virtual address. + * + */ +int user_to_dsp_map(struct iommu *mmu, u32 uva, u32 da, u32 size, + struct page **usr_pgs); + +/** + * user_to_dsp_unmap() - unmaps DSP virtual buffer. + * @mmu: Pointer to iommu handle. + * @da DSP address + * + * This function unmaps a user space buffer into DSP virtual address. + * + */ +int user_to_dsp_unmap(struct iommu *mmu, u32 da); + +#endif diff --git a/arch/arm/plat-omap/include/dspbridge/dspdeh.h b/arch/arm/plat-omap/include/dspbridge/dspdeh.h index 4394711..af19926 100644 --- a/arch/arm/plat-omap/include/dspbridge/dspdeh.h +++ b/arch/arm/plat-omap/include/dspbridge/dspdeh.h @@ -43,5 +43,4 @@ extern int bridge_deh_register_notify(struct deh_mgr *deh_mgr, extern void bridge_deh_notify(struct deh_mgr *deh_mgr, u32 ulEventMask, u32 dwErrInfo); -extern void bridge_deh_release_dummy_mem(void); #endif /* DSPDEH_ */ diff --git a/drivers/dsp/bridge/Makefile b/drivers/dsp/bridge/Makefile index 66ca10a..9f32055 100644 --- a/drivers/dsp/bridge/Makefile +++ b/drivers/dsp/bridge/Makefile @@ -5,7 +5,7 @@ libservices = services/sync.o services/cfg.o \ services/ntfy.o services/services.o libcore = core/chnl_sm.o core/msg_sm.o core/io_sm.o core/tiomap3430.o \ core/tiomap3430_pwr.o core/tiomap_io.o \ - core/mmu_fault.o core/ue_deh.o core/wdt.o core/dsp-clock.o + core/dsp-mmu.o core/ue_deh.o core/wdt.o core/dsp-clock.o libpmgr = pmgr/chnl.o pmgr
[PATCHv3 5/9] dspbridge: add mmufault support
With changes for iommu migration mmu fault report and dsp track dump is broken, this patch fixes that. Signed-off-by: Fernando Guzman Lugo --- drivers/dsp/bridge/core/mmu_fault.c | 93 ++--- drivers/dsp/bridge/core/mmu_fault.h |5 +- drivers/dsp/bridge/core/tiomap3430.c |2 + drivers/dsp/bridge/core/ue_deh.c | 31 +--- 4 files changed, 34 insertions(+), 97 deletions(-) diff --git a/drivers/dsp/bridge/core/mmu_fault.c b/drivers/dsp/bridge/core/mmu_fault.c index 5c0124f..d991c6a 100644 --- a/drivers/dsp/bridge/core/mmu_fault.c +++ b/drivers/dsp/bridge/core/mmu_fault.c @@ -23,9 +23,12 @@ /* --- Trace & Debug */ #include #include +#include /* --- OS Adaptation Layer */ #include +#include + /* --- Link Driver */ #include @@ -40,11 +43,6 @@ #include "_tiomap.h" #include "mmu_fault.h" -static u32 dmmu_event_mask; -u32 fault_addr; - -static bool mmu_check_if_fault(struct bridge_dev_context *dev_context); - /* * mmu_fault_dpc * Deferred procedure call to handle DSP MMU fault. @@ -62,78 +60,21 @@ void mmu_fault_dpc(IN unsigned long pRefData) * mmu_fault_isr * ISR to be triggered by a DSP MMU fault interrupt. */ -irqreturn_t mmu_fault_isr(int irq, IN void *pRefData) -{ - struct deh_mgr *deh_mgr_obj = (struct deh_mgr *)pRefData; - struct bridge_dev_context *dev_context; - struct cfg_hostres *resources; - - DBC_REQUIRE(irq == INT_DSP_MMU_IRQ); - DBC_REQUIRE(deh_mgr_obj); - - if (deh_mgr_obj) { - - dev_context = - (struct bridge_dev_context *)deh_mgr_obj->hbridge_context; - - resources = dev_context->resources; - - if (!resources) { - dev_dbg(bridge, "%s: Failed to get Host Resources\n", - __func__); - return IRQ_HANDLED; - } - if (mmu_check_if_fault(dev_context)) { - printk(KERN_INFO "* DSPMMU FAULT * IRQStatus " - "0x%x\n", dmmu_event_mask); - printk(KERN_INFO "* DSPMMU FAULT * fault_addr " - "0x%x\n", fault_addr); - /* -* Schedule a DPC directly. In the future, it may be -* necessary to check if DSP MMU fault is intended for -* Bridge. -*/ - tasklet_schedule(&deh_mgr_obj->dpc_tasklet); - - /* Reset err_info structure before use. */ - deh_mgr_obj->err_info.dw_err_mask = DSP_MMUFAULT; - deh_mgr_obj->err_info.dw_val1 = fault_addr >> 16; - deh_mgr_obj->err_info.dw_val2 = fault_addr & 0x; - deh_mgr_obj->err_info.dw_val3 = 0L; - /* Disable the MMU events, else once we clear it will -* start to raise INTs again */ - hw_mmu_event_disable(resources->dw_dmmu_base, -HW_MMU_TRANSLATION_FAULT); - } else { - hw_mmu_event_disable(resources->dw_dmmu_base, -HW_MMU_ALL_INTERRUPTS); - } - } - return IRQ_HANDLED; -} +int mmu_fault_isr(struct iommu *mmu) -/* - * mmu_check_if_fault - * Check to see if MMU Fault is valid TLB miss from DSP - * Note: This function is called from an ISR - */ -static bool mmu_check_if_fault(struct bridge_dev_context *dev_context) { + struct deh_mgr *dm; + u32 da; + + dev_get_deh_mgr(dev_get_first(), &dm); + + if (!dm) + return -EPERM; + + da = iommu_read_reg(mmu, MMU_FAULT_AD); + iommu_write_reg(mmu, 0, MMU_IRQENABLE); + dm->err_info.dw_val1 = da; + tasklet_schedule(&dm->dpc_tasklet); - bool ret = false; - hw_status hw_status_obj; - struct cfg_hostres *resources = dev_context->resources; - - if (!resources) { - dev_dbg(bridge, "%s: Failed to get Host Resources in\n", - __func__); - return ret; - } - hw_status_obj = - hw_mmu_event_status(resources->dw_dmmu_base, &dmmu_event_mask); - if (dmmu_event_mask == HW_MMU_TRANSLATION_FAULT) { - hw_mmu_fault_addr_read(resources->dw_dmmu_base, &fault_addr); - ret = true; - } - return ret; + return 0; } diff --git a/drivers/dsp/bridge/core/mmu_fault.h b/drivers/dsp/bridge/c
[PATCH] iovmm: add superpages support to fixed da address
This patch adds superpages support to fixed ad address inside iommu_kmap function. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/iovmm.c | 52 +++- 1 files changed, 32 insertions(+), 20 deletions(-) diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 936aef1..7cde09f 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -86,35 +86,45 @@ static size_t sgtable_len(const struct sg_table *sgt) } #define sgtable_ok(x) (!!sgtable_len(x)) + +static inline unsigned max_alignment(u32 addr) +{ + int i; + unsigned pagesize[] = { SZ_16M, SZ_1M, SZ_64K, SZ_4K, }; + for (i = 0; i < ARRAY_SIZE(pagesize) && addr & (pagesize[i] - 1); i++) + ; + return (i < ARRAY_SIZE(pagesize)) ? pagesize[i] : 0; +} + + /* * calculate the optimal number sg elements from total bytes based on * iommu superpages */ -static unsigned int sgtable_nents(size_t bytes) +static unsigned int sgtable_nents(size_t bytes, u32 da, u32 pa) { - int i; - unsigned int nr_entries; - const unsigned long pagesize[] = { SZ_16M, SZ_1M, SZ_64K, SZ_4K, }; + unsigned int nr_entries = 0, ent_sz; if (!IS_ALIGNED(bytes, PAGE_SIZE)) { pr_err("%s: wrong size %08x\n", __func__, bytes); return 0; } - nr_entries = 0; - for (i = 0; i < ARRAY_SIZE(pagesize); i++) { - if (bytes >= pagesize[i]) { - nr_entries += (bytes / pagesize[i]); - bytes %= pagesize[i]; - } + while (bytes) { + ent_sz = max_alignment(da | pa); + ent_sz = min(ent_sz, (unsigned)iopgsz_max(bytes)); + nr_entries++; + da += ent_sz; + pa += ent_sz; + bytes -= ent_sz; } - BUG_ON(bytes); return nr_entries; } /* allocate and initialize sg_table header(a kind of 'superblock') */ -static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags) +static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags, + u32 da, u32 pa) { unsigned int nr_entries; int err; @@ -126,9 +136,8 @@ static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags) if (!IS_ALIGNED(bytes, PAGE_SIZE)) return ERR_PTR(-EINVAL); - /* FIXME: IOVMF_DA_FIXED should support 'superpages' */ - if ((flags & IOVMF_LINEAR) && (flags & IOVMF_DA_ANON)) { - nr_entries = sgtable_nents(bytes); + if (flags & IOVMF_LINEAR) { + nr_entries = sgtable_nents(bytes, da, pa); if (!nr_entries) return ERR_PTR(-EINVAL); } else @@ -403,7 +412,8 @@ static inline void sgtable_drain_vmalloc(struct sg_table *sgt) BUG_ON(!sgt); } -static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) +static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, u32 da, + size_t len) { unsigned int i; struct scatterlist *sg; @@ -414,7 +424,8 @@ static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) for_each_sg(sgt->sgl, sg, sgt->nents, i) { size_t bytes; - bytes = iopgsz_max(len); + bytes = max_alignment(da | pa); + bytes = min(bytes, (size_t)iopgsz_max(len)); BUG_ON(!iopgsz_ok(bytes)); @@ -423,6 +434,7 @@ static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, size_t len) * 'pa' is cotinuous(linear). */ pa += bytes; + da += bytes; len -= bytes; } BUG_ON(len); @@ -689,7 +701,7 @@ u32 iommu_vmalloc(struct iommu *obj, u32 da, size_t bytes, u32 flags) if (!va) return -ENOMEM; - sgt = sgtable_alloc(bytes, flags); + sgt = sgtable_alloc(bytes, flags, da, 0); if (IS_ERR(sgt)) { da = PTR_ERR(sgt); goto err_sgt_alloc; @@ -740,11 +752,11 @@ static u32 __iommu_kmap(struct iommu *obj, u32 da, u32 pa, void *va, { struct sg_table *sgt; - sgt = sgtable_alloc(bytes, flags); + sgt = sgtable_alloc(bytes, flags, da, pa); if (IS_ERR(sgt)) return PTR_ERR(sgt); - sgtable_fill_kmalloc(sgt, pa, bytes); + sgtable_fill_kmalloc(sgt, pa, da, bytes); da = map_iommu_region(obj, da, sgt, va, bytes, flags); if (IS_ERR_VALUE(da)) { -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv3 9/9] dspbridge: cleanup bridge_dev_context and cfg_hostres structures
this patch cleans up cfg_hostres and bridge_dev_context structures of custom mmu code not needed anymore. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/include/dspbridge/cfgdefs.h |1 - drivers/dsp/bridge/core/_tiomap.h |5 - drivers/dsp/bridge/core/tiomap3430.c |8 drivers/dsp/bridge/core/tiomap_io.c|2 +- drivers/dsp/bridge/rmgr/drv.c |4 5 files changed, 1 insertions(+), 19 deletions(-) diff --git a/arch/arm/plat-omap/include/dspbridge/cfgdefs.h b/arch/arm/plat-omap/include/dspbridge/cfgdefs.h index 38122db..dfb55cc 100644 --- a/arch/arm/plat-omap/include/dspbridge/cfgdefs.h +++ b/arch/arm/plat-omap/include/dspbridge/cfgdefs.h @@ -68,7 +68,6 @@ struct cfg_hostres { void __iomem *dw_per_base; u32 dw_per_pm_base; u32 dw_core_pm_base; - void __iomem *dw_dmmu_base; void __iomem *dw_sys_ctrl_base; }; diff --git a/drivers/dsp/bridge/core/_tiomap.h b/drivers/dsp/bridge/core/_tiomap.h index 8a9a822..82bce7d 100644 --- a/drivers/dsp/bridge/core/_tiomap.h +++ b/drivers/dsp/bridge/core/_tiomap.h @@ -323,7 +323,6 @@ struct bridge_dev_context { */ u32 dw_dsp_ext_base_addr; /* See the comment above */ u32 dw_api_reg_base;/* API mem map'd registers */ - void __iomem *dw_dsp_mmu_base; /* DSP MMU Mapped registers */ u32 dw_api_clk_base;/* CLK Registers */ u32 dw_dsp_clk_m2_base; /* DSP Clock Module m2 */ u32 dw_public_rhea; /* Pub Rhea */ @@ -347,10 +346,6 @@ struct bridge_dev_context { /* DMMU TLB entries */ struct bridge_ioctl_extproc atlb_entry[BRDIOCTL_NUMOFMMUTLB]; u32 dw_brd_state; /* Last known board state. */ - u32 ul_int_mask;/* int mask */ - u16 io_base;/* Board I/O base */ - u32 num_tlb_entries;/* DSP MMU TLB entry counter */ - u32 fixed_tlb_entries; /* Fixed DSPMMU TLB entry count */ /* TC Settings */ bool tc_word_swap_on; /* Traffic Controller Word Swap */ diff --git a/drivers/dsp/bridge/core/tiomap3430.c b/drivers/dsp/bridge/core/tiomap3430.c index aa6e999..83a9561 100644 --- a/drivers/dsp/bridge/core/tiomap3430.c +++ b/drivers/dsp/bridge/core/tiomap3430.c @@ -753,7 +753,6 @@ static int bridge_dev_create(OUT struct bridge_dev_context dev_context->atlb_entry[entry_ndx].ul_gpp_pa = dev_context->atlb_entry[entry_ndx].ul_dsp_va = 0; } - dev_context->num_tlb_entries = 0; dev_context->dw_dsp_base_addr = (u32) MEM_LINEAR_ADDRESS((void *) (pConfig-> dw_mem_base @@ -766,11 +765,7 @@ static int bridge_dev_create(OUT struct bridge_dev_context if (DSP_SUCCEEDED(status)) { dev_context->tc_word_swap_on = drv_datap->tc_wordswapon; - /* MMU address is obtained from the host -* resources struct */ - dev_context->dw_dsp_mmu_base = resources->dw_dmmu_base; dev_context->hdev_obj = hdev_obj; - dev_context->ul_int_mask = 0; /* Store current board state. */ dev_context->dw_brd_state = BRD_STOPPED; dev_context->resources = resources; @@ -887,8 +882,6 @@ static int bridge_dev_destroy(struct bridge_dev_context *hDevContext) iounmap((void *)host_res->dw_mem_base[3]); if (host_res->dw_mem_base[4]) iounmap((void *)host_res->dw_mem_base[4]); - if (host_res->dw_dmmu_base) - iounmap(host_res->dw_dmmu_base); if (host_res->dw_per_base) iounmap(host_res->dw_per_base); if (host_res->dw_per_pm_base) @@ -902,7 +895,6 @@ static int bridge_dev_destroy(struct bridge_dev_context *hDevContext) host_res->dw_mem_base[2] = (u32) NULL; host_res->dw_mem_base[3] = (u32) NULL; host_res->dw_mem_base[4] = (u32) NULL; - host_res->dw_dmmu_base = NULL; host_res->dw_sys_ctrl_base = NULL; kfree(host_res); diff --git a/drivers/dsp/bridge/core/tiomap_io.c b/drivers/dsp/bridge/core/tiomap_io.c index 3c0d3a3..2f2f8c2 100644 --- a/drivers/dsp/bridge/core/tiomap_io.c +++ b/drivers/dsp/bridge/core/tiomap_io.c @@ -437,7 +437,7 @@ int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val) omap_mbox_restore_ctx(dev_context->mbox); /* Access MMU SYS CONFIG register to generate a short wakeup */ - __raw_readl(resources->dw_dmmu_base + 0x10); + iommu_read_reg(dev_context->dsp_mmu, MMU_SYSCONFIG);
[PATCHv3 8/9] dspbridge: add map support for big buffers
due to a restriction in scatter gather lists, it can not be created a list for a buffer bigger than 1MB. This patch is spliting big mappings into 1MB mappings. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/include/dspbridge/dsp-mmu.h |2 +- drivers/dsp/bridge/core/dsp-mmu.c | 55 ++- drivers/dsp/bridge/rmgr/proc.c |3 +- 3 files changed, 36 insertions(+), 24 deletions(-) diff --git a/arch/arm/plat-omap/include/dspbridge/dsp-mmu.h b/arch/arm/plat-omap/include/dspbridge/dsp-mmu.h index 266f38b..2e4bf6a 100644 --- a/arch/arm/plat-omap/include/dspbridge/dsp-mmu.h +++ b/arch/arm/plat-omap/include/dspbridge/dsp-mmu.h @@ -85,6 +85,6 @@ int user_to_dsp_map(struct iommu *mmu, u32 uva, u32 da, u32 size, * This function unmaps a user space buffer into DSP virtual address. * */ -int user_to_dsp_unmap(struct iommu *mmu, u32 da); +int user_to_dsp_unmap(struct iommu *mmu, u32 da, unsigned size); #endif diff --git a/drivers/dsp/bridge/core/dsp-mmu.c b/drivers/dsp/bridge/core/dsp-mmu.c index e8da327..9a46206 100644 --- a/drivers/dsp/bridge/core/dsp-mmu.c +++ b/drivers/dsp/bridge/core/dsp-mmu.c @@ -133,7 +133,7 @@ int user_to_dsp_map(struct iommu *mmu, u32 uva, u32 da, u32 size, struct page **usr_pgs) { int res, w; - unsigned pages, i; + unsigned pages, i, j = 0; struct vm_area_struct *vma; struct mm_struct *mm = current->mm; struct sg_table *sgt; @@ -162,24 +162,31 @@ int user_to_dsp_map(struct iommu *mmu, u32 uva, u32 da, u32 size, if (res < 0) return res; - sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); + while (pages) { + sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); - if (!sgt) - return -ENOMEM; + if (!sgt) + return -ENOMEM; - res = sg_alloc_table(sgt, pages, GFP_KERNEL); + res = sg_alloc_table(sgt, + min((unsigned)SG_MAX_SINGLE_ALLOC, pages), GFP_KERNEL); + pages -= min((unsigned)SG_MAX_SINGLE_ALLOC, pages); - if (res < 0) - goto err_sg; + if (res < 0) + goto err_sg; + + for_each_sg(sgt->sgl, sg, sgt->nents, i) + sg_set_page(sg, usr_pgs[j++], PAGE_SIZE, 0); - for_each_sg(sgt->sgl, sg, sgt->nents, i) - sg_set_page(sg, usr_pgs[i], PAGE_SIZE, 0); + da = iommu_vmap(mmu, da, sgt, IOVMF_ENDIAN_LITTLE | + IOVMF_ELSZ_32); - da = iommu_vmap(mmu, da, sgt, IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32); + if (IS_ERR_VALUE(da)) { + res = (int)da; + goto err_map; + } - if (IS_ERR_VALUE(da)) { - res = (int)da; - goto err_map; + da += SG_MAX_SINGLE_ALLOC * PAGE_SIZE; } return 0; @@ -198,21 +205,25 @@ err_sg: * This function unmaps a user space buffer into DSP virtual address. * */ -int user_to_dsp_unmap(struct iommu *mmu, u32 da) +int user_to_dsp_unmap(struct iommu *mmu, u32 da, unsigned size) { unsigned i; struct sg_table *sgt; struct scatterlist *sg; + const unsigned max_sz = SG_MAX_SINGLE_ALLOC * PAGE_SIZE; - sgt = iommu_vunmap(mmu, da); - if (!sgt) - return -EFAULT; - - for_each_sg(sgt->sgl, sg, sgt->nents, i) - put_page(sg_page(sg)); + while (size) { + size -= min(max_sz, size); + sgt = iommu_vunmap(mmu, da); + if (!sgt) + return -EFAULT; - sg_free_table(sgt); - kfree(sgt); + for_each_sg(sgt->sgl, sg, sgt->nents, i) + put_page(sg_page(sg)); + sg_free_table(sgt); + kfree(sgt); + da += max_sz; + } return 0; } diff --git a/drivers/dsp/bridge/rmgr/proc.c b/drivers/dsp/bridge/rmgr/proc.c index 4f10a41..997918e 100644 --- a/drivers/dsp/bridge/rmgr/proc.c +++ b/drivers/dsp/bridge/rmgr/proc.c @@ -1713,7 +1713,8 @@ int proc_un_map(void *hprocessor, void *map_addr, /* Remove mapping from the page tables. */ if (DSP_SUCCEEDED(status)) { status = user_to_dsp_unmap( - p_proc_object->hbridge_context->dsp_mmu, va_align); + p_proc_object->hbridge_context->dsp_mmu, + va_align, size_align); } mutex_unlock(&proc_lock); -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv3 4/9] dspbridge: remove custom mmu code from tiomap3430.c
This patch removes all the custom mmu code remaining in tiomap3430.c which is not needed anymore. Signed-off-by: Fernando Guzman Lugo --- drivers/dsp/bridge/core/_tiomap.h|1 - drivers/dsp/bridge/core/tiomap3430.c | 470 -- 2 files changed, 0 insertions(+), 471 deletions(-) diff --git a/drivers/dsp/bridge/core/_tiomap.h b/drivers/dsp/bridge/core/_tiomap.h index 4aa2358..c41fd8e 100644 --- a/drivers/dsp/bridge/core/_tiomap.h +++ b/drivers/dsp/bridge/core/_tiomap.h @@ -356,7 +356,6 @@ struct bridge_dev_context { /* TC Settings */ bool tc_word_swap_on; /* Traffic Controller Word Swap */ - struct pg_table_attrs *pt_attrs; u32 dsp_per_clks; }; diff --git a/drivers/dsp/bridge/core/tiomap3430.c b/drivers/dsp/bridge/core/tiomap3430.c index 88f5167..96cceea 100644 --- a/drivers/dsp/bridge/core/tiomap3430.c +++ b/drivers/dsp/bridge/core/tiomap3430.c @@ -105,56 +105,9 @@ static int bridge_dev_create(OUT struct bridge_dev_context static int bridge_dev_ctrl(struct bridge_dev_context *dev_context, u32 dw_cmd, IN OUT void *pargs); static int bridge_dev_destroy(struct bridge_dev_context *dev_context); -static u32 user_va2_pa(struct mm_struct *mm, u32 address); -static int pte_update(struct bridge_dev_context *hDevContext, u32 pa, -u32 va, u32 size, -struct hw_mmu_map_attrs_t *map_attrs); -static int pte_set(struct pg_table_attrs *pt, u32 pa, u32 va, - u32 size, struct hw_mmu_map_attrs_t *attrs); -static int mem_map_vmalloc(struct bridge_dev_context *hDevContext, - u32 ul_mpu_addr, u32 ulVirtAddr, - u32 ul_num_bytes, - struct hw_mmu_map_attrs_t *hw_attrs); bool wait_for_start(struct bridge_dev_context *dev_context, u32 dw_sync_addr); -/* --- Globals */ - -/* Attributes of L2 page tables for DSP MMU */ -struct page_info { - u32 num_entries;/* Number of valid PTEs in the L2 PT */ -}; - -/* Attributes used to manage the DSP MMU page tables */ -struct pg_table_attrs { - spinlock_t pg_lock; /* Critical section object handle */ - - u32 l1_base_pa; /* Physical address of the L1 PT */ - u32 l1_base_va; /* Virtual address of the L1 PT */ - u32 l1_size;/* Size of the L1 PT */ - u32 l1_tbl_alloc_pa; - /* Physical address of Allocated mem for L1 table. May not be aligned */ - u32 l1_tbl_alloc_va; - /* Virtual address of Allocated mem for L1 table. May not be aligned */ - u32 l1_tbl_alloc_sz; - /* Size of consistent memory allocated for L1 table. -* May not be aligned */ - - u32 l2_base_pa; /* Physical address of the L2 PT */ - u32 l2_base_va; /* Virtual address of the L2 PT */ - u32 l2_size;/* Size of the L2 PT */ - u32 l2_tbl_alloc_pa; - /* Physical address of Allocated mem for L2 table. May not be aligned */ - u32 l2_tbl_alloc_va; - /* Virtual address of Allocated mem for L2 table. May not be aligned */ - u32 l2_tbl_alloc_sz; - /* Size of consistent memory allocated for L2 table. -* May not be aligned */ - - u32 l2_num_pages; /* Number of allocated L2 PT */ - /* Array [l2_num_pages] of L2 PT info structs */ - struct page_info *pg_info; -}; /* * This Bridge driver's function interface table. @@ -210,32 +163,6 @@ static struct bridge_drv_interface drv_interface_fxns = { bridge_msg_set_queue_id, }; -static inline void tlb_flush_all(const void __iomem *base) -{ - __raw_writeb(__raw_readb(base + MMU_GFLUSH) | 1, base + MMU_GFLUSH); -} - -static inline void flush_all(struct bridge_dev_context *dev_context) -{ - if (dev_context->dw_brd_state == BRD_DSP_HIBERNATION || - dev_context->dw_brd_state == BRD_HIBERNATION) - wake_dsp(dev_context, NULL); - - tlb_flush_all(dev_context->dw_dsp_mmu_base); -} - -static void bad_page_dump(u32 pa, struct page *pg) -{ - pr_emerg("DSPBRIDGE: MAP function: COUNT 0 FOR PA 0x%x\n", pa); - pr_emerg("Bad page state in process '%s'\n" -"page:%p flags:0x%0*lx mapping:%p mapcount:%d count:%d\n" -"Backtrace:\n", -current->comm, pg, (int)(2 * sizeof(unsigned long)), -(unsigned long)pg->flags, pg->mapping, -page_mapcount(pg), page_count(pg)); - dump_stack(); -} - /* * bridge_drv_entry * purpose: @@ -637,7 +564,6 @@ static int bridge_brd_stop(struct bridge_dev_context *hDevContext) { int status = 0; struct bridge_dev_context *dev_context = hDevContext; - struct pg_table_attrs *pt
[PATCHv3 2/9] dspbridge: move shared memory iommu maps to tiomap3430.c
Now the iommu map of shared memory segments are done in bridge_brd_start and unmaped in bridge_brd_stop. NOTE: video sequencer reset is not done in dspbridge anymore, due to dspbridge does not manage it. Signed-off-by: Fernando Guzman Lugo --- drivers/dsp/bridge/core/_tiomap.h|6 + drivers/dsp/bridge/core/io_sm.c | 117 ++-- drivers/dsp/bridge/core/tiomap3430.c | 353 -- drivers/dsp/bridge/core/tiomap_io.c | 11 +- 4 files changed, 237 insertions(+), 250 deletions(-) diff --git a/drivers/dsp/bridge/core/_tiomap.h b/drivers/dsp/bridge/core/_tiomap.h index d13677a..6a822c6 100644 --- a/drivers/dsp/bridge/core/_tiomap.h +++ b/drivers/dsp/bridge/core/_tiomap.h @@ -310,6 +310,11 @@ static const struct bpwr_clk_t bpwr_clks[] = { #define CLEAR_BIT_INDEX(reg, index) (reg &= ~(1 << (index))) +struct shm_segs { + u32 seg0_da, seg0_pa, seg0_va, seg0_size; + u32 seg1_da, seg1_pa, seg1_va, seg1_size; +}; + /* This Bridge driver's device context: */ struct bridge_dev_context { struct dev_object *hdev_obj;/* Handle to Bridge device object. */ @@ -333,6 +338,7 @@ struct bridge_dev_context { struct omap_mbox *mbox; /* Mail box handle */ struct iommu *dsp_mmu; /* iommu for iva2 handler */ + struct shm_segs *sh_s; struct cfg_hostres *resources; /* Host Resources */ diff --git a/drivers/dsp/bridge/core/io_sm.c b/drivers/dsp/bridge/core/io_sm.c index 1f47f8b..aca9854 100644 --- a/drivers/dsp/bridge/core/io_sm.c +++ b/drivers/dsp/bridge/core/io_sm.c @@ -290,8 +290,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) struct cod_manager *cod_man; struct chnl_mgr *hchnl_mgr; struct msg_mgr *hmsg_mgr; - struct iommu *mmu; - struct iotlb_entry e; + struct shm_segs *sm_sg; u32 ul_shm_base; u32 ul_shm_base_offset; u32 ul_shm_limit; @@ -317,14 +316,6 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) u32 shm0_end; u32 ul_dyn_ext_base; u32 ul_seg1_size = 0; - u32 pa_curr = 0; - u32 va_curr = 0; - u32 gpp_va_curr = 0; - u32 num_bytes = 0; - u32 all_bits = 0; - u32 page_size[] = { HW_PAGE_SIZE16MB, HW_PAGE_SIZE1MB, - HW_PAGE_SIZE64KB, HW_PAGE_SIZE4KB - }; status = dev_get_bridge_context(hio_mgr->hdev_obj, &pbridge_context); if (!pbridge_context) { @@ -338,19 +329,12 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) goto func_end; } - mmu = pbridge_context->dsp_mmu; + sm_sg = kmalloc(sizeof(*sm_sg), GFP_KERNEL); - if (mmu) - iommu_put(mmu); - mmu = iommu_get("iva2"); - - if (IS_ERR_OR_NULL(mmu)) { - pr_err("Error in iommu_get\n"); - pbridge_context->dsp_mmu = NULL; - status = -EFAULT; + if (!sm_sg) { + status = -ENOMEM; goto func_end; } - pbridge_context->dsp_mmu = mmu; status = dev_get_cod_mgr(hio_mgr->hdev_obj, &cod_man); if (!cod_man) { @@ -488,74 +472,16 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) if (DSP_FAILED(status)) goto func_end; - pa_curr = ul_gpp_pa; - va_curr = ul_dyn_ext_base * hio_mgr->word_size; - gpp_va_curr = ul_gpp_va; - num_bytes = ul_seg1_size; + sm_sg->seg1_pa = ul_gpp_pa; + sm_sg->seg1_da = ul_dyn_ext_base; + sm_sg->seg1_va = ul_gpp_va; + sm_sg->seg1_size = ul_seg1_size; + sm_sg->seg0_pa = ul_gpp_pa + ul_pad_size + ul_seg1_size; + sm_sg->seg0_da = ul_dsp_va; + sm_sg->seg0_va = ul_gpp_va + ul_pad_size + ul_seg1_size; + sm_sg->seg0_size = ul_seg_size; - va_curr = iommu_kmap(mmu, va_curr, pa_curr, num_bytes, - IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32); - if (IS_ERR_VALUE(va_curr)) { - status = (int)va_curr; - goto func_end; - } - - pa_curr += ul_pad_size + num_bytes; - va_curr += ul_pad_size + num_bytes; - gpp_va_curr += ul_pad_size + num_bytes; - - /* Configure the TLB entries for the next cacheable segment */ - num_bytes = ul_seg_size; - va_curr = ul_dsp_va * hio_mgr->word_size; - while (num_bytes) { - /* -* To find the max. page size with which both PA & VA are -* aligned. -*/ - all_bits = pa_curr | va_curr; - dev_dbg(bridge, "all_bits for Seg1 %x, pa_curr %x, " - "va_curr %x, num_bytes %x\n", all_bits, pa_curr, - va_curr, num_bytes); - for (i = 0; i < 4; i++) { - if (!(num_bytes >= page_size[i]) || -
[PATCH 0/9] dspbridge: iommu migration
This set of patches remove the dspbridge custom mmu implementation and use iommu module instead. NOTE: in order to dspbridge can work properly the patch "0001-iovmm-add-superpages-support-to-fixed-da-address.patch" is needed (specifically iommu_kmap calls need this patch). Fernando Guzman Lugo (9): dspbridge: replace iommu custom for opensource implementation dspbridge: move shared memory iommu maps to tiomap3430.c dspbridge: rename bridge_brd_mem_map/unmap to a proper name dspbridge: remove custom mmu code from tiomap3430.c dspbridge: add mmufault support dspbridge: remove hw directory dspbridge: move all iommu related code to a new file dspbridge: add map support for big buffers dspbridge: cleanup bridge_dev_context and cfg_hostres structures arch/arm/plat-omap/include/dspbridge/cfgdefs.h |1 - arch/arm/plat-omap/include/dspbridge/dsp-mmu.h | 90 ++ arch/arm/plat-omap/include/dspbridge/dspdefs.h | 44 - arch/arm/plat-omap/include/dspbridge/dspdeh.h |1 - arch/arm/plat-omap/include/dspbridge/dspioctl.h |7 - drivers/dsp/bridge/Makefile |5 +- drivers/dsp/bridge/core/_deh.h |3 - drivers/dsp/bridge/core/_tiomap.h | 15 +- drivers/dsp/bridge/core/dsp-mmu.c | 229 drivers/dsp/bridge/core/io_sm.c | 185 +--- drivers/dsp/bridge/core/mmu_fault.c | 139 --- drivers/dsp/bridge/core/mmu_fault.h | 36 - drivers/dsp/bridge/core/tiomap3430.c| 1297 --- drivers/dsp/bridge/core/tiomap3430_pwr.c| 183 +--- drivers/dsp/bridge/core/tiomap_io.c | 16 +- drivers/dsp/bridge/core/ue_deh.c| 87 +-- drivers/dsp/bridge/hw/EasiGlobal.h | 41 - drivers/dsp/bridge/hw/GlobalTypes.h | 308 -- drivers/dsp/bridge/hw/MMUAccInt.h | 76 -- drivers/dsp/bridge/hw/MMURegAcM.h | 226 drivers/dsp/bridge/hw/hw_defs.h | 60 -- drivers/dsp/bridge/hw/hw_mmu.c | 587 -- drivers/dsp/bridge/hw/hw_mmu.h | 161 --- drivers/dsp/bridge/pmgr/dev.c |2 - drivers/dsp/bridge/rmgr/drv.c |4 - drivers/dsp/bridge/rmgr/node.c |4 +- drivers/dsp/bridge/rmgr/proc.c | 19 +- 27 files changed, 599 insertions(+), 3227 deletions(-) create mode 100644 arch/arm/plat-omap/include/dspbridge/dsp-mmu.h create mode 100644 drivers/dsp/bridge/core/dsp-mmu.c delete mode 100644 drivers/dsp/bridge/core/mmu_fault.c delete mode 100644 drivers/dsp/bridge/core/mmu_fault.h delete mode 100644 drivers/dsp/bridge/hw/EasiGlobal.h delete mode 100644 drivers/dsp/bridge/hw/GlobalTypes.h delete mode 100644 drivers/dsp/bridge/hw/MMUAccInt.h delete mode 100644 drivers/dsp/bridge/hw/MMURegAcM.h delete mode 100644 drivers/dsp/bridge/hw/hw_defs.h delete mode 100644 drivers/dsp/bridge/hw/hw_mmu.c delete mode 100644 drivers/dsp/bridge/hw/hw_mmu.h -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/9] dspbridge: rename bridge_brd_mem_map/unmap to a proper name
Now these functions only map user space addresses to dsp virtual addresses, so now the functions have a more meaningful name Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/include/dspbridge/dspdefs.h | 44 drivers/dsp/bridge/core/_tiomap.h | 25 +++ drivers/dsp/bridge/core/tiomap3430.c | 52 ++-- drivers/dsp/bridge/pmgr/dev.c |2 - drivers/dsp/bridge/rmgr/proc.c | 12 +++-- 5 files changed, 53 insertions(+), 82 deletions(-) diff --git a/arch/arm/plat-omap/include/dspbridge/dspdefs.h b/arch/arm/plat-omap/include/dspbridge/dspdefs.h index 493f62e..4f56ae6 100644 --- a/arch/arm/plat-omap/include/dspbridge/dspdefs.h +++ b/arch/arm/plat-omap/include/dspbridge/dspdefs.h @@ -162,48 +162,6 @@ typedef int(*fxn_brd_memwrite) (struct bridge_dev_context u32 ulMemType); /* - * bridge_brd_mem_map - * Purpose: - * Map a MPU memory region to a DSP/IVA memory space - * Parameters: - * hDevContext:Handle to Bridge driver defined device info. - * ul_mpu_addr: MPU memory region start address. - * ulVirtAddr: DSP/IVA memory region u8 address. - * ul_num_bytes: Number of bytes to map. - * map_attrs: Mapping attributes (e.g. endianness). - * Returns: - * 0:Success. - * -EPERM: Other, unspecified error. - * Requires: - * hDevContext != NULL; - * Ensures: - */ -typedef int(*fxn_brd_memmap) (struct bridge_dev_context -* hDevContext, u32 ul_mpu_addr, -u32 ulVirtAddr, u32 ul_num_bytes, -u32 ulMapAttrs, -struct page **mapped_pages); - -/* - * bridge_brd_mem_un_map - * Purpose: - * UnMap an MPU memory region from DSP/IVA memory space - * Parameters: - * hDevContext:Handle to Bridge driver defined device info. - * ulVirtAddr: DSP/IVA memory region u8 address. - * ul_num_bytes: Number of bytes to unmap. - * Returns: - * 0:Success. - * -EPERM: Other, unspecified error. - * Requires: - * hDevContext != NULL; - * Ensures: - */ -typedef int(*fxn_brd_memunmap) (struct bridge_dev_context - * hDevContext, - u32 ulVirtAddr, u32 ul_num_bytes); - -/* * bridge_brd_stop * Purpose: * Bring board to the BRD_STOPPED state. @@ -1061,8 +1019,6 @@ struct bridge_drv_interface { fxn_brd_setstate pfn_brd_set_state; /* Sets the Board State */ fxn_brd_memcopy pfn_brd_mem_copy; /* Copies DSP Memory */ fxn_brd_memwrite pfn_brd_mem_write; /* Write DSP Memory w/o halt */ - fxn_brd_memmap pfn_brd_mem_map; /* Maps MPU mem to DSP mem */ - fxn_brd_memunmap pfn_brd_mem_un_map;/* Unmaps MPU mem to DSP mem */ fxn_chnl_create pfn_chnl_create;/* Create channel manager. */ fxn_chnl_destroy pfn_chnl_destroy; /* Destroy channel manager. */ fxn_chnl_open pfn_chnl_open;/* Create a new channel. */ diff --git a/drivers/dsp/bridge/core/_tiomap.h b/drivers/dsp/bridge/core/_tiomap.h index 6a822c6..4aa2358 100644 --- a/drivers/dsp/bridge/core/_tiomap.h +++ b/drivers/dsp/bridge/core/_tiomap.h @@ -396,4 +396,29 @@ static inline void dsp_iotlb_init(struct iotlb_entry *e, u32 da, u32 pa, e->mixed = 0; } +/** + * user_to_dsp_map() - maps user to dsp virtual address + * @mmu: Pointer to iommu handle. + * @uva: Virtual user space address. + * @da DSP address + * @size Buffer size to map. + * @usr_pgsstruct page array pointer where the user pages will be stored + * + * This function maps a user space buffer into DSP virtual address. + * + */ + +int user_to_dsp_map(struct iommu *mmu, u32 uva, u32 da, u32 size, + struct page **usr_pgs); + +/** + * user_to_dsp_unmap() - unmaps DSP virtual buffer. + * @mmu: Pointer to iommu handle. + * @da DSP address + * + * This function unmaps a user space buffer into DSP virtual address. + * + */ +int user_to_dsp_unmap(struct iommu *mmu, u32 da); + #endif /* _TIOMAP_ */ diff --git a/drivers/dsp/bridge/core/tiomap3430.c b/drivers/dsp/bridge/core/tiomap3430.c index 89d4936..88f5167 100644 --- a/drivers/dsp/bridge/core/tiomap3430.c +++ b/drivers/dsp/bridge/core/tiomap3430.c @@ -98,12 +98,6 @@ static int bridge_brd_mem_copy(struct bridge_dev_context *hDevContext, static int bridge_brd_mem_write(struct bridge_dev_context *dev_context, IN u8 *pbHostBuf, u32 dwDSPAddr, u32 ul_num_bytes, u32 ulMemType); -static int bridge_brd_mem_map(struct bridge_dev_context *hDevCont
[PATCH 7/9] dspbridge: move all iommu related code to a new file
This patch moves all the code related to iommu in the dsp-mmu.c file Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/include/dspbridge/dsp-mmu.h | 90 ++ arch/arm/plat-omap/include/dspbridge/dspdeh.h |1 - drivers/dsp/bridge/Makefile|2 +- drivers/dsp/bridge/core/_deh.h |3 - drivers/dsp/bridge/core/_tiomap.h | 41 +- drivers/dsp/bridge/core/dsp-mmu.c | 218 drivers/dsp/bridge/core/mmu_fault.c| 76 drivers/dsp/bridge/core/mmu_fault.h| 35 drivers/dsp/bridge/core/tiomap3430.c | 111 + drivers/dsp/bridge/core/ue_deh.c | 68 +--- drivers/dsp/bridge/rmgr/proc.c |6 +- 11 files changed, 318 insertions(+), 333 deletions(-) create mode 100644 arch/arm/plat-omap/include/dspbridge/dsp-mmu.h create mode 100644 drivers/dsp/bridge/core/dsp-mmu.c delete mode 100644 drivers/dsp/bridge/core/mmu_fault.c delete mode 100644 drivers/dsp/bridge/core/mmu_fault.h diff --git a/arch/arm/plat-omap/include/dspbridge/dsp-mmu.h b/arch/arm/plat-omap/include/dspbridge/dsp-mmu.h new file mode 100644 index 000..266f38b --- /dev/null +++ b/arch/arm/plat-omap/include/dspbridge/dsp-mmu.h @@ -0,0 +1,90 @@ +/* + * dsp-mmu.h + * + * DSP-BIOS Bridge driver support functions for TI OMAP processors. + * + * DSP iommu. + * + * Copyright (C) 2005-2010 Texas Instruments, Inc. + * + * This package is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef _DSP_MMU_ +#define _DSP_MMU_ + +#include +#include + +/** + * dsp_iotlb_init() - initialize dsp mmu entry + * @e: Pointer tbl entry. + * @da DSP address + * @pa:physical address. + * @pgsz page size to map. + * + * This function initializes a dsp mmu entry in order to be used with + * iommu functions. + */ +static inline void dsp_iotlb_init(struct iotlb_entry *e, u32 da, u32 pa, + u32 pgsz) +{ + e->da = da; + e->pa = pa; + e->valid = 1; + e->prsvd = 1; + e->pgsz = pgsz & MMU_CAM_PGSZ_MASK; + e->endian = MMU_RAM_ENDIAN_LITTLE; + e->elsz = MMU_RAM_ELSZ_32; + e->mixed = 0; +} + +/** + * dsp_mmu_init() - initialize dsp_mmu module and returns a handle + * + * This function initialize dsp mmu module and returns a struct iommu + * handle to use it for dsp maps. + * + */ +struct iommu *dsp_mmu_init(void); + +/** + * dsp_mmu_exit() - destroy dsp mmu module + * @mmu: Pointer to iommu handle. + * + * This function destroys dsp mmu module. + * + */ +void dsp_mmu_exit(struct iommu *mmu); + +/** + * user_to_dsp_map() - maps user to dsp virtual address + * @mmu: Pointer to iommu handle. + * @uva: Virtual user space address. + * @da DSP address + * @size Buffer size to map. + * @usr_pgsstruct page array pointer where the user pages will be stored + * + * This function maps a user space buffer into DSP virtual address. + * + */ +int user_to_dsp_map(struct iommu *mmu, u32 uva, u32 da, u32 size, + struct page **usr_pgs); + +/** + * user_to_dsp_unmap() - unmaps DSP virtual buffer. + * @mmu: Pointer to iommu handle. + * @da DSP address + * + * This function unmaps a user space buffer into DSP virtual address. + * + */ +int user_to_dsp_unmap(struct iommu *mmu, u32 da); + +#endif diff --git a/arch/arm/plat-omap/include/dspbridge/dspdeh.h b/arch/arm/plat-omap/include/dspbridge/dspdeh.h index 4394711..af19926 100644 --- a/arch/arm/plat-omap/include/dspbridge/dspdeh.h +++ b/arch/arm/plat-omap/include/dspbridge/dspdeh.h @@ -43,5 +43,4 @@ extern int bridge_deh_register_notify(struct deh_mgr *deh_mgr, extern void bridge_deh_notify(struct deh_mgr *deh_mgr, u32 ulEventMask, u32 dwErrInfo); -extern void bridge_deh_release_dummy_mem(void); #endif /* DSPDEH_ */ diff --git a/drivers/dsp/bridge/Makefile b/drivers/dsp/bridge/Makefile index 66ca10a..9f32055 100644 --- a/drivers/dsp/bridge/Makefile +++ b/drivers/dsp/bridge/Makefile @@ -5,7 +5,7 @@ libservices = services/sync.o services/cfg.o \ services/ntfy.o services/services.o libcore = core/chnl_sm.o core/msg_sm.o core/io_sm.o core/tiomap3430.o \ core/tiomap3430_pwr.o core/tiomap_io.o \ - core/mmu_fault.o core/ue_deh.o core/wdt.o core/dsp-clock.o + core/dsp-mmu.o core/ue_deh.o core/wdt.o core/dsp-clock.o libpmgr = pmgr/chnl.o pmgr
[PATCH 8/9] dspbridge: add map support for big buffers
due to a restriction in scatter gather lists, it can not be created a list for a buffer bigger than 1MB. This patch is spliting big mappings into 1MB mappings. Signed-off-by: Fernando Guzman Lugo --- arch/arm/plat-omap/include/dspbridge/dsp-mmu.h |2 +- drivers/dsp/bridge/core/dsp-mmu.c | 55 ++- drivers/dsp/bridge/rmgr/proc.c |3 +- 3 files changed, 36 insertions(+), 24 deletions(-) diff --git a/arch/arm/plat-omap/include/dspbridge/dsp-mmu.h b/arch/arm/plat-omap/include/dspbridge/dsp-mmu.h index 266f38b..2e4bf6a 100644 --- a/arch/arm/plat-omap/include/dspbridge/dsp-mmu.h +++ b/arch/arm/plat-omap/include/dspbridge/dsp-mmu.h @@ -85,6 +85,6 @@ int user_to_dsp_map(struct iommu *mmu, u32 uva, u32 da, u32 size, * This function unmaps a user space buffer into DSP virtual address. * */ -int user_to_dsp_unmap(struct iommu *mmu, u32 da); +int user_to_dsp_unmap(struct iommu *mmu, u32 da, unsigned size); #endif diff --git a/drivers/dsp/bridge/core/dsp-mmu.c b/drivers/dsp/bridge/core/dsp-mmu.c index e8da327..9a46206 100644 --- a/drivers/dsp/bridge/core/dsp-mmu.c +++ b/drivers/dsp/bridge/core/dsp-mmu.c @@ -133,7 +133,7 @@ int user_to_dsp_map(struct iommu *mmu, u32 uva, u32 da, u32 size, struct page **usr_pgs) { int res, w; - unsigned pages, i; + unsigned pages, i, j = 0; struct vm_area_struct *vma; struct mm_struct *mm = current->mm; struct sg_table *sgt; @@ -162,24 +162,31 @@ int user_to_dsp_map(struct iommu *mmu, u32 uva, u32 da, u32 size, if (res < 0) return res; - sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); + while (pages) { + sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); - if (!sgt) - return -ENOMEM; + if (!sgt) + return -ENOMEM; - res = sg_alloc_table(sgt, pages, GFP_KERNEL); + res = sg_alloc_table(sgt, + min((unsigned)SG_MAX_SINGLE_ALLOC, pages), GFP_KERNEL); + pages -= min((unsigned)SG_MAX_SINGLE_ALLOC, pages); - if (res < 0) - goto err_sg; + if (res < 0) + goto err_sg; + + for_each_sg(sgt->sgl, sg, sgt->nents, i) + sg_set_page(sg, usr_pgs[j++], PAGE_SIZE, 0); - for_each_sg(sgt->sgl, sg, sgt->nents, i) - sg_set_page(sg, usr_pgs[i], PAGE_SIZE, 0); + da = iommu_vmap(mmu, da, sgt, IOVMF_ENDIAN_LITTLE | + IOVMF_ELSZ_32); - da = iommu_vmap(mmu, da, sgt, IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32); + if (IS_ERR_VALUE(da)) { + res = (int)da; + goto err_map; + } - if (IS_ERR_VALUE(da)) { - res = (int)da; - goto err_map; + da += SG_MAX_SINGLE_ALLOC * PAGE_SIZE; } return 0; @@ -198,21 +205,25 @@ err_sg: * This function unmaps a user space buffer into DSP virtual address. * */ -int user_to_dsp_unmap(struct iommu *mmu, u32 da) +int user_to_dsp_unmap(struct iommu *mmu, u32 da, unsigned size) { unsigned i; struct sg_table *sgt; struct scatterlist *sg; + const unsigned max_sz = SG_MAX_SINGLE_ALLOC * PAGE_SIZE; - sgt = iommu_vunmap(mmu, da); - if (!sgt) - return -EFAULT; - - for_each_sg(sgt->sgl, sg, sgt->nents, i) - put_page(sg_page(sg)); + while (size) { + size -= min(max_sz, size); + sgt = iommu_vunmap(mmu, da); + if (!sgt) + return -EFAULT; - sg_free_table(sgt); - kfree(sgt); + for_each_sg(sgt->sgl, sg, sgt->nents, i) + put_page(sg_page(sg)); + sg_free_table(sgt); + kfree(sgt); + da += max_sz; + } return 0; } diff --git a/drivers/dsp/bridge/rmgr/proc.c b/drivers/dsp/bridge/rmgr/proc.c index 4f10a41..997918e 100644 --- a/drivers/dsp/bridge/rmgr/proc.c +++ b/drivers/dsp/bridge/rmgr/proc.c @@ -1713,7 +1713,8 @@ int proc_un_map(void *hprocessor, void *map_addr, /* Remove mapping from the page tables. */ if (DSP_SUCCEEDED(status)) { status = user_to_dsp_unmap( - p_proc_object->hbridge_context->dsp_mmu, va_align); + p_proc_object->hbridge_context->dsp_mmu, + va_align, size_align); } mutex_unlock(&proc_lock); -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html