/*++ * common/wmt_display/uboot-vpp.c * WonderMedia video post processor (VPP) driver * * Copyright c 2014 WonderMedia Technologies, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * WonderMedia Technologies, Inc. * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C --*/ #include #include #include #include #include #include #include #include #include #define DEBUG #include "vpp.h" #include "vout.h" #include "minivgui.h" #define WMT_DISPLAY #include "../../board/wmt/include/wmt_clk.h" #include "hw_devices.h" #include "wmt_display.h" #include "vout.h" struct wmt_display_param_t g_display_param; struct wmt_display_param_t g_display_param2; struct wmt_pwm_setting_t g_pwm_setting; struct gpio_operation_t g_lcd_pw_pin; #ifdef CONFIG_VPP_SHENZHEN struct wmt_backlight_param_t g_backlight_param; #endif int g_display_vaild; unsigned int g_fb_phy; unsigned int g_img_phy; int g_logo_x; int g_logo_y; logo_scale_t g_logo_scale = LOGO_NOT_SCALE; char *video_str[] = { "SDA", "SDD" , "LCD", "DVI" , "HDMI", "DVO2HDMI", "LVDS", "VGA" }; extern int vo_dvi_initial(void); extern int vo_hdmi_initial(void); extern int vo_lvds_initial(void); extern int vo_virtual_initial(void); extern int vt1632_module_init(void); extern int sil902x_module_init(void); extern void vpp_init(void); extern struct vout_dev_t *lcd_get_dev(void); extern void vpp_config(struct vout_info_t *info); static unsigned int alignmentMemory(unsigned int memtotal) { unsigned int memmax = 2; while (memtotal > memmax) { memmax *= 2; } return memmax; } static unsigned int wmt_get_fb(unsigned int memtotal, unsigned int mbsize) { unsigned int addr; addr = alignmentMemory(memtotal); addr <<= 20; addr -= 1920 * 1200 * 4; /* avoid kernel change resolution */ addr -= 1280; /* avoid govr prefetch 1280 byte over memory boundary */ return addr; } static int wmt_init_check(void) { char *tmp; check_tf_boot(); check_display_direction(); //added by howayhuo g_fb_phy = 0; if ((tmp = getenv (ENV_DIRECTFB)) != NULL) g_fb_phy = (unsigned int)simple_strtoul(tmp, NULL, 16); if (g_fb_phy == 0) { unsigned int memtotal; unsigned int mbsize; /* we must check "memtotal" because we get framebuf from it */ if ((tmp = getenv (ENV_MEMTOTAL)) != NULL) { memtotal = (unsigned int)simple_strtoul(tmp, NULL, 10); } else { printf("err:need %s to cal fb addr\n", ENV_MEMTOTAL); return -1; } if ((tmp = getenv ("mbsize")) != NULL) { mbsize = (unsigned int)simple_strtoul (tmp, NULL, 10); } else { printf("err:need %s to cal fb addr\n", "mbsize"); return -1; } g_fb_phy = wmt_get_fb(memtotal, mbsize); } if ((tmp = getenv (ENV_IMGADDR)) != NULL) g_img_phy = (unsigned int)simple_strtoul (tmp, NULL, 16); else { printf("%s is not found,(display show) invaild\n", ENV_IMGADDR); g_img_phy = 0xFFFF; } return 0; } #if 0 int uboot_vpp_alloc_framebuffer(unsigned int resx, unsigned int resy) { return 0; } #endif void vpp_mod_init(void) { #ifdef WMT_FTBLK_GOVRH govrh_mod_init(); #endif #ifdef WMT_FTBLK_SCL scl_mod_init(); #endif /* register vout interface */ vo_dvi_initial(); vo_hdmi_initial(); vo_lvds_initial(); } void vpp_device_init(void) { auto_pll_divisor(DEV_PWM,CLK_ENABLE, 0, 0); lcd_module_init(); lcd_oem_init(); lcd_lw700at9003_init(); lcd_at070tn83_init(); lcd_a080sn01_init(); lcd_ek08009_init(); lcd_HSD101PFW2_init(); lcd_LVDS_1024x600_init(); vt1632_module_init(); vt1625_module_init(); sil902x_module_init(); } int wmt_graphic_init(void) { struct vout_info_t *info; int i; int y_bpp, c_bpp; struct vout_t *vo; if (wmt_init_check()) return -1; vpp_mod_init(); vpp_device_init(); vpp_init(); for (i = 0; i < VPP_VOUT_INFO_NUM; i++) { struct fb_videomode vmode; vdo_framebuf_t *fb; unsigned int pixel_size, line_size; mv_surface s; info = vout_info[i]; if (!info) break; memset(&vmode, 0, sizeof(struct fb_videomode)); vmode.xres = info->resx; vmode.yres = info->resy; vmode.refresh = info->fps; vmode.vmode = (info->option & VPP_OPT_INTERLACE) ? FB_VMODE_INTERLACED : 0; vout_find_match_mode(i, &vmode, 1); #if 0 printf("fb %d\n", i); vpp_show_videomode("uboot", &vmode); #endif info->resx = vmode.xres; info->resy = vmode.yres; /* get framebuffer parameter */ fb = &info->fb; fb->col_fmt = g_vpp.mb_colfmt; fb->img_w = info->resx; fb->img_h = info->resy; fb->fb_w = vpp_calc_fb_width(fb->col_fmt, info->resx); fb->fb_h = info->resy; info->resx_virtual = fb->fb_w; info->resy_virtual = fb->fb_h; vpp_get_colfmt_bpp(fb->col_fmt, &y_bpp, &c_bpp); pixel_size = y_bpp / 8; line_size = fb->fb_w * pixel_size; g_fb_phy -= (fb->fb_h * line_size); fb->y_addr = g_fb_phy; fb->c_addr = 0; /* init surface */ s.width = fb->img_w; s.height = fb->img_h; s.startAddr = (char *) fb->y_addr; s.bits_per_pixel = pixel_size * 8; s.lineBytes = line_size; mv_initSurface(i,&s); /* clear frame buffer */ memset((void *)fb->y_addr, 0, fb->fb_h * line_size); vout_config(info, &vmode, &info->fb); #if 0 DBG_MSG("[UBOOT] fb%d(%dx%d)\n", i, vmode.xres, vmode.yres); vpp_show_framebuf("uboot", fb); #endif } /* enable vout */ for (i = 0; i < VPP_VOUT_NUM; i++) { int blank; vo = vout_get_entry(i); if (!vo) continue; blank = (vo->status & VPP_VOUT_STS_ACTIVE) ? VOUT_BLANK_UNBLANK : VOUT_BLANK_POWERDOWN; blank = (vo->status & VPP_VOUT_STS_BLANK) ? VOUT_BLANK_NORMAL : blank; vout_set_blank(i, blank); } /* set pwm for LCD backlight */ g_display_param.vout = VPP_VOUT_DVI; if ( lcd_get_dev() || (lcd_get_lvds_id() != LCD_PANEL_MAX)) g_display_param.vout = VPP_VOUT_LCD; if (g_display_param.vout == VPP_VOUT_LCD) { parse_pwm_params(ENV_DISPLAY_PWM, NULL); parse_gpio_operation(ENV_LCD_POWER); if ((g_display_vaild&PWMDEFMASK) == PWMDEFTP) lcd_blt_set_pwm(g_pwm_setting.pwm_no, g_pwm_setting.duty, g_pwm_setting.period); else { /* fan : may need to check PWM power .. */ pwm_set_period(g_pwm_setting.pwm_no, g_pwm_setting.period - 1); pwm_set_duty(g_pwm_setting.pwm_no, g_pwm_setting.duty - 1); pwm_set_control(g_pwm_setting.pwm_no, (g_pwm_setting.duty - 1) ? 0x34 : 0x8); pwm_set_gpio(g_pwm_setting.pwm_no, g_pwm_setting.duty - 1); pwm_set_scalar(g_pwm_setting.pwm_no, g_pwm_setting.scalar - 1); } lcd_set_enable(1); } #if 0 p_govrh->dump_reg(); p_govrh2->dump_reg(); // hdmi_reg_dump(); // lvds_reg_dump(); #endif g_display_vaild |= DISPLAY_ENABLE; return 0; } #undef WMT_DISPLAY