void DSI_PHY_TIMCONFIG(LCM_PARAMS *lcm_params) { DSI_PHY_TIMCON0_REG timcon0; DSI_PHY_TIMCON1_REG timcon1; DSI_PHY_TIMCON2_REG timcon2; DSI_PHY_TIMCON3_REG timcon3; unsigned int div1 = lcm_params->dsi.pll_div1; unsigned int div2 = lcm_params->dsi.pll_div2; unsigned int lane_no = lcm_params->dsi.LANE_NUM; unsigned int div2_real=div2 ? div2*0x02 : 0x1; unsigned int cycle_time = (8 * 1000 * div2_real)/ (26 * (div1+0x01)); unsigned int ui = (1000 * div2_real)/ (26 * (div1+0x01)) + 1; unsigned int hs_trail_m, hs_trail_n; printk("[DISP] - uboot - DSI_PHY_TIMCONFIG, Cycle Time = %d(ns), Unit Interval = %d(ns). div1 = %d, div2 = %d, lane# = %d \n", cycle_time, ui, div1, div2, lane_no); #define NS_TO_CYCLE(n, c) ((n) / c + (( (n) % c) ? 1 : 0)) hs_trail_m=lane_no; hs_trail_n= (lcm_params->dsi.HS_TRAIL == 0) ? NS_TO_CYCLE(((lane_no * 4 * ui) + 60), cycle_time) : lcm_params->dsi.HS_TRAIL; // +3 is recommended from designer becauase of HW latency timcon0.HS_TRAIL = ((hs_trail_m > hs_trail_n) ? hs_trail_m : hs_trail_n) + 3; timcon0.HS_ZERO = (lcm_params->dsi.HS_ZERO == 0) ? NS_TO_CYCLE((105 + 6 * ui), cycle_time) : lcm_params->dsi.HS_ZERO; timcon0.HS_PRPR = (lcm_params->dsi.HS_PRPR == 0) ? NS_TO_CYCLE((40 + 4 * ui), cycle_time) : lcm_params->dsi.HS_PRPR; // HS_PRPR can't be 1. if (timcon0.HS_PRPR < 2) timcon0.HS_PRPR = 2; timcon0.LPX = (lcm_params->dsi.LPX == 0) ? NS_TO_CYCLE((50+75)/2, cycle_time) : lcm_params->dsi.LPX; timcon1.TA_SACK = (lcm_params->dsi.TA_SACK == 0) ? 1 : lcm_params->dsi.TA_SACK; timcon1.TA_GET = (lcm_params->dsi.TA_GET == 0) ? (5 * timcon0.LPX) : lcm_params->dsi.TA_GET; timcon1.TA_SURE = (lcm_params->dsi.TA_SURE == 0) ? (3 * timcon0.LPX / 2) : lcm_params->dsi.TA_SURE; timcon1.TA_GO = (lcm_params->dsi.TA_GO == 0) ? (4 * timcon0.LPX) : lcm_params->dsi.TA_GO; timcon2.CLK_TRAIL = (lcm_params->dsi.CLK_TRAIL == 0) ? NS_TO_CYCLE(60, cycle_time) : lcm_params->dsi.CLK_TRAIL; // CLK_TRAIL can't be 1. if (timcon2.CLK_TRAIL < 2) timcon2.CLK_TRAIL = 2; timcon2.CLK_ZERO = (lcm_params->dsi.CLK_ZERO == 0) ? NS_TO_CYCLE((300 - 38), cycle_time) : lcm_params->dsi.CLK_ZERO; timcon2.LPX_WAIT = (lcm_params->dsi.LPX_WAIT == 0) ? 1 : lcm_params->dsi.LPX_WAIT; timcon2.CONT_DET = lcm_params->dsi.CONT_DET; timcon3.CLK_HS_PRPR = (lcm_params->dsi.CLK_HS_PRPR == 0) ? NS_TO_CYCLE((38 + 95) / 2, cycle_time) : lcm_params->dsi.CLK_HS_PRPR; printk("[DISP] - uboot - DSI_PHY_TIMCONFIG, HS_TRAIL = %d, HS_ZERO = %d, HS_PRPR = %d, LPX = %d, TA_SACK = %d, TA_GET = %d, TA_SURE = %d, TA_GO = %d, CLK_TRAIL = %d, CLK_ZERO = %d, CLK_HS_PRPR = %d \n", \ timcon0.HS_TRAIL, timcon0.HS_ZERO, timcon0.HS_PRPR, timcon0.LPX, timcon1.TA_SACK, timcon1.TA_GET, timcon1.TA_SURE, timcon1.TA_GO, timcon2.CLK_TRAIL, timcon2.CLK_ZERO, timcon3.CLK_HS_PRPR); DSI_REG->DSI_PHY_TIMECON0=timcon0; DSI_REG->DSI_PHY_TIMECON1=timcon1; DSI_REG->DSI_PHY_TIMECON2=timcon2; DSI_REG->DSI_PHY_TIMECON3=timcon3; }
static void lcm_get_params(LCM_PARAMS *params) { unsigned int div2_real=0; unsigned int cycle_time = 0; unsigned int ui = 0; unsigned int hs_trail_m, hs_trail_n; #define NS_TO_CYCLE(n, c) ((n) / c + (( (n) % c) ? 1 : 0)) memset(params, 0, sizeof(LCM_PARAMS)); params->type = LCM_TYPE_DSI; params->width = FRAME_WIDTH; params->height = FRAME_HEIGHT; // enable tearing-free // params->dbi.te_mode = LCM_DBI_TE_MODE_VSYNC_ONLY; // params->dbi.te_edge_polarity = LCM_POLARITY_RISING; params->dsi.mode = CMD_MODE; // DSI /* Command mode setting */ params->dsi.LANE_NUM = LCM_TWO_LANE; //The following defined the fomat for data coming from LCD engine. params->dsi.data_format.color_order = LCM_COLOR_ORDER_RGB; params->dsi.data_format.trans_seq = LCM_DSI_TRANS_SEQ_MSB_FIRST; params->dsi.data_format.padding = LCM_DSI_PADDING_ON_LSB; params->dsi.data_format.format = LCM_DSI_FORMAT_RGB888; // Highly depends on LCD driver capability. params->dsi.packet_size=256; // Video mode setting params->dsi.PS=LCM_PACKED_PS_24BIT_RGB888; params->dsi.word_count=480*3; params->dsi.vertical_sync_active=2; params->dsi.vertical_backporch=2; params->dsi.vertical_frontporch=2; params->dsi.vertical_active_line=800; params->dsi.line_byte=2180; // 2256 = 752*3 params->dsi.horizontal_sync_active_byte=26; params->dsi.horizontal_backporch_byte=206; params->dsi.horizontal_frontporch_byte=206; params->dsi.rgb_byte=(480*3+6); params->dsi.horizontal_sync_active_word_count=20; params->dsi.horizontal_backporch_word_count=200; params->dsi.horizontal_frontporch_word_count=200; // Bit rate calculation params->dsi.pll_div1=38; // fref=26MHz, fvco=fref*(div1+1) (div1=0~63, fvco=500MHZ~1GHz) params->dsi.pll_div2=1; // div2=0~15: fout=fvo/(2*div2) div2_real=params->dsi.pll_div2 ? params->dsi.pll_div2*0x02 : 0x1; cycle_time = (8 * 1000 * div2_real)/ (26 * (params->dsi.pll_div1+0x01)); ui = (1000 * div2_real)/ (26 * (params->dsi.pll_div1+0x01)) + 1; hs_trail_m=params->dsi.LANE_NUM; hs_trail_n=NS_TO_CYCLE(((params->dsi.LANE_NUM * 4 * ui) + 60), cycle_time); // params->dsi.HS_TRAIL = ((hs_trail_m > hs_trail_n) ? hs_trail_m : hs_trail_n) + 3;//min max(n*8*UI, 60ns+n*4UI) params->dsi.HS_TRAIL = 20; params->dsi.HS_ZERO = NS_TO_CYCLE((115 + 6 * ui), cycle_time);//min 105ns+6*UI params->dsi.HS_PRPR = NS_TO_CYCLE((50 + 4 * ui), cycle_time);//min 40ns+4*UI; max 85ns+6UI // HS_PRPR can't be 1. if (params->dsi.HS_PRPR < 2) params->dsi.HS_PRPR = 2; params->dsi.LPX = NS_TO_CYCLE(200, cycle_time);//min 50ns params->dsi.TA_SACK = 1; params->dsi.TA_GET = 5 * params->dsi.LPX;//5*LPX params->dsi.TA_SURE = 3 * params->dsi.LPX / 2;//min LPX; max 2*LPX; params->dsi.TA_GO = 4 * params->dsi.LPX;//4*LPX params->dsi.CLK_TRAIL = NS_TO_CYCLE(70, cycle_time);//min 60ns // CLK_TRAIL can't be 1. if (params->dsi.CLK_TRAIL < 2) params->dsi.CLK_TRAIL = 2; params->dsi.CLK_ZERO = NS_TO_CYCLE((300), cycle_time);//min 300ns-38ns params->dsi.LPX_WAIT = 1; params->dsi.CONT_DET = 0; params->dsi.CLK_HS_PRPR = NS_TO_CYCLE((38 + 95) / 2, cycle_time);//min 38ns; max 95ns }