Commit 19a5eed6 authored by Hiroshi DOYU's avatar Hiroshi DOYU Committed by Juha Yrjola

ARM: OMAP: DSPGW: Deferred dsp initializtion

DSP HW-related initialization is deferred until the first DSP device
node is opened. This allows us to keep DSP powered down before the
DSP SW is loaded.
Signed-off-by: default avatarHiroshi DOYU <Hiroshi.DOYU@nokia.com>
Signed-off-by: default avatarJuha Yrjola <juha.yrjola@solidboot.com>
parent 5b4ef329
...@@ -305,8 +305,6 @@ static int __init omap_dsp_init(void) ...@@ -305,8 +305,6 @@ static int __init omap_dsp_init(void)
return -ENODEV; return -ENODEV;
} }
dsp_clk_autoidle();
#if defined(CONFIG_ARCH_OMAP1) #if defined(CONFIG_ARCH_OMAP1)
dsp_ck_handle = clk_get(NULL, "dsp_ck"); dsp_ck_handle = clk_get(NULL, "dsp_ck");
if (IS_ERR(dsp_ck_handle)) { if (IS_ERR(dsp_ck_handle)) {
...@@ -347,12 +345,12 @@ static int __init omap_dsp_init(void) ...@@ -347,12 +345,12 @@ static int __init omap_dsp_init(void)
} }
#if defined(CONFIG_ARCH_OMAP1) #if defined(CONFIG_ARCH_OMAP1)
static int dsp_late_init(void) static int __dsp_late_init(void)
{ {
clk_disable(api_ck_handle); clk_disable(api_ck_handle);
return 0; return 0;
} }
late_initcall(dsp_late_init); late_initcall(__dsp_late_init);
#endif #endif
static void dsp_cpustat_update(void) static void dsp_cpustat_update(void)
......
...@@ -189,6 +189,7 @@ struct omap_dsp { ...@@ -189,6 +189,7 @@ struct omap_dsp {
struct omap_mbox *mbox; struct omap_mbox *mbox;
struct device *dev; struct device *dev;
struct list_head *kdev_list; struct list_head *kdev_list;
int initialized;
}; };
#if defined(CONFIG_ARCH_OMAP1) #if defined(CONFIG_ARCH_OMAP1)
...@@ -203,4 +204,6 @@ struct omap_dsp { ...@@ -203,4 +204,6 @@ struct omap_dsp {
extern struct omap_dsp *omap_dsp; extern struct omap_dsp *omap_dsp;
extern int dsp_late_init(void);
#endif /* DRIVER_DSP_COMMON_H */ #endif /* DRIVER_DSP_COMMON_H */
...@@ -45,6 +45,8 @@ static struct sync_seq *mbseq; ...@@ -45,6 +45,8 @@ static struct sync_seq *mbseq;
static u16 mbseq_expect_tmp; static u16 mbseq_expect_tmp;
static u16 *mbseq_expect = &mbseq_expect_tmp; static u16 *mbseq_expect = &mbseq_expect_tmp;
extern void dsp_mem_late_init(void);
/* /*
* mailbox commands * mailbox commands
*/ */
...@@ -511,6 +513,30 @@ static void mbox_kfunc(struct mbcmd *mb) ...@@ -511,6 +513,30 @@ static void mbox_kfunc(struct mbcmd *mb)
} }
} }
int dsp_late_init(void)
{
int ret;
dsp_clk_autoidle();
#ifdef CONFIG_ARCH_OMAP2
clk_enable(dsp_fck_handle);
clk_enable(dsp_ick_handle);
__dsp_per_enable();
#endif
dsp_mem_late_init();
#ifdef CONFIG_ARCH_OMAP1
dsp_set_idle_boot_base(IDLEPG_BASE, IDLEPG_SIZE);
#endif
ret = dsp_kfunc_enable_devices(omap_dsp,
DSP_KFUNC_DEV_TYPE_COMMON, 0);
if (ret == 0)
omap_dsp->enabled = 0;
return 0;
}
extern int dsp_ctl_core_init(void); extern int dsp_ctl_core_init(void);
extern void dsp_ctl_core_exit(void); extern void dsp_ctl_core_exit(void);
extern void dsp_ctl_init(void); extern void dsp_ctl_init(void);
...@@ -557,12 +583,6 @@ static int __init dsp_drv_probe(struct platform_device *pdev) ...@@ -557,12 +583,6 @@ static int __init dsp_drv_probe(struct platform_device *pdev)
goto fail1; goto fail1;
} }
#ifdef CONFIG_ARCH_OMAP2
clk_enable(dsp_fck_handle);
clk_enable(dsp_ick_handle);
__dsp_per_enable();
#endif
if ((ret = dsp_ctl_core_init()) < 0) if ((ret = dsp_ctl_core_init()) < 0)
goto fail2; goto fail2;
if ((ret = dsp_mem_init()) < 0) if ((ret = dsp_mem_init()) < 0)
...@@ -585,11 +605,6 @@ static int __init dsp_drv_probe(struct platform_device *pdev) ...@@ -585,11 +605,6 @@ static int __init dsp_drv_probe(struct platform_device *pdev)
fail3: fail3:
dsp_ctl_core_exit(); dsp_ctl_core_exit();
fail2: fail2:
#ifdef CONFIG_ARCH_OMAP2
__dsp_per_disable();
clk_disable(dsp_ick_handle);
clk_disable(dsp_fck_handle);
#endif
fail1: fail1:
dsp_kfunc_remove_devices(info); dsp_kfunc_remove_devices(info);
fail0: fail0:
......
...@@ -40,6 +40,20 @@ extern struct file_operations dsp_ctl_fops, ...@@ -40,6 +40,20 @@ extern struct file_operations dsp_ctl_fops,
static int dsp_ctl_core_open(struct inode *inode, struct file *file) static int dsp_ctl_core_open(struct inode *inode, struct file *file)
{ {
static DEFINE_MUTEX(open_lock);
int ret = 0;
mutex_lock_interruptible(&open_lock);
if (omap_dsp->initialized == 0) {
ret = dsp_late_init();
if (ret != 0) {
mutex_unlock(&open_lock);
return ret;
}
omap_dsp->initialized = 1;
}
mutex_unlock(&open_lock);
switch (iminor(inode)) { switch (iminor(inode)) {
case CTL_MINOR: case CTL_MINOR:
file->f_op = &dsp_ctl_fops; file->f_op = &dsp_ctl_fops;
......
...@@ -2453,24 +2453,32 @@ void dsp_mem_stop(void) ...@@ -2453,24 +2453,32 @@ void dsp_mem_stop(void)
#endif #endif
} }
static char devid_mmu; /*
* later half of dsp memory initialization
int __init dsp_mem_init(void) */
void dsp_mem_late_init(void)
{ {
int i;
int ret = 0;
#ifdef CONFIG_ARCH_OMAP2 #ifdef CONFIG_ARCH_OMAP2
int i;
int dspmem_pg_count; int dspmem_pg_count;
dspmem_pg_count = dspmem_size >> 12; dspmem_pg_count = dspmem_size >> 12;
for (i = 0; i < dspmem_pg_count; i++) { for (i = 0; i < dspmem_pg_count; i++) {
dsp_ipi_write_reg(i, DSP_IPI_INDEX); dsp_ipi_write_reg(i, DSP_IPI_INDEX);
dsp_ipi_write_reg(DSP_IPI_ENTRY_ELMSIZEVALUE_16, DSP_IPI_ENTRY); dsp_ipi_write_reg(DSP_IPI_ENTRY_ELMSIZEVALUE_16,
DSP_IPI_ENTRY);
} }
dsp_ipi_write_reg(1, DSP_IPI_ENABLE); dsp_ipi_write_reg(1, DSP_IPI_ENABLE);
dsp_ipi_write_reg(IOMAP_VAL, DSP_IPI_IOMAP); dsp_ipi_write_reg(IOMAP_VAL, DSP_IPI_IOMAP);
#endif #endif
dsp_mmu_init();
}
static char devid_mmu;
int __init dsp_mem_init(void)
{
int i, ret;
for (i = 0; i < DSP_MMU_TLB_LINES; i++) for (i = 0; i < DSP_MMU_TLB_LINES; i++)
exmap_tbl[i].valid = 0; exmap_tbl[i].valid = 0;
...@@ -2482,10 +2490,6 @@ int __init dsp_mem_init(void) ...@@ -2482,10 +2490,6 @@ int __init dsp_mem_init(void)
"for dsp vector table\n"); "for dsp vector table\n");
return -ENOMEM; return -ENOMEM;
} }
dsp_mmu_init();
#ifdef CONFIG_ARCH_OMAP1
dsp_set_idle_boot_base(IDLEPG_BASE, IDLEPG_SIZE);
#endif
/* /*
* DSP MMU interrupt setup * DSP MMU interrupt setup
...@@ -2495,7 +2499,7 @@ int __init dsp_mem_init(void) ...@@ -2495,7 +2499,7 @@ int __init dsp_mem_init(void)
if (ret) { if (ret) {
printk(KERN_ERR printk(KERN_ERR
"failed to register DSP MMU interrupt: %d\n", ret); "failed to register DSP MMU interrupt: %d\n", ret);
goto fail; return ret;
} }
/* MMU interrupt is not enabled until DSP runs */ /* MMU interrupt is not enabled until DSP runs */
...@@ -2506,15 +2510,6 @@ int __init dsp_mem_init(void) ...@@ -2506,15 +2510,6 @@ int __init dsp_mem_init(void)
device_create_file(omap_dsp->dev, &dev_attr_mempool); device_create_file(omap_dsp->dev, &dev_attr_mempool);
return 0; return 0;
fail:
#ifdef CONFIG_ARCH_OMAP1
dsp_reset_idle_boot_base();
#endif
dsp_mmu_shutdown();
free_page((unsigned long)dspvect_page);
dspvect_page = NULL;
return ret;
} }
void dsp_mem_exit(void) void dsp_mem_exit(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment