From: Hiroshi DOYU Date: Mon, 25 Sep 2006 20:04:31 +0000 (+0300) Subject: ARM: OMAP: DSPGW: Deferred dsp initializtion X-Git-Tag: v2.6.18-omap1~40^2~3 X-Git-Url: http://www.pilppa.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=19a5eed60dab25b49c86575356004e618d7f78c8;p=linux-2.6-omap-h63xx.git 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: Hiroshi DOYU Signed-off-by: Juha Yrjola --- diff --git a/arch/arm/plat-omap/dsp/dsp_common.c b/arch/arm/plat-omap/dsp/dsp_common.c index 70e58122fa9..873509b7103 100644 --- a/arch/arm/plat-omap/dsp/dsp_common.c +++ b/arch/arm/plat-omap/dsp/dsp_common.c @@ -305,8 +305,6 @@ static int __init omap_dsp_init(void) return -ENODEV; } - dsp_clk_autoidle(); - #if defined(CONFIG_ARCH_OMAP1) dsp_ck_handle = clk_get(NULL, "dsp_ck"); if (IS_ERR(dsp_ck_handle)) { @@ -347,12 +345,12 @@ static int __init omap_dsp_init(void) } #if defined(CONFIG_ARCH_OMAP1) -static int dsp_late_init(void) +static int __dsp_late_init(void) { clk_disable(api_ck_handle); return 0; } -late_initcall(dsp_late_init); +late_initcall(__dsp_late_init); #endif static void dsp_cpustat_update(void) diff --git a/arch/arm/plat-omap/dsp/dsp_common.h b/arch/arm/plat-omap/dsp/dsp_common.h index dc846628f7d..872d838f420 100644 --- a/arch/arm/plat-omap/dsp/dsp_common.h +++ b/arch/arm/plat-omap/dsp/dsp_common.h @@ -189,6 +189,7 @@ struct omap_dsp { struct omap_mbox *mbox; struct device *dev; struct list_head *kdev_list; + int initialized; }; #if defined(CONFIG_ARCH_OMAP1) @@ -203,4 +204,6 @@ struct omap_dsp { extern struct omap_dsp *omap_dsp; +extern int dsp_late_init(void); + #endif /* DRIVER_DSP_COMMON_H */ diff --git a/arch/arm/plat-omap/dsp/dsp_core.c b/arch/arm/plat-omap/dsp/dsp_core.c index 66b28529f4d..ab3b921689c 100644 --- a/arch/arm/plat-omap/dsp/dsp_core.c +++ b/arch/arm/plat-omap/dsp/dsp_core.c @@ -45,6 +45,8 @@ static struct sync_seq *mbseq; static u16 mbseq_expect_tmp; static u16 *mbseq_expect = &mbseq_expect_tmp; +extern void dsp_mem_late_init(void); + /* * mailbox commands */ @@ -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 void dsp_ctl_core_exit(void); extern void dsp_ctl_init(void); @@ -557,12 +583,6 @@ static int __init dsp_drv_probe(struct platform_device *pdev) 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) goto fail2; if ((ret = dsp_mem_init()) < 0) @@ -585,11 +605,6 @@ static int __init dsp_drv_probe(struct platform_device *pdev) fail3: dsp_ctl_core_exit(); fail2: -#ifdef CONFIG_ARCH_OMAP2 - __dsp_per_disable(); - clk_disable(dsp_ick_handle); - clk_disable(dsp_fck_handle); -#endif fail1: dsp_kfunc_remove_devices(info); fail0: diff --git a/arch/arm/plat-omap/dsp/dsp_ctl_core.c b/arch/arm/plat-omap/dsp/dsp_ctl_core.c index bfb6f8b20b0..04420df0476 100644 --- a/arch/arm/plat-omap/dsp/dsp_ctl_core.c +++ b/arch/arm/plat-omap/dsp/dsp_ctl_core.c @@ -40,6 +40,20 @@ extern struct file_operations dsp_ctl_fops, 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)) { case CTL_MINOR: file->f_op = &dsp_ctl_fops; diff --git a/arch/arm/plat-omap/dsp/dsp_mem.c b/arch/arm/plat-omap/dsp/dsp_mem.c index 48b7a7935d2..7c9a728a017 100644 --- a/arch/arm/plat-omap/dsp/dsp_mem.c +++ b/arch/arm/plat-omap/dsp/dsp_mem.c @@ -2453,24 +2453,32 @@ void dsp_mem_stop(void) #endif } -static char devid_mmu; - -int __init dsp_mem_init(void) +/* + * later half of dsp memory initialization + */ +void dsp_mem_late_init(void) { - int i; - int ret = 0; #ifdef CONFIG_ARCH_OMAP2 + int i; int dspmem_pg_count; dspmem_pg_count = dspmem_size >> 12; for (i = 0; i < dspmem_pg_count; i++) { 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(IOMAP_VAL, DSP_IPI_IOMAP); #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++) exmap_tbl[i].valid = 0; @@ -2482,10 +2490,6 @@ int __init dsp_mem_init(void) "for dsp vector table\n"); return -ENOMEM; } - dsp_mmu_init(); -#ifdef CONFIG_ARCH_OMAP1 - dsp_set_idle_boot_base(IDLEPG_BASE, IDLEPG_SIZE); -#endif /* * DSP MMU interrupt setup @@ -2495,7 +2499,7 @@ int __init dsp_mem_init(void) if (ret) { printk(KERN_ERR "failed to register DSP MMU interrupt: %d\n", ret); - goto fail; + return ret; } /* MMU interrupt is not enabled until DSP runs */ @@ -2506,15 +2510,6 @@ int __init dsp_mem_init(void) device_create_file(omap_dsp->dev, &dev_attr_mempool); 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)