int ddp_mutex_hw_dcm_off(int mutex_idx,void * handle)
{
    if(gMutexFreeRun==1 && primary_display_is_video_mode()==0 && mutex_idx==0)
    {
        DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_HW_DCM,0);
    }
    DDPDBG("mutex %d hw_dcm 0x%x \n", mutex_idx, DISP_REG_GET(DISP_REG_CONFIG_MUTEX_HW_DCM));
    return 0;
}
static int ddp_mutex_set_l(int mutex_id, int* module_list, DDP_MODE ddp_mode, void * handle)
{
    int i=0;
    kal_uint32 value = 0;
    int module_num = ddp_get_module_num_l(module_list);
    MUTEX_SOF mode = ddp_get_mutex_sof(module_list[module_num-1],ddp_mode);
    if(mutex_id < DISP_MUTEX_DDP_FIRST || mutex_id > DISP_MUTEX_DDP_LAST)
    {
        DDPERR("exceed mutex max (0 ~ %d)\n",DISP_MUTEX_DDP_LAST);
        return -1;
    }
    for(i = 0 ; i < module_num ; i++)
    {
        if(module_mutex_map[module_list[i]].bit != -1)
        {
            DDPDBG("module %s added to mutex %d\n",ddp_get_module_name(module_list[i]),mutex_id);
            value |= (1 << module_mutex_map[module_list[i]].bit);
        }
        else
        {
            DDPDBG("module %s not added to mutex %d\n",ddp_get_module_name(module_list[i]),mutex_id);
        }
    }
    DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_MOD(mutex_id),value);
    DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_SOF(mutex_id),mode);

    // for primary config thread, save more time for register config
    if(gEnableMutexRisingEdge==1 && primary_display_is_video_mode()==1 && mutex_id==0)
    {
        DISP_REG_SET_FIELD(handle, SOF_FLD_MUTEX0_SOF_TIMING, DISP_REG_CONFIG_MUTEX0_SOF, 1);
    }

    if(gEnableSWTrigger==1 && primary_display_is_video_mode()==1 && mutex_id==0)
    {
        // set OVL0/OVL1 to separate mutex
        DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_MOD(DISP_OVL_SEPARATE_MUTEX_ID),value&((1 << module_mutex_map[DISP_MODULE_OVL0].bit)|(1 << module_mutex_map[DISP_MODULE_OVL1].bit)));
        DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_SOF(DISP_OVL_SEPARATE_MUTEX_ID), SOF_SINGLE);
        // move OVL0/OVL1 out from primary path
        DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_MOD(mutex_id),value&(~((1 << module_mutex_map[DISP_MODULE_OVL0].bit)|(1 << module_mutex_map[DISP_MODULE_OVL1].bit))));
    }
    
    DDPDBG("mutex %d value=0x%x, sof=%s\n",mutex_id, value, ddp_get_mutex_sof_name(mode));
    return 0;
}
int ddp_insert_config_dirty_rec(void *handle)
{
	int ret = 0;

	if(handle == NULL)
	{
		ASSERT(0);
	}
	if(primary_display_is_video_mode())
	// TODO: modify this
	{
		//do nothing
	}
	else
	{
		ret = cmdqRecSetEventToken(handle, CMDQ_SYNC_TOKEN_CONFIG_DIRTY);
	}
	return ret;
}
Beispiel #4
0
int ddp_insert_config_allow_rec(void *handle)
{
	int ret = 0;

	if(handle == NULL)
	{
		ASSERT(0);
	}

	if(primary_display_is_video_mode())
	{
		ret = cmdqRecWaitNoClear(handle, CMDQ_EVENT_MUTEX0_STREAM_EOF);
	}
	else
	{
		ret = cmdqRecWaitNoClear(handle, CMDQ_SYNC_TOKEN_STREAM_EOF);
	}

	return ret;
}
Beispiel #5
0
void mt_disp_update(UINT32 x, UINT32 y, UINT32 width, UINT32 height)
{
	{
	
		unsigned int va = fb_addr;
		dprintf(0,"fb dump: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", *(unsigned int*)va, *(unsigned int*)(va+4), *(unsigned int*)(va+8), *(unsigned int*)(va+0xC));
	}
	arch_clean_cache_range((unsigned int)fb_addr, DISP_GetFBRamSize());
	primary_display_trigger(TRUE);
    if(!primary_display_is_video_mode())
    {
        /*video mode no need to wait*/
	    mdelay(30);
    }

/*
	// TODO: Fixit!!!!!
    if(fb_isdirty)
    {
        fb_isdirty = 0;
        MASKREG32(0x1400E000, 0x1, 0x1); //Enable DISP MUTEX0
	    MASKREG32(0x1400E004, 0x1, 0x0);
        LCD_CHECK_RET(LCD_LayerSetAddress(FB_LAYER - 1, (UINT32)fb_addr + fb_offset_logo * fb_size));
        printk("[wwy] hardware address = %x, fb_offset_logo = %d\n",(UINT32)fb_addr + fb_offset_logo * fb_size,fb_offset_logo);
		arch_clean_cache_range((unsigned int)fb_addr, DISP_GetFBRamSize());
        DISP_CHECK_RET(DISP_UpdateScreen(x, y, width, height));
        //wait reg update to set fb_offset_logo
        DISP_WaitRegUpdate();
        fb_offset_logo = fb_offset_logo ? 0 : 3;

    }
    else
    {
    arch_clean_cache_range((unsigned int)fb_addr, DISP_GetFBRamSize());
    DISP_CHECK_RET(DISP_UpdateScreen(x, y, width, height));
    }
    */
}
irqreturn_t disp_irq_handler(int irq, void *dev_id)
{
    DISP_MODULE_ENUM module = DISP_MODULE_UNKNOWN;
    unsigned long reg_val = 0;
    unsigned int index = 0;
    unsigned int mutexID = 0;
    unsigned long reg_temp_val = 0;
    DDPDBG("disp_irq_handler, irq=%d, module=%s \n", irq, disp_irq_module(irq));
    MMProfileLogEx(ddp_mmp_get_events()->DDP_IRQ, MMProfileFlagStart, irq, 0);

    //switch(irq)
    {
    	if(irq==dispsys_irq[DISP_REG_DSI0])
	{
            module = DISP_MODULE_DSI0;
	    reg_val = (DISP_REG_GET(dsi_reg_va + 0xC) & 0xff);
            if(atomic_read(&ESDCheck_byCPU) == 0)
            {
	        reg_temp_val=reg_val&0xfffe;//rd_rdy don't clear and wait for ESD & Read LCM will clear the bit.
                DISP_CPU_REG_SET(dsi_reg_va + 0xC, ~reg_temp_val);
            }
            else
            {
                DISP_CPU_REG_SET(dsi_reg_va + 0xC, ~reg_val);
            }
            MMProfileLogEx(ddp_mmp_get_events()->DSI_IRQ[0], MMProfileFlagPulse, reg_val, 0);
        }
        else if(irq==dispsys_irq[DISP_REG_OVL0] || irq==dispsys_irq[DISP_REG_OVL1])
		{
                index = (irq==dispsys_irq[DISP_REG_OVL0]) ? 0 : 1;
                module= (irq==dispsys_irq[DISP_REG_OVL0]) ? DISP_MODULE_OVL0 : DISP_MODULE_OVL1;
                reg_val = DISP_REG_GET(DISP_REG_OVL_INTSTA+index*DISP_OVL_INDEX_OFFSET);
                if(reg_val&(1<<1))
                {
                    DDPIRQ("IRQ: OVL%d frame done! \n",index);
                    ovl_complete_irq_cnt[index]++;

                    // update OVL addr
                    {
                        unsigned int i = 0;
                        if(index==0)
	                    {
	                        for(i=0;i<4;i++)
	                        {
	                            if(DISP_REG_GET(DISP_REG_OVL_SRC_CON)&(0x1<<i))
	                                MMProfileLogEx(ddp_mmp_get_events()->layer[i], MMProfileFlagPulse, DISP_REG_GET(DISP_REG_OVL_L0_ADDR+i*0x20), 0);	  
	                        } 
                        }
                        if(index==1)
	                    {
	                        for(i=0;i<4;i++)
	                        {
	                            if(DISP_REG_GET(DISP_REG_OVL_SRC_CON+DISP_OVL_INDEX_OFFSET)&(0x1<<i))
	                                MMProfileLogEx(ddp_mmp_get_events()->ovl1_layer[i], MMProfileFlagPulse, DISP_REG_GET(DISP_REG_OVL_L0_ADDR+DISP_OVL_INDEX_OFFSET+i*0x20), 0);	  
	                        }
	                    }
                    }
                }
                if(reg_val&(1<<2))
                {
                    //DDPERR("IRQ: OVL%d frame underrun! cnt=%d \n",index, cnt_ovl_underflow[index]++);
                    //disp_irq_log_module |= 1<<module;
                }
                if(reg_val&(1<<3))
                {
                      DDPIRQ("IRQ: OVL%d sw reset done\n",index);
                }
                if(reg_val&(1<<4))
                {
                      DDPIRQ("IRQ: OVL%d hw reset done\n",index);
                }  
                if(reg_val&(1<<5))
                {
                    DDPERR("IRQ: OVL%d-L0 not complete untill EOF!\n",index);
                    //disp_irq_log_module |= 1<<module;
                }
                if(reg_val&(1<<6))
                {
                    DDPERR("IRQ: OVL%d-L1 not complete untill EOF!\n",index);
                    //disp_irq_log_module |= 1<<module;
                }                
                if(reg_val&(1<<7))
                {
                    DDPERR("IRQ: OVL%d-L2 not complete untill EOF!\n",index);
                    //disp_irq_log_module |= 1<<module;
                }  
                if(reg_val&(1<<8))
                {
                    DDPERR("IRQ: OVL%d-L3 not complete untill EOF!\n",index);
                    //disp_irq_log_module |= 1<<module;
                }  
                if(reg_val&(1<<9))
                {
                    //DDPERR("IRQ: OVL%d-L0 fifo underflow!\n",index);
                    //disp_irq_log_module |= 1<<module;
                }  

                if(reg_val&(1<<10))
                {
                    //DDPERR("IRQ: OVL%d-L1 fifo underflow!\n",index);
                    //disp_irq_log_module |= 1<<module;
                }  
                if(reg_val&(1<<11))
                {
                    //DDPERR("IRQ: OVL%d-L2 fifo underflow!\n",index);
                    //disp_irq_log_module |= 1<<module;
                }  
                if(reg_val&(1<<12))
                {
                    //DDPERR("IRQ: OVL%d-L3 fifo underflow!\n",index);
                    //disp_irq_log_module |= 1<<module;
                }
                //clear intr

                if(reg_val&(0xf<<5))
                {
                    ddp_dump_analysis(DISP_MODULE_CONFIG);
                    if(index==0)
                    {
                        ddp_dump_analysis(DISP_MODULE_OVL1);
                        ddp_dump_analysis(DISP_MODULE_OVL0);
                        ddp_dump_analysis(DISP_MODULE_COLOR0);
                        ddp_dump_analysis(DISP_MODULE_AAL);
                        ddp_dump_analysis(DISP_MODULE_RDMA0);
                    }
                    else
                    {
                        ddp_dump_analysis(DISP_MODULE_OVL1);
                        ddp_dump_analysis(DISP_MODULE_RDMA1);
                        ddp_dump_reg(DISP_MODULE_CONFIG);
                    }
                }
                
                DISP_CPU_REG_SET(DISP_REG_OVL_INTSTA+index*DISP_OVL_INDEX_OFFSET, ~reg_val);     
                MMProfileLogEx(ddp_mmp_get_events()->OVL_IRQ[index], MMProfileFlagPulse, reg_val, 0);
                if(reg_val&0x1e0)
                {
                    MMProfileLogEx(ddp_mmp_get_events()->ddp_abnormal_irq, MMProfileFlagPulse, (index<<16)|reg_val, module<<24);
                }
        	}
        else if(irq==dispsys_irq[DISP_REG_WDMA0] || irq==dispsys_irq[DISP_REG_WDMA1])
		{
                index = (irq==dispsys_irq[DISP_REG_WDMA0]) ? 0 : 1;
                module =(irq==dispsys_irq[DISP_REG_WDMA0]) ? DISP_MODULE_WDMA0 : DISP_MODULE_WDMA1;
                reg_val = DISP_REG_GET(DISP_REG_WDMA_INTSTA+index*DISP_WDMA_INDEX_OFFSET);
                if(reg_val&(1<<0))
                {
                    DDPIRQ("IRQ: WDMA%d frame done!\n",index);
                }
                if(reg_val&(1<<1))
                {
                    DDPERR("IRQ: WDMA%d underrun! cnt=%d\n",index,cnt_wdma_underflow[index]++);
                    disp_irq_log_module |= 1<<module;
                }
                //clear intr
                DISP_CPU_REG_SET(DISP_REG_WDMA_INTSTA+index*DISP_WDMA_INDEX_OFFSET,~reg_val);
                MMProfileLogEx(ddp_mmp_get_events()->WDMA_IRQ[index], MMProfileFlagPulse, reg_val, DISP_REG_GET(DISP_REG_WDMA_CLIP_SIZE));
                if(reg_val&0x2)
                {
                    MMProfileLogEx(ddp_mmp_get_events()->ddp_abnormal_irq, MMProfileFlagPulse, (index<<16)|reg_val, cnt_wdma_underflow[index]|(module<<24));
                }
        }
        else if(irq==dispsys_irq[DISP_REG_RDMA0] || irq==dispsys_irq[DISP_REG_RDMA1])
		{
                if(dispsys_irq[DISP_REG_RDMA0]==irq)
                {
                    index = 0;
                    module = DISP_MODULE_RDMA0;
                }
                else if(dispsys_irq[DISP_REG_RDMA1]==irq)
                {
                    index = 1;
                    module = DISP_MODULE_RDMA1;
                }

                reg_val = DISP_REG_GET(DISP_REG_RDMA_INT_STATUS+index*DISP_RDMA_INDEX_OFFSET);
                if(reg_val&(1<<0))
                {
                      DDPIRQ("IRQ: RDMA%d reg update done! \n",index);
                }
                if(reg_val&(1<<1))
                {
                      MMProfileLogEx(ddp_mmp_get_events()->SCREEN_UPDATE[index], MMProfileFlagStart, reg_val, DISP_REG_GET(DISP_REG_RDMA_MEM_START_ADDR));
              	      
					  rdma_start_time[index]= sched_clock();
                      DDPIRQ("IRQ: RDMA%d frame start! \n",index);
                      rdma_start_irq_cnt[index]++;
                      
                      // rdma start/end irq should equal, else need reset ovl
                      if(gResetRDMAEnable == 1 &&
                         is_hwc_enabled == 1 &&
                         index ==0 &&
                         primary_display_is_video_mode()==1 &&
                         rdma_start_irq_cnt[0] > rdma_done_irq_cnt[0]+3)
                      {
                          ovl_reset(DISP_MODULE_OVL0, NULL);
                          if(ovl_get_status()!=DDP_OVL1_STATUS_SUB)
                          {
                              ovl_reset(DISP_MODULE_OVL1, NULL);
                          }
                          rdma_done_irq_cnt[0] = rdma_start_irq_cnt[0];
                          DDPERR("warning: reset ovl!\n");
                      }
                      
#ifdef CONFIG_MTK_SEGMENT_TEST
						if(record_rdma_end_interval == 1)
						{
							if(rdma_end_begin_time == 0)
							{
								rdma_end_begin_time = sched_clock();
								//printk("[display_test]====RDMA frame end time1:%lld\n",rdma_end_begin_time);	
							}
							else
							{
								unsigned long long time_now = sched_clock();
								//printk("[display_test]====RDMA frame end time2:%lld\n",time_now);	

								//printk("[display_test]====RDMA frame end time3:this=%lld,max=%lld,min=%lld\n",time_now - rdma_end_begin_time,rdma_end_max_interval,rdma_end_min_interval);	
								if((time_now - rdma_end_begin_time) > rdma_end_max_interval)
								{
									rdma_end_max_interval = time_now - rdma_end_begin_time;
								}
								if((time_now - rdma_end_begin_time) < rdma_end_min_interval)
								{
									rdma_end_min_interval = time_now - rdma_end_begin_time;
								}
								rdma_end_begin_time = time_now;
							}
						}
#endif
                }
                if(reg_val&(1<<2))
                {
                      MMProfileLogEx(ddp_mmp_get_events()->SCREEN_UPDATE[index], MMProfileFlagEnd, reg_val, 0);
					  rdma_end_time[index]= sched_clock();
                      DDPIRQ("IRQ: RDMA%d frame done! \n",index);
                      //rdma_done_irq_cnt[index] ++;
                      rdma_done_irq_cnt[index] = rdma_start_irq_cnt[index];
                }
                if(reg_val&(1<<3))
                {
                      DDPERR("IRQ: RDMA%d abnormal! cnt=%d \n",index, cnt_rdma_abnormal[index]++);
                      disp_irq_log_module |= 1<<module;

                }
                if(reg_val&(1<<4))
                {
                      DDPERR("IRQ: RDMA%d underflow! cnt=%d \n",index, cnt_rdma_underflow[index]++);
                      disp_irq_log_module |= 1<<module;
                      rdma_underflow_irq_cnt[index]++;
                }
                if(reg_val&(1<<5))
                {
                      DDPIRQ("IRQ: RDMA%d target line! \n",index);
                      rdma_targetline_irq_cnt[index]++;
                }
                //clear intr
                DISP_CPU_REG_SET(DISP_REG_RDMA_INT_STATUS+index*DISP_RDMA_INDEX_OFFSET,~reg_val);       
                MMProfileLogEx(ddp_mmp_get_events()->RDMA_IRQ[index], MMProfileFlagPulse, reg_val, 0);
                if(reg_val&0x18)
                {
                    MMProfileLogEx(ddp_mmp_get_events()->ddp_abnormal_irq, MMProfileFlagPulse, (index<<16)|reg_val, rdma_underflow_irq_cnt[index]|(cnt_rdma_abnormal[index]<<8)||(module<<24));
                }
        }
        else if(irq==dispsys_irq[DISP_REG_COLOR])
		{

        }
        else if(irq==dispsys_irq[DISP_REG_MUTEX])
		{
            // mutex0: perimary disp
            // mutex1: sub disp
            // mutex2: aal
            module = DISP_MODULE_MUTEX;
            reg_val = DISP_REG_GET(DISP_REG_CONFIG_MUTEX_INTSTA) & 0x7C1F;
            for(mutexID = 0; mutexID<5; mutexID++)
            {
                if(reg_val & (0x1<<mutexID))
                {
                    DDPIRQ("IRQ: mutex%d sof!\n",mutexID);
                    MMProfileLogEx(ddp_mmp_get_events()->MUTEX_IRQ[mutexID], MMProfileFlagPulse, reg_val, 0);
                }
                if(reg_val & (0x1<<(mutexID+DISP_MUTEX_TOTAL)))
                {
                    DDPIRQ("IRQ: mutex%d eof!\n",mutexID);
                    MMProfileLogEx(ddp_mmp_get_events()->MUTEX_IRQ[mutexID], MMProfileFlagPulse, reg_val, 1);
                }
            }
            DISP_CPU_REG_SET(DISP_REG_CONFIG_MUTEX_INTSTA, ~reg_val);
        }
        else if(irq==dispsys_irq[DISP_REG_AAL])
		{
            module = DISP_MODULE_AAL;
            reg_val = DISP_REG_GET(DISP_AAL_INTSTA);
            disp_aal_on_end_of_frame();
        }
        else if(irq==dispsys_irq[DISP_REG_CONFIG])  // MMSYS error intr
		{
            reg_val = DISP_REG_GET(DISP_REG_CONFIG_MMSYS_INTSTA) & 0x7;
            if(reg_val&(1<<0))
            {
                DDPERR("MMSYS to MFG APB TX Error, MMSYS clock off but MFG clock on! \n");
            }
            if(reg_val&(1<<1))
            {
                DDPERR("MMSYS to MJC APB TX Error, MMSYS clock off but MJC clock on! \n");
            }
            if(reg_val&(1<<2))
            {
                DDPERR("PWM APB TX Error! \n");
            }

            DISP_CPU_REG_SET(DISP_REG_CONFIG_MMSYS_INTSTA, ~reg_val);
		}
        else
        {
            module = DISP_MODULE_UNKNOWN;
            reg_val = 0;
            DDPERR("invalid irq=%d \n ", irq); 
        }
    }
    disp_invoke_irq_callbacks(module, reg_val);
    if(disp_irq_log_module!=0)
    {
        wake_up_interruptible(&disp_irq_log_wq);
    }
    MMProfileLogEx(ddp_mmp_get_events()->DDP_IRQ, MMProfileFlagEnd, irq, reg_val);
    return IRQ_HANDLED;
}