void DSI_set_cmdq_V2(unsigned cmd, unsigned char count, unsigned char *para_list, unsigned char force_update) { UINT32 i, layer, layer_state, lane_num; UINT32 goto_addr, mask_para, set_para; UINT32 fbPhysAddr, fbVirAddr; DSI_T0_INS t0; DSI_T1_INS t1; DSI_T2_INS t2; _WaitForEngineNotBusy(); if (count > 59) { UINT32 pixel = count/3 + ((count%3) ? 1 : 0); LCD_REG_LAYER fb_layer_info; LCD_REG_DSI_DC dsi_info; // backup layer state. layer_state = AS_UINT32(&LCD_REG->WROI_CONTROL) & 0xFC000000; // backup FB layer info. memcpy((void *)&fb_layer_info, (void *)&LCD_REG->LAYER[FB_LAYER], sizeof(LCD_REG_LAYER)); // backup LCD-DSI I/F configuration. dsi_info = LCD_REG->DS_DSI_CON; // backup lane number. lane_num = DSI_REG->DSI_TXRX_CTRL.LANE_NUM; // HW limitation. // LP type-1 command can't go with 2 lanes. So we must switch to lane mode. DSI_REG->DSI_TXRX_CTRL.LANE_NUM = 1; DSI_PHY_REG->MIPITX_CON1.RG_DSI_CK_SEL = 0; // Modify LCD-DSI configuration LCD_REG->DS_DSI_CON.DC_DSI = TRUE; // Let LSB of RGB(BGR in buffer) first. LCD_REG->DS_DSI_CON.RGB_SWAP = LCD_DSI_IF_FMT_COLOR_ORDER_BGR; // Let parameters be in unit of byte. LCD_REG->DS_DSI_CON.CLR_FMT = LCD_DSI_IF_FORMAT_RGB888; // HW limitation // It makes package numbers > 1. LCD_REG->DS_DSI_CON.PACKET_SIZE = 30; // Start of Enable only one layer (FB layer) to push data to DSI LCD_CHECK_RET(LCD_LayerEnable(LCD_LAYER_ALL, FALSE)); LCD_CHECK_RET(LCD_LayerEnable(FB_LAYER, TRUE)); LCD_CHECK_RET(LCD_SetRoiWindow(0, 0, pixel, 1)); LCD_CHECK_RET(LCD_SetBackgroundColor(0)); // operates on FB layer { extern void disp_get_fb_address(UINT32 *fbVirAddr, UINT32 *fbPhysAddr); disp_get_fb_address(&fbVirAddr ,&fbPhysAddr); // copy parameters to FB layer buffer. memcpy((void *)fbVirAddr, (void *)para_list, count); LCD_REG->LAYER[FB_LAYER].ADDRESS = fbPhysAddr; } LCD_CHECK_RET(LCD_LayerSetFormat(FB_LAYER, LCD_LAYER_FORMAT_RGB888)); LCD_CHECK_RET(LCD_LayerSetPitch(FB_LAYER, pixel*3)); LCD_CHECK_RET(LCD_LayerSetOffset(FB_LAYER, 0, 0)); LCD_CHECK_RET(LCD_LayerSetSize(FB_LAYER, pixel, 1)); // End of Enable only one layer (FB layer) to push data to DSI t1.CONFG = 1; t1.Data_ID = DSI_DCS_LONG_PACKET_ID; t1.mem_start0 = (cmd&0xFF); t1.mem_start1 = (cmd>>8); OUTREG32(&DSI_CMDQ_REG->data0[0], AS_UINT32(&t1)); OUTREG32(&DSI_REG->DSI_CMDQ_SIZE, 1); DISP_LOG_PRINT(ANDROID_LOG_INFO, "DSI", "[DISP] - kernel - DSI_set_cmdq_V2. command(0x%x) parameter count = %d > 59, pixel = %d \n", cmd, count, pixel); DISP_LOG_PRINT(ANDROID_LOG_INFO, "DSI", "[DISP] - kernel - command queue only support 16 x 4 bytes. Header used 4 byte. DCS used 1 byte. If parameter > 59 byte, work around by Type-1 command. \n"); DISP_LOG_PRINT(ANDROID_LOG_INFO, "DSI", "para_list[%d] = {", count); for (i = 0; i < count; i++) DISP_LOG_PRINT(ANDROID_LOG_INFO, "DSI", "0x%02x, ", para_list[i]); DISP_LOG_PRINT(ANDROID_LOG_INFO, "DSI", "} \n"); LCD_M4U_On(0); if(force_update) { LCD_CHECK_RET(LCD_StartTransfer(FALSE)); DSI_EnableClk(); } _WaitForEngineNotBusy(); LCD_M4U_On(1); // restore FB layer info. memcpy((void *)&LCD_REG->LAYER[FB_LAYER], (void *)&fb_layer_info, sizeof(LCD_REG_LAYER)); // restore LCD-DSI I/F configuration. LCD_REG->DS_DSI_CON = dsi_info; // restore lane number. DSI_REG->DSI_TXRX_CTRL.LANE_NUM = lane_num; DSI_PHY_REG->MIPITX_CON1.RG_DSI_CK_SEL = (lane_num - 1); // restore layer state. for(layer=LCD_LAYER_0; layer<LCD_LAYER_NUM; layer++) { if(layer_state&(0x80000000>>layer)) LCD_CHECK_RET(LCD_LayerEnable(layer, TRUE)); else LCD_CHECK_RET(LCD_LayerEnable(layer, FALSE)); }
DISP_STATUS DISP_M4U_On(BOOL enable) { LCD_M4U_On(enable); return DISP_STATUS_OK; }