From c12abc012e18b362204345c323536f228d65c4db Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Fri, 7 Aug 2009 09:59:47 +0300 Subject: ARM: OMAP: McBSP: Fix ASoC on OMAP1510 by fixing API of omap_mcbsp_start/stop Simultaneous audio playback and capture on OMAP1510 can cause that second stream is stalled if there is enough delay between startup of the audio streams. Current implementation of the omap_mcbsp_start is starting both transmitter and receiver at the same time and it is called only for firstly started audio stream from the OMAP McBSP based ASoC DAI driver. Since DMA request lines on OMAP1510 are edge sensitive, the DMA request is missed if there is no DMA transfer set up at that time when the first word after McBSP startup is transmitted. The problem hasn't noted before since later OMAPs are using level sensitive DMA request lines. Fix the problem by changing API of omap_mcbsp_start and omap_mcbsp_stop by allowing to start and stop individually McBSP transmitter and receiver logics. Then call those functions individually for both audio playback and capture streams. This ensures that DMA transfer is setup before transmitter or receiver is started. Thanks to Janusz Krzysztofik for detailed problem analysis and Peter Ujfalusi for info about DMA request line behavior differences between the OMAP generations. Reported-and-tested-by: Janusz Krzysztofik Signed-off-by: Jarkko Nikula Acked-by: Tony Lindgren Acked-by: Peter Ujfalusi Signed-off-by: Mark Brown --- arch/arm/plat-omap/include/mach/mcbsp.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/arm/plat-omap/include/mach') diff --git a/arch/arm/plat-omap/include/mach/mcbsp.h b/arch/arm/plat-omap/include/mach/mcbsp.h index bb154ea7676..57249bb1e9b 100644 --- a/arch/arm/plat-omap/include/mach/mcbsp.h +++ b/arch/arm/plat-omap/include/mach/mcbsp.h @@ -387,8 +387,8 @@ void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config); int omap_mcbsp_request(unsigned int id); void omap_mcbsp_free(unsigned int id); -void omap_mcbsp_start(unsigned int id); -void omap_mcbsp_stop(unsigned int id); +void omap_mcbsp_start(unsigned int id, int tx, int rx); +void omap_mcbsp_stop(unsigned int id, int tx, int rx); void omap_mcbsp_xmit_word(unsigned int id, u32 word); u32 omap_mcbsp_recv_word(unsigned int id); -- cgit v1.2.3 From 9abea08e43c6cfc18399e42cbc6028d111532f61 Mon Sep 17 00:00:00 2001 From: Eero Nurkkala Date: Thu, 20 Aug 2009 16:18:07 +0300 Subject: OMAP: McBSP: Provide functions for ASoC frame syncronization ASoC has an annoying bug letting either L or R channel to be played on L channel. In other words, L and R channels can switch at random. This provides McBSP funtionality that may be used to fix this feature. Signed-off-by: Eero Nurkkala Acked-by: Tony Lindgren Signed-off-by: Mark Brown --- arch/arm/plat-omap/include/mach/mcbsp.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/arm/plat-omap/include/mach') diff --git a/arch/arm/plat-omap/include/mach/mcbsp.h b/arch/arm/plat-omap/include/mach/mcbsp.h index 57249bb1e9b..b85e6e600ed 100644 --- a/arch/arm/plat-omap/include/mach/mcbsp.h +++ b/arch/arm/plat-omap/include/mach/mcbsp.h @@ -389,6 +389,8 @@ int omap_mcbsp_request(unsigned int id); void omap_mcbsp_free(unsigned int id); void omap_mcbsp_start(unsigned int id, int tx, int rx); void omap_mcbsp_stop(unsigned int id, int tx, int rx); +void omap_mcbsp_xmit_enable(unsigned int id, u8 enable); +void omap_mcbsp_recv_enable(unsigned int id, u8 enable); void omap_mcbsp_xmit_word(unsigned int id, u32 word); u32 omap_mcbsp_recv_word(unsigned int id); -- cgit v1.2.3 From 946a49a95dabc9dd10344ae9ab4db9f14c5ad502 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Thu, 20 Aug 2009 16:18:08 +0300 Subject: OMAP: McBSP: Add IRQEN, IRQSTATUS, THRESHOLD2 and THRESHOLD1 registers. Adding McBSP register definition for IRQEN, IRQSTATUS, THRESHOLD2 and THRESHOLD1 registers. Signed-off-by: Eduardo Valentin Acked-by: Tony Lindgren Signed-off-by: Mark Brown --- arch/arm/plat-omap/include/mach/mcbsp.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/arm/plat-omap/include/mach') diff --git a/arch/arm/plat-omap/include/mach/mcbsp.h b/arch/arm/plat-omap/include/mach/mcbsp.h index b85e6e600ed..ceaf9eee61b 100644 --- a/arch/arm/plat-omap/include/mach/mcbsp.h +++ b/arch/arm/plat-omap/include/mach/mcbsp.h @@ -134,6 +134,10 @@ #define OMAP_MCBSP_REG_XCERG 0x74 #define OMAP_MCBSP_REG_XCERH 0x78 #define OMAP_MCBSP_REG_SYSCON 0x8C +#define OMAP_MCBSP_REG_THRSH2 0x90 +#define OMAP_MCBSP_REG_THRSH1 0x94 +#define OMAP_MCBSP_REG_IRQST 0xA0 +#define OMAP_MCBSP_REG_IRQEN 0xA4 #define OMAP_MCBSP_REG_XCCR 0xAC #define OMAP_MCBSP_REG_RCCR 0xB0 -- cgit v1.2.3 From 7aa9ff56cae7a6a4fa2e1a503cc5f8bbd887d6e3 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Thu, 20 Aug 2009 16:18:10 +0300 Subject: OMAP: McBSP: Add transmit/receive threshold handler This patch adds a way to handle transmit/receive threshold. It export to mcbsp users a callback registration procedure. Signed-off-by: Eduardo Valentin Acked-by: Tony Lindgren Signed-off-by: Mark Brown --- arch/arm/plat-omap/include/mach/mcbsp.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch/arm/plat-omap/include/mach') diff --git a/arch/arm/plat-omap/include/mach/mcbsp.h b/arch/arm/plat-omap/include/mach/mcbsp.h index ceaf9eee61b..2544aa5bccd 100644 --- a/arch/arm/plat-omap/include/mach/mcbsp.h +++ b/arch/arm/plat-omap/include/mach/mcbsp.h @@ -389,6 +389,15 @@ int omap_mcbsp_init(void); void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, int size); void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config); +#ifdef CONFIG_ARCH_OMAP34XX +void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold); +void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold); +#else +static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold) +{ } +static inline void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold) +{ } +#endif int omap_mcbsp_request(unsigned int id); void omap_mcbsp_free(unsigned int id); void omap_mcbsp_start(unsigned int id, int tx, int rx); -- cgit v1.2.3 From a1a56f5faa41327116bf960a8e79f21a8ea35dce Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Thu, 20 Aug 2009 16:18:11 +0300 Subject: OMAP: McBSP: Create and export max_(r|t)x_thres property This patch export through sysfs two properties to configure maximum threshold for transmission and reception on each mcbsp instance. Also, it exports two helper functions to allow mcbsp users to read this values. Signed-off-by: Eduardo Valentin Acked-by: Tony Lindgren Signed-off-by: Mark Brown --- arch/arm/plat-omap/include/mach/mcbsp.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'arch/arm/plat-omap/include/mach') diff --git a/arch/arm/plat-omap/include/mach/mcbsp.h b/arch/arm/plat-omap/include/mach/mcbsp.h index 2544aa5bccd..832330d7cb3 100644 --- a/arch/arm/plat-omap/include/mach/mcbsp.h +++ b/arch/arm/plat-omap/include/mach/mcbsp.h @@ -348,6 +348,9 @@ struct omap_mcbsp_platform_data { u8 dma_rx_sync, dma_tx_sync; u16 rx_irq, tx_irq; struct omap_mcbsp_ops *ops; +#ifdef CONFIG_ARCH_OMAP34XX + u16 buffer_size; +#endif }; struct omap_mcbsp { @@ -381,6 +384,10 @@ struct omap_mcbsp { struct omap_mcbsp_platform_data *pdata; struct clk *iclk; struct clk *fclk; +#ifdef CONFIG_ARCH_OMAP34XX + u16 max_tx_thres; + u16 max_rx_thres; +#endif }; extern struct omap_mcbsp **mcbsp_ptr; extern int omap_mcbsp_count; @@ -392,11 +399,15 @@ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config #ifdef CONFIG_ARCH_OMAP34XX void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold); void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold); +u16 omap_mcbsp_get_max_tx_threshold(unsigned int id); +u16 omap_mcbsp_get_max_rx_threshold(unsigned int id); #else static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold) { } static inline void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold) { } +static inline u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) { return 0; } +static inline u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) { return 0; } #endif int omap_mcbsp_request(unsigned int id); void omap_mcbsp_free(unsigned int id); -- cgit v1.2.3 From 98cb20e88957faf9c99e194242caac7f55dd47e4 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 20 Aug 2009 16:18:14 +0300 Subject: OMAP: McBSP: Add link DMA mode selection It adds a new sysfs file, where the user can configure the mcbsp mode to use. If the mcbsp channel is in use, it does not allow the change. Than in omap_pcm_open we can call the omap_mcbsp_get_opmode to get the mode, store it, than use it to implement the different modes. Signed-off-by: Peter Ujfalusi Signed-off-by: Eduardo Valentin Acked-by: Tony Lindgren Signed-off-by: Mark Brown --- arch/arm/plat-omap/include/mach/mcbsp.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch/arm/plat-omap/include/mach') diff --git a/arch/arm/plat-omap/include/mach/mcbsp.h b/arch/arm/plat-omap/include/mach/mcbsp.h index 832330d7cb3..bd5b759991c 100644 --- a/arch/arm/plat-omap/include/mach/mcbsp.h +++ b/arch/arm/plat-omap/include/mach/mcbsp.h @@ -255,6 +255,11 @@ /********************** McBSP SYSCONFIG bit definitions ********************/ #define SOFTRST 0x0002 +/********************** McBSP DMA operating modes **************************/ +#define MCBSP_DMA_MODE_ELEMENT 0 +#define MCBSP_DMA_MODE_THRESHOLD 1 +#define MCBSP_DMA_MODE_FRAME 2 + /* we don't do multichannel for now */ struct omap_mcbsp_reg_cfg { u16 spcr2; @@ -385,6 +390,7 @@ struct omap_mcbsp { struct clk *iclk; struct clk *fclk; #ifdef CONFIG_ARCH_OMAP34XX + int dma_op_mode; u16 max_tx_thres; u16 max_rx_thres; #endif @@ -401,6 +407,7 @@ void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold); void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold); u16 omap_mcbsp_get_max_tx_threshold(unsigned int id); u16 omap_mcbsp_get_max_rx_threshold(unsigned int id); +int omap_mcbsp_get_dma_op_mode(unsigned int id); #else static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold) { } @@ -408,6 +415,7 @@ static inline void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold) { } static inline u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) { return 0; } static inline u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) { return 0; } +static inline int omap_mcbsp_get_dma_op_mode(unsigned int id) { return 0; } #endif int omap_mcbsp_request(unsigned int id); void omap_mcbsp_free(unsigned int id); -- cgit v1.2.3 From 2122fdc629f05634537e796c0630028e4db76953 Mon Sep 17 00:00:00 2001 From: Eero Nurkkala Date: Thu, 20 Aug 2009 16:18:15 +0300 Subject: OMAP: McBSP: Wakeups utilized This patch enables the smart idle mode while McBPS is being utilized. Once it's done, force idle mode is taken instead. Apart of it, it also configures what signals will wake mcbsp up. Signed-off-by: Eero Nurkkala Signed-off-by: Eduardo Valentin Acked-by: Tony Lindgren Signed-off-by: Mark Brown --- arch/arm/plat-omap/include/mach/mcbsp.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'arch/arm/plat-omap/include/mach') diff --git a/arch/arm/plat-omap/include/mach/mcbsp.h b/arch/arm/plat-omap/include/mach/mcbsp.h index bd5b759991c..333061d4f4a 100644 --- a/arch/arm/plat-omap/include/mach/mcbsp.h +++ b/arch/arm/plat-omap/include/mach/mcbsp.h @@ -138,6 +138,7 @@ #define OMAP_MCBSP_REG_THRSH1 0x94 #define OMAP_MCBSP_REG_IRQST 0xA0 #define OMAP_MCBSP_REG_IRQEN 0xA4 +#define OMAP_MCBSP_REG_WAKEUPEN 0xA8 #define OMAP_MCBSP_REG_XCCR 0xAC #define OMAP_MCBSP_REG_RCCR 0xB0 @@ -253,6 +254,8 @@ #define RDISABLE 0x0001 /********************** McBSP SYSCONFIG bit definitions ********************/ +#define SIDLEMODE(value) ((value)<<3) +#define ENAWAKEUP 0x0004 #define SOFTRST 0x0002 /********************** McBSP DMA operating modes **************************/ @@ -260,6 +263,20 @@ #define MCBSP_DMA_MODE_THRESHOLD 1 #define MCBSP_DMA_MODE_FRAME 2 +/********************** McBSP WAKEUPEN bit definitions *********************/ +#define XEMPTYEOFEN 0x4000 +#define XRDYEN 0x0400 +#define XEOFEN 0x0200 +#define XFSXEN 0x0100 +#define XSYNCERREN 0x0080 +#define RRDYEN 0x0008 +#define REOFEN 0x0004 +#define RFSREN 0x0002 +#define RSYNCERREN 0x0001 +#define WAKEUPEN_ALL (XEMPTYEOFEN | XRDYEN | XEOFEN | XFSXEN | \ + XSYNCERREN | RRDYEN | REOFEN | RFSREN | \ + RSYNCERREN) + /* we don't do multichannel for now */ struct omap_mcbsp_reg_cfg { u16 spcr2; -- cgit v1.2.3 From d9a9b3f5f7d4736cfe6fae95b9d63b07faeb702e Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Thu, 20 Aug 2009 16:18:16 +0300 Subject: OMAP: McBSP: Change wakeup signals Configure only XRDYEN and RRDYEN wakeup signals in order to get better power consumption. Signed-off-by: Eduardo Valentin Acked-by: Tony Lindgren Signed-off-by: Mark Brown --- arch/arm/plat-omap/include/mach/mcbsp.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch/arm/plat-omap/include/mach') diff --git a/arch/arm/plat-omap/include/mach/mcbsp.h b/arch/arm/plat-omap/include/mach/mcbsp.h index 333061d4f4a..fe10ae8b027 100644 --- a/arch/arm/plat-omap/include/mach/mcbsp.h +++ b/arch/arm/plat-omap/include/mach/mcbsp.h @@ -273,9 +273,6 @@ #define REOFEN 0x0004 #define RFSREN 0x0002 #define RSYNCERREN 0x0001 -#define WAKEUPEN_ALL (XEMPTYEOFEN | XRDYEN | XEOFEN | XFSXEN | \ - XSYNCERREN | RRDYEN | REOFEN | RFSREN | \ - RSYNCERREN) /* we don't do multichannel for now */ struct omap_mcbsp_reg_cfg { -- cgit v1.2.3 From 2ba93f8fa77c0140de163e8a31bb9c09b5ded74c Mon Sep 17 00:00:00 2001 From: Eero Nurkkala Date: Thu, 20 Aug 2009 16:18:17 +0300 Subject: OMAP: McBSP: Retain McBSP FCLK clockactivity FCLK may get autogated so that it prevents the McBSP to work properly. It is the bit 9 that must be set for maintaining the McBSP FCLK. Signed-off-by: Eero Nurkkala Signed-off-by: Eduardo Valentin Acked-by: Jarkko Nikula Acked-by: Tony Lindgren Signed-off-by: Mark Brown --- arch/arm/plat-omap/include/mach/mcbsp.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/arm/plat-omap/include/mach') diff --git a/arch/arm/plat-omap/include/mach/mcbsp.h b/arch/arm/plat-omap/include/mach/mcbsp.h index fe10ae8b027..70e950e295e 100644 --- a/arch/arm/plat-omap/include/mach/mcbsp.h +++ b/arch/arm/plat-omap/include/mach/mcbsp.h @@ -254,6 +254,7 @@ #define RDISABLE 0x0001 /********************** McBSP SYSCONFIG bit definitions ********************/ +#define CLOCKACTIVITY(value) ((value)<<8) #define SIDLEMODE(value) ((value)<<3) #define ENAWAKEUP 0x0004 #define SOFTRST 0x0002 -- cgit v1.2.3 From d09a2afc9359407114b7062519101f1ee2d05388 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Sun, 23 Aug 2009 12:24:27 +0300 Subject: ARM: OMAP: McBSP: Merge two functions into omap_mcbsp_start/_stop Functionality of functions omap_mcbsp_xmit_enable and omap_mcbsp_recv_enable can be merged into omap_mcbsp_start and omap_mcbsp_stop since API of those omap_mcbsp_start and omap_mcbsp_stop was changed recently allowing to start and stop individually the transmitter and receiver. This cleans up the code in arch/arm/plat-omap/mcbsp.c and in sound/soc/omap/omap-mcbsp.c which was the only user for those removed functions. Signed-off-by: Jarkko Nikula Acked-by: Eero Nurkkala Cc: Peter Ujfalusi Signed-off-by: Mark Brown --- arch/arm/plat-omap/include/mach/mcbsp.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch/arm/plat-omap/include/mach') diff --git a/arch/arm/plat-omap/include/mach/mcbsp.h b/arch/arm/plat-omap/include/mach/mcbsp.h index 70e950e295e..63a3f254af7 100644 --- a/arch/arm/plat-omap/include/mach/mcbsp.h +++ b/arch/arm/plat-omap/include/mach/mcbsp.h @@ -436,8 +436,6 @@ int omap_mcbsp_request(unsigned int id); void omap_mcbsp_free(unsigned int id); void omap_mcbsp_start(unsigned int id, int tx, int rx); void omap_mcbsp_stop(unsigned int id, int tx, int rx); -void omap_mcbsp_xmit_enable(unsigned int id, u8 enable); -void omap_mcbsp_recv_enable(unsigned int id, u8 enable); void omap_mcbsp_xmit_word(unsigned int id, u32 word); u32 omap_mcbsp_recv_word(unsigned int id); -- cgit v1.2.3