#include <asm/io.h>
#include <asm/div64.h>
#include <asm/uaccess.h>
+#include <asm/cacheflush.h>
#include "rk29_fb.h"
#include <linux/hdmi.h>
#endif
+
#include <mach/iomux.h>
#include <mach/gpio.h>
#include <mach/rk29_iomap.h>
#include <mach/pmu.h>
#include <mach/rk29-ipp.h>
+#include <mach/ddr.h>
#include "./display/screen/screen.h"
+#ifdef CONFIG_MFD_RK610
+#include "./display/lcd/rk610_lcd.h"
+#endif
#define ANDROID_USE_THREE_BUFS 0 //android use three buffers to accelerate UI display in rgb plane
#define CURSOR_BUF_SIZE 256 //RK2818 cursor need 256B buf
int rk29_cursor_buf[CURSOR_BUF_SIZE];
int mcu_usetimer;
int mcu_stopflush;
+ int setFlag;
/* external memery */
char __iomem *screen_base2;
__u32 smem_len2;
TRSP_MASK,
TRSP_INVAL
} TRSP_MODE;
-
+#ifdef FB_WIMO_FLAG
+struct wimo_fb_info{
+ unsigned long bitperpixel;
+ unsigned long mode;
+ unsigned long xaff;
+ unsigned long yaff;
+ unsigned long xpos;
+ unsigned long ypos;
+ unsigned long xsize;
+ unsigned long ysize;
+ unsigned long src_y;
+ unsigned long src_uv;
+ unsigned long dst_width;
+ unsigned long dst_height;
+ //struct mutex fb_lock;
+ volatile unsigned long fb_lock;
+
+
+};
+struct wimo_fb_info wimo_info;
+unsigned char* ui_buffer;
+unsigned char* ui_buffer_map;
+//unsigned char* overlay_buffer;
+//unsigned char* overlay_buffer_map;
+#endif
struct platform_device *g_pdev = NULL;
//static int win1fb_set_par(struct fb_info *info);
#else
#define CHK_SUSPEND(inf)
#endif
+static DECLARE_WAIT_QUEUE_HEAD(fb0_wait_queue);
+static volatile int idle_condition = 1; //1:idel, 0:busy
static DECLARE_WAIT_QUEUE_HEAD(wq);
static int wq_condition = 0;
static int wq_condition2 = 0;
+static int fb1_open_init = 0;
#if ANDROID_USE_THREE_BUFS
static int new_frame_seted = 1;
#endif
static bool has_set_rotate;
static u32 last_yuv_phy[2] = {0,0};
#endif
+int fb0_first_buff_bits = 32;
+int fb0_second_buff_bits = 32;
+int fb_compose_layer_count = 0;
+static BLOCKING_NOTIFIER_HEAD(rk29fb_notifier_list);
+int rk29fb_register_notifier(struct notifier_block *nb)
+{
+ int ret = 0;
+ if (g_pdev) {
+ struct rk29fb_inf *inf = platform_get_drvdata(g_pdev);
+ if (inf) {
+ if (inf->cur_screen && inf->cur_screen->type == SCREEN_HDMI)
+ nb->notifier_call(nb, RK29FB_EVENT_HDMI_ON, inf->cur_screen);
+ if (inf->fb1 && inf->fb1->par) {
+ struct win0_par *par = inf->fb1->par;
+ if (par->refcount)
+ nb->notifier_call(nb, RK29FB_EVENT_FB1_ON, inf->cur_screen);
+ }
+ }
+ }
+ ret = blocking_notifier_chain_register(&rk29fb_notifier_list, nb);
+
+ return ret;
+}
+
+int rk29fb_unregister_notifier(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_unregister(&rk29fb_notifier_list, nb);
+}
+
+static int rk29fb_notify(struct rk29fb_inf *inf, unsigned long event)
+{
+ return blocking_notifier_call_chain(&rk29fb_notifier_list, event, inf->cur_screen);
+}
+void rk29_lcd_set(bool on)
+{
+ struct rk29fb_info *mach_info = g_pdev->dev.platform_data;
+ if(on == 1 &&mach_info->io_enable)
+ mach_info->io_enable(); //open lcd out
+ else if(mach_info->io_disable)
+ mach_info->io_disable(); //close lcd out
+}
int mcu_do_refresh(struct rk29fb_inf *inf)
{
if(inf->mcu_stopflush) return 0;
if(initscreen == 0) //not init
{
clk_disable(inf->dclk);
- clk_disable(inf->aclk);
+ // clk_disable(inf->aclk);
}
- clk_disable(inf->aclk_ddr_lcdc);
- clk_disable(inf->aclk_disp_matrix);
- clk_disable(inf->hclk_cpu_display);
+ // clk_disable(inf->aclk_ddr_lcdc);
+ // clk_disable(inf->aclk_disp_matrix);
+ // clk_disable(inf->hclk_cpu_display);
- clk_disable(inf->clk);
- ret = clk_set_parent(inf->aclk, inf->aclk_parent);
+ // clk_disable(inf->clk);
+
fbprintk(">>>>>> set lcdc dclk need %d HZ, clk_parent = %d hz ret =%d\n ", screen->pixclock, screen->lcdc_aclk, ret);
{
printk(KERN_ERR ">>>>>> set lcdc dclk failed\n");
}
-
- if(screen->lcdc_aclk){
- aclk_rate = screen->lcdc_aclk;
- }
- ret = clk_set_rate(inf->aclk, aclk_rate);
- if(ret){
- printk(KERN_ERR ">>>>>> set lcdc aclk failed\n");
+ inf->fb0->var.pixclock = inf->fb1->var.pixclock = div_u64(1000000000000llu, clk_get_rate(inf->dclk));
+ if(initscreen)
+ {
+ ret = clk_set_parent(inf->aclk, inf->aclk_parent);
+ if(screen->lcdc_aclk){
+ aclk_rate = screen->lcdc_aclk;
+ }
+ ret = clk_set_rate(inf->aclk, aclk_rate);
+ if(ret){
+ printk(KERN_ERR ">>>>>> set lcdc aclk failed\n");
+ }
+ clk_enable(inf->aclk);
}
-
- clk_enable(inf->aclk_ddr_lcdc);
- clk_enable(inf->aclk_disp_matrix);
- clk_enable(inf->hclk_cpu_display);
-
- clk_enable(inf->aclk);
- clk_enable(inf->clk);
+ // clk_enable(inf->aclk_ddr_lcdc);
+ // clk_enable(inf->aclk_disp_matrix);
+ // clk_enable(inf->hclk_cpu_display);
+ // clk_enable(inf->clk);
clk_enable(inf->dclk);
// init screen panel
int rk29_set_cursor_img(struct rk29fb_inf *inf, char *data)
{
- if(data)
- {
- rk29_set_cursor_img_transform(data);
+ if(data)
+ {
+ rk29_set_cursor_img_transform(data);
}
- else
- {
- rk29_set_cursor_img_transform(cursor_img);
- }
- LcdWrReg(inf, HWC_MST, __pa(rk29_cursor_buf));
- LcdSetRegisterBit(inf, SYS_CONFIG,m_HWC_RELOAD_EN);
- LcdWrReg(inf, REG_CFG_DONE, 0x01);
+ else
+ {
+ rk29_set_cursor_img_transform(cursor_img);
+ }
+ LcdWrReg(inf, HWC_MST, __pa(rk29_cursor_buf));
+ //LcdSetBit(inf, SYS_CONFIG,m_HWC_RELOAD_EN);
+ LcdSetBit(inf, SYS_CONFIG, m_HWC_RELOAD_EN);
+ flush_cache_all();
+ LcdWrReg(inf, REG_CFG_DONE, 0x01);
return 0;
}
+
int rk29_set_cursor_test(struct fb_info *info)
{
struct rk29fb_inf *inf = dev_get_drvdata(info->device);
return 0;
}
#endif
-
+static int hdmi_get_fbscale(void)
+{
+#ifdef CONFIG_HDMI
+ return hdmi_get_scale();
+#else
+ return 100;
+#endif
+}
+static void hdmi_set_fbscale(struct fb_info *info)
+{
+#ifdef CONFIG_HDMI
+ struct rk29fb_inf *inf = dev_get_drvdata(info->device);
+ struct rk29fb_screen *screen = inf->cur_screen;
+ struct win0_par *par = info->par;
+ int scale;
+
+ scale = hdmi_get_scale();
+ if(scale == 100)
+ return;
+ par->xpos += screen->x_res * (100-scale) / 200;
+ par->ypos += screen->y_res * (100-scale) / 200;
+ par->xsize = par->xsize *scale /100;
+ par->ysize = par->ysize *scale /100;
+#endif
+}
static int win0_blank(int blank_mode, struct fb_info *info)
{
struct rk29fb_inf *inf = dev_get_drvdata(info->device);
{
case FB_BLANK_UNBLANK:
LcdMskReg(inf, SYS_CONFIG, m_W0_ENABLE, v_W0_ENABLE(1));
+ LcdWrReg(inf, REG_CFG_DONE, 0x01);
break;
+ case FB_BLANK_NORMAL:
+ LcdMskReg(inf, SYS_CONFIG, m_W0_ENABLE, v_W0_ENABLE(0));
+ break;
default:
LcdMskReg(inf, SYS_CONFIG, m_W0_ENABLE, v_W0_ENABLE(0));
+ LcdWrReg(inf, REG_CFG_DONE, 0x01);
+#ifdef CONFIG_DDR_RECONFIG
+ msleep(40);
+#endif
break;
}
- LcdWrReg(inf, REG_CFG_DONE, 0x01);
mcu_refresh(inf);
return 0;
struct fb_var_screeninfo *var = &info->var;
struct fb_fix_screeninfo *fix = &info->fix;
struct win0_par *par = info->par;
-
- u32 xact = var->xres; /* visible resolution */
- u32 yact = var->yres;
- u32 xvir = var->xres_virtual; /* virtual resolution */
- u32 yvir = var->yres_virtual;
+ u32 xact, yact, xvir, yvir, xpos, ypos, ScaleYrgbX,ScaleYrgbY, ScaleCbrX, ScaleCbrY, y_addr,uv_addr;
+ hdmi_set_fbscale(info);
+ xact = var->xres; /* visible resolution */
+ yact = var->yres;
+ xvir = var->xres_virtual; /* virtual resolution */
+ yvir = var->yres_virtual;
//u32 xact_st = var->xoffset; /* offset from virtual to visible */
//u32 yact_st = var->yoffset; /* resolution */
- u32 xpos = par->xpos;
- u32 ypos = par->ypos;
+ xpos = par->xpos;
+ ypos = par->ypos;
- u32 ScaleYrgbX=0x1000,ScaleYrgbY=0x1000;
- u32 ScaleCbrX=0x1000, ScaleCbrY=0x1000;
+ ScaleYrgbX=0x1000;
+ ScaleYrgbY=0x1000;
+ ScaleCbrX=0x1000;
+ ScaleCbrY=0x1000;
- u32 y_addr = 0; //user alloc buf addr y
- u32 uv_addr = 0;
+ y_addr = 0; //user alloc buf addr y
+ uv_addr = 0;
fbprintk(">>>>>> %s : %s\n", __FILE__, __FUNCTION__);
CHK_SUSPEND(inf);
- if(((var->rotate == 270)||(var->rotate == 90)) && (inf->video_mode))
+ if((var->rotate%360!=0)&& (inf->video_mode))
{
#ifdef CONFIG_FB_ROTATE_VIDEO
- // if(xact > screen->x_res)
+ if(xact > screen->x_res)
{
xact = screen->x_res; /* visible resolution */
yact = screen->y_res;
xvir = screen->x_res; /* virtual resolution */
yvir = screen->y_res;
- } // else {
- // xact = var->yres; /* visible resolution */
- // yact = var->xres;
- // xvir = var->yres_virtual; /* virtual resolution */
- // yvir = var->xres_virtual;
- // }
+ } else {
+ xact = var->xres; /* visible resolution */
+ yact = var->yres;
+ xvir = var->xres_virtual; /* virtual resolution */
+ yvir = var->yres_virtual;
+ printk("xact=%d yact =%d \n",xact,yact);
+ }
#else //CONFIG_FB_ROTATE_VIDEO
printk("LCDC not support rotate!\n");
return -EINVAL;
{
case FB_BLANK_UNBLANK:
LcdMskReg(inf, SYS_CONFIG, m_W1_ENABLE, v_W1_ENABLE(1));
+ LcdWrReg(inf, REG_CFG_DONE, 0x01);
break;
+ case FB_BLANK_NORMAL:
+ LcdMskReg(inf, SYS_CONFIG, m_W1_ENABLE, v_W1_ENABLE(0));
+ break;
default:
LcdMskReg(inf, SYS_CONFIG, m_W1_ENABLE, v_W1_ENABLE(0));
+ LcdWrReg(inf, REG_CFG_DONE, 0x01);
break;
}
- LcdWrReg(inf, REG_CFG_DONE, 0x01);
+
mcu_refresh(inf);
return 0;
}
+
+#ifdef CONFIG_CLOSE_WIN1_DYNAMIC
+static void win1_check_work_func(struct work_struct *work)
+{
+ struct rk29fb_inf *inf = platform_get_drvdata(g_pdev);
+ struct fb_info *fb0_inf = inf->fb0;
+ struct fb_var_screeninfo *var = &fb0_inf->var;
+ int i=0;
+ int *p = NULL;
+ int blank_data,total_data;
+ int format = 0;
+ u16 xres_virtual = fb0_inf->var.xres_virtual; //virtual screen size
+ u16 xpos_virtual = fb0_inf->var.xoffset; //visiable offset in virtual screen
+ u16 ypos_virtual = fb0_inf->var.yoffset;
+
+ int offset = 0;//(ypos_virtual*xres_virtual + xpos_virtual)*((inf->fb0_color_deepth || fb0_inf->var.bits_per_pixel==32)? 4:2)/4;
+ switch(var->bits_per_pixel)
+ {
+ case 16:
+ format = 1;
+ offset = (ypos_virtual*xres_virtual + xpos_virtual)*(inf->fb0_color_deepth ? 4:2);
+ if(ypos_virtual == 3*var->yres && inf->fb0_color_deepth)
+ offset -= var->yres * var->xres *2;
+ break;
+ default:
+ format = 0;
+ offset = (ypos_virtual*xres_virtual + xpos_virtual)*4;
+ if(ypos_virtual >= 2*var->yres)
+ {
+ format = 1;
+ if(ypos_virtual == 3*var->yres)
+ {
+ offset -= var->yres * var->xres *2;
+ }
+ }
+ break;
+ }
+ p = (u32)fb0_inf->screen_base + offset;
+ blank_data = (inf->fb0_color_deepth==32) ? 0xff000000 : 0;
+ total_data = fb0_inf->var.xres * fb0_inf->var.yres / (format+1);
+
+ // printk("var->bits_per_pixel=%d,ypos_virtual=%d, var->yres=%d,offset=%d,total_data=%d\n",var->bits_per_pixel,ypos_virtual,var->yres,offset,total_data);
+
+ for(i=0; i < total_data; i++)
+ {
+ if(*p++ != blank_data)
+ {
+ //printk("win1 have no 0 data in %d, total %d\n",i,total_data);
+ return;
+ }
+ }
+
+ win1_blank(FB_BLANK_POWERDOWN, fb0_inf);
+ // printk("%s close win1!\n",__func__);
+}
+static DECLARE_DELAYED_WORK(rk29_win1_check_work, win1_check_work_func);
+#endif
static int win1_set_par(struct fb_info *info)
{
struct rk29fb_inf *inf = dev_get_drvdata(info->device);
struct rk29fb_screen *screen = inf->cur_screen;
struct win0_par *par = info->par;
struct fb_var_screeninfo *var = &info->var;
-
+ u32 addr;
+ u16 xres_virtual,xpos,ypos;
+ u8 trspval,trspmode;
+ #ifdef CONFIG_CLOSE_WIN1_DYNAMIC
+ cancel_delayed_work_sync(&rk29_win1_check_work);
+ #endif
+ if(((screen->x_res != var->xres) || (screen->y_res != var->yres))
+ #ifndef CONFIG_FB_SCALING_OSD_1080P
+ && !((screen->x_res>1280) && (var->bits_per_pixel == 32))
+ #endif
+ )
+ {
+ hdmi_set_fbscale(info);
+ }
+ #ifndef CONFIG_FB_SCALING_OSD_1080P
+ else if(((screen->x_res==1920) ))
+ {
+ if(hdmi_get_fbscale() < 100)
+ par->ypos -=screen->y_res * (100-hdmi_get_fbscale()) / 200;
+ }
+ #endif
//u32 offset=0, addr=0, map_size=0, smem_len=0;
- u32 addr=0;
- u16 xres_virtual = 0; //virtual screen size
+ addr=0;
+ xres_virtual = 0; //virtual screen size
//u16 xpos_virtual = var->xoffset; //visiable offset in virtual screen
//u16 ypos_virtual = var->yoffset;
- u16 xpos = par->xpos; //visiable offset in panel
- u16 ypos = par->ypos;
+ xpos = par->xpos; //visiable offset in panel
+ ypos = par->ypos;
- u8 trspmode = TRSP_CLOSE;
- u8 trspval = 0;
+ trspmode = TRSP_CLOSE;
+ trspval = 0;
- //fbprintk(">>>>>> %s : %s\n", __FILE__, __FUNCTION__);
+ fbprintk(">>>>>> %s : %s\n", __FILE__, __FUNCTION__);
#ifdef CONFIG_FB_SCALING_OSD
- if(((screen->x_res != var->xres) || (screen->y_res != var->yres))
- && !((screen->x_res>1280) && (var->bits_per_pixel == 32)))
+ if(((screen->x_res != var->xres) || (screen->y_res != var->yres))
+ #ifndef CONFIG_FB_SCALING_OSD_1080P
+ && (screen->x_res<=1280)
+ #endif
+ )
{
- addr = fix->mmio_start + par->y_offset;
- xres_virtual = screen->x_res; //virtual screen size
+ addr = fix->mmio_start + par->y_offset* hdmi_get_fbscale()/100;
+ xres_virtual = screen->x_res* hdmi_get_fbscale()/100; //virtual screen size
}
else
#endif
addr = fix->smem_start + par->y_offset;
xres_virtual = var->xres_virtual; //virtual screen size
}
- LcdMskReg(inf, SYS_CONFIG, m_W1_ENABLE|m_W1_FORMAT, v_W1_ENABLE(1)|v_W1_FORMAT(par->format));
+ LcdMskReg(inf, SYS_CONFIG, m_W1_ENABLE|m_W1_FORMAT, v_W1_ENABLE(fb1_open_init?0:1)|v_W1_FORMAT(par->format));
xpos += (screen->left_margin + screen->hsync_len);
ypos += (screen->upper_margin + screen->vsync_len);
}
LcdWrReg(inf, REG_CFG_DONE, 0x01);
+
+#ifdef CONFIG_CLOSE_WIN1_DYNAMIC
+ schedule_delayed_work(&rk29_win1_check_work, msecs_to_jiffies(5000));
+#endif
return 0;
}
#ifdef CONFIG_FB_SCALING_OSD
struct rk29fb_screen *screen = inf->cur_screen;
struct fb_var_screeninfo *var = &info->var;
- if(((screen->x_res != var->xres) || (screen->y_res != var->yres))
- && !((screen->x_res>1280) && (var->bits_per_pixel == 32)))
+ if(((screen->x_res != var->xres) || (screen->y_res != var->yres))
+ #ifndef CONFIG_FB_SCALING_OSD_1080P
+ && (screen->x_res<=1280)
+ #endif
+ )
{
- addr = fix1->mmio_start + par->y_offset;
+ addr = fix1->mmio_start + par->y_offset* hdmi_get_fbscale()/100;
}
else
#endif
}
if( (var->xoffset+var->xres)>var->xres_virtual ||
- (var->yoffset+var->yres)>var->yres_virtual )
+ (var->yoffset+var->yres)>var->yres_virtual*2 )
{
printk(">>>>>> fb0_check_var fail 2!!! \n");
printk(">>>>>> (%d+%d)>%d || ", var->xoffset,var->xres,var->xres_virtual);
#ifdef CONFIG_FB_SCALING_OSD
struct rk29_ipp_req ipp_req;
u32 dstoffset=0;
+ memset(&ipp_req, 0, sizeof(struct rk29_ipp_req));
#endif
fbprintk(">>>>>> %s : %s\n", __FILE__, __FUNCTION__);
+ wait_event_interruptible(fb0_wait_queue, idle_condition);
+ idle_condition = 0;
+ inf->setFlag = 0;
CHK_SUSPEND(inf);
if(inf->fb0_color_deepth)var->bits_per_pixel=inf->fb0_color_deepth;
{
case 16: // rgb565
par->format = 1;
+ if( ypos_virtual == 0)
+ fb0_first_buff_bits = 16;
+ else
+ fb0_second_buff_bits = 16;
+
//fix->line_length = 2 * xres_virtual;
fix->line_length = (inf->fb0_color_deepth ? 4:2) * xres_virtual; //32bit and 16bit change
ipp_req.dst0.fmt = IPP_RGB_565;
#endif
offset = (ypos_virtual*xres_virtual + xpos_virtual)*(inf->fb0_color_deepth ? 4:2);
+ if(ypos_virtual == 3*var->yres && inf->fb0_color_deepth)
+ offset -= var->yres * var->xres *2;
break;
case 32: // rgb888
default:
par->format = 0;
+ if( ypos_virtual == 0)
+ fb0_first_buff_bits = 32;
+ else
+ fb0_second_buff_bits = 32;
fix->line_length = 4 * xres_virtual;
#ifdef CONFIG_FB_SCALING_OSD
- dstoffset = ((ypos_virtual*screen->y_res/var->yres) *screen->x_res + (xpos_virtual*screen->x_res)/var->xres )*4;
+ dstoffset = ((ypos_virtual*screen->y_res/var->yres) *screen->x_res + (xpos_virtual*screen->x_res)/var->xres )*4;
+
ipp_req.src0.fmt = IPP_XRGB_8888;
ipp_req.dst0.fmt = IPP_XRGB_8888;
#endif
offset = (ypos_virtual*xres_virtual + xpos_virtual)*4;
+
+ if(ypos_virtual >= 2*var->yres)
+ {
+ par->format = 1;
+ #ifdef CONFIG_FB_SCALING_OSD
+ dstoffset = (((ypos_virtual-2*var->yres)*screen->y_res/var->yres) *screen->x_res + (xpos_virtual*screen->x_res)/var->xres )*4;
+ ipp_req.src0.fmt = IPP_RGB_565;
+ ipp_req.dst0.fmt = IPP_RGB_565;
+ #endif
+ if(ypos_virtual == 3*var->yres)
+ {
+ offset -= var->yres * var->xres *2;
+ }
+ }
break;
}
if(inf->video_mode == 1)
{
#ifdef CONFIG_FB_SCALING_OSD
- if(((screen->x_res != var->xres) || (screen->y_res != var->yres))
- && !((screen->x_res>1280) && (var->bits_per_pixel == 32)))
+ if(((screen->x_res != var->xres) || (screen->y_res != var->yres))
+ #ifndef CONFIG_FB_SCALING_OSD_1080P
+ && (screen->x_res<=1280)
+ #endif
+ )
{
par->xpos = 0;
par->ypos = 0;
ipp_req.src0.w = var->xres;
ipp_req.src0.h = var->yres;
- ipp_req.dst0.YrgbMst = fix->mmio_start + dstoffset;
- ipp_req.dst0.w = screen->x_res;
- ipp_req.dst0.h = screen->y_res;
+ ipp_req.dst0.YrgbMst = fix->mmio_start + dstoffset* hdmi_get_fbscale()/100;
+ ipp_req.dst0.w = screen->x_res* hdmi_get_fbscale()/100;
+ ipp_req.dst0.h = screen->y_res* hdmi_get_fbscale()/100;
ipp_req.src_vir_w = ipp_req.src0.w;
ipp_req.dst_vir_w = ipp_req.dst0.w;
ipp_req.timeout = 100;
ipp_req.flag = IPP_ROT_0;
- ipp_do_blit(&ipp_req);
+ //ipp_do_blit(&ipp_req);
+ ipp_blit_sync(&ipp_req);
}else
#endif
{
par->ysize = screen->y_res;
win0_set_par(info);
}
-
+ inf->setFlag = 1;
+ idle_condition = 1;
+ wake_up_interruptible_sync(&fb0_wait_queue);
return 0;
}
#ifdef CONFIG_FB_SCALING_OSD
struct fb_fix_screeninfo *fix = &info->fix;
struct rk29_ipp_req ipp_req;
- u32 dstoffset = 0
+ u32 dstoffset = 0;
+ memset(&ipp_req, 0, sizeof(struct rk29_ipp_req));
#endif
//fbprintk(">>>>>> %s : %s \n", __FILE__, __FUNCTION__);
ipp_req.dst0.fmt = IPP_RGB_565;
#endif
offset = (ypos_virtual*var1->xres_virtual + xpos_virtual)*(inf->fb0_color_deepth ? 4:2);
+ if(ypos_virtual == 3*var->yres && inf->fb0_color_deepth)
+ offset -= var->yres * var->xres *2;
break;
case 32: // rgb888
#ifdef CONFIG_FB_SCALING_OSD
ipp_req.dst0.fmt = IPP_XRGB_8888;
#endif
offset = (ypos_virtual*var1->xres_virtual + xpos_virtual)*4;
+ if(ypos_virtual >= 2*var->yres)
+ {
+ par->format = 1;
+ #ifdef CONFIG_FB_SCALING_OSD
+ dstoffset = (((ypos_virtual-2*var->yres)*screen->y_res/var->yres) *screen->x_res + (xpos_virtual*screen->x_res)/var->xres )*4;
+ ipp_req.src0.fmt = IPP_RGB_565;
+ ipp_req.dst0.fmt = IPP_RGB_565;
+ #endif
+ if(ypos_virtual == 3*var->yres)
+ {
+ offset -= var->yres * var->xres *2;
+ }
+ }
break;
default:
return -EINVAL;
if(inf->video_mode == 1)
{
#ifdef CONFIG_FB_SCALING_OSD
- if(((screen->x_res != var->xres) || (screen->y_res != var->yres))
- && !((screen->x_res>1280) && (var->bits_per_pixel == 32)))
+ if(((screen->x_res != var->xres) || (screen->y_res != var->yres))
+ #ifndef CONFIG_FB_SCALING_OSD_1080P
+ && (screen->x_res<=1280)
+ #endif
+ )
{
par->y_offset = dstoffset;
ipp_req.src0.w = var->xres;
ipp_req.src0.h = var->yres;
- ipp_req.dst0.YrgbMst = fix->mmio_start + dstoffset;
- ipp_req.dst0.w = screen->x_res;
- ipp_req.dst0.h = screen->y_res;
+ ipp_req.dst0.YrgbMst = fix->mmio_start + dstoffset* hdmi_get_fbscale()/100;
+ ipp_req.dst0.w = screen->x_res* hdmi_get_fbscale()/100;
+ ipp_req.dst0.h = screen->y_res* hdmi_get_fbscale()/100;
ipp_req.src_vir_w = ipp_req.src0.w;
ipp_req.dst_vir_w = ipp_req.dst0.w;
ipp_req.timeout = 100;
ipp_req.flag = IPP_ROT_0;
- ipp_do_blit(&ipp_req);
+ //ipp_do_blit(&ipp_req);
+ ipp_blit_sync(&ipp_req);
win1_pan(info);
return 0;
}else
return 0;
}
+#ifdef FB_WIMO_FLAG
+unsigned long temp_vv;
+static int frame_num = 0;
+static int wimo_set_buff(struct fb_info *info,unsigned long *temp)
+{
+ struct rk29fb_inf *inf = dev_get_drvdata(info->device);
+
+ ui_buffer = temp[0];
+ ui_buffer_map = ioremap(temp[0],temp[1]);
+ if(ui_buffer_map == NULL)
+ {
+ printk("can't map a buffer for ui\n");
+ return -EFAULT;
+ }
+
+ printk("ui_buffer %x ",ui_buffer_map);
+ memset(&wimo_info,0,sizeof(wimo_info) );
+
+ wimo_info.mode = inf->video_mode;
+// wimo_info.bitperpixel = var->bits_per_pixel;
+
+
+ wimo_info.dst_width = (temp[2] + 15) & 0xfff0;
+ wimo_info.dst_height = (temp[3] + 15) & 0xfff0;
+}
+static int wimo_get_buff(struct fb_info *info)
+{
+
+ struct rk29_ipp_req overlay_req;
+ struct rk29_ipp_req overlay_req_1;
+ struct rk29fb_inf *inf = dev_get_drvdata(info->device);
+ int ret;
+ memset(&overlay_req, 0 , sizeof(overlay_req));
+ memset(&overlay_req_1, 0 , sizeof(overlay_req_1));
+
+ if(inf->video_mode == 0 )
+ {
+ struct win0_par *par = info->par;
+ wimo_info.xpos = 0;
+ wimo_info.ypos = 0;
+ wimo_info.xsize = 0;
+ wimo_info.ysize = 0;
+ wimo_info.mode = 0;
+ if(par->format == 1)
+ wimo_info.bitperpixel = 16;
+ else
+ wimo_info.bitperpixel =32;// wimo_info.bitperpixel_fb1;
+ overlay_req.src0.YrgbMst = info->fix.smem_start + par->y_offset;//info->screen_base + par->y_offset;//info_buffer[8];
+ overlay_req.src0.CbrMst = info->fix.smem_start + par->y_offset + wimo_info.dst_width * wimo_info.dst_height;//dst_width*dst_height;//+ par->y_offset + dst_width*dst_height;//info_buffer[9];
+ overlay_req.src0.w = wimo_info.dst_width ;//dst_width;//info_buffer[2];
+ overlay_req.src0.h = wimo_info.dst_height ;//dst_height;//info_buffer[3];
+ overlay_req.src0.fmt = (wimo_info.bitperpixel == 16) ? 1 : 0;//3;
+ overlay_req.dst0.YrgbMst = ui_buffer;//overlay_buffer + info_buffer[4] + info_buffer[5] * dst_width;
+ overlay_req.dst0.CbrMst = ui_buffer + wimo_info.dst_width * wimo_info.dst_height;//dst_width*dst_height;//(unsigned char*) overlay_buffer + dst_width*dst_height +info_buffer[4] + ( info_buffer[5] * dst_width) / 2;// info_buffer[6] * info_buffer[7];
+ overlay_req.dst0.w = wimo_info.dst_width ;//dst_width;//info_buffer[6];
+ overlay_req.dst0.h = wimo_info.dst_height ;//dst_height;//info_buffer[7];
+ overlay_req.dst0.fmt = (wimo_info.bitperpixel== 16) ? 1 : 0;//3;3;
+ overlay_req.deinterlace_enable = 0;
+ overlay_req.timeout = 1000000;
+ overlay_req.src_vir_w = wimo_info.dst_width ;//dst_width;//info_buffer[2];
+ overlay_req.dst_vir_w = wimo_info.dst_width ;//dst_width;
+ overlay_req.flag = IPP_ROT_0;
+ ipp_blit_sync(&overlay_req);
+
+ ret = 0;
+ }
+ else
+ {
+
+ int err = 0;
+ static int wimo_time = 0;
+ unsigned long *overlay_buffer_map_temp;
+ unsigned long *map_temp;
+ unsigned long sign_memset = 0;
+ struct fb_var_screeninfo *var = &inf->fb1->var;
+ struct win0_par *par = inf->fb1->par;
+ wimo_info.mode = 1;
+ // printk("overlay setbuffer in\n");
+ // mutex_lock(&wimo_info.fb_lock);
+ wimo_info.fb_lock = 1;
+ {
+ wimo_info.xaff = var->xres;
+ wimo_info.yaff = var->yres;
+ if((wimo_info.xpos != par->xpos) ||(wimo_info.ypos != par->ypos)||(wimo_info.xsize != par->xsize) ||(wimo_info.ysize != par->ysize))
+ {
+ wimo_info.xpos = par->xpos;
+ wimo_info.ypos = par->ypos;
+ wimo_info.xsize = par->xsize;
+ wimo_info.ysize = par->ysize;
+ sign_memset = 1;
+ memset(ui_buffer_map,0,wimo_info.dst_height * wimo_info.dst_width);//dst_width*dst_height);
+ memset(ui_buffer_map + wimo_info.dst_height * wimo_info.dst_width, 0x80,wimo_info.dst_height * wimo_info.dst_width / 2);//dst_width*dst_height,0x80,dst_width*dst_height/2);
+ printk("wimo_info.xpos %d wimo_info.ypos %d wimo_info.xsize %d wimo_info.ysize %d\n",wimo_info.xpos, wimo_info.ypos, wimo_info.xsize, wimo_info.ysize );
+ }
+ }
+ //printk("wimo_info.xpos %d wimo_info.ypos %d wimo_info.xsize %d wimo_info.ysize %d\n",wimo_info.xpos, wimo_info.ypos, wimo_info.xsize, wimo_info.ysize );
+ if(wimo_info.xaff * 3 < wimo_info.xsize || wimo_info.yaff * 3 < wimo_info.ysize)// 3time or bigger scale up
+ {
+ unsigned long mid_width, mid_height;
+ struct rk29_ipp_req overlay_req_1;
+ if(wimo_info.xaff * 3 < wimo_info.xsize)
+ mid_width = wimo_info.xaff * 3;
+ else
+ mid_width = wimo_info.xsize;
+
+ if(wimo_info.yaff * 3 < wimo_info.ysize)
+ mid_height = wimo_info.yaff * 3;
+ else
+ mid_height = wimo_info.ysize;
+ overlay_req.src0.YrgbMst = wimo_info.src_y;//info_buffer[8];
+ overlay_req.src0.CbrMst = wimo_info.src_uv;//info_buffer[9];
+ overlay_req.src0.w = wimo_info.xaff;// info_buffer[2];
+ overlay_req.src0.h = wimo_info.yaff;// info_buffer[3];
+ overlay_req.src0.fmt = 3;
+ overlay_req.dst0.YrgbMst = ui_buffer + 2048000 ;//info_buffer[4] + info_buffer[5] * dst_width; //С³ß´çƬԴÐèÒª2´Î·Å´ó£¬ËùÒÔ½«bufferµÄºó°ë¶ÎÓÃÓÚ»º´æ
+ overlay_req.dst0.CbrMst = (unsigned char*) ui_buffer + mid_height * mid_width + 2048000;
+
+ overlay_req.dst0.w = mid_width;//info_buffer[6];
+ overlay_req.dst0.h = mid_height;//info_buffer[7];
+ overlay_req.dst0.fmt = 3;
+ overlay_req.timeout = 100000;
+ overlay_req.src_vir_w = wimo_info.xaff;//info_buffer[2];
+ overlay_req.dst_vir_w = mid_width;//dst_width;
+ overlay_req.flag = IPP_ROT_0;
+
+ overlay_req_1.src0.YrgbMst = ui_buffer + 2048000;
+ overlay_req_1.src0.CbrMst = (unsigned char*) ui_buffer + mid_height * mid_width + 2048000;
+ overlay_req_1.src0.w = mid_width;
+ overlay_req_1.src0.h = mid_height;// info_buffer[3];
+ overlay_req_1.src0.fmt = 3;
+ overlay_req_1.dst0.YrgbMst = ui_buffer + ((wimo_info.xpos + 1)&0xfffe) + wimo_info.ypos * wimo_info.dst_width;//info_buffer[4] + info_buffer[5] * dst_width;
+ overlay_req_1.dst0.CbrMst =(unsigned char*) ui_buffer + wimo_info.dst_width * wimo_info.dst_height + ((wimo_info.xpos + 1)&0xfffe) + ( wimo_info.ypos / 2)* wimo_info.dst_width ;
+
+ overlay_req_1.dst0.w = wimo_info.xsize;//info_buffer[6];
+ overlay_req_1.dst0.h = wimo_info.ysize;//info_buffer[7];
+ overlay_req_1.dst0.fmt = 3;
+ overlay_req_1.timeout = 100000;
+ overlay_req_1.src_vir_w = mid_width;//info_buffer[2];
+ overlay_req_1.dst_vir_w = wimo_info.dst_width;//dst_width;
+ overlay_req_1.flag = IPP_ROT_0;
+
+
+ err = ipp_blit_sync(&overlay_req);
+ dmac_flush_range(ui_buffer_map,ui_buffer_map + wimo_info.dst_height * wimo_info.dst_width * 3/2);//dst_width*dst_height*3/2);
+ err = ipp_blit_sync(&overlay_req_1);
+
+ }
+ else
+ {
+ overlay_req.src0.YrgbMst = wimo_info.src_y;//info_buffer[8];
+ overlay_req.src0.CbrMst = wimo_info.src_uv;//info_buffer[9];
+ overlay_req.src0.w = wimo_info.xaff;// info_buffer[2];
+ overlay_req.src0.h = wimo_info.yaff;// info_buffer[3];
+ overlay_req.src0.fmt = 3;
+ overlay_req.dst0.YrgbMst = ui_buffer + ((wimo_info.xpos + 1)&0xfffe) + wimo_info.ypos * wimo_info.dst_width;//info_buffer[4] + info_buffer[5] * dst_width;
+ overlay_req.dst0.CbrMst =(unsigned char*) ui_buffer + wimo_info.dst_width * wimo_info.dst_height + ((wimo_info.xpos + 1)&0xfffe) + ( wimo_info.ypos / 2)* wimo_info.dst_width ;
+
+ overlay_req.dst0.w = wimo_info.xsize;//wimo_info.xsize;//wimo_info.xaff;// wimo_info.xsize;//info_buffer[6];
+ overlay_req.dst0.h = (wimo_info.ysize + 1) & 0xfffe;//(wimo_info.ysize + 1) & 0xfffe;//wimo_info.yaff;//(wimo_info.ysize + 1) & 0xfffe;//info_buffer[7];
+ overlay_req.dst0.fmt = 3;
+ overlay_req.timeout = 100000;
+ overlay_req.src_vir_w = wimo_info.xaff;//info_buffer[2];
+ overlay_req.dst_vir_w = wimo_info.dst_width;//wimo_info.dst_width;//wimo_info.yaff;//wimo_info.dst_width;//dst_width;
+ overlay_req.flag = IPP_ROT_0;
+
+ dmac_flush_range(ui_buffer_map,ui_buffer_map + wimo_info.dst_height * wimo_info.dst_width * 3/2);//dst_width*dst_height*3/2);
+ err = ipp_blit_sync(&overlay_req);
+
+ }
+ // printk("overlay setbuffer exit\n");
+ ret = 1;
+ wimo_info.fb_lock = 0;
+ }
+
+
+ return ret;
+}
+#endif
static int fb0_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
{
struct rk29fb_inf *inf = dev_get_drvdata(info->device);
inf->fb0_color_deepth = arg;
break;
+ case FBIOGET_16OR32:
+ return inf->fb0_color_deepth;
+ case FBIOGET_IDLEFBUff_16OR32:
+ if(info->var.yoffset == 0)
+ {
+ return fb0_second_buff_bits;
+ }
+ else
+ {
+ return fb0_first_buff_bits;
+ }
+ case FBIOSET_COMPOSE_LAYER_COUNTS:
+ fb_compose_layer_count = arg;
+ break;
+
+ case FBIOGET_COMPOSE_LAYER_COUNTS:
+
+ return fb_compose_layer_count;
+
case FBIOPUT_FBPHYADD:
return info->fix.smem_start;
case FBIOGET_OVERLAY_STATE:
{
u32 panel_size[2];
//struct rk29fb_inf *inf = dev_get_drvdata(info->device);
- if(inf->fb1->var.rotate == 270) {
+ if((inf->fb1->var.rotate &0x1ff ) == 270) {
panel_size[0] = inf->cur_screen->y_res; //inf->cur_screen->y_res; change for hdmi video size
panel_size[1] = inf->cur_screen->x_res;
} else {
if(copy_to_user((void*)arg, &en, 4)) return -EFAULT;
break;
}
+#ifdef FB_WIMO_FLAG
+ case FB0_IOCTL_SET_BUF:
+ {
+ unsigned long temp[4];
+ copy_from_user(temp, (void*)arg, 20);
+ wimo_set_buff( info,temp);
+
+ }
+ break;
+ case FB0_IOCTL_CLOSE_BUF:
+ {
+ if(ui_buffer != NULL && ui_buffer_map !=NULL )
+ {
+ iounmap(ui_buffer_map);
+ ui_buffer_map = 0;
+ ui_buffer = 0;
+ memset(&wimo_info,0,sizeof(wimo_info));
+ }
+ else
+ printk("somethint wrong with wimo in close");
+
+ }
+ break;
+
+ case FB0_IOCTL_COPY_CURBUF:
+ {
+ unsigned long temp_data[3];
+ copy_from_user(&temp_vv, (void*)arg, 4);
+ if(ui_buffer != NULL && ui_buffer_map !=NULL )
+ {
+ temp_data[1] = wimo_get_buff(info);
+ temp_data[0] = wimo_info.bitperpixel;
+
+ }
+ else
+ {
+ temp_data[1] = 1;
+ temp_data[0] = wimo_info.bitperpixel;
+ printk("somethint wrong with wimo in getbuf");
+ }
+ temp_data[2] = frame_num++;
+ //printk("FB0_IOCTL_COPY_CURBUF %d %d %d\n",temp_data[0],temp_data[1],temp_data[2]);
+ copy_to_user((void*)arg, &temp_data, 12);
+ break;
+ }
+#endif
default:
break;
}
u16 xlcd = screen->x_res; //size of panel
u16 ylcd = screen->y_res;
u16 yres = 0;
-#ifdef CONFIG_HDMI
+#if 0
struct hdmi *hdmi = get_hdmi_struct(0);
#endif
- if((var->rotate == 270)||(var->rotate == 90)) {
+ if((var->rotate & 0x1ff) == 90 ||(var->rotate &0x1ff)== 270) {
#ifdef CONFIG_FB_ROTATE_VIDEO
xlcd = screen->y_res;
ylcd = screen->x_res;
return -EINVAL;
}
- if((var->rotate == 270)||(var->rotate == 90))
+ if((var->rotate & 0x1ff ) == 90 ||(var->rotate & 0x1ff ) == 270)
{
yres = var->xres;
}
{
return -EINVAL; // multiple of scale down or scale up can't exceed 8
}
-#ifdef CONFIG_HDMI
+#if 0
if(inf->video_mode == 1) {
if(hdmi_resolution_changed(hdmi,var->xres,var->yres, 1) == 1)
{
// u32 uv_addr = var->reserved[4];
fbprintk(">>>>>> %s : %s\n", __FILE__, __FUNCTION__);
-
- CHK_SUSPEND(inf);
- if((var->rotate == 270)||(var->rotate == 90))
+ CHK_SUSPEND(inf);
+ if((var->rotate & 0x1ff ) == 90 || (var->rotate & 0x1ff ) == 270)
{
#ifdef CONFIG_FB_ROTATE_VIDEO
xpos = (var->nonstd>>20) & 0xfff; //visiable pos in panel
printk("LCDC not support rotate!\n");
return -EINVAL;
#endif
- }else{
+ } else{
xpos = (xpos * screen->x_res) / inf->panel1_info.x_res;
ypos = (ypos * screen->y_res) / inf->panel1_info.y_res;
xsize = (xsize * screen->x_res) / inf->panel1_info.x_res;
struct rk29_ipp_req ipp_req;
static u32 dstoffset = 0;
static int fb_index = 0;
-
+ memset(&ipp_req, 0, sizeof(struct rk29_ipp_req));
yuv_phy[0] = last_yuv_phy[0];
yuv_phy[1] = last_yuv_phy[1];
yuv_phy[0] += par->y_offset;
yuv_phy[1] += par->c_offset;
+ #if 0
if((var->rotate == 90) ||(var->rotate == 270))
+ #else
+ if(var->rotate%360 != 0)
+ #endif
{
+ #ifdef CONFIG_FB_ROTATE_VIDEO
dstoffset = (dstoffset+1)%2;
ipp_req.src0.fmt = 3;
ipp_req.src0.YrgbMst = yuv_phy[0];
ipp_req.src0.CbrMst = yuv_phy[1];
ipp_req.src0.w = var->xres;
ipp_req.src0.h = var->yres;
+
+ ipp_req.src_vir_w= (var->xres + 15) & (~15);
+ ipp_req.dst_vir_w=screen->x_res;
- ipp_req.dst0.fmt = 3;
- ipp_req.dst0.YrgbMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*2*dstoffset;
- ipp_req.dst0.CbrMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*(2*dstoffset+1);
- // if(var->xres > screen->x_res)
- // {
+ ipp_req.dst0.fmt = 3;
+ #ifdef CONFIG_FB_MIRROR_X_Y
+ if((var->rotate & 0x1ff)!=0 &&(var->rotate&(X_MIRROR|Y_MIRROR))!= 0 )
+ {
+ ipp_req.dst0.YrgbMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*4;
+ ipp_req.dst0.CbrMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*5;
+ }
+ else
+ {
+ ipp_req.dst0.YrgbMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*2*dstoffset;
+ ipp_req.dst0.CbrMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*(2*dstoffset+1);
+
+ }
+ if(var->xres > screen->x_res)
+ {
ipp_req.dst0.w = screen->x_res;
ipp_req.dst0.h = screen->y_res;
- // } else {
- // ipp_req.dst0.w = var->yres;
- // ipp_req.dst0.h = var->xres;
- // }
- ipp_req.src_vir_w = ipp_req.src0.w;
- ipp_req.dst_vir_w = ipp_req.dst0.w;
+ } else {
+ ipp_req.dst0.w = var->xres;
+ ipp_req.dst0.h = var->yres;
+ }
+ ipp_req.dst_vir_w = (ipp_req.dst0.w + 15) & (~15);
ipp_req.timeout = 100;
- if(var->rotate == 90)
+ if((var->rotate & 0x1ff) == 90)
ipp_req.flag = IPP_ROT_90;
- else if(var->rotate == 270)
+ else if ((var->rotate & 0x1ff) == 180)
+ ipp_req.flag = IPP_ROT_180;
+ else if((var->rotate & 0x1ff) == 270)
ipp_req.flag = IPP_ROT_270;
-
- ipp_do_blit(&ipp_req);
- fbprintk("yaddr=0x%x,uvaddr=0x%x\n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
+ else if((var->rotate & X_MIRROR) == X_MIRROR )
+ ipp_req.flag = IPP_ROT_X_FLIP;
+ else if((var->rotate & Y_MIRROR) == Y_MIRROR)
+ ipp_req.flag = IPP_ROT_Y_FLIP;
+ //ipp_do_blit(&ipp_req);
+ ipp_blit_sync(&ipp_req);
yuv_phy[0] = ipp_req.dst0.YrgbMst;
- yuv_phy[1] = ipp_req.dst0.CbrMst;
- fix->smem_start = yuv_phy[0];
- fix->mmio_start = yuv_phy[1];
- }
- else
+ yuv_phy[1] = ipp_req.dst0.CbrMst;
+ if((var->rotate & 0x1ff)!=0 &&(var->rotate&(X_MIRROR|Y_MIRROR))!= 0 )
+ {
+ memset(&ipp_req,0,sizeof(struct rk29_ipp_req));
+
+ if((var->rotate & X_MIRROR) == X_MIRROR)
+ ipp_req.flag = IPP_ROT_X_FLIP;
+ else if((var->rotate & Y_MIRROR) == Y_MIRROR)
+ ipp_req.flag = IPP_ROT_Y_FLIP;
+ else
+ printk(">>>>>> %d rotate is not support!\n",var->rotate);
+
+ if(var->xres > screen->x_res)
+ {
+ ipp_req.dst0.w = screen->x_res;
+ ipp_req.dst0.h = screen->y_res;
+ } else {
+ ipp_req.dst0.w = var->xres;
+ ipp_req.dst0.h = var->yres;
+ }
+ ipp_req.src0.fmt = 3;
+ ipp_req.src0.YrgbMst = yuv_phy[0];
+ ipp_req.src0.CbrMst = yuv_phy[1];
+ ipp_req.src0.w = ipp_req.dst0.w;
+ ipp_req.src0.h = ipp_req.dst0.h;
+
+ ipp_req.src_vir_w= (ipp_req.dst0.w + 15) & (~15);
+ ipp_req.dst_vir_w= (ipp_req.dst0.w + 15) & (~15);
+
+ ipp_req.dst0.fmt = 3;
+ ipp_req.dst0.YrgbMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*2*dstoffset;
+ ipp_req.dst0.CbrMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*(2*dstoffset+1);
+
+ ipp_req.timeout = 100;
+ ipp_blit_sync(&ipp_req);
+ yuv_phy[0] = ipp_req.dst0.YrgbMst;
+ yuv_phy[1] = ipp_req.dst0.CbrMst;
+ }
+ fbprintk("yaddr=0x%x,uvaddr=0x%x\n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
+ #else
+ ipp_req.dst0.YrgbMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*2*dstoffset;
+ ipp_req.dst0.CbrMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*(2*dstoffset+1);
+ if(var->xres > screen->x_res)
+ {
+ ipp_req.dst0.w = screen->x_res;
+ ipp_req.dst0.h = screen->y_res;
+ } else {
+ ipp_req.dst0.w = var->xres;
+ ipp_req.dst0.h = var->yres;
+
+ }
+ ipp_req.dst_vir_w = (ipp_req.dst0.w + 15) & (~15);
+ ipp_req.timeout = 100;
+ if(var->rotate == 90)
+ ipp_req.flag = IPP_ROT_90;
+ else if(var->rotate == 180)
+ ipp_req.flag = IPP_ROT_180;
+ else if(var->rotate == 270)
+ ipp_req.flag = IPP_ROT_270;
+ //ipp_do_blit(&ipp_req);
+ ipp_blit_sync(&ipp_req);
+
+ fbprintk("yaddr=0x%x,uvaddr=0x%x\n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
+ yuv_phy[0] = ipp_req.dst0.YrgbMst;
+ yuv_phy[1] = ipp_req.dst0.CbrMst;
+ #endif
+ fix->smem_start = yuv_phy[0];
+ fix->mmio_start = yuv_phy[1];
+ #else //CONFIG_FB_ROTATE_VIDEO
+ printk("LCDC not support rotate!\n");
+ #endif
+ }
+ else
{
fix->smem_start = yuv_phy[0];
{
struct rk29fb_inf *inf = dev_get_drvdata(info->device);
struct win0_par *par = info->par;
+ struct rk29fb_screen *screen = inf->cur_screen;
fbprintk(">>>>>> %s : %s \n", __FILE__, __FUNCTION__);
return -EACCES;
} else {
par->refcount++;
+ win0_blank(FB_BLANK_NORMAL, info);
+ if(screen->x_res>1280)
+ fb1_open_init=1;
fb0_set_par(inf->fb0);
- fb0_pan_display(&inf->fb0->var, inf->fb0);
- win0_blank(FB_BLANK_POWERDOWN, info);
+ fb1_open_init=0;
+ rk29fb_notify(inf, RK29FB_EVENT_FB1_ON);
return 0;
}
}
struct fb_var_screeninfo *var0 = &info->var;
fbprintk(">>>>>> %s : %s \n", __FILE__, __FUNCTION__);
-
+ if(inf->setFlag == 0)
+ {
+ wait_event_interruptible_timeout(wq, inf->setFlag, HZ*10);
+ }
if(par->refcount) {
par->refcount--;
inf->video_mode = 0;
par->par_seted = 0;
par->addr_seted = 0;
- //win0_blank(FB_BLANK_POWERDOWN, info);
- fb0_set_par(inf->fb0);
- fb0_pan_display(&inf->fb0->var, inf->fb0);
- win1_blank(FB_BLANK_POWERDOWN, info);
- // wait for lcdc stop access memory
- //msleep(50);
+ win1_blank(FB_BLANK_NORMAL, info);
+
+ //if(inf->cur_screen->type != SCREEN_HDMI)
+ fb0_set_par(inf->fb0);
// unmap memory
info->screen_base = 0;
info->fix.smem_len = 0;
// clean the var param
memset(var0, 0, sizeof(struct fb_var_screeninfo));
+ rk29fb_notify(inf, RK29FB_EVENT_FB1_OFF);
+ #ifdef CONFIG_CLOSE_WIN1_DYNAMIC
+ cancel_delayed_work_sync(&rk29_win1_check_work);
+ #endif
}
return 0;
struct rk29fb_screen *screen = inf->cur_screen;
struct rk29_ipp_req ipp_req;
static u32 dstoffset = 0;
-
+ memset(&ipp_req, 0, sizeof(struct rk29_ipp_req));
#endif
fbprintk(">>>>>> %s : %s \n", __FILE__, __FUNCTION__);
case FB1_IOCTL_GET_PANEL_SIZE: //get panel size
{
u32 panel_size[2];
- if((var->rotate == 270)||(var->rotate == 90)) {
+ if((var->rotate & 0x1ff) == 270 ||(var->rotate & 0x1ff) == 90) {
panel_size[0] = inf->panel1_info.y_res; //inf->cur_screen->y_res; change for hdmi video size
panel_size[1] = inf->panel1_info.x_res;
} else {
case FB1_IOCTL_SET_YUV_ADDR: //set y&uv address to register direct
{
u32 yuv_phy[2];
+#ifdef FB_WIMO_FLAG
+ // printk("FB1_IOCTL_SET_YUV_ADDR1 \n");
+ // while(wimo_info.fb_lock)
+ // {
+ // msleep(10);
+ // }
+ // printk("FB1_IOCTL_SET_YUV_ADDR 2\n");
+#endif
if (copy_from_user(yuv_phy, argp, 8))
return -EFAULT;
#ifdef CONFIG_FB_ROTATE_VIDEO
fix0->mmio_start = yuv_phy[1];
yuv_phy[0] += par->y_offset;
yuv_phy[1] += par->c_offset;
+#ifdef FB_WIMO_FLAG
+ wimo_info.src_y = yuv_phy[0];
+ wimo_info.src_uv = yuv_phy[1];
+
+#endif
- if((var->rotate == 270)||(var->rotate == 90))
+ #if 0
+ if((var->rotate == 90) ||(var->rotate == 270))
+ #else
+ if(var->rotate%360 != 0)
+ #endif
{
#ifdef CONFIG_FB_ROTATE_VIDEO
dstoffset = (dstoffset+1)%2;
ipp_req.src0.fmt = 3;
ipp_req.src0.YrgbMst = yuv_phy[0];
ipp_req.src0.CbrMst = yuv_phy[1];
- ipp_req.src0.w = var->xres;
- ipp_req.src0.h = var->yres;
+ ipp_req.src0.w = var->xres ;
+ ipp_req.src0.h = var->yres ;
+ ipp_req.src_vir_w= (var->xres + 15) & (~15);
+ ipp_req.dst_vir_w=screen->x_res;
ipp_req.dst0.fmt = 3;
- ipp_req.dst0.YrgbMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*2*dstoffset;
+ #ifdef CONFIG_FB_MIRROR_X_Y
+ if((var->rotate & 0x1ff)!=0 &&(var->rotate&(X_MIRROR|Y_MIRROR))!= 0 )
+ {
+ ipp_req.dst0.YrgbMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*4;
+ ipp_req.dst0.CbrMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*5;
+ }
+ else
+ {
+ ipp_req.dst0.YrgbMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*2*dstoffset;
+ ipp_req.dst0.CbrMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*(2*dstoffset+1);
+
+ }
+ if(var->xres > screen->x_res)
+ {
+ ipp_req.dst0.w = screen->x_res;
+ ipp_req.dst0.h = screen->y_res;
+ } else {
+ ipp_req.dst0.w = var->xres;
+ ipp_req.dst0.h = var->yres;
+ }
+ ipp_req.dst_vir_w = (ipp_req.dst0.w + 15) & (~15);
+ ipp_req.timeout = 100;
+ if((var->rotate & 0x1ff) == 90)
+ ipp_req.flag = IPP_ROT_90;
+ else if ((var->rotate & 0x1ff) == 180)
+ ipp_req.flag = IPP_ROT_180;
+ else if((var->rotate & 0x1ff) == 270)
+ ipp_req.flag = IPP_ROT_270;
+ else if((var->rotate & X_MIRROR) == X_MIRROR )
+ ipp_req.flag = IPP_ROT_X_FLIP;
+ else if((var->rotate & Y_MIRROR) == Y_MIRROR)
+ ipp_req.flag = IPP_ROT_Y_FLIP;
+ //ipp_do_blit(&ipp_req);
+ ipp_blit_sync(&ipp_req);
+ yuv_phy[0] = ipp_req.dst0.YrgbMst;
+ yuv_phy[1] = ipp_req.dst0.CbrMst;
+ if((var->rotate & 0x1ff)!=0 &&(var->rotate&(X_MIRROR|Y_MIRROR))!= 0 )
+ {
+ memset(&ipp_req,0,sizeof(struct rk29_ipp_req));
+
+ if((var->rotate & X_MIRROR) == X_MIRROR)
+ ipp_req.flag = IPP_ROT_X_FLIP;
+ else if((var->rotate & Y_MIRROR) == Y_MIRROR)
+ ipp_req.flag = IPP_ROT_Y_FLIP;
+ else
+ printk(">>>>>> %d rotate is not support!\n",var->rotate);
+
+ if(var->xres > screen->x_res)
+ {
+ ipp_req.dst0.w = screen->x_res;
+ ipp_req.dst0.h = screen->y_res;
+ } else {
+ ipp_req.dst0.w = var->xres;
+ ipp_req.dst0.h = var->yres;
+ }
+ ipp_req.src0.fmt = 3;
+ ipp_req.src0.YrgbMst = yuv_phy[0];
+ ipp_req.src0.CbrMst = yuv_phy[1];
+ ipp_req.src0.w = ipp_req.dst0.w;
+ ipp_req.src0.h = ipp_req.dst0.h;
+
+ ipp_req.src_vir_w= (ipp_req.dst0.w + 15) & (~15);
+ ipp_req.dst_vir_w= (ipp_req.dst0.w + 15) & (~15);
+
+ ipp_req.dst0.fmt = 3;
+ ipp_req.dst0.YrgbMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*2*dstoffset;
+ ipp_req.dst0.CbrMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*(2*dstoffset+1);
+
+ ipp_req.timeout = 100;
+ ipp_blit_sync(&ipp_req);
+ yuv_phy[0] = ipp_req.dst0.YrgbMst;
+ yuv_phy[1] = ipp_req.dst0.CbrMst;
+ }
+ fbprintk("yaddr=0x%x,uvaddr=0x%x\n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
+ #else
+ ipp_req.dst0.YrgbMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*2*dstoffset;
ipp_req.dst0.CbrMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*(2*dstoffset+1);
- // if(var->xres > screen->x_res)
- // {
+ if(var->xres > screen->x_res)
+ {
ipp_req.dst0.w = screen->x_res;
ipp_req.dst0.h = screen->y_res;
- // } else {
- // ipp_req.dst0.w = var->yres;
- // ipp_req.dst0.h = var->xres;
- // }
- ipp_req.src_vir_w = ipp_req.src0.w;
- ipp_req.dst_vir_w = ipp_req.dst0.w;
+ } else {
+ ipp_req.dst0.w = var->xres;
+ ipp_req.dst0.h = var->yres;
+
+ }
+ ipp_req.dst_vir_w = (ipp_req.dst0.w + 15) & (~15);
ipp_req.timeout = 100;
if(var->rotate == 90)
ipp_req.flag = IPP_ROT_90;
+ else if(var->rotate == 180)
+ ipp_req.flag = IPP_ROT_180;
else if(var->rotate == 270)
ipp_req.flag = IPP_ROT_270;
- ipp_do_blit(&ipp_req);
+ //ipp_do_blit(&ipp_req);
+ ipp_blit_sync(&ipp_req);
+
fbprintk("yaddr=0x%x,uvaddr=0x%x\n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
yuv_phy[0] = ipp_req.dst0.YrgbMst;
- yuv_phy[1] = ipp_req.dst0.CbrMst;
+ yuv_phy[1] = ipp_req.dst0.CbrMst;
+ #endif
fix0->smem_start = yuv_phy[0];
fix0->mmio_start = yuv_phy[1];
#else //CONFIG_FB_ROTATE_VIDEO
#ifdef CONFIG_FB_ROTATE_VIDEO
//zyc add
has_set_rotate = true;
- if(arg == 0 || arg==180)
- var->rotate = arg;
- else if (arg == 90 || arg==270)
- var->rotate = arg;
+ #ifdef CONFIG_FB_MIRROR_X_Y
+ if( ((arg&0x1ff)%90) == 0 && ( arg&(~0xfff))==0 )
+ {
+ if( (arg&( X_MIRROR | Y_MIRROR ) )== (X_MIRROR | Y_MIRROR) )
+ var->rotate = ROTATE_180;
+ else if((arg&( ROTATE_90 | X_MIRROR | Y_MIRROR ) )== ( ROTATE_90 | X_MIRROR | Y_MIRROR))
+ var->rotate = ROTATE_270;
+ else if((arg&( ROTATE_180 | X_MIRROR | Y_MIRROR ) )== ( ROTATE_180 | X_MIRROR | Y_MIRROR))
+ var->rotate = ROTATE_90;
+ else if((arg&( ROTATE_270 | X_MIRROR | Y_MIRROR ) )== ( ROTATE_270 | X_MIRROR | Y_MIRROR))
+ var->rotate = ROTATE_0;
+ else
+ #else
+ if(arg == ROTATE_0 || arg==ROTATE_90 || arg == ROTATE_180 || arg==ROTATE_270)
+ {
+ #endif
+ var->rotate = arg;
+ }
+ else
+ printk(">>>>>> %d rotate is not support!\n",(int)arg);
+
#else //CONFIG_FB_ROTATE_VIDEO
printk("LCDC not support rotate!\n");
#endif
//.fb_cursor = rk29_set_cursor,
};
+int fb_get_video_mode(void)
+{
+ struct rk29fb_inf *inf;
+ if(!g_pdev)
+ return 0;
+ inf = platform_get_drvdata(g_pdev);
+ return inf->video_mode;
+}
/*
enable: 1, switch to tv or hdmi; 0, switch to lcd
*/
if(inf->cur_screen->standby) inf->cur_screen->standby(1);
// operate the display_on pin to power down the lcd
-
+#ifdef CONFIG_HDMI_DUAL_DISP
+ if(inf->panel1_info.sscreen_get!=NULL)
+ inf->panel1_info.sscreen_get(&inf->panel1_info,inf->panel2_info.hdmi_resolution);
+ else
+ printk("warnig : LCD driver do not support dual display");
+ if(inf->panel1_info.sscreen_set!=NULL)
+ inf->panel1_info.sscreen_set(&inf->panel1_info,enable);
+ else
+ printk("warnig : LCD driver do not support dual display");
+#else
if(enable && mach_info->io_disable)mach_info->io_disable(); //close lcd out
else if (mach_info->io_enable)mach_info->io_enable(); //open lcd out
-
+#endif
load_screen(inf->fb0, 0);
mcu_refresh(inf);
fb0_set_par(inf->fb0);
LcdMskReg(inf, DSP_CTRL1, m_BLACK_MODE, v_BLACK_MODE(0));
LcdWrReg(inf, REG_CFG_DONE, 0x01);
+
+ rk29fb_notify(inf, enable ? RK29FB_EVENT_HDMI_ON : RK29FB_EVENT_HDMI_OFF);
return 0;
}
wq_condition = 1;
wake_up_interruptible(&wq);
+ rk29fb_irq_notify_ddr();
return IRQ_HANDLED;
}
return;
}
+#ifdef CONFIG_CLOSE_WIN1_DYNAMIC
+ cancel_delayed_work_sync(&rk29_win1_check_work);
+#endif
+#ifdef CONFIG_HDMI_DUAL_DISP
+ if(mach_info->io_disable) // close lcd pwr when output screen is lcd
+ mach_info->io_disable(); //close lcd out
+#else
if((inf->cur_screen != &inf->panel2_info) && mach_info->io_disable) // close lcd pwr when output screen is lcd
mach_info->io_disable(); //close lcd out
-
+#endif
if(inf->cur_screen->standby)
{
fbprintk(">>>>>> power down the screen! \n");
inf->cur_screen->standby(1);
}
+ LcdMskReg(inf, SYS_CONFIG, m_W0_ENABLE | m_W1_ENABLE, v_W0_ENABLE(0) | v_W1_ENABLE(0));
LcdMskReg(inf, DSP_CTRL0, m_HSYNC_POLARITY | m_VSYNC_POLARITY | m_DEN_POLARITY ,
v_HSYNC_POLARITY(1) | v_VSYNC_POLARITY(1) | v_DEN_POLARITY(1) );
if(inf->clk){
clk_disable(inf->aclk);
}
- clk_disable(inf->pd_display);
+ //clk_disable(inf->pd_display);
inf->in_suspend = 1;
}
{
inf->in_suspend = 0;
fbprintk(">>>>>> enable the lcdc clk! \n");
- clk_enable(inf->pd_display);
+ // clk_enable(inf->pd_display);
clk_enable(inf->aclk_disp_matrix);
clk_enable(inf->hclk_cpu_display);
clk_enable(inf->clk);
if(inf->clk){
clk_enable(inf->aclk);
}
- msleep(100);
+ usleep_range(100*1000, 100*1000);
}
LcdMskReg(inf, DSP_CTRL1, m_BLANK_MODE , v_BLANK_MODE(0));
LcdMskReg(inf, SYS_CONFIG, m_STANDBY, v_STANDBY(0));
fbprintk(">>>>>> power on the screen! \n");
inf->cur_screen->standby(0);
}
- msleep(10);
+ usleep_range(10*1000, 10*1000);
memcpy((u8*)inf->preg, (u8*)&inf->regbak, 0xa4); //resume reg
- msleep(40);
-
+ usleep_range(40*1000, 40*1000);
+ #ifdef CONFIG_HDMI_DUAL_DISP
+ if(mach_info->io_enable) // open lcd pwr when output screen is lcd
+ mach_info->io_enable(); //close lcd out
+ #else
if((inf->cur_screen != &inf->panel2_info) && mach_info->io_enable) // open lcd pwr when output screen is lcd
mach_info->io_enable(); //close lcd out
-
+ #endif
}
static struct suspend_info suspend_info = {
};
#endif
struct fb_info *g_fb0_inf = NULL; //add cym@rk 20101027 for charger logo
-static int __init rk29fb_probe (struct platform_device *pdev)
+static int __devinit rk29fb_probe (struct platform_device *pdev)
{
struct rk29fb_inf *inf = NULL;
struct resource *res = NULL;
#else
set_lcd_info(&inf->panel1_info, mach_info->lcd_info);
#endif
+
inf->cur_screen = &inf->panel1_info;
screen = inf->cur_screen;
if(SCREEN_NULL==screen->type)
inf->fb0->var.yres_virtual = screen->y_res;
inf->fb0->var.width = screen->width;
inf->fb0->var.height = screen->height;
- inf->fb0->var.pixclock = screen->pixclock;
+ //inf->fb0->var.pixclock = div_u64(1000000000000llu, screen->pixclock);
inf->fb0->var.left_margin = screen->left_margin;
inf->fb0->var.right_margin = screen->right_margin;
inf->fb0->var.upper_margin = screen->upper_margin;
inf->fb1->var.yres_virtual = screen->y_res;
inf->fb1->var.width = screen->width;
inf->fb1->var.height = screen->height;
- inf->fb1->var.pixclock = screen->pixclock;
+ //inf->fb1->var.pixclock = div_u64(1000000000000llu, screen->pixclock);
inf->fb1->var.left_margin = screen->left_margin;
inf->fb1->var.right_margin = screen->right_margin;
inf->fb1->var.upper_margin = screen->upper_margin;
goto release_irq;
}
}
-
+ #ifdef CONFIG_MFD_RK610
+ rk610_lcd_scaler_set_param(&inf->panel1_info,0);
+ #endif
#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
fb0_set_par(inf->fb0);
if (fb_prepare_logo(inf->fb0, FB_ROTATE_UR)) {
return ret;
}
-static int rk29fb_remove(struct platform_device *pdev)
+static int __devexit rk29fb_remove(struct platform_device *pdev)
{
struct rk29fb_inf *inf = platform_get_drvdata(pdev);
struct fb_info *info = NULL;
static struct platform_driver rk29fb_driver = {
.probe = rk29fb_probe,
- .remove = rk29fb_remove,
+ .remove = __devexit_p(rk29fb_remove),
.driver = {
.name = "rk29-fb",
.owner = THIS_MODULE,