int ddp_mutex_reset(int mutex_id, void * handle) { DDPDBG("mutex %d reset\n", mutex_id); DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_RST(mutex_id),1); DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_RST(mutex_id),0); return 0; }
int ddp_mutex_Interrupt_enable(int mutex_id,void * handle) { DDPDBG("mutex %d interrupt enable\n", mutex_id); DISP_REG_MASK(handle,DISP_REG_CONFIG_MUTEX_INTEN,0x1<<mutex_id,0x1<<mutex_id); DISP_REG_MASK(handle,DISP_REG_CONFIG_MUTEX_INTEN,1<<(mutex_id+DISP_MUTEX_TOTAL),0x1<<(mutex_id+DISP_MUTEX_TOTAL)); return 0; }
static DISP_MODULE_ENUM find_module_by_irq(int irq) { // should sort irq_id_to_module_table by numberic sequence int i = 0; #define DISP_IRQ_NUM_MAX (DISP_REG_NUM) static struct irq_module_map { int irq; DISP_MODULE_ENUM module; }irq_id_to_module_table[DISP_IRQ_NUM_MAX] = { {0, DISP_MODULE_OVL0 }, {0, DISP_MODULE_OVL1 }, {0, DISP_MODULE_RDMA0 }, {0, DISP_MODULE_RDMA1 }, {0, DISP_MODULE_WDMA0 }, {0, DISP_MODULE_COLOR0 }, {0, DISP_MODULE_CCORR }, {0, DISP_MODULE_AAL }, {0, DISP_MODULE_GAMMA }, {0, DISP_MODULE_DITHER }, {0, DISP_MODULE_UFOE }, {0, DISP_MODULE_PWM0 }, {0, DISP_MODULE_WDMA1 }, {0, DISP_MODULE_MUTEX }, {0, DISP_MODULE_DSI0 }, {0, DISP_MODULE_DPI }, }; irq_id_to_module_table[0].irq = dispsys_irq[DISP_REG_OVL0 ]; irq_id_to_module_table[1].irq = dispsys_irq[DISP_REG_OVL1 ]; irq_id_to_module_table[2].irq = dispsys_irq[DISP_REG_RDMA0 ]; irq_id_to_module_table[3].irq = dispsys_irq[DISP_REG_RDMA1 ]; irq_id_to_module_table[4].irq = dispsys_irq[DISP_REG_WDMA0 ]; irq_id_to_module_table[5].irq = dispsys_irq[DISP_REG_COLOR ]; irq_id_to_module_table[6].irq = dispsys_irq[DISP_REG_CCORR ]; irq_id_to_module_table[7].irq = dispsys_irq[DISP_REG_AAL ]; irq_id_to_module_table[8].irq = dispsys_irq[DISP_REG_GAMMA ]; irq_id_to_module_table[9].irq = dispsys_irq[DISP_REG_DITHER]; irq_id_to_module_table[10].irq = dispsys_irq[DISP_REG_UFOE ]; irq_id_to_module_table[11].irq = dispsys_irq[DISP_REG_PWM ]; irq_id_to_module_table[12].irq = dispsys_irq[DISP_REG_WDMA1]; irq_id_to_module_table[13].irq = dispsys_irq[DISP_REG_MUTEX]; irq_id_to_module_table[14].irq = dispsys_irq[DISP_REG_DSI0 ]; irq_id_to_module_table[15].irq = dispsys_irq[DISP_REG_DPI0 ]; for(i = 0;i<DISP_IRQ_NUM_MAX ;i++) { if(irq_id_to_module_table[i].irq == irq) { DDPDBG("find module %d by irq %d \n", irq,irq_id_to_module_table[i].module); return irq_id_to_module_table[i].module; } } if(i==DISP_IRQ_NUM_MAX) { DDPERR("can not find irq=%d in irq_id_to_module_table\n", irq); } return DISP_MODULE_UNKNOWN; }
static void process_dbg_cmd(char *cmd) { char *tok; DDPDBG("cmd: %s\n", cmd); memset(dbg_buf, 0, sizeof(dbg_buf)); while ((tok = strsep(&cmd, " ")) != NULL) process_dbg_opt(tok); }
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; }
static int write_tplay_handle(unsigned int handle_value) { if (NULL != tplay_handle_virt_addr) { DDPDBG("[SVP] write_tplay_handle 0x%x \n", handle_value); *tplay_handle_virt_addr = handle_value; return 0; } return -EFAULT; }
int ddp_mutex_clear(int mutex_id, void * handle) { DDPDBG("mutex %d clear\n", mutex_id); DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_MOD(mutex_id),0); DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_SOF(mutex_id),0); /*reset mutex*/ ddp_mutex_reset(mutex_id,handle); return 0; }
static int dump_tplay_physcial_addr(void) { DDPDBG("[SVP] dump_tplay_physcial_addr \n"); int ret = 0; enum mc_result mcRet = MC_DRV_OK; open_tplay_driver_connection(); if (tplaySessionHandle.session_id == 0) { DDPERR("[SVP] invalid tplay session \n"); return -1; } /* set TCI command */ pTplayTci->cmd.header.commandId = CMD_TPLAY_DUMP_PHY; /* notify the trustlet */ DDPMSG("[SVP] notify Tlsec trustlet CMD_TPLAY_DUMP_PHY \n"); mcRet = mc_notify(&tplaySessionHandle); if (MC_DRV_OK != mcRet) { DDPERR("[SVP] mc_notify failed: %d @%s line %d\n", mcRet, __func__, __LINE__); ret = -1; goto _notify_to_trustlet_fail; } /* wait for response from the trustlet */ mcRet = mc_wait_notification(&tplaySessionHandle, MC_INFINITE_TIMEOUT); if (MC_DRV_OK != mcRet) { DDPERR("[SVP] mc_wait_notification failed: %d @%s line %d\n", mcRet, __func__, __LINE__); ret = -1; goto _notify_from_trustlet_fail; } DDPDBG("[SVP] CMD_TPLAY_DUMP_PHY result=%d, return code=%d\n", pTplayTci->result, pTplayTci->rsp.header.returnCode); _notify_from_trustlet_fail: _notify_to_trustlet_fail: close_tplay_driver_connection(); return ret; }
void OVLRegRestore(DISP_MODULE_ENUM module,void * handle) { int idx = ovl_index(module); int i = reg_back_cnt[idx]; while(i > 0) { i--; DISP_REG_SET(handle,reg_back[idx][i].address, reg_back[idx][i].value); } DDPDBG("restore %d cnt registers on ovl %d",reg_back_cnt[idx],idx); reg_back_cnt[idx] = 0; }
int ddp_mutex_add_module(int mutex_id, DISP_MODULE_ENUM module, void * handle) { int value = 0; if (module < DISP_MODULE_UNKNOWN ){ if (module_mutex_map[module].bit != -1){ DDPDBG("module %s added to mutex %d\n",ddp_get_module_name(module),mutex_id); value |= (1 << module_mutex_map[module].bit); DISP_REG_MASK(handle,DISP_REG_CONFIG_MUTEX_MOD(mutex_id), value, value); } } return 0; }
// id: mutex ID, 0~5 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); } DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_MOD(mutex_id),value); DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_SOF(mutex_id),mode); DDPDBG("mutex %d value=0x%x, sof=%s\n",mutex_id, value, ddp_get_mutex_sof_name(mode)); return 0; }
static enum mc_result late_open_mobicore_device(void) { enum mc_result mcRet = MC_DRV_OK; if (0 == opened_device) { DDPDBG("=============== open mobicore device ===============\n"); /* Open MobiCore device */ mcRet = mc_open_device(mc_deviceId); if (MC_DRV_ERR_INVALID_OPERATION == mcRet) { // skip false alarm when the mc_open_device(mc_deviceId) is called more than once DDPDBG("mc_open_device already done\n"); } else if (MC_DRV_OK != mcRet) { DDPERR("mc_open_device failed: %d @%s line %d\n", mcRet, __func__, __LINE__); return mcRet; } opened_device = 1; } return MC_DRV_OK; }
static int ddp_find_module_index(DDP_SCENARIO_ENUM ddp_scenario, DISP_MODULE_ENUM module) { int i=0; for(i=0; i< DDP_ENING_NUM; i++) { if(module_list_scenario[ddp_scenario][i] == module) { return i; } } DDPDBG("find module: can not find module %s on scenario %s\n",ddp_get_module_name(module), ddp_get_scenario_name(ddp_scenario)); return -1; }
// allocate a fixed physical memory address for storing tplay handle void init_tplay_handle(struct device *dev) { void *va; va = dma_alloc_coherent(dev, sizeof(unsigned int), &handle_pa, GFP_KERNEL); if (NULL != va) { DDPDBG("[SVP] allocate handle_pa[%pa]\n", &va); } else { DDPERR("[SVP] failed to allocate handle_pa \n"); } tplay_handle_virt_addr = (unsigned int *)va; }
// set ultra registers void rdma_set_ultra(unsigned int idx, unsigned int width, unsigned int height, unsigned int bpp, unsigned int frame_rate,void * handle) { // constant static const unsigned int blank_overhead = 115; //it is 1.15, need to divide 100 later static const unsigned int rdma_fifo_width = 16; //in unit of byte static const unsigned int ultra_low_time = 5; //in unit of us static const unsigned int pre_ultra_low_time = 7; //in unit of us static const unsigned int pre_ultra_high_time = 8; //in unit of us static const unsigned int fifo_size = 512; static const unsigned int fifo_valid_line_ratio = 125; //valid size 1/8 line; static const unsigned int fifo_min_size = 24; // working variables unsigned int consume_levels_per_sec; unsigned int ultra_low_level; unsigned int pre_ultra_low_level; unsigned int pre_ultra_high_level; unsigned int ultra_high_ofs; unsigned int pre_ultra_low_ofs; unsigned int pre_ultra_high_ofs; unsigned int fifo_valid_size = 16; /* compute fifo valid size */ fifo_valid_size = (width * bpp * fifo_valid_line_ratio) / (rdma_fifo_width * 1000); fifo_valid_size = fifo_valid_size > fifo_min_size ? fifo_valid_size : fifo_min_size; //consume_levels_per_sec = ((long long unsigned int)width*height*frame_rate*blank_overhead*bpp)/rdma_fifo_width/100; //change calculation order to prevent overflow of unsigned int consume_levels_per_sec = (width*height*frame_rate*bpp/rdma_fifo_width/100)*blank_overhead; // /1000000 for ultra_low_time in unit of us ultra_low_level = (unsigned int)(ultra_low_time * consume_levels_per_sec / 1000000 ); pre_ultra_low_level = (unsigned int)(pre_ultra_low_time * consume_levels_per_sec / 1000000 ); pre_ultra_high_level = (unsigned int)(pre_ultra_high_time * consume_levels_per_sec / 1000000 ); pre_ultra_low_ofs = pre_ultra_low_level - ultra_low_level; ultra_high_ofs = 1; pre_ultra_high_ofs = pre_ultra_high_level - pre_ultra_low_level ; //write ultra_low_level, ultra_high_ofs, pre_ultra_low_ofs, pre_ultra_high_ofs into register DISP_RDMA_MEM_GMC_SETTING_0 DISP_REG_SET(handle,idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_MEM_GMC_SETTING_0, ultra_low_level|(pre_ultra_low_ofs<<8)|(ultra_high_ofs<<16)|(pre_ultra_high_ofs<<24)); DISP_REG_SET_FIELD(handle,FIFO_CON_FLD_OUTPUT_VALID_FIFO_THRESHOLD, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_FIFO_CON, fifo_valid_size); DDPDBG("FIFO_VALID_Size = 0x%03x = %d\n", fifo_valid_size , fifo_valid_size ); DDPDBG("ultra_low_level = 0x%03x = %d\n", ultra_low_level , ultra_low_level ); DDPDBG("pre_ultra_low_level = 0x%03x = %d\n", pre_ultra_low_level , pre_ultra_low_level ); DDPDBG("pre_ultra_high_level = 0x%03x = %d\n", pre_ultra_high_level, pre_ultra_high_level); DDPDBG("ultra_high_ofs = 0x%03x = %d\n", ultra_high_ofs , ultra_high_ofs ); DDPDBG("pre_ultra_low_ofs = 0x%03x = %d\n", pre_ultra_low_ofs , pre_ultra_low_ofs ); DDPDBG("pre_ultra_high_ofs = 0x%03x = %d\n", pre_ultra_high_ofs , pre_ultra_high_ofs ); }
void OVLRegStore(DISP_MODULE_ENUM module) { int i =0; int idx = ovl_index(module); static const unsigned int regs[] = { //start DISP_REG_OVL_INTEN , DISP_REG_OVL_EN ,DISP_REG_OVL_DATAPATH_CON, // roi DISP_REG_OVL_ROI_SIZE , DISP_REG_OVL_ROI_BGCLR , //layers enable DISP_REG_OVL_SRC_CON, //layer0 DISP_REG_OVL_RDMA0_CTRL , DISP_REG_OVL_L0_CON ,DISP_REG_OVL_L0_SRC_SIZE, DISP_REG_OVL_L0_OFFSET , DISP_REG_OVL_L0_ADDR ,DISP_REG_OVL_L0_PITCH, DISP_REG_OVL_L0_SRCKEY , //layer1 DISP_REG_OVL_RDMA1_CTRL , DISP_REG_OVL_L1_CON ,DISP_REG_OVL_L1_SRC_SIZE, DISP_REG_OVL_L1_OFFSET , DISP_REG_OVL_L1_ADDR ,DISP_REG_OVL_L1_PITCH, DISP_REG_OVL_L1_SRCKEY , //layer2 DISP_REG_OVL_RDMA2_CTRL , DISP_REG_OVL_L2_CON ,DISP_REG_OVL_L2_SRC_SIZE, DISP_REG_OVL_L2_OFFSET , DISP_REG_OVL_L2_ADDR ,DISP_REG_OVL_L2_PITCH, DISP_REG_OVL_L2_SRCKEY , //layer3 DISP_REG_OVL_RDMA3_CTRL , DISP_REG_OVL_L3_CON ,DISP_REG_OVL_L3_SRC_SIZE, DISP_REG_OVL_L3_OFFSET , DISP_REG_OVL_L3_ADDR ,DISP_REG_OVL_L3_PITCH, DISP_REG_OVL_L3_SRCKEY , }; reg_back_cnt[idx] = sizeof(regs)/sizeof(unsigned int); ASSERT(reg_back_cnt[idx] <= OVL_REG_BACK_MAX); for(i =0; i< reg_back_cnt[idx]; i++) { reg_back[idx][i].address = regs[i]; reg_back[idx][i].value = DISP_REG_GET(regs[i]); } DDPDBG("store % cnt registers on ovl %d",reg_back_cnt[idx],idx); }
void ddp_connect_path(DDP_SCENARIO_ENUM scenario, void * handle) { DDPDBG("path connect on scenario %s\n", ddp_get_scenario_name(scenario)); if(scenario == DDP_SCENARIO_PRIMARY_ALL) { ddp_connect_path_l(module_list_scenario[DDP_SCENARIO_PRIMARY_DISP], handle); ddp_connect_path_l(module_list_scenario[DDP_SCENARIO_PRIMARY_OVL_MEMOUT],handle); } else if(scenario == DDP_SCENARIO_SUB_ALL) { ddp_connect_path_l(module_list_scenario[DDP_SCENARIO_SUB_DISP], handle); ddp_connect_path_l(module_list_scenario[DDP_SCENARIO_SUB_OVL_MEMOUT], handle); } else { ddp_connect_path_l(module_list_scenario[scenario], handle); } return ; }
static int disp_release(struct inode *inode, struct file *file) { disp_node_struct *pNode = NULL; unsigned int index = 0; DDPDBG("enter disp_release() process:%s\n",current->comm); pNode = (disp_node_struct *)file->private_data; spin_lock(&pNode->node_lock); spin_unlock(&pNode->node_lock); if(NULL != file->private_data) { kfree(file->private_data); file->private_data = NULL; } return 0; }
void ddp_check_path(DDP_SCENARIO_ENUM scenario) { DDPDBG("path check path on scenario %s\n", ddp_get_scenario_name(scenario)); if(scenario == DDP_SCENARIO_PRIMARY_ALL) { ddp_check_path_l(module_list_scenario[DDP_SCENARIO_PRIMARY_DISP]); ddp_check_path_l(module_list_scenario[DDP_SCENARIO_PRIMARY_OVL_MEMOUT]); } else if(scenario == DDP_SCENARIO_SUB_ALL) { ddp_check_path_l(module_list_scenario[DDP_SCENARIO_SUB_DISP]); ddp_check_path_l(module_list_scenario[DDP_SCENARIO_SUB_OVL_MEMOUT]); } else { ddp_check_path_l(module_list_scenario[scenario]); } return ; }
static int open_tplay_driver_connection(void) { enum mc_result mcRet = MC_DRV_OK; if (tplaySessionHandle.session_id != 0) { DDPMSG("tplay TDriver session already created\n"); return 0; } DDPDBG("=============== late init tplay TDriver session ===============\n"); do { late_open_mobicore_device(); /* Allocating WSM for DCI */ mcRet = mc_malloc_wsm(mc_deviceId, 0, sizeof(tplay_tciMessage_t), (uint8_t **) &pTplayTci, 0); if (MC_DRV_OK != mcRet) { DDPERR("mc_malloc_wsm failed: %d @%s line %d\n", mcRet, __func__, __LINE__); return -1; } /* Open session the TDriver */ memset(&tplaySessionHandle, 0, sizeof(tplaySessionHandle)); tplaySessionHandle.device_id = mc_deviceId; mcRet = mc_open_session(&tplaySessionHandle, &MC_UUID_TPLAY, (uint8_t *) pTplayTci, (uint32_t) sizeof(tplay_tciMessage_t)); if (MC_DRV_OK != mcRet) { DDPERR("mc_open_session failed: %d @%s line %d\n", mcRet, __func__, __LINE__); // if failed clear session handle memset(&tplaySessionHandle, 0, sizeof(tplaySessionHandle)); return -1; } } while (0); return (MC_DRV_OK == mcRet) ? 0 : -1; }
// set display interface when kernel init int ddp_set_dst_module(DDP_SCENARIO_ENUM scenario, DISP_MODULE_ENUM dst_module) { int i = 0; DDPMSG("ddp_set_dst_module, scenario=%s, dst_module=%s \n", ddp_get_scenario_name(scenario), ddp_get_module_name(dst_module)); if (ddp_find_module_index(scenario,dst_module) > 0) { DDPDBG("%s is already on path\n",ddp_get_module_name(dst_module)); return 0; } i = ddp_get_module_num_l(module_list_scenario[scenario])-1; ASSERT(i>=0); if (dst_module == DISP_MODULE_DSIDUAL) { if (i < (DDP_ENING_NUM -1)) { module_list_scenario[scenario][i++] = DISP_MODULE_SPLIT1; }else{ DDPERR("set dst module over up bound\n"); return -1; } } else { if(ddp_get_dst_module(scenario)==DISP_MODULE_DSIDUAL) { if (i >= 1) { module_list_scenario[scenario][i--] = -1; }else{ DDPERR("set dst module over low bound\n"); return -1; } } } module_list_scenario[scenario][i] = dst_module; if (scenario == DDP_SCENARIO_PRIMARY_ALL) { ddp_set_dst_module(DDP_SCENARIO_PRIMARY_DISP,dst_module); }else if(scenario==DDP_SCENARIO_SUB_ALL) { ddp_set_dst_module(DDP_SCENARIO_SUB_DISP,dst_module); } ddp_print_scenario(scenario); return 0; }
static int disp_open(struct inode *inode, struct file *file) { disp_node_struct *pNode = NULL; DDPDBG("enter disp_open() process:%s\n",current->comm); //Allocate and initialize private data file->private_data = kmalloc(sizeof(disp_node_struct) , GFP_ATOMIC); if(NULL == file->private_data) { DDPMSG("Not enough entry for DDP open operation\n"); return -ENOMEM; } pNode = (disp_node_struct *)file->private_data; pNode->open_pid = current->pid; pNode->open_tgid = current->tgid; INIT_LIST_HEAD(&(pNode->testList)); spin_lock_init(&pNode->node_lock); return 0; }
static MUTEX_SOF ddp_get_mutex_sof(DISP_MODULE_ENUM dest_module, DDP_MODE ddp_mode) { MUTEX_SOF mode = SOF_SINGLE; switch(dest_module) { case DISP_MODULE_DSI0: { mode = (ddp_mode==DDP_VIDEO_MODE ? SOF_DSI0 : SOF_SINGLE); break; } case DISP_MODULE_DSI1: { mode = (ddp_mode==DDP_VIDEO_MODE ? SOF_DSI1 : SOF_SINGLE); break; } case DISP_MODULE_DSIDUAL: { mode = (ddp_mode==DDP_VIDEO_MODE ? SOF_DSI0 : SOF_SINGLE); break; } case DISP_MODULE_DPI: { mode = SOF_DSI1;//SOF_DPI0; has one DSI, so the DPI should use 1 for mutex_sof break; } case DISP_MODULE_WDMA0: case DISP_MODULE_WDMA1: mode = SOF_SINGLE; break; default: DDPERR("get mutex sof, invalid param dst module = %s(%d), dis mode %s\n", ddp_get_module_name(dest_module), dest_module,ddp_get_mode_name(ddp_mode)); } DDPDBG("mutex sof: %s dst module %s:%s\n", ddp_get_mutex_sof_name(mode), ddp_get_module_name(dest_module),ddp_get_mode_name(ddp_mode)); return mode; }
int OVLLayerConfig(DISP_MODULE_ENUM module, unsigned int layer, unsigned int source, DpColorFormat format, unsigned int addr, unsigned int src_x, // ROI x offset unsigned int src_y, // ROI y offset unsigned int src_pitch, unsigned int dst_x, // ROI x offset unsigned int dst_y, // ROI y offset unsigned int dst_w, // ROT width unsigned int dst_h, // ROI height unsigned int keyEn, unsigned int key, // color key unsigned int aen, // alpha enable unsigned char alpha, void * handle) { int idx = ovl_index(module); unsigned int value = 0; enum OVL_INPUT_FORMAT fmt = ovl_input_fmt_convert(format); unsigned int bpp = ovl_input_fmt_bpp(fmt); unsigned int input_swap = ovl_input_fmt_byte_swap(fmt); unsigned int input_fmt = ovl_input_fmt_reg_value(fmt); enum OVL_COLOR_SPACE space = ovl_input_fmt_color_space(fmt); /*0100 MTX_JPEG_TO_RGB (YUV FUll TO RGB)*/ int color_matrix = 0x4; unsigned int idx_offset = idx*DISP_INDEX_OFFSET; unsigned int layer_offset = idx_offset + layer * 0x20; ASSERT((dst_w <= OVL_MAX_WIDTH) && (dst_h <= OVL_MAX_HEIGHT) && (layer <= 3)); if (addr == 0) { DDPERR("source from memory, but addr is 0!\n"); ASSERT(0); } DDPDBG("ovl%d, layer=%d, source=%s, off(x=%d, y=%d), dst(%d, %d, %d, %d),pitch=%d," "fmt=%s, addr=%lx, keyEn=%d, key=%d, aen=%d, alpha=%d \n", idx, layer, (source==0)?"memory":"constant_color", src_x, src_y, dst_x, dst_y, dst_w, dst_h, src_pitch, ovl_intput_format_name(fmt, input_swap), addr, keyEn, key, aen, alpha); if(source==OVL_LAYER_SOURCE_RESERVED) //==1, means constant color { if(aen==0) { DDPERR("dim layer ahpha enable should be 1!\n"); } if(fmt!=OVL_INPUT_FORMAT_RGB565) { DDPERR("dim layer format should be RGB565"); fmt = OVL_INPUT_FORMAT_RGB565; } } DISP_REG_SET(handle, DISP_REG_OVL_RDMA0_CTRL+layer_offset, 0x1); value = (REG_FLD_VAL((L_CON_FLD_LARC), (source)) | REG_FLD_VAL((L_CON_FLD_CFMT), (input_fmt)) | REG_FLD_VAL((L_CON_FLD_AEN), (aen)) | REG_FLD_VAL((L_CON_FLD_APHA), (alpha)) | REG_FLD_VAL((L_CON_FLD_SKEN), (keyEn)) | REG_FLD_VAL((L_CON_FLD_BTSW), (input_swap))); if (space == OVL_COLOR_SPACE_YUV) value = value | REG_FLD_VAL((L_CON_FLD_MTX), (color_matrix)); DISP_REG_SET(handle, DISP_REG_OVL_L0_CON+layer_offset, value); DISP_REG_SET(handle, DISP_REG_OVL_L0_SRC_SIZE+layer_offset, dst_h<<16 | dst_w); DISP_REG_SET(handle, DISP_REG_OVL_L0_OFFSET+layer_offset, dst_y<<16 | dst_x); DISP_REG_SET(handle, DISP_REG_OVL_L0_ADDR+layer_offset, addr+src_x*bpp+src_y*src_pitch); DISP_REG_SET(handle, DISP_REG_OVL_L0_SRCKEY+layer_offset, key); value = (REG_FLD_VAL((L_PITCH_FLD_SUR_ALFA), (value)) | REG_FLD_VAL((L_PITCH_FLD_LSP), (src_pitch))); DISP_REG_SET(handle, DISP_REG_OVL_L0_PITCH+layer_offset, value); DISP_REG_SET(handle, DISP_REG_OVL_RDMA0_MEM_GMC_SETTING+layer_offset, 0x6070); }
static int rdma_config(DISP_MODULE_ENUM module, enum RDMA_MODE mode, unsigned long address, DpColorFormat inFormat, unsigned pitch, unsigned width, unsigned height, unsigned ufoe_enable, DISP_BUFFER_TYPE sec, void * handle) { unsigned int output_is_yuv = 0; enum RDMA_INPUT_FORMAT inputFormat = rdma_input_format_convert(inFormat); unsigned int bpp = rdma_input_format_bpp(inputFormat); unsigned int input_is_yuv = rdma_input_format_color_space(inputFormat); unsigned int input_swap = rdma_input_format_byte_swap(inputFormat); unsigned int input_format_reg = rdma_input_format_reg_value(inputFormat); unsigned int color_matrix = 0x4; //0100 MTX_JPEG_TO_RGB (YUV FUll TO RGB) unsigned int idx = rdma_index(module); #if defined(CONFIG_TRUSTONIC_TEE_SUPPORT) && defined(CONFIG_MTK_SEC_VIDEO_PATH_SUPPORT) DDPMSG("RDMAConfig idx %d, mode %d, address 0x%lx, inputformat %s, pitch %u, width %u, height %u,sec%d\n", idx, mode, address, rdma_intput_format_name(inputFormat,input_swap), pitch,width, height, sec); #else DDPDBG("RDMAConfig idx %d, mode %d, address 0x%lx, inputformat %s, pitch %u, width %u, height %u,sec%d\n", idx, mode, address, rdma_intput_format_name(inputFormat,input_swap), pitch,width, height, sec); #endif ASSERT(idx <= 2); if((width > RDMA_MAX_WIDTH) || (height > RDMA_MAX_HEIGHT)) { DDPERR("RDMA input overflow, w=%d, h=%d, max_w=%d, max_h=%d\n", width, height, RDMA_MAX_WIDTH, RDMA_MAX_HEIGHT); } if(input_is_yuv==1 && output_is_yuv==0) { DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_ENABLE, idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 1); DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_INT_MTX_SEL, idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, color_matrix); } else if(input_is_yuv==0 && output_is_yuv==1) { color_matrix = 0x2; //0x0010, RGB_TO_BT601 DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_ENABLE, idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 1); DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_INT_MTX_SEL, idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, color_matrix); } else { DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_ENABLE, idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 0); DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_INT_MTX_SEL, idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 0); } DISP_REG_SET_FIELD(handle,GLOBAL_CON_FLD_MODE_SEL, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_GLOBAL_CON, mode); // FORMAT & SWAP only works when RDMA memory mode, set both to 0 when RDMA direct link mode. DISP_REG_SET_FIELD(handle,MEM_CON_FLD_MEM_MODE_INPUT_FORMAT, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_MEM_CON, ((mode == RDMA_MODE_DIRECT_LINK) ? 0 : input_format_reg&0xf)); DISP_REG_SET_FIELD(handle,MEM_CON_FLD_MEM_MODE_INPUT_SWAP, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_MEM_CON, ((mode == RDMA_MODE_DIRECT_LINK) ? 0 : input_swap)); if(sec != DISP_SECURE_BUFFER) { DISP_REG_SET(handle,idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_MEM_START_ADDR, address); } else { int m4u_port; unsigned int size = pitch * height; m4u_port = idx==0 ? M4U_PORT_DISP_RDMA0 : M4U_PORT_DISP_RDMA1; /* for sec layer, addr variable stores sec handle*/ /* we need to pass this handle and offset to cmdq driver */ /* cmdq sec driver will help to convert handle to correct address */ cmdqRecWriteSecure(handle, disp_addr_convert(idx*DISP_RDMA_INDEX_OFFSET+DISP_REG_RDMA_MEM_START_ADDR), CMDQ_SAM_H_2_MVA, address, 0, size, m4u_port); //DISP_REG_SET(handle,idx*DISP_RDMA_INDEX_OFFSET+DISP_REG_RDMA_MEM_START_ADDR, address-0xbc000000+0x8c00000); } DISP_REG_SET(handle,idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_MEM_SRC_PITCH, pitch); //DISP_REG_SET(handle,idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_INT_ENABLE, 0x3F); DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_OUTPUT_FRAME_WIDTH, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_SIZE_CON_0, width); DISP_REG_SET_FIELD(handle,SIZE_CON_1_FLD_OUTPUT_FRAME_HEIGHT, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_SIZE_CON_1, height); rdma_set_ultra(idx, width, height, bpp, rdma_fps[idx], handle); #if 1 if(0) //UFOE bypassed, enable RDMA underflow intr, else disable RDMA underflow intr { DISP_REG_SET_FIELD(handle,FIFO_CON_FLD_FIFO_UNDERFLOW_EN, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_FIFO_CON, 1); DISP_REG_SET_FIELD(handle,FIFO_CON_FLD_OUTPUT_VALID_FIFO_THRESHOLD, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_FIFO_CON, gRDMAFIFOLen); } else { DISP_REG_SET_FIELD(handle,FIFO_CON_FLD_FIFO_UNDERFLOW_EN, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_FIFO_CON, 1); DISP_REG_SET_FIELD(handle,FIFO_CON_FLD_OUTPUT_VALID_FIFO_THRESHOLD, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_FIFO_CON, width*3*3/16/2); //FHD:304, HD:203, QHD:151 } #endif return 0; }
void rdma_set_ultra(unsigned int idx, unsigned int width, unsigned int height, unsigned int bpp, unsigned int frame_rate,void * handle) { // constant static const unsigned int blank_overhead = 115; //it is 1.15, need to divide 100 later static const unsigned int rdma_fifo_width = 16; //in unit of byte static const unsigned int ultra_low_time = 6; //in unit of us static const unsigned int pre_ultra_low_time = 8; //in unit of us static const unsigned int pre_ultra_high_time = 9; //in unit of us static const unsigned int fifo_size = 512; static const unsigned int fifo_valid_line_ratio = 125; //valid size 1/8 line; static const unsigned int fifo_min_size = 32; // working variables unsigned int consume_levels_per_sec; unsigned int ultra_low_level; unsigned int pre_ultra_low_level; unsigned int pre_ultra_high_level; unsigned int ultra_high_ofs; unsigned int pre_ultra_low_ofs; unsigned int pre_ultra_high_ofs; unsigned int fifo_valid_size = 16; /* compute fifo valid size */ fifo_valid_size = (width * bpp * fifo_valid_line_ratio) / (rdma_fifo_width * 1000); fifo_valid_size = fifo_valid_size > fifo_min_size ? fifo_valid_size : fifo_min_size; //consume_levels_per_sec = ((long long unsigned int)width*height*frame_rate*blank_overhead*bpp)/rdma_fifo_width/100; //change calculation order to prevent overflow of unsigned int consume_levels_per_sec = (width*height*frame_rate*bpp/rdma_fifo_width/100)*blank_overhead; // /1000000 for ultra_low_time in unit of us ultra_low_level = (unsigned int)(ultra_low_time * consume_levels_per_sec / 1000000 ); pre_ultra_low_level = (unsigned int)(pre_ultra_low_time * consume_levels_per_sec / 1000000 ); pre_ultra_high_level = (unsigned int)(pre_ultra_high_time * consume_levels_per_sec / 1000000 ); pre_ultra_low_ofs = pre_ultra_low_level - ultra_low_level; ultra_high_ofs = 1; pre_ultra_high_ofs = pre_ultra_high_level - pre_ultra_low_level ; if(gUltraEnable==1) { ultra_low_level = 0x6b; pre_ultra_low_ofs = 0xa0; ultra_high_ofs = 1; pre_ultra_high_ofs = 1; } //write ultra_low_level, ultra_high_ofs, pre_ultra_low_ofs, pre_ultra_high_ofs into register DISP_RDMA_MEM_GMC_SETTING_0 DISP_REG_SET(handle,idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_MEM_GMC_SETTING_0, ultra_low_level|(pre_ultra_low_ofs<<8)|(ultra_high_ofs<<16)|(pre_ultra_high_ofs<<24)); // set rdma ultra/pre-ultra according to resolution #if 0 if(idx==0) { if(width>=1080) { DISP_REG_SET(handle,idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_MEM_GMC_SETTING_0, 0x1b01356b); } else if(width>=720) { DISP_REG_SET(handle,idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_MEM_GMC_SETTING_0, 0x0b011730); } else { DISP_REG_SET(handle,idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_MEM_GMC_SETTING_0, 0x08010f20); } } else { if(width>=1080) { DISP_REG_SET(handle,idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_MEM_GMC_SETTING_0, 0x0e011b38); } else if(width>=720) { DISP_REG_SET(handle,idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_MEM_GMC_SETTING_0, 0x0e011b38); } } #else DISP_REG_SET(handle,idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_MEM_GMC_SETTING_0, gRDMAUltraSetting); #endif DISP_REG_SET_FIELD(handle,FIFO_CON_FLD_OUTPUT_VALID_FIFO_THRESHOLD, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_FIFO_CON, fifo_valid_size); DDPDBG("FIFO_VALID_Size = 0x%03x = %d\n", fifo_valid_size , fifo_valid_size ); DDPDBG("ultra_low_level = 0x%03x = %d\n", ultra_low_level , ultra_low_level ); DDPDBG("pre_ultra_low_level = 0x%03x = %d\n", pre_ultra_low_level , pre_ultra_low_level ); DDPDBG("pre_ultra_high_level = 0x%03x = %d\n", pre_ultra_high_level, pre_ultra_high_level); DDPDBG("ultra_high_ofs = 0x%03x = %d\n", ultra_high_ofs , ultra_high_ofs ); DDPDBG("pre_ultra_low_ofs = 0x%03x = %d\n", pre_ultra_low_ofs , pre_ultra_low_ofs ); DDPDBG("pre_ultra_high_ofs = 0x%03x = %d\n", pre_ultra_high_ofs , pre_ultra_high_ofs ); }
// fixme: spec has no RDMA format, fix enum definition here int rdma_config(DISP_MODULE_ENUM module, enum RDMA_MODE mode, unsigned long address, DpColorFormat inFormat, unsigned pitch, unsigned width, unsigned height, unsigned ufoe_enable, void * handle) // ourput setting { unsigned int output_is_yuv = 0; enum RDMA_INPUT_FORMAT inputFormat = rdma_input_format_convert(inFormat); unsigned int bpp = rdma_input_format_bpp(inputFormat); unsigned int input_is_yuv = rdma_input_format_color_space(inputFormat); unsigned int input_swap = rdma_input_format_byte_swap(inputFormat); unsigned int input_format_reg = rdma_input_format_reg_value(inputFormat); unsigned int color_matrix = 0x4; //0100 MTX_JPEG_TO_RGB (YUV FUll TO RGB) unsigned int idx = rdma_index(module); DDPDBG("RDMAConfig idx %d, mode %d, address 0x%x, inputformat %s, pitch %u, width %u, height %u\n", idx, mode, address, rdma_intput_format_name(inputFormat,input_swap), pitch,width, height); ASSERT(idx <= 2); if((width > RDMA_MAX_WIDTH) || (height > RDMA_MAX_HEIGHT)) { DDPERR("RDMA input overflow, w=%d, h=%d, max_w=%d, max_h=%d\n", width, height, RDMA_MAX_WIDTH, RDMA_MAX_HEIGHT); } if(input_is_yuv==1 && output_is_yuv==0) { DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_ENABLE, idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 1); DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_INT_MTX_SEL, idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, color_matrix); } else if(input_is_yuv==0 && output_is_yuv==1) { color_matrix = 0x2; //0x0010, RGB_TO_BT601 DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_ENABLE, idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 1); DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_INT_MTX_SEL, idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, color_matrix); } else { DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_ENABLE, idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 0); DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_MATRIX_INT_MTX_SEL, idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 0); } DISP_REG_SET_FIELD(handle,GLOBAL_CON_FLD_MODE_SEL, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_GLOBAL_CON, mode); // FORMAT & SWAP only works when RDMA memory mode, set both to 0 when RDMA direct link mode. DISP_REG_SET_FIELD(handle,MEM_CON_FLD_MEM_MODE_INPUT_FORMAT, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_MEM_CON, ((mode == RDMA_MODE_DIRECT_LINK) ? 0 : input_format_reg&0xf)); DISP_REG_SET_FIELD(handle,MEM_CON_FLD_MEM_MODE_INPUT_SWAP, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_MEM_CON, ((mode == RDMA_MODE_DIRECT_LINK) ? 0 : input_swap)); DISP_REG_SET(handle,idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_MEM_START_ADDR, address); DISP_REG_SET(handle,idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_MEM_SRC_PITCH, pitch); DISP_REG_SET(handle,idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_INT_ENABLE, 0x3F); DISP_REG_SET_FIELD(handle,SIZE_CON_0_FLD_OUTPUT_FRAME_WIDTH, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_SIZE_CON_0, width); DISP_REG_SET_FIELD(handle,SIZE_CON_1_FLD_OUTPUT_FRAME_HEIGHT, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_SIZE_CON_1, height); rdma_set_ultra(idx, width, height, bpp, rdma_fps[idx], handle); #if 1 if(ufoe_enable==0) //UFOE bypassed, enable RDMA underflow intr, else disable RDMA underflow intr { DISP_REG_SET_FIELD(handle,FIFO_CON_FLD_FIFO_UNDERFLOW_EN, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_FIFO_CON, 1); DISP_REG_SET_FIELD(handle,FIFO_CON_FLD_OUTPUT_VALID_FIFO_THRESHOLD, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_FIFO_CON, 16); } else { DISP_REG_SET_FIELD(handle,FIFO_CON_FLD_FIFO_UNDERFLOW_EN, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_FIFO_CON, 1); DISP_REG_SET_FIELD(handle,FIFO_CON_FLD_OUTPUT_VALID_FIFO_THRESHOLD, idx*DISP_RDMA_INDEX_OFFSET+ DISP_REG_RDMA_FIFO_CON, width*3*3/16/2); //FHD:304, HD:203, QHD:151 } #endif return 0; }
int ddp_mutex_disenable(int mutex_id,DDP_SCENARIO_ENUM scenario,void * handle) { DDPDBG("mutex %d disable\n", mutex_id); DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_EN(mutex_id),0); return 0; }
static int ddp_mutex_enable_l(int mutex_idx,void * handle) { DDPDBG("mutex %d enable\n", mutex_idx); DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_EN(mutex_idx),1); return 0; }