static ssize_t disp_colorbar_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int err; unsigned long val; err = strict_strtoul(buf, 10, &val); if (err) { printk("Invalid size\n"); return err; } if((val>7)) { printk("Invalid value, 0~7 is expected!\n"); } else { fb_draw_colorbar((__u32)g_fbi.fbinfo[val]->screen_base, g_fbi.fbinfo[val]->var.xres, g_fbi.fbinfo[val]->var.yres, &(g_fbi.fbinfo[val]->var));; } return count; }
__s32 Fb_Init() { __disp_fb_create_para_t fb_para; __s32 i; __bool need_open_hdmi = 0; __u32 num_screens; num_screens = bsp_disp_feat_get_num_screens(); pr_info("[DISP]==Fb_Init==\n"); INIT_WORK(&g_fbi.vsync_work[0], send_vsync_work_0); INIT_WORK(&g_fbi.vsync_work[1], send_vsync_work_1); INIT_WORK(&g_fbi.post2_cb_work, post2_cb); mutex_init(&g_fbi.runtime_lock); for(i=0; i<8; i++) { g_fbi.fbinfo[i] = framebuffer_alloc(0, g_fbi.dev); g_fbi.fbinfo[i]->fbops = &dispfb_ops; g_fbi.fbinfo[i]->flags = 0; g_fbi.fbinfo[i]->device = g_fbi.dev; g_fbi.fbinfo[i]->par = &g_fbi; g_fbi.fbinfo[i]->var.xoffset = 0; g_fbi.fbinfo[i]->var.yoffset = 0; g_fbi.fbinfo[i]->var.xres = 800; g_fbi.fbinfo[i]->var.yres = 480; g_fbi.fbinfo[i]->var.xres_virtual = 800; g_fbi.fbinfo[i]->var.yres_virtual = 480*2; g_fbi.fbinfo[i]->var.nonstd = 0; g_fbi.fbinfo[i]->var.bits_per_pixel = 32; g_fbi.fbinfo[i]->var.transp.length = 8; g_fbi.fbinfo[i]->var.red.length = 8; g_fbi.fbinfo[i]->var.green.length = 8; g_fbi.fbinfo[i]->var.blue.length = 8; g_fbi.fbinfo[i]->var.transp.offset = 24; g_fbi.fbinfo[i]->var.red.offset = 16; g_fbi.fbinfo[i]->var.green.offset = 8; g_fbi.fbinfo[i]->var.blue.offset = 0; g_fbi.fbinfo[i]->var.activate = FB_ACTIVATE_FORCE; g_fbi.fbinfo[i]->fix.type = FB_TYPE_PACKED_PIXELS; g_fbi.fbinfo[i]->fix.type_aux = 0; g_fbi.fbinfo[i]->fix.visual = FB_VISUAL_TRUECOLOR; g_fbi.fbinfo[i]->fix.xpanstep = 1; g_fbi.fbinfo[i]->fix.ypanstep = 1; g_fbi.fbinfo[i]->fix.ywrapstep = 0; g_fbi.fbinfo[i]->fix.accel = FB_ACCEL_NONE; g_fbi.fbinfo[i]->fix.line_length = g_fbi.fbinfo[i]->var.xres_virtual * 4; g_fbi.fbinfo[i]->fix.smem_len = g_fbi.fbinfo[i]->fix.line_length * g_fbi.fbinfo[i]->var.yres_virtual * 2; g_fbi.fbinfo[i]->screen_base = 0x0; g_fbi.fbinfo[i]->fix.smem_start = 0x0; register_framebuffer(g_fbi.fbinfo[i]); } parser_disp_init_para(&(g_fbi.disp_init)); if(g_fbi.disp_init.b_init) { __u32 sel = 0; for(sel = 0; sel<num_screens; sel++) { if((sel==0) && (g_fbi.disp_init.disp_mode == DISP_INIT_MODE_SCREEN0)) { if(g_fbi.disp_init.output_type[sel] == DISP_OUTPUT_TYPE_HDMI) { need_open_hdmi = 1; } } } } if(g_fbi.disp_init.b_init) { __u32 fb_num = 0; fb_num = (g_fbi.disp_init.disp_mode==DISP_INIT_MODE_TWO_DIFF_SCREEN)?2:1; for(i = 0; i<fb_num; i++) { __u32 screen_id = i; disp_fb_to_var(g_fbi.disp_init.format[i], g_fbi.disp_init.seq[i], g_fbi.disp_init.br_swap[i], &(g_fbi.fbinfo[i]->var)); if(g_fbi.disp_init.disp_mode == DISP_INIT_MODE_SCREEN1) { screen_id = 1; } fb_para.buffer_num= g_fbi.disp_init.buffer_num[i]; if((g_fbi.disp_init.fb_width[i] == 0) || (g_fbi.disp_init.fb_height[i] == 0)) { fb_para.width = bsp_disp_get_screen_width_from_output_type(screen_id, g_fbi.disp_init.output_type[screen_id], g_fbi.disp_init.output_mode[screen_id]); fb_para.height = bsp_disp_get_screen_height_from_output_type(screen_id, g_fbi.disp_init.output_type[screen_id], g_fbi.disp_init.output_mode[screen_id]); } else { fb_para.width = g_fbi.disp_init.fb_width[i]; fb_para.height = g_fbi.disp_init.fb_height[i]; } fb_para.output_width = bsp_disp_get_screen_width_from_output_type(screen_id, g_fbi.disp_init.output_type[screen_id], g_fbi.disp_init.output_mode[screen_id]); fb_para.output_height = bsp_disp_get_screen_height_from_output_type(screen_id, g_fbi.disp_init.output_type[screen_id], g_fbi.disp_init.output_mode[screen_id]); fb_para.mode = (g_fbi.disp_init.scaler_mode[i]==0)?DISP_LAYER_WORK_MODE_NORMAL:DISP_LAYER_WORK_MODE_SCALER; if(g_fbi.disp_init.disp_mode == DISP_INIT_MODE_SCREEN0) { fb_para.fb_mode = FB_MODE_SCREEN0; } else if(g_fbi.disp_init.disp_mode == DISP_INIT_MODE_SCREEN1) { fb_para.fb_mode = FB_MODE_SCREEN1; } else if(g_fbi.disp_init.disp_mode == DISP_INIT_MODE_TWO_DIFF_SCREEN) { if(i == 0) { fb_para.fb_mode = FB_MODE_SCREEN0; } else { fb_para.fb_mode = FB_MODE_SCREEN1; } } else if(g_fbi.disp_init.disp_mode == DISP_INIT_MODE_TWO_SAME_SCREEN) { fb_para.fb_mode = FB_MODE_DUAL_SAME_SCREEN_TB; fb_para.height *= 2; fb_para.output_height *= 2; } else if(g_fbi.disp_init.disp_mode == DISP_INIT_MODE_TWO_DIFF_SCREEN_SAME_CONTENTS) { fb_para.fb_mode = FB_MODE_DUAL_DIFF_SCREEN_SAME_CONTENTS; fb_para.output_width = bsp_disp_get_screen_width_from_output_type(fb_para.primary_screen_id, g_fbi.disp_init.output_type[fb_para.primary_screen_id], g_fbi.disp_init.output_mode[fb_para.primary_screen_id]); fb_para.output_height = bsp_disp_get_screen_height_from_output_type(fb_para.primary_screen_id, g_fbi.disp_init.output_type[fb_para.primary_screen_id], g_fbi.disp_init.output_mode[fb_para.primary_screen_id]); fb_para.aux_output_width = bsp_disp_get_screen_width(1 - fb_para.primary_screen_id); fb_para.aux_output_height = bsp_disp_get_screen_width_from_output_type(1 - fb_para.primary_screen_id, g_fbi.disp_init.output_type[1 - fb_para.primary_screen_id], g_fbi.disp_init.output_mode[1 - fb_para.primary_screen_id]); } Display_Fb_Request(i, &fb_para); #if defined (CONFIG_FPGA_V4_PLATFORM) fb_draw_colorbar((__u32)g_fbi.fbinfo[i]->screen_base, fb_para.width, fb_para.height*fb_para.buffer_num, &(g_fbi.fbinfo[i]->var)); #endif } #if 0 if(g_fbi.disp_init.scaler_mode[0]) { bsp_disp_print_reg(0, DISP_MOD_FE0, 0); } if(g_fbi.disp_init.scaler_mode[1]) { bsp_disp_print_reg(0, DISP_MOD_FE1, 0); } if(g_fbi.disp_init.disp_mode != DISP_INIT_MODE_SCREEN1) { bsp_disp_print_reg(0, DISP_MOD_BE0, 0); bsp_disp_print_reg(0, DISP_MOD_LCD0, 0); if((g_fbi.disp_init.output_type[0] == DISP_OUTPUT_TYPE_TV) || (g_fbi.disp_init.output_type[0] == DISP_OUTPUT_TYPE_VGA)) { bsp_disp_print_reg(0, DISP_MOD_TVE0, 0); } } if(g_fbi.disp_init.disp_mode != DISP_INIT_MODE_SCREEN0) { bsp_disp_print_reg(0, DISP_MOD_BE1, 0); bsp_disp_print_reg(0, DISP_MOD_LCD1, 0); if((g_fbi.disp_init.output_type[1] == DISP_OUTPUT_TYPE_TV) || (g_fbi.disp_init.output_type[1] == DISP_OUTPUT_TYPE_VGA)) { bsp_disp_print_reg(0, DISP_MOD_TVE1, 0); } } bsp_disp_print_reg(0, DISP_MOD_CCMU, 0); bsp_disp_print_reg(0, DISP_MOD_PWM, 0); bsp_disp_print_reg(0, DISP_MOD_PIOC, 0); #endif } return 0; }
__s32 Fb_Init(__u32 from) { __s32 i; __bool need_open_hdmi = 0; __disp_fb_create_para_t fb_para = { .primary_screen_id = 0, }; __inf("Fb_Init:%d\n", from); if (from == 0) { /* call from lcd driver */ #ifdef CONFIG_FB_SUNXI_RESERVED_MEM __inf("fbmem: fb_start=%lu, fb_size=%lu\n", fb_start, fb_size); disp_create_heap((unsigned long)(__va(fb_start)), fb_size); #endif for (i = 0; i < SUNXI_MAX_FB; i++) { g_fbi.fbinfo[i] = framebuffer_alloc(0, g_fbi.dev); g_fbi.fbinfo[i]->fbops = &dispfb_ops; g_fbi.fbinfo[i]->flags = 0; g_fbi.fbinfo[i]->device = g_fbi.dev; g_fbi.fbinfo[i]->par = &g_fbi; g_fbi.fbinfo[i]->var.xoffset = 0; g_fbi.fbinfo[i]->var.yoffset = 0; g_fbi.fbinfo[i]->var.xres = 800; g_fbi.fbinfo[i]->var.yres = 480; g_fbi.fbinfo[i]->var.xres_virtual = 800; g_fbi.fbinfo[i]->var.yres_virtual = 480 * 2; g_fbi.fbinfo[i]->var.nonstd = 0; g_fbi.fbinfo[i]->var.grayscale = 0; g_fbi.fbinfo[i]->var.bits_per_pixel = 32; g_fbi.fbinfo[i]->var.transp.length = 8; g_fbi.fbinfo[i]->var.red.length = 8; g_fbi.fbinfo[i]->var.green.length = 8; g_fbi.fbinfo[i]->var.blue.length = 8; g_fbi.fbinfo[i]->var.transp.offset = 24; g_fbi.fbinfo[i]->var.red.offset = 16; g_fbi.fbinfo[i]->var.green.offset = 8; g_fbi.fbinfo[i]->var.blue.offset = 0; g_fbi.fbinfo[i]->var.activate = FB_ACTIVATE_FORCE; g_fbi.fbinfo[i]->fix.type = FB_TYPE_PACKED_PIXELS; g_fbi.fbinfo[i]->fix.type_aux = 0; g_fbi.fbinfo[i]->fix.visual = FB_VISUAL_TRUECOLOR; g_fbi.fbinfo[i]->fix.xpanstep = 1; g_fbi.fbinfo[i]->fix.ypanstep = 1; g_fbi.fbinfo[i]->fix.ywrapstep = 0; g_fbi.fbinfo[i]->fix.accel = FB_ACCEL_NONE; g_fbi.fbinfo[i]->fix.line_length = g_fbi.fbinfo[i]->var.xres_virtual * 4; g_fbi.fbinfo[i]->fix.smem_len = g_fbi.fbinfo[i]->fix.line_length * g_fbi.fbinfo[i]->var.yres_virtual * 2; g_fbi.fbinfo[i]->screen_base = NULL; g_fbi.fbinfo[i]->pseudo_palette = g_fbi.pseudo_palette[i]; g_fbi.fbinfo[i]->fix.smem_start = 0x0; g_fbi.fbinfo[i]->fix.mmio_start = 0; g_fbi.fbinfo[i]->fix.mmio_len = 0; if (fb_alloc_cmap(&g_fbi.fbinfo[i]->cmap, 256, 1) < 0) return -ENOMEM; } parser_disp_init_para(&(g_fbi.disp_init)); } if (g_fbi.disp_init.b_init) { __u32 sel = 0; for (sel = 0; sel < 2; sel++) { if (((sel == 0) && (g_fbi.disp_init.disp_mode != DISP_INIT_MODE_SCREEN1)) || ((sel == 1) && (g_fbi.disp_init.disp_mode != DISP_INIT_MODE_SCREEN0))) { if (g_fbi.disp_init.output_type[sel] == DISP_OUTPUT_TYPE_HDMI) need_open_hdmi = 1; } } } if (need_open_hdmi == 1 && from == 0) /* it is called from lcd driver, but hdmi need to be opened */ return 0; else if (need_open_hdmi == 0 && from == 1) /* it is called from hdmi driver, but hdmi need not be opened */ return 0; if (g_fbi.disp_init.b_init) { __u32 fb_num = 0, sel = 0; for (sel = 0; sel < 2; sel++) { if (((sel == 0) && (g_fbi.disp_init.disp_mode != DISP_INIT_MODE_SCREEN1)) || ((sel == 1) && (g_fbi.disp_init.disp_mode != DISP_INIT_MODE_SCREEN0))) { if (g_fbi.disp_init.output_type[sel] == DISP_OUTPUT_TYPE_LCD) { DRV_lcd_open(sel); } else if (g_fbi.disp_init.output_type[sel] == DISP_OUTPUT_TYPE_TV) { BSP_disp_tv_set_mode(sel, g_fbi.disp_init. tv_mode[sel]); BSP_disp_tv_open(sel); } else if (g_fbi.disp_init.output_type[sel] == DISP_OUTPUT_TYPE_HDMI) { BSP_disp_hdmi_set_mode(sel, g_fbi.disp_init. tv_mode[sel]); BSP_disp_hdmi_open(sel); } else if (g_fbi.disp_init.output_type[sel] == DISP_OUTPUT_TYPE_VGA) { BSP_disp_vga_set_mode(sel, g_fbi.disp_init. vga_mode[sel]); BSP_disp_vga_open(sel); } } } fb_num = (g_fbi.disp_init.disp_mode == DISP_INIT_MODE_TWO_DIFF_SCREEN) ? 2 : 1; for (i = 0; i < fb_num; i++) { __u32 screen_id = i; disp_fb_to_var(g_fbi.disp_init.format[i], g_fbi.disp_init.seq[i], g_fbi.disp_init.br_swap[i], &(g_fbi.fbinfo[i]->var)); if (g_fbi.disp_init.disp_mode == DISP_INIT_MODE_SCREEN1) screen_id = 1; fb_para.buffer_num = g_fbi.disp_init.buffer_num[i]; fb_para.width = BSP_disp_get_screen_width(screen_id); fb_para.height = BSP_disp_get_screen_height(screen_id); fb_para.output_width = BSP_disp_get_screen_width(screen_id); fb_para.output_height = BSP_disp_get_screen_height(screen_id); fb_para.mode = (g_fbi.disp_init.scaler_mode[i] == 0) ? DISP_LAYER_WORK_MODE_NORMAL : DISP_LAYER_WORK_MODE_SCALER; if (g_fbi.disp_init.disp_mode == DISP_INIT_MODE_SCREEN0) { fb_para.fb_mode = FB_MODE_SCREEN0; } else if (g_fbi.disp_init.disp_mode == DISP_INIT_MODE_SCREEN1) { fb_para.fb_mode = FB_MODE_SCREEN1; } else if (g_fbi.disp_init.disp_mode == DISP_INIT_MODE_TWO_DIFF_SCREEN) { if (i == 0) fb_para.fb_mode = FB_MODE_SCREEN0; else fb_para.fb_mode = FB_MODE_SCREEN1; } else if (g_fbi.disp_init.disp_mode == DISP_INIT_MODE_TWO_SAME_SCREEN) { fb_para.fb_mode = FB_MODE_DUAL_SAME_SCREEN_TB; fb_para.height *= 2; fb_para.output_height *= 2; } else if (g_fbi.disp_init.disp_mode == DISP_INIT_MODE_TWO_DIFF_SCREEN_SAME_CONTENTS) { fb_para.fb_mode = FB_MODE_DUAL_DIFF_SCREEN_SAME_CONTENTS; fb_para.output_width = BSP_disp_get_screen_width(fb_para. primary_screen_id); fb_para.output_height = BSP_disp_get_screen_height(fb_para. primary_screen_id); fb_para.aux_output_width = BSP_disp_get_screen_width(1 - fb_para. primary_screen_id); fb_para.aux_output_height = BSP_disp_get_screen_height(1 - fb_para. primary_screen_id); } Display_Fb_Request(i, &fb_para); #if 0 fb_draw_colorbar((__u32)g_fbi.fbinfo[i]->screen_base, fb_para.width, fb_para.height * fb_para.buffer_num, &(g_fbi.fbinfo[i]->var)); #endif } for (i = 0; i < SUNXI_MAX_FB; i++) /* Register framebuffers after they are initialized */ register_framebuffer(g_fbi.fbinfo[i]); if (g_fbi.disp_init.scaler_mode[0]) BSP_disp_print_reg(0, DISP_REG_SCALER0); if (g_fbi.disp_init.scaler_mode[1]) BSP_disp_print_reg(0, DISP_REG_SCALER1); if (g_fbi.disp_init.disp_mode != DISP_INIT_MODE_SCREEN1) { BSP_disp_print_reg(0, DISP_REG_IMAGE0); BSP_disp_print_reg(0, DISP_REG_LCDC0); if ((g_fbi.disp_init.output_type[0] == DISP_OUTPUT_TYPE_TV) || (g_fbi.disp_init.output_type[0] == DISP_OUTPUT_TYPE_VGA)) BSP_disp_print_reg(0, DISP_REG_TVEC0); } if (g_fbi.disp_init.disp_mode != DISP_INIT_MODE_SCREEN0) { BSP_disp_print_reg(0, DISP_REG_IMAGE1); BSP_disp_print_reg(0, DISP_REG_LCDC1); if ((g_fbi.disp_init.output_type[1] == DISP_OUTPUT_TYPE_TV) || (g_fbi.disp_init.output_type[1] == DISP_OUTPUT_TYPE_VGA)) BSP_disp_print_reg(0, DISP_REG_TVEC1); } BSP_disp_print_reg(0, DISP_REG_CCMU); BSP_disp_print_reg(0, DISP_REG_PWM); BSP_disp_print_reg(0, DISP_REG_PIOC); } __inf("Fb_Init: END\n"); return 0; } EXPORT_SYMBOL(Fb_Init); __s32 Fb_Exit(void) { __u8 fb_id = 0; for (fb_id = 0; fb_id < SUNXI_MAX_FB; fb_id++) { if (g_fbi.fbinfo[fb_id] == NULL) continue; Display_Fb_Release(fb_id); unregister_framebuffer(g_fbi.fbinfo[fb_id]); framebuffer_release(g_fbi.fbinfo[fb_id]); g_fbi.fbinfo[fb_id] = NULL; } return 0; }