aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornhcao <nhcao@marvell.com>2012-08-21 20:43:51 +0800
committerLubomir Rintel <lkundrak@v3.sk>2019-07-22 19:39:58 +0200
commitcc8c8aabf008867eebbb671563b5e8d90a01c239 (patch)
treec707cb693fcc2774a410d9e721ac45f4b547c173
parent284fc1d7f952f508977c4f198f3c36a2eaa354b8 (diff)
downloadlinux-mmp3-dell-ariel-cc8c8aabf008867eebbb671563b5e8d90a01c239.tar.gz
audio: zsp: add IPC for frequency change
1. Add IPC for frequency change done signal. 2. Refine zsp registers names 3. add handling for frequency change, and add a test case for it. Change-Id: I6e9c852b3c5eb25894f614087ba1a1acd65c8458 Signed-off-by: Henry Zhao <xzhao10@marvell.com> Signed-off-by: nhcao <nhcao@marvell.com>
-rw-r--r--arch/arm/mach-mmp/include/mach/mmp-zsp.h2
-rw-r--r--arch/arm/mach-mmp/include/mach/regs-zsp.h36
-rw-r--r--arch/arm/mach-mmp/mmp3.c76
-rw-r--r--drivers/char/mmp_zmq.c10
-rw-r--r--drivers/char/mmp_zsp.c126
5 files changed, 198 insertions, 52 deletions
diff --git a/arch/arm/mach-mmp/include/mach/mmp-zsp.h b/arch/arm/mach-mmp/include/mach/mmp-zsp.h
index 44b64bdb9b003f..a40b8d50e840c5 100644
--- a/arch/arm/mach-mmp/include/mach/mmp-zsp.h
+++ b/arch/arm/mach-mmp/include/mach/mmp-zsp.h
@@ -90,6 +90,7 @@ enum ipc_client_id{
IPC_TEST_ID = 0x5,
IPC_IPM_ID = 0x6,
IPC_SOFT_RESET_ID = 0x7,
+ IPC_FREQ_DONE_ID = 0x8,
IPC_MAX_NUM,
};
@@ -111,6 +112,7 @@ struct mmp_zsp_platform_device *zsp_get_devop(void);
int zsp_mmap_datawnd(struct vm_area_struct *vma);
int zsp_set_clock_preference(u32 opmask, struct mmp_zsp_clkcfg * pcfg);
+int zsp_freq_test(int dumponly);
#ifdef __cplusplus
}
#endif
diff --git a/arch/arm/mach-mmp/include/mach/regs-zsp.h b/arch/arm/mach-mmp/include/mach/regs-zsp.h
index 2781e1f1448225..59f00f1ab88a50 100644
--- a/arch/arm/mach-mmp/include/mach/regs-zsp.h
+++ b/arch/arm/mach-mmp/include/mach/regs-zsp.h
@@ -48,8 +48,8 @@
* THE BIT DEFINES
*/
/* zsp boot vector */
-#define ZSP_CONFIG_SVTADDR_ZSP_SVTADDR_MSK (0xffffff << 8)
-#define ZSP_CONFIG_SVTADDR_ZSP_SVTADDR_BASE 8
+#define ZSP_AUD_CTRL_REG_2_ZSP_SVTADDR_MSK (0xffffff << 8)
+#define ZSP_AUD_CTRL_REG_2_ZSP_SVTADDR_BASE 8
/* ZSP halt */
#define ZSP_CONFIG_DBG_Z_HALT (1 << 4)
/* ZSP external breakpoint */
@@ -125,17 +125,27 @@
/*ZSP INT_STATUS1 0x0210 ZSP INT_STATUS1 */
/*Bit(s) ZSPINT_STATUS1_RSRV_31_13 reserved */
#elif defined(CONFIG_CPU_MMP3)
-#define ZSP_AUD_CONFIG_REG ZSP_REG(0x0000)
-#define ZSP_TIM_13M_CLK_RES ZSP_REG(0x003C)
-#define ZSP_CORE_FREQ_CHG ZSP_REG(0x0018)
-#define ZSP_CORE_CLK_RES ZSP_REG(0x0028)
-#define ZSP_CTRL_REG ZSP_REG(0x0054)
-#define ZSP_CONFIG_SVTADDR ZSP_REG(0x0058)
-#define ZSP_APB_CLK_RES ZSP_REG(0x002C)
-#define ZSP_SSP_CLK_RES ZSP_REG(0x0030)
-#define ZSP_SLIM_CLK_RES ZSP_REG(0x0044)
-#define ZSP_SLIM_CLK_RES_2 ZSP_REG(0x0050)
-#define ZSP_AUX_CORE_INT_STATUS ZSP_REG(0x0008)
+#define ZSP_AUD_CONFIG ZSP_REG(0x0000)
+#define ZSP_AUX_CORE_PRID ZSP_REG(0x0004)
+#define ZSP_AUX_CORE_INT_ST ZSP_REG(0x0008)
+#define ZSP_AUD_CORE_IPC ZSP_REG(0x000C)
+#define ZSP_APPS_CORE_IPC ZSP_REG(0x0010)
+#define ZSP_AUD_INT_MSK ZSP_REG(0x0014)
+#define ZSP_AUD_CORE_FREQ_CHG ZSP_REG(0x0018)
+#define ZSP_AUD_D1D0_WAKEUP_MSK ZSP_REG(0x001C)
+#define ZSP_AUD_D1D0G_WAKEUP_MSK ZSP_REG(0x0020)
+#define ZSP_AUD_D0CG2D1_ENTRY_MSK ZSP_REG(0x0024)
+#define ZSP_AUD_DSA_CORE_CLK_RES ZSP_REG(0x0028)
+#define ZSP_AUD_DSA_APB_CLK_RES ZSP_REG(0x002C)
+#define ZSP_AUD_SSP_CLK_RES ZSP_REG(0x0030)
+#define ZSP_AUD_TIM_13M_CLK_RES ZSP_REG(0x003C)
+#define ZSP_AUD_TIM_32K_CLK_RES ZSP_REG(0x0040)
+#define ZSP_AUD_SLIM_CLK_RES ZSP_REG(0x0044)
+#define ZSP_XCORE_ADDR_TRANS ZSP_REG(0x0048)
+#define ZSP_XCORE_ADDR_TRANS_CTRL ZSP_REG(0x004C)
+#define ZSP_AUD_SLIM_CLK_RES_2 ZSP_REG(0x0050)
+#define ZSP_AUD_CTRL_REG ZSP_REG(0x0054)
+#define ZSP_AUD_CTRL_REG_2 ZSP_REG(0x0058)
#define ZSP_DTCM_START 0xC6080000
#define ZSP_DATA_OFFSET 0x00000000
diff --git a/arch/arm/mach-mmp/mmp3.c b/arch/arm/mach-mmp/mmp3.c
index 7956c471d9989a..49e9d8bb53d009 100644
--- a/arch/arm/mach-mmp/mmp3.c
+++ b/arch/arm/mach-mmp/mmp3.c
@@ -1097,7 +1097,7 @@ static void mmp_zsp_domain_on(int spd, int src, int asclk)
__raw_writel(value, APMU_ISLD_DSPA_CTRL);
udelay(10);
/* enable dummy clocks for SRAMs */
- value = readl(APMU_ISLD_DSPA_CTRL);
+ value = __raw_readl(APMU_ISLD_DSPA_CTRL);
value |= (0x1 << 4);
__raw_writel(value, APMU_ISLD_DSPA_CTRL);
udelay(300);
@@ -1153,41 +1153,43 @@ static void mmp_zsp_domain_on(int spd, int src, int asclk)
}
aud_pwr_status.aud_pll_cnt++;
+ __raw_modify(ZSP_AUD_DSA_CORE_CLK_RES, 0x0, 0x4);
+ udelay(100);
+ /* switch to audio PLL, divide 1*/
+ __raw_modify(ZSP_AUD_DSA_CORE_CLK_RES, 0x0, 0x30);
+ __raw_modify(ZSP_AUD_CORE_FREQ_CHG, 0xE, 0x0);
+ /* enable divider*/
+ __raw_modify(ZSP_AUD_DSA_CORE_CLK_RES, 0x0, 0x8);
+ /* enabled core clock and release reset*/
+ __raw_modify(ZSP_AUD_DSA_CORE_CLK_RES, 0x4, 0x0);
+ udelay(10);
+ __raw_modify(ZSP_AUD_CORE_FREQ_CHG, 0x0, 0x1);
+ udelay(10);
+ do {
+ value = readl(ZSP_AUD_CORE_FREQ_CHG);
+ udelay(10);
+ } while ((value & 0x1) != 0);
+ __raw_modify(ZSP_AUD_DSA_CORE_CLK_RES, 0x0, 0x3);
+
/* timer clock, src Audio PLL, div 12 */
- __raw_modify(ZSP_TIM_13M_CLK_RES, 0x0, 0x64);
+ __raw_modify(ZSP_AUD_TIM_13M_CLK_RES, 0x0, 0x64);
udelay(10);
/* enable and release reset*/
- __raw_modify(ZSP_TIM_13M_CLK_RES, 0x0, 0x3);
+ __raw_modify(ZSP_AUD_TIM_13M_CLK_RES, 0x0, 0x3);
/* set SSPA to fast audio PLL with M/N divider */
- __raw_modify(ZSP_SSP_CLK_RES, 0x0, 0x30000);
- __raw_modify(ZSP_SLIM_CLK_RES, 0xFFFFFFFF, 0x00100100);
- __raw_modify(ZSP_SLIM_CLK_RES_2, 0x3FFFFFFF, 0xC0010002);
- __raw_modify(ZSP_SLIM_CLK_RES, 0x0, 0xE);
+ __raw_modify(ZSP_AUD_SSP_CLK_RES, 0x0, 0x30000);
+ __raw_modify(ZSP_AUD_SLIM_CLK_RES, 0xFFFFFFFF, 0x00100100);
+ __raw_modify(ZSP_AUD_SLIM_CLK_RES_2, 0x3FFFFFFF, 0xC0010002);
+ __raw_modify(ZSP_AUD_SLIM_CLK_RES, 0x0, 0xE);
/* config ZSP core peripherals */
- __raw_modify(ZSP_CTRL_REG, 0xFFFFFFF, 0x141B05);
+ __raw_modify(ZSP_AUD_CTRL_REG, 0xFFFFFFF, 0x141B05);
udelay(100);
- __raw_modify(ZSP_CTRL_REG, 0x0, 0x18);
+ __raw_modify(ZSP_AUD_CTRL_REG, 0x0, 0x18);
udelay(10);
aud_pwr_status.zsp_cnt++;
- __raw_modify(ZSP_CORE_CLK_RES, 0x3, 0x4);
- udelay(100);
- /* switch to audio PLL, divide 1*/
- __raw_modify(ZSP_CORE_CLK_RES, 0x0, 0x30);
- __raw_modify(ZSP_CORE_FREQ_CHG, 0xE, 0x0);
- /* enable divider*/
- __raw_modify(ZSP_CORE_CLK_RES, 0x0, 0x8);
- /* enabled core clock and release reset*/
- __raw_modify(ZSP_CORE_CLK_RES, 0x4, 0x3);
- udelay(10);
- __raw_modify(ZSP_CORE_FREQ_CHG, 0x0, 0x1);
- udelay(10);
- do {
- value = readl(ZSP_CORE_FREQ_CHG);
- udelay(10);
- } while ((value & 0x1) != 0);
return;
}
@@ -1198,21 +1200,21 @@ static void mmp_zsp_domain_halt(void)
aud_pwr_status.zsp_cnt--;
if (aud_pwr_status.zsp_cnt == 0) {
/* reset audio peripheral */
- __raw_modify(ZSP_CORE_CLK_RES, 0x3, 0x4);
+ __raw_modify(ZSP_AUD_DSA_CORE_CLK_RES, 0x0, 0x4);
udelay(100);
/* switch to pll1*/
- __raw_modify(ZSP_CORE_CLK_RES, 0x30, 0x0);
+ __raw_modify(ZSP_AUD_DSA_CORE_CLK_RES, 0x30, 0x0);
/* set divider 2*/
- __raw_modify(ZSP_CORE_FREQ_CHG, 0xE, 0x4);
+ __raw_modify(ZSP_AUD_CORE_FREQ_CHG, 0xE, 0x4);
/* enable divider*/
- __raw_modify(ZSP_CORE_CLK_RES, 0x0, 0x8);
+ __raw_modify(ZSP_AUD_DSA_CORE_CLK_RES, 0x0, 0x8);
/* enabled core clock and release reset*/
- __raw_modify(ZSP_CORE_CLK_RES, 0x4, 0x3);
+ __raw_modify(ZSP_AUD_DSA_CORE_CLK_RES, 0x4, 0x0);
udelay(10);
- __raw_modify(ZSP_CORE_FREQ_CHG, 0x0, 0x1);
+ __raw_modify(ZSP_AUD_CORE_FREQ_CHG, 0x0, 0x1);
udelay(10);
do {
- value = readl(ZSP_CORE_FREQ_CHG);
+ value = readl(ZSP_AUD_CORE_FREQ_CHG);
udelay(10);
} while ((value & 0x1) != 0);
}
@@ -1258,18 +1260,18 @@ static void mmp_zsp_start_core(void)
{
int value;
- writel(0x0000, ZSP_CONFIG_SVTADDR);
+ writel(0x0000, ZSP_AUD_CTRL_REG_2);
udelay(5);
- value = readl(ZSP_CTRL_REG);
+ value = readl(ZSP_AUD_CTRL_REG);
value &= ~0x2;
- writel(value, ZSP_CTRL_REG);
+ writel(value, ZSP_AUD_CTRL_REG);
udelay(100);
/* release reset */
- value = readl(ZSP_CTRL_REG);
+ value = readl(ZSP_AUD_CTRL_REG);
value |= 0x2;
- writel(value, ZSP_CTRL_REG);
+ writel(value, ZSP_AUD_CTRL_REG);
udelay(10);
}
diff --git a/drivers/char/mmp_zmq.c b/drivers/char/mmp_zmq.c
index d6bfb0ae5e4d14..91c265900063e4 100644
--- a/drivers/char/mmp_zmq.c
+++ b/drivers/char/mmp_zmq.c
@@ -2972,7 +2972,17 @@ static void zmq_diagnose_clk(u32 flags)
}
static void zmq_diagnoze(zmq_instance_t * pins, char op)
{
+ int cnt;
+ int ret;
+ u32 value;
switch (op) {
+ case 'q':
+ ret = 0;
+ for (cnt = 0; cnt < 100; cnt++) {
+ ret = zsp_freq_test(ret);
+ udelay(200);
+ }
+ break;
case 'a':
zmq_diagnose_session_control(pins);
break;
diff --git a/drivers/char/mmp_zsp.c b/drivers/char/mmp_zsp.c
index 8fd754241a0a40..a37425f791082b 100644
--- a/drivers/char/mmp_zsp.c
+++ b/drivers/char/mmp_zsp.c
@@ -51,7 +51,6 @@
#define IPC_ICR 0x000C
#define IPC_IIR 0x0010
-
#define pzipc_readl(pszp, off) \
__raw_readl(pzsp->_ipc_regs_base + (off))
#define pzipc_writel(pzsp, off, v) \
@@ -95,6 +94,7 @@ typedef struct {
struct mutex _floadlock;
volatile bool _ready;
volatile bool _zspup;
+ volatile bool _zspfreqdone;
zsp_ipc_cft_t _ipcmap[IPC_MAX_NUM];
void *pbuffer;
void *pbuffer_aligned;
@@ -105,7 +105,8 @@ typedef struct {
static zsp_device_t gs_zsp = {
NULL, NULL, false, NULL, NULL, NULL,
- 0, 0, 0, 0, NULL, 0, 0, 0, NULL, 0, 0, -1, {0}, {{1},}, false, false,
+ 0, 0, 0, 0, NULL, 0, 0, 0, NULL, 0, 0, -1, {0},
+ {{1},}, false, false, false,
{
/*client id */ /* interrupt bit*/ /* handler */
{IPC_HANDSHAKE_ID, IPC_INTERRUPT_BIT_0_0, NULL},
@@ -115,6 +116,8 @@ static zsp_device_t gs_zsp = {
{IPC_PORT_FLOWCONTROL_ID, IPC_INTERRUPT_BIT_0_4, NULL},
{IPC_TEST_ID, IPC_INTERRUPT_BIT_0_5, NULL},
{IPC_IPM_ID, IPC_INTERRUPT_BIT_2_9, NULL},
+ {IPC_SOFT_RESET_ID, IPC_INTERRUPT_BIT_3_10, NULL},
+ {IPC_FREQ_DONE_ID, IPC_INTERRUPT_BIT_0_6, NULL},
/* TBD */
},
NULL, NULL, 0, 0, false
@@ -185,6 +188,14 @@ static irqreturn_t zsp_ap_handshake_isr(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static irqreturn_t zsp_freq_done_isr(int irq, void *dev_id)
+{
+ zsp_device_t * pzsp = (zsp_device_t *)dev_id;
+
+ pzsp->_zspfreqdone = true;
+
+ return IRQ_HANDLED;
+}
static irqreturn_t zsp_dmem_req_isr(int irq, void *dev_id)
{
zsp_device_t * pzsp;
@@ -383,6 +394,12 @@ static int zsp_doreset(struct platform_device *pdev, int timeout_ms) {
return -EINVAL;
}
+ ret = pzipc_add_isr(IPC_FREQ_DONE_ID, zsp_freq_done_isr);
+ if (PZIPC_RC_OK != ret) {
+ printk(KERN_ERR "%s: cannot register freq_done\n", __func__);
+ return -EINVAL;
+ }
+
pzsp->_zspup = false;
zsp_start_core(pzsp);
@@ -808,6 +825,111 @@ static void __exit zsp_exit(void)
}
+#define __raw_modify(addr, toclear, toset) \
+ do { \
+ volatile unsigned int tval; \
+ tval = __raw_readl(addr); \
+ tval &= ~toclear; \
+ tval |= toset; \
+ __raw_writel(tval, (addr)); \
+ tval = __raw_readl(addr); \
+ udelay(100); \
+ } while (0)
+
+void dump_aux_regs(void)
+{
+ u32 value;
+
+ value = readl(ZSP_AUD_CONFIG);
+ printk(KERN_ERR "ZSP_AUD_CONFIG: 0x%08X\n", value);
+
+ value = readl(ZSP_AUX_CORE_PRID);
+ printk(KERN_ERR "ZSP_AUX_CORE_PRID: 0x%08X\n", value);
+
+ value = readl(ZSP_AUX_CORE_INT_ST);
+ printk(KERN_ERR "ZSP_AUX_CORE_INT_ST: 0x%08X\n", value);
+
+ value = readl(ZSP_AUD_CORE_IPC);
+ printk(KERN_ERR "ZSP_AUD_CORE_IPC: 0x%08X\n", value);
+
+ value = readl(ZSP_APPS_CORE_IPC);
+ printk(KERN_ERR "ZSP_APPS_CORE_IPC: 0x%08X\n", value);
+
+ value = readl(ZSP_AUD_INT_MSK);
+ printk(KERN_ERR "ZSP_AUD_INT_MSK: 0x%08X\n", value);
+
+ value = readl(ZSP_AUD_CORE_FREQ_CHG);
+ printk(KERN_ERR "ZSP_AUD_CORE_FREQ_CHG: 0x%08X\n", value);
+
+ value = readl(ZSP_AUD_D1D0_WAKEUP_MSK);
+ printk(KERN_ERR "ZSP_AUD_D1D0_WAKEUP_MSK: 0x%08X\n", value);
+
+ value = readl(ZSP_AUD_D1D0G_WAKEUP_MSK);
+ printk(KERN_ERR "ZSP_AUD_D1D0G_WAKEUP_MSK: 0x%08X\n", value);
+
+ value = readl(ZSP_AUD_D0CG2D1_ENTRY_MSK);
+ printk(KERN_ERR "ZSP_AUD_D0CG2D1_ENTRY_MSK: 0x%08X\n", value);
+
+ value = readl(ZSP_AUD_DSA_CORE_CLK_RES);
+ printk(KERN_ERR "ZSP_AUD_DSA_CORE_CLK_RES: 0x%08X\n", value);
+
+ value = readl(ZSP_AUD_DSA_APB_CLK_RES);
+ printk(KERN_ERR "ZSP_AUD_DSA_APB_CLK_RES: 0x%08X\n", value);
+
+ value = readl(ZSP_AUD_SSP_CLK_RES);
+ printk(KERN_ERR "ZSP_AUD_SSP_CLK_RES: 0x%08X\n", value);
+
+ value = readl(ZSP_AUD_TIM_13M_CLK_RES);
+ printk(KERN_ERR "ZSP_AUD_TIM_13M_CLK_RES: 0x%08X\n", value);
+
+ value = readl(ZSP_AUD_TIM_32K_CLK_RES);
+ printk(KERN_ERR "ZSP_AUD_TIM_32K_CLK_RES: 0x%08X\n", value);
+
+ value = readl(ZSP_AUD_SLIM_CLK_RES);
+ printk(KERN_ERR "ZSP_AUD_SLIM_CLK_RES: 0x%08X\n", value);
+
+ value = readl(ZSP_XCORE_ADDR_TRANS);
+ printk(KERN_ERR "ZSP_XCORE_ADDR_TRANS: 0x%08X\n", value);
+
+ value = readl(ZSP_XCORE_ADDR_TRANS_CTRL);
+ printk(KERN_ERR "ZSP_XCORE_ADDR_TRANS_CTRL: 0x%08X\n", value);
+
+ value = readl(ZSP_AUD_SLIM_CLK_RES_2);
+ printk(KERN_ERR "ZSP_AUD_SLIM_CLK_RES_2: 0x%08X\n", value);
+
+ value = readl(ZSP_AUD_CTRL_REG);
+ printk(KERN_ERR "ZSP_AUD_CTRL_REG: 0x%08X\n", value);
+
+ value = readl(ZSP_AUD_CTRL_REG_2);
+ printk(KERN_ERR "ZSP_AUD_CTRL_REG_2: 0x%08X\n\n", value);
+
+ return;
+}
+
+int zsp_freq_test(int dumponly)
+{
+ u32 value, loop;
+ zsp_device_t *pzsp = &gs_zsp;
+
+ pzipc_set_interrupt(IPC_TEST_ID);
+
+ loop = 1000;
+ while (loop > 0) {
+ if (pzsp->_zspfreqdone) {
+ pzsp->_zspfreqdone = false;
+ value = __raw_readl(ZSP_AUD_DSA_CORE_CLK_RES);
+ break;
+ }
+ loop--;
+ udelay(100);
+ }
+ if (loop == 0)
+ return 1;
+
+ return 0;
+}
+EXPORT_SYMBOL(zsp_freq_test);
+
module_init(zsp_init);
module_exit(zsp_exit);