#endif
#define USE_PLL_REG 0 //ÊÇ·ñÖ±½Ó¿ØÖÆPLL¼Ä´æÆ÷
-
-#define CLOSE_CLK_GATE 1 //ÊÍ·ÅDSPʱÊÇ·ñÁ¬clock gateÒ»Æð¹Øµô
-
-#define CONFIG_CHIP_RK2818
+#define ENTER_SLOW 0 //ÊÇ·ñ²»Ê¹ÓÃDSPµÄʱºòÁ¢¼´½øÈëSLOW MODE(DSP PLL BYPASS)
+#define FIXED_REQ 560 //ʹÓù̶¨ÆµÂÊÖµ, 0Ϊ½ûÓÃ
+#define CLOSE_CLK_GATE 0 //ÊÍ·ÅDSPʱÊÇ·ñÁ¬clock gateÒ»Æð¹Øµô
struct rk28dsp_inf {
struct miscdevice miscdev;
void *pmu_base;
void *l1_dbase;
void *l2_idbase;
+ void *scu_base;
+ void *regfile_base;
int irq0;
int irq1;
static int rcv_quit = 0;
-static int video_type = 0;//h264:1 ,rv40:2 , other: 0.
void dsp_powerctl(int ctl, int arg);
+
//need reset reg value when finishing the video play
static void resetRegValueForVideo()
{
#ifdef CONFIG_CHIP_RK2818
- void * r1 = (void *)ioremap(APB_SCU_BASE, 0x60);
- void * r3 = (void *)ioremap(APB_REG_FILE_BASE, 0x60);
-
struct rk28dsp_inf *inf = g_inf;
if(!inf) return;
//disable the AXI bus
//__raw_writel((__raw_readl(r3+0x14) & (~0x20002000)) , r3+0x14);
if(video_type)
{
- dsp_powerctl(DPC_SLEEP, 0);
- inf->dsp_status = DS_SLEEP;
-
-
- __raw_writel((__raw_readl(r1+0x20) | (1<<25)) , r1+0x20);
+ __raw_writel((__raw_readl(inf->scu_base+0x20) | (1<<25)) , inf->scu_base+0x20);
if(video_type == 2)
{
//mdelay(10);
- __raw_writel((__raw_readl(r1+0x1c) | (0x400)) , r1+0x1c);
- printk("close rv40 hardware advice\n");
+ __raw_writel((__raw_readl(inf->scu_base+0x1c) | (0x400)) , inf->scu_base+0x1c);
+ dspprintk("close rv40 hardware advice\n");
}
else
{
- __raw_writel((__raw_readl(r1+0x20) | (1<<20)) , r1+0x20);
- printk("close h264 hardware advice\n");
+ __raw_writel((__raw_readl(inf->scu_base+0x20) | (1<<20)) , inf->scu_base+0x20);
+ dspprintk("close h264 hardware advice\n");
}
video_type = 0;
}
-
- //mdelay(1);
- iounmap((void __iomem *)(r1));
- iounmap((void __iomem *)(r3));
#endif
- return;
+ return;
}
//add by Charles Chen for test 281x play RMVB
static void setRegValueForVideo(unsigned long type)
µÈ´ýһЩʱ¼äÔÙÓëÉÏ ¡«0x00000110
0x18019018 »òÉÏ 0x00200000
*/
- void * r1 = (void *)ioremap(APB_SCU_BASE, 0x60);
- //void * r2 = (void *)ioremap(APB_SCU_BASE, 0x28);
- void * r3 = (void *)ioremap(APB_REG_FILE_BASE, 0x60);
+ struct rk28dsp_inf *inf = g_inf;
+ if(!inf) return;
video_type = 1;
//axi bus
- __raw_writel((__raw_readl(r1+0x20) | (0x08000000)) , r1+0x20);
+ __raw_writel((__raw_readl(inf->scu_base+0x20) | (0x08000000)) , inf->scu_base+0x20);
//mc dma
- __raw_writel((__raw_readl(r1+0x20) & ~(1<<25)) , r1+0x20);
+ __raw_writel((__raw_readl(inf->scu_base+0x20) & ~(1<<25)) , inf->scu_base+0x20);
//printk("------->0x18018020 value 0x%08x\n",__raw_readl(r1+0x20));
if(!type)
{
video_type ++;
//rv deblocking clock
- __raw_writel((__raw_readl(r1+0x1c) & (~0x400)) , r1+0x1c);
+ __raw_writel((__raw_readl(inf->scu_base+0x1c) & (~0x400)) , inf->scu_base+0x1c);
mdelay(1);
- __raw_writel((__raw_readl(r1+0x28) | (0x00000100)) , r1+0x28);
+ __raw_writel((__raw_readl(inf->scu_base+0x28) | (0x00000100)) , inf->scu_base+0x28);
mdelay(5);
- __raw_writel((__raw_readl(r1+0x28) & (~0x00000100)) , r1+0x28);
+ __raw_writel((__raw_readl(inf->scu_base+0x28) & (~0x00000100)) , inf->scu_base+0x28);
//rv deblocking bridge select
- __raw_writel((__raw_readl(r3+0x14) | (0x20002000)) , r3+0x14);
+ __raw_writel((__raw_readl(inf->regfile_base+0x14) | (0x20002000)) , inf->regfile_base+0x14);
- printk("%s this is rm 9 video\n",__func__);
+ dspprintk("%s this is rm 9 video\n",__func__);
}
else
{
//h264 hardware
- __raw_writel((__raw_readl(r1+0x20) & ~(1<<20)) , r1+0x20);
- printk("%s this is h264 video\n",__func__);
+ __raw_writel((__raw_readl(inf->scu_base+0x20) & ~(1<<20)) , inf->scu_base+0x20);
+ dspprintk("%s this is h264 video\n",__func__);
}
- iounmap((void __iomem *)(r1));
- iounmap((void __iomem *)(r3));
-
#endif
return;
}
unsigned int freqreg = 0;
int cnt = 0;
- if(24==clkrate || 0==clkrate) {
+ if(0==clkrate) {
/* pll set 300M */
freqreg = ( __raw_readl(SCU_BASE_ADDR_VA+0x04)&(~0x003FFFFE) ) | 0x00030310;
__raw_writel(freqreg, SCU_BASE_ADDR_VA+0x04);
return;
}
+ if(clkrate) {
+ clkrate = FIXED_REQ ? FIXED_REQ : clkrate;
+ }
+
/* dsp pll enable */
__raw_writel((__raw_readl(SCU_BASE_ADDR_VA+0x04) & (~(0x01u<<22))) , SCU_BASE_ADDR_VA+0x04);
udelay(300); //0.3ms
}
#else
struct rk28dsp_inf *inf = g_inf;
+ if(clkrate) {
+ clkrate = FIXED_REQ ? FIXED_REQ : clkrate;
+ }
if(inf) {
if(inf->clk) clk_set_rate(inf->clk, clkrate*1000000);
}
{
case DPC_NORMAL:
{
+#if 0 //def CONFIG_CHIP_RK2818 //coreµçѹ²»ÎÈʱ,dspÉϵç»áµ¼ÖÂAHBȡָ´íÎó,ËùÒÔdspÉϵçºóµ½Îȶ¨ÆÚ¼ä²»²Ù×÷AHB
+ unsigned long flags;
+ local_irq_save(flags);
+ /* dsp subsys power on 0x21*/
+ ddr_pll_delay(6000); //¿ªÖ®Ç°Ò²µÃ¼Ó,±ÜÃâ×ÜÏß»¹ÔÚ·ÃÎÊ
+ __raw_writel((__raw_readl(SCU_BASE_ADDR_VA+0x10) & (~0x21)) , SCU_BASE_ADDR_VA+0x10);
+ ddr_pll_delay(6000); //¹ØÖжÏʱ¼ä²»ÄÜÌ«³¤ (6000´ó¸ÅΪ1us)
+ local_irq_restore(flags);
+ mdelay(10);
+#else
/* dsp subsys power on 0x21*/
__raw_writel((__raw_readl(SCU_BASE_ADDR_VA+0x10) & (~0x21)) , SCU_BASE_ADDR_VA+0x10);
mdelay(15);
-
+#endif
/* dsp clock enable 0x12*/
DSP_CLOCK_ENABLE();
/* dsp set clk */
dsp_set_clk(arg);
+ mdelay(5);
/* dsp peripheral urst */
__raw_writel((__raw_readl(SCU_BASE_ADDR_VA+0x28) & (~0x02000020)) , SCU_BASE_ADDR_VA+0x28);
/* set CXCLK, XHCLK, XPCLK */
__raw_writel(0, inf->pmu_base+0x08); //CXCLK_DIV (clki:ceva)
- __raw_writel(1, inf->pmu_base+0x0c); //XHCLK_DIV (ceva:hclk)
+ __raw_writel(2, inf->pmu_base+0x0c); //XHCLK_DIV (ceva:hclk)
__raw_writel(1, inf->pmu_base+0x10); //XPCLK_DIV (hclk:pclk)
}
break;
+
case DPC_SLEEP:
{
/* dsp work mode :slow mode*/
DSP_CLOCK_DISABLE();
/* dsp pll close */
- dsp_set_clk(24);
+ dsp_set_clk(0);
/* dsp subsys power off 0x21*/
__raw_writel((__raw_readl(SCU_BASE_ADDR_VA+0x10) | (0x21)) , SCU_BASE_ADDR_VA+0x10);
+
+ /* close rv/h264 hardware advice after dsp has closed */
+ udelay(10);
+ resetRegValueForVideo();
}
break;
default:
inf->dsp_status = DS_NORMAL;
dspprintk("down firmware (%s) ... \n", fwname);
- {
- if(0==strcmp(fwname,"rk28_rv40.rkl"))
+ {
+ if(0==strcmp(fwname,"rk28_rv40.rkl"))
{
setRegValueForVideo(0);
}
{
setRegValueForVideo(1);
}
- }
+ }
{
const struct firmware *fw;
char *buf,*code_buf;
dsp_powerctl(DPC_NORMAL, inf->cur_freq);
/* down dsp boot */
- dspprintk("\nrequest_firmware ... \n");
+ dspprintk("request_firmware ... \n");
ret = request_firmware(&fw, "DspBoot.rkl", &inf->dev);
if (ret) {
printk(KERN_ERR "Failed to load boot image \"DspBoot.rkl\" err %d\n",ret);
DSP_BOOT_CTRL();
mdelay(10);
+#if ENTER_SLOW
/* dsp work mode :slow mode*/
__raw_writel((__raw_readl(SCU_BASE_ADDR_VA+0x0c) & (~0x03)) , SCU_BASE_ADDR_VA+0x0c);
mdelay(1);
+#endif
/* dsp core urst*/
__raw_writel((__raw_readl(SCU_BASE_ADDR_VA+0x28) & (~0x00000010)) , SCU_BASE_ADDR_VA+0x28);
+ mdelay(1);
/* change dsp & arm to normal mode */
__raw_writel(0x5, SCU_BASE_ADDR_VA+0x0c);
down(&sem);
if(inf->cur_pid!=current->tgid || inf->cur_file!=file) {
dspprintk("res is obtain by pid %d(cur_file=0x%08x), refuse this req(pid=%d file=0x%08x cmd=0x%08x) \n",
- inf->cur_pid, inf->cur_file, current->tgid, file, cmd);
+ inf->cur_pid, (u32)inf->cur_file, current->tgid, (u32)file, cmd);
up(&sem);
return -EBUSY;
}
}
if(0==ret) {
+ del_timer(&inf->dsp_timer);
_down_firmware(req.fwname, inf);
queue_flush(inf->rcvmsg_q);
rcv_quit = 0;
wake_up(&wq);
} else {
if(strcmp(inf->req1fwname, "")) {
- _down_firmware(inf->req1fwname, inf);
+ //_down_firmware(inf->req1fwname, inf);
}
}
- if(inf->cur_req == 2)
- resetRegValueForVideo();//when finishing the video ,must reset some reg value;
inf->cur_req = 0;
inf->cur_pid = 0;
inf->cur_file = NULL;
+#if ENTER_SLOW
/* dsp work mode :slow mode*/
__raw_writel((__raw_readl(SCU_BASE_ADDR_VA+0x0c) & (~0x03)) , SCU_BASE_ADDR_VA+0x0c);
+#endif
#if CLOSE_CLK_GATE
/* dsp clock disable */
/* sram dsp clock disable */
__raw_writel((__raw_readl(SCU_BASE_ADDR_VA+0x1c) | (0x10)) , SCU_BASE_ADDR_VA+0x1c);
#endif
+
if(DS_SLEEP!=inf->dsp_status) {
- inf->dsp_status = DS_TOSLEEP;
- mod_timer(&inf->dsp_timer, jiffies + 5*HZ);
+ mod_timer(&inf->dsp_timer, jiffies + 5*HZ);
+ inf->dsp_status = DS_TOSLEEP;
}
}
wake_up(&wq2);
up(&sem);
+ dspprintk("\n");
break;
case DSP_IOCTL_SEND_MSG:
inf->pmu_base = (void*)ioremap(PMU_BASE_ADDR, 0x3000);
inf->l1_dbase = (void*)ioremap(DSP_BASE_ADDR, 0x10000);
inf->l2_idbase = (void*)ioremap(DSP_L2_IMEM_BASE, 0x400000);
+ inf->scu_base = (void *)ioremap(APB_SCU_BASE, 0x60);
+ inf->regfile_base = (void *)ioremap(APB_REG_FILE_BASE, 0x60);
inf->irq0 = pdev->resource[1].start;
inf->irq1 = pdev->resource[2].start;
iounmap((void __iomem *)(inf->pmu_base));
iounmap((void __iomem *)(inf->l1_dbase));
iounmap((void __iomem *)(inf->l2_idbase));
+ iounmap((void __iomem *)(inf->scu_base));
+ iounmap((void __iomem *)(inf->regfile_base));
if(inf->clk) {
DSP_CLOCK_DISABLE();
return -EINVAL;
}
- if(DS_NORMAL==inf->dsp_status) return -EPERM;
+ if(DS_NORMAL==inf->dsp_status) return -EPERM; //DSPÕýÔÚʹÓÃÖÐ
if(DS_SLEEP != inf->dsp_status ) {
inf->dsp_status = DS_SLEEP;
dsp_powerctl(DPC_SLEEP, 0);
dspprintk("dsp : normal -> sleep \n");
}
+
return 0;
}