From deb2b8e514ef7bf84733010dce3f9418f65d6979 Mon Sep 17 00:00:00 2001 From: Wang Quanxian Date: Wed, 12 Sep 2012 10:53:42 +0800 Subject: [PATCH] update to 3104 build Signed-Off-By Quanxian Wang --- drivers/emgd/core/init/cmn/igd_init.c | 2 +- drivers/emgd/core/init/plb/micro_init_plb.c | 21 +- drivers/emgd/core/init/tnc/micro_init_tnc.c | 42 +-- drivers/emgd/display/dsp/cmn/dsp.c | 6 +- drivers/emgd/display/dsp/tnc/dsp_tnc.c | 8 +- drivers/emgd/display/mode/cmn/igd_mode.c | 30 ++- drivers/emgd/display/mode/cmn/micro_mode.c | 8 +- drivers/emgd/display/mode/cmn/mode_dispatch.h | 4 + drivers/emgd/display/mode/plb/micro_mode_plb.c | 12 +- drivers/emgd/display/mode/plb/mode_plb.c | 17 ++ drivers/emgd/display/mode/tnc/kms_mode_tnc.c | 2 +- drivers/emgd/display/mode/tnc/micro_mode_tnc.c | 14 +- drivers/emgd/display/mode/tnc/mode_tnc.c | 209 +++++++++++--- drivers/emgd/display/pi/cmn/pi.c | 3 + drivers/emgd/drm/emgd_connector.c | 12 +- drivers/emgd/drm/emgd_crtc.c | 84 +++--- drivers/emgd/drm/emgd_drv.c | 111 +++++++- drivers/emgd/drm/emgd_drv.h | 4 +- drivers/emgd/drm/emgd_fb.c | 2 +- drivers/emgd/drm/emgd_fbcon.c | 2 +- drivers/emgd/drm/emgd_interface.c | 13 +- drivers/emgd/drm/user_config.c | 6 +- drivers/emgd/drm/user_config.h | 4 + drivers/emgd/gmm/gmm.c | 48 ++-- drivers/emgd/gmm/gtt.c | 116 ++++++-- drivers/emgd/include/context.h | 5 +- drivers/emgd/include/msvdx.h | 2 +- drivers/emgd/include/pd.h | 1 + drivers/emgd/pal/ch7036/ch7036_port.c | 10 +- drivers/emgd/pal/sdvo/sdvo_attr.c | 4 +- drivers/emgd/pal/sdvo/sdvo_port.c | 30 +-- drivers/emgd/pal/sdvo/sdvo_port.h | 4 +- drivers/emgd/state/reg/plb/reg_plb.c | 2 +- drivers/emgd/state/reg/tnc/reg_tnc.c | 4 +- drivers/emgd/video/msvdx/msvdx.c | 56 ++-- drivers/emgd/video/msvdx/msvdx_init.c | 151 ++++++++--- drivers/emgd/video/msvdx/msvdx_pvr.c | 2 +- drivers/emgd/video/overlay/cmn/igd_ovl.c | 36 ++- drivers/emgd/video/overlay/tnc/ovl2_tnc.c | 4 +- drivers/emgd/video/overlay/tnc/ovl_tnc.c | 300 ++++++++++++++++++++- drivers/emgd/video/overlay/tnc/ovl_tnc_cache.c | 2 +- drivers/emgd/video/topaz/topaz.c | 60 ++++- drivers/emgd/video/topaz/topaz_init.c | 24 +- drivers/include/emgd_drm.h | 45 +++- drivers/include/emgd_shared.h | 56 +++- drivers/include/igd.h | 5 + drivers/include/igd_gmm.h | 11 +- drivers/include/igd_mode.h | 3 +- drivers/include/igd_pd.h | 2 + drivers/include/igd_render.h | 52 +++- drivers/include/igd_version.h | 6 +- .../services4/3rdparty/emgd_bufferclass/emgd_bc.c | 10 +- .../services4/3rdparty/emgd_bufferclass/emgd_bc.h | 1 + .../3rdparty/emgd_bufferclass/emgd_bc_linux.c | 88 ++++-- .../srvkm/bridged/sgx/bridged_sgx_bridge.c | 26 +- drivers/pvr/services4/srvkm/devices/sgx/sgxinit.c | 1 - 56 files changed, 1460 insertions(+), 323 deletions(-) diff --git a/drivers/emgd/core/init/cmn/igd_init.c b/drivers/emgd/core/init/cmn/igd_init.c index 335a796..54449c5 100644 --- a/drivers/emgd/core/init/cmn/igd_init.c +++ b/drivers/emgd/core/init/cmn/igd_init.c @@ -913,6 +913,6 @@ void igd_query_2d_caps_hwhint(igd_driver_h driver_handle, /*---------------------------------------------------------------------------- * File Revision History * $Id: igd_init.c,v 1.24 2011/09/30 07:53:25 rlim Exp $ - * $Source: /nfs/fm/proj/eia/cvsroot/koheo/linux/egd_drm/emgd/core/init/cmn/igd_init.c,v $ + * $Source: /nfs/sie/disks/sie-cidgit_disk001/git_repos/GFX/cvs_fri22/koheo/linux/egd_drm/emgd/core/init/cmn/igd_init.c,v $ *---------------------------------------------------------------------------- */ diff --git a/drivers/emgd/core/init/plb/micro_init_plb.c b/drivers/emgd/core/init/plb/micro_init_plb.c index c91adb6..22425b3 100644 --- a/drivers/emgd/core/init/plb/micro_init_plb.c +++ b/drivers/emgd/core/init/plb/micro_init_plb.c @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: micro_init_plb.c - * $Revision: 1.13 $ + * $Revision: 1.13.102.1 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2010, Intel Corporation. * @@ -184,6 +184,7 @@ static void gtt_init_plb(igd_context_t *context) /* Get the page table control register */ pge_ctl = readl(mmio + PSB_PGETBL_CTL); gtt_phys_start = pge_ctl & PAGE_MASK; + context->device_context.valid_firmware_init = (pge_ctl != 0); gtt_enabled = pge_ctl & PSB_PGETBL_ENABLED; @@ -218,14 +219,14 @@ static void gtt_init_plb(igd_context_t *context) context->device_context.virt_gttadr = gtt_table; for (i=0; i < (1 << gtt_order); i++) { - gtt_table_page = virt_to_page(gtt_table + (PAGE_SIZE * i)); + gtt_table_page = virt_to_page(((unsigned char *)gtt_table) + (PAGE_SIZE * i)); EMGD_DEBUG("Setting reserved bit on %p", gtt_table_page); set_bit(PG_reserved, >t_table_page->flags); } gtt_phys_start = virt_to_phys(gtt_table); - for (i = 0; i < gtt_pages; i++) { + for (i = 0; i < gtt_pages * 1024; i++) { gtt_table[i] = (unsigned long)context->device_context.scratch_page; } @@ -624,6 +625,20 @@ static int set_param_plb(igd_context_t *context, unsigned long id, static void shutdown_plb(igd_context_t *context) { gtt_shutdown_plb(context); + /* If firmware didn't initialize the hardware, free the memory + * we allocated to do that and restore the state */ + if(!context->device_context.valid_firmware_init) { + int gtt_pages; + unsigned char *mmio = context->device_context.virt_mmadr; + + printk(KERN_INFO "Freeing allocated GTT and clearing PSB_PGETBL_CTL to restore firmware state\n"); + + gtt_pages = pci_resource_len(((struct drm_device *)context->drm_dev)->pdev, + PSB_GTT_RESOURCE) >> PAGE_SHIFT; + free_pages((unsigned long)context->device_context.virt_gttadr, gtt_pages); + writel(0, mmio + PSB_PGETBL_CTL); + } + OPT_MICRO_VOID_CALL(full_shutdown_plb(context)); } diff --git a/drivers/emgd/core/init/tnc/micro_init_tnc.c b/drivers/emgd/core/init/tnc/micro_init_tnc.c index cb803a1..b0c6eab 100644 --- a/drivers/emgd/core/init/tnc/micro_init_tnc.c +++ b/drivers/emgd/core/init/tnc/micro_init_tnc.c @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: micro_init_tnc.c - * $Revision: 1.26 $ + * $Revision: 1.25.44.2 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2010, Intel Corporation. * @@ -253,6 +253,7 @@ static void gtt_init_tnc(igd_context_t *context) /* Get the page table control register */ pge_ctl = readl(mmio + PSB_PGETBL_CTL); gtt_phys_start = pge_ctl & PAGE_MASK; + context->device_context.valid_firmware_init = (pge_ctl != 0); /* Create a scratch page to initialize empty GTT entries */ if(NULL == context->device_context.scratch_page){ @@ -287,14 +288,14 @@ static void gtt_init_tnc(igd_context_t *context) context->device_context.virt_gttadr = gtt_table; for (i=0; i < (1 << gtt_order); i++) { - gtt_table_page = virt_to_page(gtt_table + (PAGE_SIZE * i)); + gtt_table_page = virt_to_page(((unsigned char *)gtt_table) + (PAGE_SIZE * i)); EMGD_DEBUG("Setting reserved bit on %p", gtt_table_page); set_bit(PG_reserved, >t_table_page->flags); } gtt_phys_start = virt_to_phys(gtt_table); - for (i = 0; i < gtt_pages; i++) { + for (i = 0; i < gtt_pages * 1024; i++) { gtt_table[i] = (unsigned long)context->device_context.scratch_page; } @@ -738,8 +739,7 @@ static int config_tnc(igd_context_t *context, #endif gtt_init_tnc(context); - - /* + /* * Setting the LBB to 0xFF if it is 0. * This register is used to dynamic LVDS backlight control. By default, * the register will reset to 0x0, this will cause the LVDS to be "off" when @@ -750,20 +750,18 @@ static int config_tnc(igd_context_t *context, * then set the register through pd. But this will add more code to VBIOS * (as we need to add dispatch functions in pd) */ - if(OS_PCI_READ_CONFIG_32(platform_context->pcidev0, 0xF4, &lbb)) { - EMGD_DEBUG("Reading Legacy Backlight Brightness"); - return -IGD_ERROR_NODEV; - } + EMGD_ERROR_EXIT("Reading Legacy Backlight Brightness"); + return -IGD_ERROR_NODEV; + } if(!(lbb & 0xFF)){ - if(OS_PCI_WRITE_CONFIG_32(platform_context->pcidev0, - 0xF4, (lbb | 0xFF))){ - EMGD_DEBUG("Writing into Legacy Backlight Brightness"); - return -IGD_ERROR_INVAL; - } + if(OS_PCI_WRITE_CONFIG_32(platform_context->pcidev0, + 0xF4, (lbb | 0xFF))){ + EMGD_ERROR_EXIT("Writing into Legacy Backlight Brightness"); + return -IGD_ERROR_INVAL; + } } - EMGD_TRACE_EXIT; return 0; } @@ -980,6 +978,20 @@ static void shutdown_tnc(igd_context_t *context) { gtt_shutdown_tnc(context); + /* If firmware didn't initialize the hardware, free the memory + * we allocated to do that and restore the state */ + if(!context->device_context.valid_firmware_init) { + int gtt_pages; + unsigned char *mmio = context->device_context.virt_mmadr; + + printk(KERN_INFO "Freeing allocated GTT and clearing PSB_PGETBL_CTL to restore firmware state\n"); + + gtt_pages = pci_resource_len(((struct drm_device *)context->drm_dev)->pdev, + PSB_GTT_RESOURCE) >> PAGE_SHIFT; + free_pages((unsigned long)context->device_context.virt_gttadr, gtt_pages); + writel(0, mmio + PSB_PGETBL_CTL); + } + OPT_MICRO_VOID_CALL(full_shutdown_tnc(context)); } diff --git a/drivers/emgd/display/dsp/cmn/dsp.c b/drivers/emgd/display/dsp/cmn/dsp.c index d4abefb..38641fc 100755 --- a/drivers/emgd/display/dsp/cmn/dsp.c +++ b/drivers/emgd/display/dsp/cmn/dsp.c @@ -179,14 +179,14 @@ static unsigned long dsp_get_fw_dc(igd_context_t *context) int port_allocated = 0; unsigned long port_value; unsigned long fw_dc = 0; - unsigned char *mmio = EMGD_MMIO(context->device_context.virt_mmadr); EMGD_TRACE_ENTER; /* Go through the port table */ while ((p = dsp_get_next_port(context, p, 0)) != NULL) { - port_value = EMGD_READ32(mmio + p->port_reg); + port_value = dsp_context.context->mod_dispatch.get_port_control(p->port_number, p->port_reg); + EMGD_DEBUG("port number = %lx, port reg = %lx, value = %lx", p->port_number, p->port_reg, port_value); if(port_value & BIT(31)) { /* is the port ON? */ if(port1) { @@ -1892,6 +1892,8 @@ int dsp_init(igd_context_t *context) */ (*(igd_display_plane_t **)plane)->fb_info->fb_base_offset = 0; (*(igd_display_plane_t **)plane)->fb_info->visible_offset = 0; + (*(igd_display_plane_t **)plane)->fb_info->saved_offset = 0; + (*(igd_display_plane_t **)plane)->fb_info->lock = FALSE; dsp_context.num_dsp_planes++; } plane++; diff --git a/drivers/emgd/display/dsp/tnc/dsp_tnc.c b/drivers/emgd/display/dsp/tnc/dsp_tnc.c index 0697657..9d5072d 100644 --- a/drivers/emgd/display/dsp/tnc/dsp_tnc.c +++ b/drivers/emgd/display/dsp/tnc/dsp_tnc.c @@ -301,15 +301,15 @@ static igd_clock_t clock_b_tnc = { static igd_display_pipe_t pipea_tnc = { 0, PIPEA_CONF, PIPEA_TIMINGS, DPALETTE_A, &clock_a_tnc, (IGD_PIPE_IS_PIPEA | IGD_PORT_SHARE_LVDS), - 0, 0,{NULL, NULL, NULL}, NULL, NULL, NULL, - NULL, NULL + 0, 0,{NULL, NULL, NULL}, &planea_tnc, NULL, NULL, + NULL, NULL, NULL }; static igd_display_pipe_t pipeb_tnc = { 1, PIPEB_CONF, PIPEB_TIMINGS, DPALETTE_B, &clock_b_tnc, (IGD_PIPE_IS_PIPEB | IGD_PORT_SHARE_DIGITAL), - 0, 0,{NULL, NULL, NULL}, NULL, NULL, NULL, - NULL, NULL + 0, 0,{NULL, NULL, NULL}, &planeb_tnc, NULL, NULL, + NULL, NULL, NULL }; static igd_display_pipe_t *pipe_table_tnc[] = { diff --git a/drivers/emgd/display/mode/cmn/igd_mode.c b/drivers/emgd/display/mode/cmn/igd_mode.c index 8457774..c2c4df5 100755 --- a/drivers/emgd/display/mode/cmn/igd_mode.c +++ b/drivers/emgd/display/mode/cmn/igd_mode.c @@ -1864,6 +1864,8 @@ int full_mode_init(igd_context_t *context, mode_context->dispatch->check_port_supported; context->mod_dispatch.get_refresh_in_border = mode_context->dispatch->get_refresh_in_border; + context->mod_dispatch.get_port_control = + mode_context->dispatch->full->get_port_control; /* Hook up Core specific IGD dispatch table entries */ @@ -1883,6 +1885,7 @@ int full_mode_init(igd_context_t *context, dispatch->disable_vblank_callback = mode_context->dispatch->full->disable_vblank_callback; + dispatch->unlock_planes = mode_context->dispatch->full->unlock_planes; /* Assign the fw_info structure and Zero-out the contents */ mode_context->fw_info = &global_fw_info; OS_MEMSET(mode_context->fw_info, 0, sizeof(fw_info_t)); @@ -2113,6 +2116,7 @@ int query_seamless(unsigned long dc, int ret = FALSE; igd_display_info_t *timing; igd_framebuffer_info_t *fb_info; + unsigned long in_pitch; EMGD_TRACE_ENTER; EMGD_DEBUG("Incoming dc = 0x%08lx", dc); @@ -2123,9 +2127,16 @@ int query_seamless(unsigned long dc, mode_context->fw_info->fw_dc = mode_context->context->mod_dispatch.dsp_fw_dc; + EMGD_DEBUG("firmware dc = 0x%08lx",mode_context->fw_info->fw_dc ); + if(dc != mode_context->fw_info->fw_dc) { - /* DC doesn't match */ - return FALSE; + /*special case when seamless transition from fw clone to vext */ + if(!(IGD_DC_VEXT(dc) && IGD_DC_CLONE(mode_context->fw_info->fw_dc))) + { + /* DC doesn't match */ + return FALSE; + } + EMGD_DEBUG("past dc check"); } /* Note: this test both overcomes a compiler warning, as well as a @@ -2148,7 +2159,7 @@ int query_seamless(unsigned long dc, /* Have to build in some tolerance here because the fresh rate may * not match exactly */ - if (abs(timing->refresh - pt->refresh) <= 1) { + if (abs(timing->refresh - pt->refresh) <= 2) { ret = TRUE; } @@ -2175,11 +2186,15 @@ int query_seamless(unsigned long dc, /* Check Plane information */ if(pf != NULL) { fb_info = &mode_context->fw_info->fb_info[index]; - ret = FALSE; + ret = TRUE; + /* the incoming pitch=0, since it won't be filled until FB is allocated, calculating it now, so that + * it can be compared with the fw pitch */ + in_pitch = (IGD_PF_DEPTH(pf->pixel_format) * pf->width) >> 3; + + /* Pitch for both PLB and TNC requires 64-byte alignment */ + in_pitch = ALIGN(in_pitch, 64); - if( (fb_info->screen_pitch != pf->screen_pitch) || - (fb_info->width != pf->width) || - (fb_info->height != pf->height) ) { + if(fb_info->screen_pitch != in_pitch) { /* If width, height or pitch is different * Don't have to turn-off pipe, just update @@ -2188,7 +2203,6 @@ int query_seamless(unsigned long dc, * the registers. */ mode_context->fw_info->program_plane = 1; - ret = TRUE; } } diff --git a/drivers/emgd/display/mode/cmn/micro_mode.c b/drivers/emgd/display/mode/cmn/micro_mode.c index 5d615aa..fc0a627 100644 --- a/drivers/emgd/display/mode/cmn/micro_mode.c +++ b/drivers/emgd/display/mode/cmn/micro_mode.c @@ -724,7 +724,8 @@ static int configure_display( 0)); EMGD_DEBUG(":Seamless = %s", seamless ?"ON" : "OFF"); - mode_context->seamless = FALSE; + /* moved this to alter_displays to handle the case for CLONE */ + /*mode_context->seamless = FALSE;*/ /* FIXME: For clone you get called twice. Need to * Fix that corner case */ @@ -853,6 +854,10 @@ static int configure_display( */ EMGD_DEBUG(" Seamless is TRUE"); + /* special handling for fw clone to vext seamless */ + if((IGD_DC_VEXT(config_drm.dc) && IGD_DC_CLONE(mode_context->fw_info->fw_dc))){ + mode_context->dispatch->full->lock_planes(display); + } if(mode_context->fw_info->program_plane == 1) { /* This means we have to update the plane registers @@ -1431,6 +1436,7 @@ int igd_alter_displays( mode_context->dispatch->wait_vblank(*secondary); } + EMGD_TRACE_EXIT; return 0; } diff --git a/drivers/emgd/display/mode/cmn/mode_dispatch.h b/drivers/emgd/display/mode/cmn/mode_dispatch.h index b2ae62e..e1074b5 100644 --- a/drivers/emgd/display/mode/cmn/mode_dispatch.h +++ b/drivers/emgd/display/mode/cmn/mode_dispatch.h @@ -139,6 +139,10 @@ typedef struct _mode_full_dispatch { * @return Non-zero if the requested VBlank occured, zero if not. */ int (*vblank_occured)(unsigned long request_for); + unsigned long (*get_port_control)(unsigned long port_num, unsigned long port_reg); + void (*lock_planes)(igd_display_h display_handle); + int (*unlock_planes)(igd_display_h display_handle, unsigned int scrn_num); + } mode_full_dispatch_t; typedef struct _mode_dispatch { diff --git a/drivers/emgd/display/mode/plb/micro_mode_plb.c b/drivers/emgd/display/mode/plb/micro_mode_plb.c index 9fbb378..43bdbb6 100644 --- a/drivers/emgd/display/mode/plb/micro_mode_plb.c +++ b/drivers/emgd/display/mode/plb/micro_mode_plb.c @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: micro_mode_plb.c - * $Revision: 1.22 $ + * $Revision: 1.22.60.1 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2010, Intel Corporation. * @@ -901,7 +901,15 @@ static void reset_plane_pipe_ports_plb(igd_context_t *context) if(port->pd_type == PD_DISPLAY_TVOUT) { tv_port = port; }else { - port->pd_driver->set_power(port->pd_context, IGD_POWERSTATE_D3); + /*CH7036*/ + if(context->device_context.power_state == IGD_POWERSTATE_D1) { //ACPI + /* D1 power state for graphics is requested*/ + port->pd_driver->set_power(port->pd_context,context->device_context.power_state); + /*pass it to pd*/ + } + else { + port->pd_driver->set_power(port->pd_context, IGD_POWERSTATE_D3); + }/* else end*/ } #endif } diff --git a/drivers/emgd/display/mode/plb/mode_plb.c b/drivers/emgd/display/mode/plb/mode_plb.c index ac6ea5d..55a90cc 100644 --- a/drivers/emgd/display/mode/plb/mode_plb.c +++ b/drivers/emgd/display/mode/plb/mode_plb.c @@ -87,6 +87,7 @@ DEFINE_SPINLOCK(vblank_lock_plb); int set_flip_pending_plb(unsigned char *mmio, unsigned long pipe_status_reg); int check_flip_pending_plb(unsigned char *mmio, unsigned long pipe_status_reg); +unsigned long get_port_control_plb(unsigned long port_num, unsigned long port_reg); /*! * @addtogroup display_group * @{ @@ -1917,6 +1918,21 @@ void disable_vblank_callback_plb(emgd_vblank_callback_h callback_h) EMGD_TRACE_EXIT; } +/*! + * checks if the port is enabled + */ +unsigned long get_port_control_plb(unsigned long port_num, unsigned long port_reg) +{ + unsigned long port_value=0; + unsigned char* mmio = NULL; + + EMGD_TRACE_ENTER; + mmio = EMGD_MMIO(mode_context->context->device_context.virt_mmadr); + port_value = EMGD_READ32(mmio+port_reg); + + EMGD_TRACE_EXIT; + return port_value; +} mode_full_dispatch_t mode_full_dispatch_plb = { igd_alter_cursor_pos_plb, @@ -1942,5 +1958,6 @@ mode_full_dispatch_t mode_full_dispatch_plb = { request_vblanks_plb, end_request_plb, vblank_occured_plb, + get_port_control_plb, }; diff --git a/drivers/emgd/display/mode/tnc/kms_mode_tnc.c b/drivers/emgd/display/mode/tnc/kms_mode_tnc.c index 53c2c71..c8932ba 100644 --- a/drivers/emgd/display/mode/tnc/kms_mode_tnc.c +++ b/drivers/emgd/display/mode/tnc/kms_mode_tnc.c @@ -1665,7 +1665,7 @@ static int kms_post_program_port_tnc(emgd_encoder_t * emgd_encoder, if (port->pd_driver->post_set_mode) { if (port->port_type == IGD_PORT_SDVO){ ret = port->pd_driver->post_set_mode(port->pd_context, timings, - status); /*Needed for OKI*/ + status); /*Needed for LAPIS*/ } else { ret = port->pd_driver->post_set_mode(port->pd_context, timings, 1<pipe_num); diff --git a/drivers/emgd/display/mode/tnc/micro_mode_tnc.c b/drivers/emgd/display/mode/tnc/micro_mode_tnc.c index 78f7ba4..3a79817 100644 --- a/drivers/emgd/display/mode/tnc/micro_mode_tnc.c +++ b/drivers/emgd/display/mode/tnc/micro_mode_tnc.c @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: micro_mode_tnc.c - * $Revision: 1.47 $ + * $Revision: 1.47.60.1 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2010, Intel Corporation. * @@ -1755,7 +1755,15 @@ void reset_plane_pipe_ports_tnc(igd_context_t *context) if(port->pd_type == PD_DISPLAY_TVOUT) { tv_port = port; }else { - port->pd_driver->set_power(port->pd_context, IGD_POWERSTATE_D3); + /*CH7036:for Meego killallX issue*/ + if(context->device_context.power_state == IGD_POWERSTATE_D1) { //ACPI + /* D1 power state for graphics is requested*/ + port->pd_driver->set_power(port->pd_context,context->device_context.power_state); + /*pass it to pd */ + } + else { + port->pd_driver->set_power(port->pd_context, IGD_POWERSTATE_D3); + }/* else end*/ } } @@ -2131,7 +2139,7 @@ int post_program_port_tnc(igd_display_context_t *display, #ifndef CONFIG_MICRO if (pt == IGD_PORT_SDVO){ ret = port->pd_driver->post_set_mode(port->pd_context, timings, - status); /*Needed for OKI*/ + status); /*Needed for LAPIS*/ } else { ret = port->pd_driver->post_set_mode(port->pd_context, timings, 1<pipe_num); diff --git a/drivers/emgd/display/mode/tnc/mode_tnc.c b/drivers/emgd/display/mode/tnc/mode_tnc.c index 6c1e34b..b908432 100644 --- a/drivers/emgd/display/mode/tnc/mode_tnc.c +++ b/drivers/emgd/display/mode/tnc/mode_tnc.c @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: mode_tnc.c - * $Revision: 1.36 $ + * $Revision: 1.35.12.1 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2010, Intel Corporation. * @@ -59,7 +59,7 @@ #include #include #include - +#include /* Get this table from clocks_tnc.c, use this in get_pipe_info */ extern unsigned long lvds_m_converts[]; @@ -96,6 +96,7 @@ DEFINE_SPINLOCK(vblank_lock_tnc); int set_flip_pending_tnc(unsigned char *mmio, unsigned long pipe_status_reg); int check_flip_pending_tnc(unsigned char *mmio, unsigned long pipe_status_reg); +unsigned long get_port_control_tnc(unsigned long port_num, unsigned long port_reg); /* KMS callback from emgd_crtc.c */ int crtc_pageflip_handler(struct drm_device *dev, int port); @@ -382,6 +383,8 @@ static int set_color_correct_tnc(igd_display_context_t *display) static int set_display_base_tnc(igd_display_context_t *display, igd_framebuffer_info_t *fb, unsigned long *x, unsigned long *y) { + unsigned long reg; + unsigned long temp; EMGD_TRACE_ENTER; EMGD_DEBUG ("Pan linear to (%lu,%lu)", *x, *y); @@ -390,10 +393,21 @@ static int set_display_base_tnc(igd_display_context_t *display, PLANE(display)->fb_info->visible_offset = ((*y * fb->screen_pitch) + (*x * IGD_PF_BYPP(fb->pixel_format))); - /* Plane registers are always on 0:2:0 */ - WRITE_MMIO_REG(display, PLANE(display)->plane_reg + DSP_LINEAR_OFFSET, - PLANE(display)->fb_info->visible_offset); + temp = PLANE(display)->fb_info->visible_offset; + EMGD_DEBUG ("visible offset = %lx",temp ); + if(PLANE(display)->fb_info->lock) { + + EMGD_DEBUG ("Plane is locked"); + reg = (unsigned long)READ_MMIO_REG(display, PLANE(display)->plane_reg- 4); + EMGD_DEBUG("Plane B start addr = %lx", reg); + reg = (unsigned long)READ_MMIO_REG(display,PLANE(display)->plane_reg + 4); + EMGD_DEBUG("Plane B start offset = %lx", reg); + } else { + /* Plane registers are always on 0:2:0 */ + WRITE_MMIO_REG(display, PLANE(display)->plane_reg + DSP_LINEAR_OFFSET, + PLANE(display)->fb_info->visible_offset); + } EMGD_TRACE_EXIT; return 0; } @@ -887,13 +901,15 @@ static int igd_set_surface_tnc(igd_display_h display_handle, * 1) the plane_reg - 4 if async * 2) plane_reg + DSP_START_OFFSET (+0x1C) if not async */ - EMGD_WRITE32(plane_control, MMIO(display) + plane_reg); - EMGD_WRITE32(surface->pitch, - MMIO(display) + plane_reg + DSP_STRIDE_OFFSET); - EMGD_WRITE32(visible_offset, - MMIO(display) + plane_reg + DSP_LINEAR_OFFSET); - EMGD_WRITE32(surface->offset, - MMIO(display) + plane_reg + DSP_START_OFFSET); + if(!PLANE(display)->fb_info->lock){ + EMGD_WRITE32(plane_control, MMIO(display) + plane_reg); + EMGD_WRITE32(surface->pitch, + MMIO(display) + plane_reg + DSP_STRIDE_OFFSET); + EMGD_WRITE32(visible_offset, + MMIO(display) + plane_reg + DSP_LINEAR_OFFSET); + EMGD_WRITE32(surface->offset, + MMIO(display) + plane_reg + DSP_START_OFFSET); + } EMGD_TRACE_EXIT; return 0; @@ -1057,6 +1073,21 @@ static int get_plane_info_tnc(void) /* Following are NOT offset by 1 in fb info */ buffer_info[0].width++; buffer_info[0].height++; + if((plane_control & (BIT27 | BIT30)) == (BIT27 | BIT30)){ + buffer_info[0].pixel_format = PF_DEPTH_8; + } + if((plane_control & (BIT28 | BIT26)) == (BIT28 | BIT26)){ + buffer_info[0].pixel_format = PF_DEPTH_16; + } + if((plane_control & (BIT28 | BIT27)) == (BIT28 | BIT27)){ + buffer_info[0].pixel_format = PF_DEPTH_32; + } + + EMGD_DEBUG("Plane A info height==%d, width=%d, pitch=%d", buffer_info[0].height, buffer_info[0].width, buffer_info[0].screen_pitch); + reg = (unsigned long)EMGD_READ32(mmio + DSPACNTR - 4); + EMGD_DEBUG("Plane A start addr = %lx", reg); + reg = (unsigned long)EMGD_READ32(mmio + DSPACNTR + 4); + EMGD_DEBUG("Plane A start offset = %lx", reg); } /* Check that plane B is active and process it */ @@ -1076,7 +1107,23 @@ static int get_plane_info_tnc(void) /* Following are NOT offset by 1 in fb info */ buffer_info[1].width++; buffer_info[1].height++; - } + + if((plane_control & (BIT27 | BIT30)) == (BIT27 | BIT30)){ + buffer_info[1].pixel_format = PF_DEPTH_8; + } + if((plane_control & (BIT28 | BIT26)) == (BIT28 | BIT26)){ + buffer_info[1].pixel_format = PF_DEPTH_16; + } + if((plane_control & (BIT28 | BIT27)) == (BIT28 | BIT27)){ + buffer_info[1].pixel_format = PF_DEPTH_32; + } + + EMGD_DEBUG("Plane B info height==%d, width=%d, pitch=%d", buffer_info[1].height, buffer_info[1].width, buffer_info[1].screen_pitch); + reg = (unsigned long)EMGD_READ32(mmio + DSPBCNTR - 4); + EMGD_DEBUG("Plane B start addr = %lx", reg); + reg = (unsigned long)EMGD_READ32(mmio + DSPBCNTR + 4); + EMGD_DEBUG("Plane B start offset = %lx", reg); +} EMGD_TRACE_EXIT; return 0; @@ -1284,32 +1331,32 @@ static int get_pipe_info_tnc(igd_display_h *display) /* For 2nd display pipe, pipe b registers in both 0:2:0 and 0:3:0 * supposed to be programmed to same values. So these values can be * read from either devices */ - pipe_conf = EMGD_READ32(mmio_sdvo + PIPEB_CONF); + pipe_conf = READ_MMIO_REG_TNC(IGD_PORT_SDVO, PIPEB_CONF); if(pipe_conf & BIT(31)) { /* pipe B is active */ timing = &mode_context->fw_info->timing_arr[0]; - reg = EMGD_READ32(mmio_sdvo + HTOTAL_B); + reg = READ_MMIO_REG_TNC(IGD_PORT_SDVO, HTOTAL_B); timing[1].htotal = (unsigned short)(reg >> 16) & 0x1FFF; timing[1].width = (unsigned short)reg & 0xFFF; - reg = EMGD_READ32(mmio + HBLANK_B); + reg = READ_MMIO_REG_TNC(IGD_PORT_SDVO, HBLANK_B); timing[1].hblank_start = (unsigned short)reg & 0x1FFF; timing[1].hblank_end = (unsigned short)(reg >> 16) & 0x1FFF; - reg = EMGD_READ32(mmio + HSYNC_B); + reg = READ_MMIO_REG_TNC(IGD_PORT_SDVO, HSYNC_B); timing[1].hsync_start = (unsigned short)reg & 0x1FFF; timing[1].hsync_end = (unsigned short)(reg >> 16) & 0x1FFF; - reg = EMGD_READ32(mmio + VTOTAL_B); + reg = READ_MMIO_REG_TNC(IGD_PORT_SDVO, VTOTAL_B); timing[1].vtotal = (unsigned short)(reg >> 16) & 0x1FFF; timing[1].height = (unsigned short)reg & 0xFFF; - reg = EMGD_READ32(mmio + VBLANK_B); + reg = READ_MMIO_REG_TNC(IGD_PORT_SDVO, VBLANK_B); timing[1].vblank_start = (unsigned short)reg & 0x1FFF; timing[1].vblank_end = (unsigned short)(reg >> 16) & 0x1FFF; - EMGD_READ32(mmio + VSYNC_B); + READ_MMIO_REG_TNC(IGD_PORT_SDVO, VSYNC_B); timing[1].vsync_start = (unsigned short)reg & 0x1FFF; timing[1].vsync_end = (unsigned short)(reg >> 16) & 0x1FFF; @@ -1322,20 +1369,21 @@ static int get_pipe_info_tnc(igd_display_h *display) unsigned long dpllb, fpb0, fpb1; unsigned long mb1, mb2, nb, pb1, pb2, pllb_select; unsigned long ref_freq = 0, dclk; + unsigned long port_mult = 1; unsigned long temp; /* To store intermediate values b4 dclk */ int j; - dpllb = EMGD_READ32(mmio_sdvo + DPLLBCNTR); - fpb0 = EMGD_READ32(mmio_sdvo + FPB0); - fpb1 = EMGD_READ32(mmio_sdvo + FPB1); + dpllb = READ_MMIO_REG_TNC(IGD_PORT_SDVO, DPLLBCNTR); + fpb0 = READ_MMIO_REG_TNC(IGD_PORT_SDVO, FPB0); + fpb1 = READ_MMIO_REG_TNC(IGD_PORT_SDVO, FPB1); if(dpllb & BIT(31)) { mb1 = (fpb0 >> 8) & 0x3F; /* M1 is bits 13:8 */ - mb2 = (fpb0) & 0x1F; /* M1 is bits 5:0 */ - nb = (fpb0 >> 16) & 0x3F; /* N is bits 21:16 */ + mb2 = (fpb0) & 0xFF; /* M1 is bits 7:0 */ + nb = (fpb0 >> 16) & 0xFF; /* N is bits 23:16 */ pb1 = (dpllb >> 16) & 0xFF; /* P1 is bits 23:16 */ - + port_mult = (((dpllb >> 4) & 0x0F) + 1); /* Check for illegal values of P1 * The bit representation MUST be power of 2 * All other values are illegal including zero. @@ -1346,9 +1394,16 @@ static int get_pipe_info_tnc(igd_display_h *display) return -IGD_ERROR_INVAL; } + /* 0000001 = Divide by two (default value); 0000010 = Divide by three and so on*/ for(j = 0; j < 8; j++) { if(pb1 & BIT(j)) { /* P1 is divide by 1 to 8 */ pb1 = j+1; + break; } + } + + for(j = 0; j < 8; j++) { + if(nb & BIT(j)) { + nb = j+1; break; } } @@ -1399,11 +1454,11 @@ static int get_pipe_info_tnc(igd_display_h *display) * integer division */ temp = 1000 * 1000; - temp = temp * (5 * (mb1+2) + (mb2+2)); - temp = temp /(nb+2); - dclk = temp/(pb1*pb2); - - dclk = temp * ref_freq; + temp = temp * (mb2+2); + temp = temp / nb; + temp = temp/(pb1*pb2); + dclk = temp * ref_freq; + dclk = dclk / port_mult; if( (dclk == 0) || (ref_freq == 0) ) { EMGD_ERROR_EXIT("Dot Clock/Ref Frequency is Zero!!!"); @@ -2045,6 +2100,95 @@ void disable_vblank_callback_tnc(emgd_vblank_callback_h callback_h) EMGD_TRACE_EXIT; } +/*! + * checks if the port is enabled + */ +unsigned long get_port_control_tnc(unsigned long port_num, unsigned long port_reg) +{ + unsigned long port_value=0; + + EMGD_TRACE_ENTER; + if( port_num == IGD_PORT_TYPE_SDVOB) { + port_value = READ_MMIO_REG_TNC(IGD_PORT_SDVO,port_reg); + } else { + port_value = READ_MMIO_REG_TNC(IGD_PORT_LVDS,port_reg); + } + + EMGD_TRACE_EXIT; + return port_value; +} + + +/*! + * locks the plane + * set_surface() and set_display_base_tnc() will not update the registers + * when the planes are locked. + */ +void lock_planes(igd_display_h display_handle) +{ + igd_display_context_t *display = (igd_display_context_t *)display_handle; + + EMGD_TRACE_ENTER; + if(!display){ + EMGD_ERROR_EXIT("Display is NULL"); + return; + } + PLANE(display)->fb_info->lock = TRUE; + EMGD_TRACE_EXIT; +} + + +/*! + * unlocks the plane + * resets the lock flag and writes to plane registers + * + */ +int unlock_planes(igd_display_h display_handle, unsigned int scrn_num) +{ + igd_display_context_t *display = (igd_display_context_t *)display_handle; + unsigned long plane_reg; + unsigned long plane_control; + unsigned long visible_offset; + + EMGD_TRACE_ENTER; + if(!display){ + EMGD_ERROR_EXIT("Display is NULL"); + return FALSE; + } + + /* plane registers are always on 0:2:0, so no need to use _TNC macros */ + plane_reg = PLANE(display)->plane_reg; + plane_control = EMGD_READ32(MMIO(display) + plane_reg); + + /* + * Write the current plane_control value to the plane_reg + * Write the surface stride to DSP_STRIDE_OFFSET + * Write the visible from start of plane to DSP_LINEAR_OFFSET + * Write the base surface offset to either: + */ + PLANE(display)->fb_info->lock = FALSE; + + if(scrn_num == PRIMARY_DISPLAY){ + visible_offset = 0; + }else { + visible_offset = PLANE(display)->fb_info->visible_offset; + } + + EMGD_DEBUG("visible offset= %lx", visible_offset); + + EMGD_WRITE32(plane_control, MMIO(display) + plane_reg); + EMGD_WRITE32(PLANE(display)->fb_info->screen_pitch, + MMIO(display) + plane_reg + DSP_STRIDE_OFFSET); + EMGD_WRITE32(visible_offset, + MMIO(display) + plane_reg + DSP_LINEAR_OFFSET); + EMGD_WRITE32(PLANE(display)->fb_info->fb_base_offset, + MMIO(display) + plane_reg + DSP_START_OFFSET); + EMGD_TRACE_EXIT; + return TRUE; +} + + + mode_full_dispatch_t mode_full_dispatch_tnc = { igd_alter_cursor_pos_tnc, @@ -2070,5 +2214,8 @@ mode_full_dispatch_t mode_full_dispatch_tnc = { request_vblanks_tnc, end_request_tnc, vblank_occured_tnc, + get_port_control_tnc, + lock_planes, + unlock_planes, }; diff --git a/drivers/emgd/display/pi/cmn/pi.c b/drivers/emgd/display/pi/cmn/pi.c index 8eca6c7..119eba7 100755 --- a/drivers/emgd/display/pi/cmn/pi.c +++ b/drivers/emgd/display/pi/cmn/pi.c @@ -459,6 +459,9 @@ int pi_pd_register(pd_driver_t *pd_driver) /* SDVO port driver needs the port number */ port->callback->port_num = port->port_number; + /* SDVO port driver should not reset for seamless mode */ + port->callback->reset = (init_params->qb_seamless == 1) ? 0 : 1; + /* now save the pd_driver in port entry */ port->pd_driver = pd_driver; diff --git a/drivers/emgd/drm/emgd_connector.c b/drivers/emgd/drm/emgd_connector.c index b62c2ca..3ae2b23 100644 --- a/drivers/emgd/drm/emgd_connector.c +++ b/drivers/emgd/drm/emgd_connector.c @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: emgd_connector.c - * $Revision: 1.3 $ + * $Revision: 1.2.106.1 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2011, Intel Corporation. * @@ -37,6 +37,7 @@ #include "drm_emgd_private.h" +#include "user_config.h" @@ -60,7 +61,7 @@ static struct drm_encoder *emgd_connector_best_encoder( struct drm_connector *connector); static void emgd_connector_save (struct drm_connector *connector); static void emgd_connector_restore (struct drm_connector *connector); - +extern emgd_drm_config_t config_drm; const struct drm_connector_funcs emgd_connector_funcs = { @@ -106,6 +107,13 @@ static void emgd_mode_to_kms(igd_display_info_t *emgd_mode, drm_mode->flags = emgd_mode->flags; drm_mode->vrefresh = emgd_mode->refresh; + if ((unsigned short)config_drm.width == emgd_mode->width && + (unsigned short)config_drm.height == emgd_mode->height && + (unsigned short)config_drm.refresh == emgd_mode->refresh) { + + drm_mode->type |= DRM_MODE_TYPE_PREFERRED; + } + drm_mode_set_name(drm_mode); } diff --git a/drivers/emgd/drm/emgd_crtc.c b/drivers/emgd/drm/emgd_crtc.c index c38e4f0..f08994e 100644 --- a/drivers/emgd/drm/emgd_crtc.c +++ b/drivers/emgd/drm/emgd_crtc.c @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: emgd_crtc.c - * $Revision: 1.7 $ + * $Revision: 1.4.14.1 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2011, Intel Corporation. * @@ -158,55 +158,42 @@ static void emgd_crtc_dpms(struct drm_crtc *crtc, int mode) EMGD_DEBUG("pipe=%d, mode=%d", emgd_crtc->crtc_id, mode); pipe = emgd_crtc->igd_pipe; - /* The following check is a work around.KMS tries to program - * both the crtcs and ports (LVDS and SDVO) even if it is in - * single mode. It results in a SIGSEGV. - * By putting this check we ensure that it moves forward - * only if there is a valid context associated with the - * crtc. We check it by checking the owner of the pipe which - * should not be null. - */ - if (pipe->owner){ - - switch(mode) { - - case DRM_MODE_DPMS_ON: - EMGD_DEBUG("Checking if we have pipe timings"); - if (!pipe->timing) { - /* If there is no pipe timing, we cannot enable */ - EMGD_ERROR("No pipe timing, can't enable pipe=%d, mode=%d", - emgd_crtc->crtc_id, DRM_MODE_DPMS_ON ); - } else { - EMGD_DEBUG("Calling program pipe"); - mode_context->kms_dispatch->kms_program_pipe(emgd_crtc); - EMGD_DEBUG("Calling program plane"); - mode_context->kms_dispatch-> - kms_set_plane_pwr(emgd_crtc, TRUE); - - crtc->enabled = true; - } - break; - - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - if (emgd_crtc->igd_pipe->inuse && crtc->enabled) { - EMGD_DEBUG("Calling program plane"); - mode_context->kms_dispatch-> - kms_set_plane_pwr(emgd_crtc, FALSE); - - EMGD_DEBUG("Calling program pipe"); - mode_context->kms_dispatch-> - kms_set_pipe_pwr(emgd_crtc, FALSE); - crtc->enabled = false; - }else { - EMGD_ERROR("pipe is already off"); - } - break; - default: - break; + + switch(mode) { + case DRM_MODE_DPMS_ON: + EMGD_DEBUG("Checking if we have pipe timings"); + if (!pipe->timing) { + /* If there is no pipe timing, we cannot enable */ + EMGD_ERROR("No pipe timing, can't enable pipe"); + } else { + EMGD_DEBUG("Calling program pipe"); + mode_context->kms_dispatch->kms_program_pipe(emgd_crtc); + + EMGD_DEBUG("Calling program plane"); + mode_context->kms_dispatch->kms_set_plane_pwr(emgd_crtc, TRUE); + + crtc->enabled = true; } + break; + + case DRM_MODE_DPMS_STANDBY: + case DRM_MODE_DPMS_SUSPEND: + case DRM_MODE_DPMS_OFF: + if (emgd_crtc->igd_pipe->inuse && crtc->enabled) { + EMGD_DEBUG("Calling program plane"); + mode_context->kms_dispatch->kms_set_plane_pwr(emgd_crtc, FALSE); + + EMGD_DEBUG("Calling program pipe"); + mode_context->kms_dispatch->kms_set_pipe_pwr(emgd_crtc, FALSE); + crtc->enabled = false; + } else { + EMGD_ERROR("pipe is already off"); + } + break; + default: + break; } + EMGD_TRACE_EXIT; } @@ -702,7 +689,6 @@ int crtc_pageflip_handler(struct drm_device *dev, int port_num) } } - emgd_crtc = devpriv->crtcs[crtcnum]; /* Protect access to CRTC */ diff --git a/drivers/emgd/drm/emgd_drv.c b/drivers/emgd/drm/emgd_drv.c index 3a87fd6..d715842 100644 --- a/drivers/emgd/drm/emgd_drv.c +++ b/drivers/emgd/drm/emgd_drv.c @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: emgd_drv.c - * $Revision: 1.147 $ + * $Revision: 1.145.28.6 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2010, Intel Corporation. * @@ -82,6 +82,10 @@ extern int msvdx_pre_init_plb(struct drm_device *dev); extern int msvdx_shutdown_plb(igd_context_t *context); extern emgd_drm_config_t config_drm; extern int context_count; +#ifdef SUPPORT_V2G_CAMERA +/* V2G Camera Module Exported API */ +extern int v2g_start_camera(); +#endif extern void emgd_drm_override_user_config(int type); /* This must be defined whether debug or release build */ @@ -391,6 +395,8 @@ static struct drm_ioctl_desc emgd_ioctl[] = { DRM_MASTER|DRM_UNLOCKED), EMGD_IOCTL_DEF(DRM_IOCTL_IGD_DIHCLONE_SET_SURFACE, emgd_dihclone_set_surface, DRM_MASTER|DRM_UNLOCKED), EMGD_IOCTL_DEF(DRM_IOCTL_IGD_PREINIT_MMU, emgd_preinit_mmu, DRM_MASTER|DRM_UNLOCKED), + EMGD_IOCTL_DEF(DRM_IOCTL_IGD_UNLOCK_PLANES, emgd_unlock_planes, DRM_MASTER|DRM_UNLOCKED), + /* * For VIDEO (MSVDX/TOPAZ @@ -408,19 +414,19 @@ static struct drm_ioctl_desc emgd_ioctl[] = { /* For Buffer Class of Texture Stream */ EMGD_IOCTL_DEF(DRM_IOCTL_IGD_BC_TS_INIT, emgd_bc_ts_cmd_init, - DRM_AUTH|DRM_UNLOCKED), + DRM_AUTH), EMGD_IOCTL_DEF(DRM_IOCTL_IGD_BC_TS_UNINIT, emgd_bc_ts_cmd_uninit, - DRM_AUTH|DRM_UNLOCKED), + DRM_AUTH), EMGD_IOCTL_DEF(DRM_IOCTL_IGD_BC_TS_REQUEST_BUFFERS, emgd_bc_ts_cmd_request_buffers, - DRM_AUTH|DRM_UNLOCKED), + DRM_AUTH), EMGD_IOCTL_DEF(DRM_IOCTL_IGD_BC_TS_RELEASE_BUFFERS, emgd_bc_ts_cmd_release_buffers, - DRM_AUTH|DRM_UNLOCKED), + DRM_AUTH), EMGD_IOCTL_DEF(DRM_IOCTL_IGD_BC_TS_SET_BUFFER_INFO, emgd_bc_ts_set_buffer_info, - DRM_AUTH|DRM_UNLOCKED), + DRM_AUTH), EMGD_IOCTL_DEF(DRM_IOCTL_IGD_BC_TS_GET_BUFFERS_COUNT, emgd_bc_ts_get_buffers_count, - DRM_AUTH|DRM_UNLOCKED), + DRM_AUTH), EMGD_IOCTL_DEF(DRM_IOCTL_IGD_BC_TS_GET_BUFFER_INDEX, emgd_bc_ts_get_buffer_index, - DRM_AUTH|DRM_UNLOCKED), + DRM_AUTH), }; static int emgd_max_ioctl = DRM_ARRAY_SIZE(emgd_ioctl); @@ -459,7 +465,75 @@ static igd_context_t *drm_HAL_context = NULL; static igd_dispatch_t *drm_HAL_dispatch = NULL; +int emgd_get_display_handle(void **display_handle, int screen_number) +{ + emgd_drm_get_display_t drm_data; + struct drm_file file_priv; + int ret; + drm_emgd_priv_t *priv = NULL; + igd_display_pipe_t *primary_pipe = NULL; + igd_display_pipe_t *secondary_pipe = NULL; + igd_plane_t *primary_plane = NULL; + igd_plane_t *secondary_plane = NULL; + unsigned long pipe_num = 0; + unsigned long port_num = 0; + EMGD_TRACE_ENTER; + + memset(&drm_data, 0, sizeof(emgd_drm_get_display_t)); + memset(&file_priv, 0, sizeof(struct drm_file)); + + drm_HAL_context->mod_dispatch.dsp_get_planes_pipes(&primary_plane, &secondary_plane, &primary_pipe, &secondary_pipe); + + priv = (drm_emgd_priv_t *)((struct drm_device *)drm_HAL_context->drm_dev)->dev_private; + + if (0 == screen_number) { + if (NULL == priv->primary || NULL == primary_pipe) { + EMGD_ERROR("Primary Display & Pipe does not exist!"); + return 1; + } + port_num = priv->primary_port_number; + pipe_num = primary_pipe->pipe_num; + } else { + if (NULL == priv->secondary || NULL == secondary_pipe ) { + EMGD_ERROR("Secondary Display does not exist!"); + return 1; + } + port_num = priv->secondary_port_number; + pipe_num = secondary_pipe->pipe_num; + } + + drm_data.port_number = port_num; + + ret = emgd_get_display(drm_HAL_context->drm_dev, (void *)&drm_data, &file_priv); + + /* set the requested display handle for the caller */ + *display_handle = ret ? NULL : (void *)drm_data.display_handle; + if (NULL != *display_handle) { + PIPE(*display_handle)->pipe_num = pipe_num; + EMGD_DEBUG("port_num: %lu, pipe_number: %lu", port_num, pipe_num); + } + + EMGD_TRACE_EXIT; + return ret; +} +EXPORT_SYMBOL(emgd_get_display_handle); + +int emgd_get_screen_size(int screen_num, unsigned short *width, unsigned short *height) +{ + EMGD_TRACE_ENTER; + + if (NULL == width || NULL == height) { + return 1; + } + + *width = (unsigned short)config_drm.width; + *height = (unsigned short)config_drm.height; + + EMGD_TRACE_EXIT; + return 0; +} +EXPORT_SYMBOL(emgd_get_screen_size); /*! * get_pre_driver_info * @@ -663,7 +737,6 @@ int emgd_startup_hal(struct drm_device *dev, igd_param_t *params) EMGD_TRACE_ENTER; - /* Initialize the various HAL modules: */ EMGD_DEBUG("Calling igd_module_init()"); @@ -1015,7 +1088,11 @@ void emgd_init_display(int merge_mod_params, drm_emgd_priv_t *priv) *************************************/ temp_bg_color = mode_context->display_color; mode_context->display_color = config_drm.ss_data->bg_color; - full_clear_fb(mode_context, primary_fb_info, fb); + if(mode_context->seamless == FALSE) + { + full_clear_fb(mode_context, primary_fb_info, fb); + } + mode_context->display_color = temp_bg_color; /************************************* @@ -1048,6 +1125,8 @@ void emgd_init_display(int merge_mod_params, drm_emgd_priv_t *priv) EMGD_ERROR("framebuffer base address is 0"); } + mode_context->seamless = FALSE; + if (!config_drm.kms) { mode_context->context->dispatch.gmm_unmap(fb); } @@ -1389,6 +1468,17 @@ int emgd_driver_load(struct drm_device *dev, unsigned long flags) } #endif +#ifdef SUPPORT_V2G_CAMERA + /* to start v2g camera module */ + if (1 == config_drm.v2g) { + EMGD_DEBUG("V2G Camera Enabled."); + if (0 == v2g_start_camera()) { + EMGD_DEBUG("v2g camera started successfully!"); + } else { + EMGD_ERROR("Fail to start v2g camera!"); + } + } +#endif /* can not work out how to start PVRSRV */ /* Load Buffer Class Module*/ emgd_bc_ts_init(); @@ -2389,7 +2479,6 @@ static struct pci_driver emgd_pci_driver = EMGD_PCI_DRIVER; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) static const struct file_operations emgd_driver_fops = EMGD_FOPS; #endif - /** * DRM Sub driver entry points */ diff --git a/drivers/emgd/drm/emgd_drv.h b/drivers/emgd/drm/emgd_drv.h index c7e334a..274be55 100644 --- a/drivers/emgd/drm/emgd_drv.h +++ b/drivers/emgd/drm/emgd_drv.h @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: emgd_drv.h - * $Revision: 1.76 $ + * $Revision: 1.76.28.1 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2010, Intel Corporation. * @@ -198,6 +198,8 @@ int emgd_set_overlay_display(struct drm_device *dev, void *arg, struct drm_file *file_priv); int emgd_query_2d_caps_hwhint(struct drm_device *dev, void *arg, struct drm_file *file_priv); +int emgd_unlock_planes(struct drm_device *dev, void *arg, + struct drm_file *file_priv); /* For Buffer Class of Texture Stream */ int emgd_bc_ts_cmd_init(struct drm_device *dev, void *arg, struct drm_file *file_priv); int emgd_bc_ts_cmd_uninit(struct drm_device *dev, void *arg, struct drm_file *file_priv); diff --git a/drivers/emgd/drm/emgd_fb.c b/drivers/emgd/drm/emgd_fb.c index 6e8b368..deaf38e 100644 --- a/drivers/emgd/drm/emgd_fb.c +++ b/drivers/emgd/drm/emgd_fb.c @@ -876,7 +876,7 @@ static struct drm_framebuffer *emgd_user_framebuffer_create( /* TODO: Free the allocation at mode_cmd->handle */ kfree(emgd_fb); emgd_fb = NULL; - return NULL; + return (void *)-EINVAL; } EMGD_TRACE_EXIT; diff --git a/drivers/emgd/drm/emgd_fbcon.c b/drivers/emgd/drm/emgd_fbcon.c index d3f02b3..348f282 100644 --- a/drivers/emgd/drm/emgd_fbcon.c +++ b/drivers/emgd/drm/emgd_fbcon.c @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: emgd_fbcon.c - * $Revision: 1.5 $ + * $Revision: 1.4.14.1 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2011, Intel Corporation. * diff --git a/drivers/emgd/drm/emgd_interface.c b/drivers/emgd/drm/emgd_interface.c index fc2c918..8b717c0 100644 --- a/drivers/emgd/drm/emgd_interface.c +++ b/drivers/emgd/drm/emgd_interface.c @@ -1,6 +1,6 @@ /*----------------------------------------------------------------------------- * Filename: emgd_interface.c - * $Revision: 1.191 $ + * $Revision: 1.190.12.1 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2010, Intel Corporation. * @@ -2728,3 +2728,14 @@ int emgd_query_2d_caps_hwhint(struct drm_device *dev, void *arg, return 0; } + +int emgd_unlock_planes(struct drm_device *dev, void *arg, + struct drm_file *file_priv) +{ + emgd_drm_unlock_planes_t *drm_data; + drm_data = arg; + + /* do plane unlocking */ + drm_data->rtn = dispatch->unlock_planes(drm_data->display_handle, drm_data->screen_num); + return 0; +} diff --git a/drivers/emgd/drm/user_config.c b/drivers/emgd/drm/user_config.c index c3848bc..31efee7 100644 --- a/drivers/emgd/drm/user_config.c +++ b/drivers/emgd/drm/user_config.c @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: user_config.c - * $Revision: 1.24 $ + * $Revision: 1.24.60.2 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2010, Intel Corporation. * @@ -581,6 +581,10 @@ emgd_drm_config_t config_drm = { &config_params_config4, &config_params_config5 } +#ifdef SUPPORT_V2G_CAMERA + , + 0 /* disable v2g camera*/ +#endif }; diff --git a/drivers/emgd/drm/user_config.h b/drivers/emgd/drm/user_config.h index 7c60a79..f5f2627 100644 --- a/drivers/emgd/drm/user_config.h +++ b/drivers/emgd/drm/user_config.h @@ -111,6 +111,10 @@ typedef struct _emgd_drm_config { * abstraction layer code. */ igd_param_t *hal_params[USER_CONFIG_NUM]; + /** Enable V2G Camera Module **/ +#ifdef SUPPORT_V2G_CAMERA + int v2g; +#endif } emgd_drm_config_t; #endif diff --git a/drivers/emgd/gmm/gmm.c b/drivers/emgd/gmm/gmm.c index b44dec7..6e0b751 100644 --- a/drivers/emgd/gmm/gmm.c +++ b/drivers/emgd/gmm/gmm.c @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: gmm.c - * $Revision: 1.53 $ + * $Revision: 1.53.6.1 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2010, Intel Corporation. * @@ -41,6 +41,7 @@ #include #include +#include "igd_gmm.h" #define AGP_PHYS_MEMORY 2 /* Physical contigous memory */ struct emgd_ci_surface_t{ @@ -49,6 +50,7 @@ struct emgd_ci_surface_t{ unsigned int virt; unsigned long size; unsigned long gtt_offset; + unsigned long vbufqueue_handle; }; #define MAX_CI_LIST_SIZE 14 struct emgd_ci_surface_t ci_surfaces[MAX_CI_LIST_SIZE]; @@ -885,13 +887,17 @@ int gmm_map_to_graphics(unsigned long phys_addr, EMGD_TRACE_EXIT; return ret; } +EXPORT_SYMBOL(gmm_map_to_graphics); + + + /* * find gtt_offset and virtual address from ci_surface list according to the same v4l2_offset */ static int gmm_map_ci(unsigned long *gtt_offset, - unsigned long ci_param, /* virtaddr or v4l2_offset */ + unsigned long ci_param, /* cast to (struct emgd_ci_meminfo_t *) */ unsigned long *virt_addr, unsigned int map_method, unsigned long size) @@ -899,9 +905,14 @@ static int gmm_map_ci(unsigned long *gtt_offset, { unsigned char i; int ret; + struct emgd_ci_meminfo_t * ci_meminfo; + unsigned long virt; + + ci_meminfo = (struct emgd_ci_meminfo_t *)ci_param; + virt = ci_meminfo->virt; if(map_method){ - ret = gmm_map_to_graphics(virt_to_phys((unsigned long *)ci_param),size,gtt_offset); + ret = gmm_map_to_graphics(virt_to_phys((unsigned long *)virt),size,gtt_offset); if(ret) return ret; else{ @@ -910,10 +921,10 @@ static int gmm_map_ci(unsigned long *gtt_offset, if(!ci_surfaces[i].used){ ci_surfaces[i].used = 1; - ci_surfaces[i].virt = ci_param; + ci_surfaces[i].virt = virt; ci_surfaces[i].size = size; ci_surfaces[i].gtt_offset = *gtt_offset; - *virt_addr = ci_param; + *virt_addr = virt; break; } } @@ -922,7 +933,8 @@ static int gmm_map_ci(unsigned long *gtt_offset, else{ for(i=0;ivbufqueue_handle) + && (ci_surfaces[i].v4l2_offset ==ci_meminfo->v4l2_offset)){ *gtt_offset = ci_surfaces[i].gtt_offset; *virt_addr = ci_surfaces[i].virt; @@ -1112,7 +1124,12 @@ static int gmm_alloc_chunk_space(gmm_context_t *gmm_context, * */ if (gmm_context->tail_chunk == NULL) { - chunk->offset = 0; + /* 1st ever chunk */ + if(gmm_context->context->mod_dispatch.init_params->qb_seamless) { + chunk->offset = (gmm_context->context->device_context.stolen_pages) * PAGE_SIZE; + } else { + chunk->offset = 0; + } } else { chunk->offset = gmm_context->tail_chunk->offset + gmm_context->tail_chunk->size; @@ -1187,7 +1204,6 @@ static int gmm_import_pages(void **pagelist, unsigned long numpages) { gmm_chunk_t *chunk; - EMGD_TRACE_ENTER; EMGD_DEBUG("Importing %lu pages into GTT\n", numpages); @@ -1233,7 +1249,11 @@ static int gmm_import_pages(void **pagelist, if (gmm_context.tail_chunk == NULL) { /* First chunk ever! */ gmm_context.head_chunk = chunk; - chunk->offset = 0; + if(gmm_context.context->mod_dispatch.init_params->qb_seamless) { + chunk->offset = (gmm_context.context->device_context.stolen_pages) * PAGE_SIZE; + } else { + chunk->offset = 0; + } } else { chunk->offset = gmm_context.tail_chunk->offset + gmm_context.tail_chunk->size; @@ -1343,12 +1363,6 @@ static int gmm_get_page_list(unsigned long offset, return 0; } -struct emgd_ci_meminfo_t { - unsigned long v4l2_offset; - unsigned long virt; - unsigned long size; - }; - int emgd_map_ci_buf(struct emgd_ci_meminfo_t * ci_meminfo) { int ret; @@ -1363,9 +1377,11 @@ int emgd_map_ci_buf(struct emgd_ci_meminfo_t * ci_meminfo) for(i=0;ivirt); + ci_surfaces[i].virt = ci_meminfo->virt; ci_surfaces[i].size = ci_meminfo->size; ci_surfaces[i].gtt_offset = gtt_offset; + ci_surfaces[i].vbufqueue_handle = ci_meminfo->vbufqueue_handle; + ci_surfaces[i].v4l2_offset = ci_meminfo->v4l2_offset; return 0; } } diff --git a/drivers/emgd/gmm/gtt.c b/drivers/emgd/gmm/gtt.c index f530ca6..e426dd5 100644 --- a/drivers/emgd/gmm/gtt.c +++ b/drivers/emgd/gmm/gtt.c @@ -172,6 +172,8 @@ gmm_mem_buffer_t *emgd_alloc_pages(unsigned long num_pages, int type) { struct page *page; int i; int order; + long num_pages_left = num_pages; + unsigned long num_pages_done = 0; mem = (gmm_mem_buffer_t *)kzalloc(sizeof(gmm_mem_buffer_t), GFP_KERNEL); if (mem == NULL) { @@ -207,38 +209,67 @@ gmm_mem_buffer_t *emgd_alloc_pages(unsigned long num_pages, int type) { * mem->pages[1] = mem->pages[0] + PAGE_SIZE */ - if ((type == 1) || (type == 0)) { - /* Next allocate the pages */ - for (i = 0; i < num_pages; i++) { - page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO); - if (page == NULL) { + if ((type == 1) || (type == 0)) + { + /* Next allocate the pages */ + + for( i = 0; num_pages_left > 0; i++) + { + int j; + unsigned long num_pages_block; + + /* calculate order for the page block */ + + for( order = 0; order < MAX_ORDER; order++ ) + { + int temp_num_pages = POW2( order ); + + if( temp_num_pages == num_pages_left ) + break; + if( temp_num_pages > num_pages_left ) + { + --order; + break; + } + if( temp_num_pages == MAX_ORDER_NR_PAGES ) + break; + } + + num_pages_block = POW2( order ); + page = alloc_pages(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO | __GFP_COMP, order); + + if(page == NULL) + { /* Error! */ printk(KERN_ERR "[EMGD] Memory allocation failure!\n"); - if (mem->vmalloc_flag) { - vfree(mem->pages); - } else { - kfree(mem->pages); - } - kfree(mem); + emgd_free_pages(mem); + return NULL; } - /* Make sure this page isn't cached */ - if (set_memory_uc((unsigned long) page_address(page), 1) < 0) { + /* Make sure this page block isn't cached */ + if (set_memory_uc((unsigned long) page_address(page), num_pages_block) < 0) { printk(KERN_ERR "[EMGD] Unable to set page attributes for newly" " allocated graphics memory.\n"); /* Rely on the fact that we've kept up the data structures: */ emgd_free_pages(mem); /* XXX - THIS IS WHAT SOME OLD IEGD CODE DID--A GOOD IDEA??? */ - set_memory_wb((unsigned long) page_address(page), 1); - __free_page(page); + set_memory_wb((unsigned long) page_address(page), num_pages_block); + __free_pages(page, order); return NULL; } - get_page(page); - mem->pages[i] = page; - mem->page_count++; + get_page( page ); + for( j = 0; j < num_pages_block; j++ ) + { + mem->pages[ num_pages_done + j ] = page + j; + } + + num_pages_done += num_pages_block; + num_pages_left -= num_pages_block; + mem->page_count = num_pages_done; } + } else { if (num_pages == 1) { order = 0; @@ -277,7 +308,7 @@ gmm_mem_buffer_t *emgd_alloc_pages(unsigned long num_pages, int type) { " allocated physical graphics memory.\n"); /* XXX - THIS IS WHAT SOME OLD IEGD CODE DID--A GOOD IDEA??? */ set_memory_wb((unsigned long) page_address(page), num_pages); - __free_pages(page, num_pages); + __free_pages(page, order); if (mem->vmalloc_flag) { vfree(mem->pages); } else { @@ -306,16 +337,49 @@ gmm_mem_buffer_t *emgd_alloc_pages(unsigned long num_pages, int type) { * Free memory pages. */ void emgd_free_pages(gmm_mem_buffer_t *mem) { - int i; + int i, order; struct page *page; + long num_pages_left = mem->page_count; + unsigned long num_pages_done = 0; + + for( i = 0; num_pages_left > 0; i++) + { + int j; + unsigned long num_pages_block; + + /* calculate order for the page block */ + + for( order = 0; order < MAX_ORDER; order++ ) + { + int temp_num_pages = POW2( order ); + + if( temp_num_pages == num_pages_left ) + break; + if( temp_num_pages > num_pages_left ) + { + --order; + break; + } + if( temp_num_pages == MAX_ORDER_NR_PAGES ) + break; + } + + num_pages_block = POW2( order ); + page = mem->pages[ num_pages_done ]; - for (i = 0; i < mem->page_count; i++) { - page = mem->pages[i]; /* XXX - THIS IS WHAT SOME OLD IEGD CODE DID--A GOOD IDEA??? */ - set_memory_wb((unsigned long) page_address(page), 1); - put_page(page); - __free_page(page); - mem->pages[i] = NULL; + set_memory_wb((unsigned long) page_address(page), num_pages_block); + + put_page( page ); + for( j = 0; j < num_pages_block; j++ ) + { + mem->pages[ num_pages_done + j ] = NULL; + } + + __free_pages(page, order); + + num_pages_done += num_pages_block; + num_pages_left -= num_pages_block; } if (mem->vmalloc_flag) { diff --git a/drivers/emgd/include/context.h b/drivers/emgd/include/context.h index c1afb31..be7757b 100644 --- a/drivers/emgd/include/context.h +++ b/drivers/emgd/include/context.h @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: context.h - * $Revision: 1.22 $ + * $Revision: 1.22.60.1 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2010, Intel Corporation. * @@ -77,6 +77,8 @@ typedef struct _inter_module_dispatch { struct _igd_display_port *port, struct _pd_timing *in_list); + unsigned long (*get_port_control)(unsigned long port_num, unsigned long port_reg); + /* FIXME: This should be a dsp function */ unsigned long (*mode_get_gpio_sets)(unsigned long **gpio); @@ -230,6 +232,7 @@ typedef struct _device_context { unsigned long hw_status_offset; /* Hw status page offset */ unsigned short gfx_freq; /* Graphics Frequency, used to calculate PWM */ unsigned short core_freq; /* Core Frequency, used to calculate DPLL freq */ + int valid_firmware_init; /* PSB_PGETBL_CTL != 0 */ } device_context_t; struct _igd_context { diff --git a/drivers/emgd/include/msvdx.h b/drivers/emgd/include/msvdx.h index f0699af..01be26c 100644 --- a/drivers/emgd/include/msvdx.h +++ b/drivers/emgd/include/msvdx.h @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: msvdx.h - * $Revision: 1.21 $ + * $Revision: 1.20 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2010, Intel Corporation. * diff --git a/drivers/emgd/include/pd.h b/drivers/emgd/include/pd.h index 388a2af..a12cac5 100644 --- a/drivers/emgd/include/pd.h +++ b/drivers/emgd/include/pd.h @@ -372,6 +372,7 @@ typedef struct _pd_callback { pd_write_regs_p write_regs; unsigned long port_num; /* Added for SDVO port driver */ cea_extension_t **eld; /* EDID like Data */ + unsigned char reset; }pd_callback_t; /* IMP NOTE: All below structures should be with same size. diff --git a/drivers/emgd/pal/ch7036/ch7036_port.c b/drivers/emgd/pal/ch7036/ch7036_port.c index 1d33f50..275625d 100644 --- a/drivers/emgd/pal/ch7036/ch7036_port.c +++ b/drivers/emgd/pal/ch7036/ch7036_port.c @@ -546,9 +546,6 @@ int ch7036_post_set_mode(void *p_context, pd_timing_t *p_mode, int ret; - - - if (!p_ctx || !p_mode ) { return (PD_ERR_NULL_PTR); } @@ -597,7 +594,7 @@ int ch7036_post_set_mode(void *p_context, pd_timing_t *p_mode, #endif - return PD_SUCCESS; + return p_ctx->pwr_state = PD_POWER_MODE_D0; } @@ -1339,6 +1336,11 @@ int ch7036_restore(void *p_context, void *state, unsigned long flags) return PD_INTERNAL_LVDS_MODULE_RESTORE(ch7036_restore,(p_ctx->internal_lvds, state, flags)); #endif +#ifdef T_LINUX + if(p_ctx->pwr_state=! PD_POWER_MODE_D1) + return PD_SUCCESS; +#endif + if (ch7036_load_firmware(p_ctx) != SS_SUCCESS) { PD_DEBUG("ch7036: ch7036_restore()- load fw is NOT a SUCCESS\n"); diff --git a/drivers/emgd/pal/sdvo/sdvo_attr.c b/drivers/emgd/pal/sdvo/sdvo_attr.c index 6d2d3c8..81f458a 100644 --- a/drivers/emgd/pal/sdvo/sdvo_attr.c +++ b/drivers/emgd/pal/sdvo/sdvo_attr.c @@ -1085,7 +1085,7 @@ unsigned long sdvo_get_bool_attrs(sdvo_device_context_t *p_ctx, num_attrs = 0; for (i = 0; i < ARRAY_SIZE(g_bool_data); i++) { - if((p_ctx->dev_cap.vendor_id == VENDOR_ID_OKI) && + if((p_ctx->dev_cap.vendor_id == VENDOR_ID_LAPIS) && (p_ctx->dev_cap.device_id == 0x1) && ((g_bool_data[i].id == PD_ATTR_ID_PANEL_PROTECT_HSYNC) || (g_bool_data[i].id == PD_ATTR_ID_PANEL_PROTECT_VSYNC))) { @@ -1117,7 +1117,7 @@ unsigned long sdvo_get_bool_attrs(sdvo_device_context_t *p_ctx, p_attr_cur->type = PD_ATTR_TYPE_BOOL; p_attr_cur->flags |= PD_ATTR_FLAG_DYNAMIC; - if((p_ctx->dev_cap.vendor_id == VENDOR_ID_OKI) && + if((p_ctx->dev_cap.vendor_id == VENDOR_ID_LAPIS) && (p_ctx->dev_cap.device_id == 0x1) && ((g_bool_data[i].id == PD_ATTR_ID_PANEL_PROTECT_HSYNC) || (g_bool_data[i].id == PD_ATTR_ID_PANEL_PROTECT_VSYNC))) { diff --git a/drivers/emgd/pal/sdvo/sdvo_port.c b/drivers/emgd/pal/sdvo/sdvo_port.c index 7651199..2b4017e 100644 --- a/drivers/emgd/pal/sdvo/sdvo_port.c +++ b/drivers/emgd/pal/sdvo/sdvo_port.c @@ -1842,12 +1842,12 @@ int sdvo_open(pd_callback_t *p_callback, void **pp_context) #ifndef CONFIG_MICRO /* reset context to avoid wrong timing list */ - if ((p_ctx->dev_cap.vendor_id != VENDOR_ID_OKI) - && (p_ctx->dev_cap.device_id != 0x1)){ + if ((p_ctx->dev_cap.vendor_id != VENDOR_ID_LAPIS) + && (p_ctx->dev_cap.device_id != 0x1) && p_callback->reset ){ + printk(KERN_INFO"@@@@@@@@resetting encoder\n"); sdvo_reset_encoder(p_ctx); } #endif - status = sdvo_get_device_capabilities(p_ctx, &p_ctx->dev_cap); if (status != SS_SUCCESS) { @@ -1916,7 +1916,7 @@ int sdvo_open(pd_callback_t *p_callback, void **pp_context) #ifndef CONFIG_MICRO /*We want this in (Windows XP driver) AND (in VBIOS when LVDS is not linked.)*/ - if ((p_ctx->dev_cap.vendor_id == VENDOR_ID_OKI) + if ((p_ctx->dev_cap.vendor_id == VENDOR_ID_LAPIS) && (p_ctx->dev_cap.device_id == 0x1)){ status = sdvo_set_target_input(p_ctx, p_ctx->inp_dev); if (status != SS_SUCCESS) { @@ -2417,13 +2417,13 @@ int sdvo_set_mode(void *p_context, pd_timing_t *p_mode, unsigned long flags) #ifndef CONFIG_MICRO /*We want this in (Windows XP driver) AND (in VBIOS when LVDS is not linked.)*/ - /* This workaround needed for OKI solution only. + /* This workaround needed for LAPIS solution only. It would probably give problem if the SDVO is connected to - analog display, but that is not the usage model for OKI. + analog display, but that is not the usage model for LAPIS. */ - if ((p_ctx->dev_cap.vendor_id == VENDOR_ID_OKI) + if ((p_ctx->dev_cap.vendor_id == VENDOR_ID_LAPIS) && (p_ctx->dev_cap.device_id == 0x1)){ - /* The OKI SDVO receiver to return “Invalid Argument” when: + /* The LAPIS SDVO receiver to return “Invalid Argument” when: (1) Horizontal Active < 600 (2) Horizontal Blanking < 16 (3) HSync pulse width < 2 @@ -2528,8 +2528,8 @@ int sdvo_post_set_mode(void *p_context, pd_timing_t *p_mode, PD_DEBUG("sdvo: sdvo_post_set_mode()"); #ifndef CONFIG_MICRO - /* This is a workaround specific to OKI */ - if((p_ctx->dev_cap.vendor_id == VENDOR_ID_OKI) + /* This is a workaround specific to LAPIS */ + if((p_ctx->dev_cap.vendor_id == VENDOR_ID_LAPIS) && (p_ctx->dev_cap.device_id == 0x1)){ pd_timing_t local_p_mode; @@ -2538,7 +2538,7 @@ int sdvo_post_set_mode(void *p_context, pd_timing_t *p_mode, local_p_mode = *p_mode; sdvo_reset_encoder(p_context); - /* sdvo_reset(p_context);*/ /* THIS is workaround for OKI SDVO flashing issue.*/ + /* sdvo_reset(p_context);*/ /* THIS is workaround for LAPIS SDVO flashing issue.*/ sdvo_set_power(p_context, 0); if (p_ctx->display_pwr_state == 0x0) { @@ -2695,11 +2695,11 @@ int sdvo_get_attributes(void *p_context, unsigned long *p_num_attr, return 0; } #ifndef CONFIG_MICRO - /* This is a workaround specific to OKI */ - if(p_ctx->dev_cap.vendor_id == VENDOR_ID_OKI + /* This is a workaround specific to LAPIS */ + if(p_ctx->dev_cap.vendor_id == VENDOR_ID_LAPIS && p_ctx->dev_cap.device_id == 0x1){ /* TODO: sdvo_set_target_output return pending when the power state is D3 on - * ML7213 A0. other sdvo cards don't have this problem and OKI don't see + * ML7213 A0. other sdvo cards don't have this problem and LAPIS don't see * this problem on their site. verify this on A1 and remove the code if * it return success */ sdvo_set_power(p_ctx, PD_POWER_MODE_D0); @@ -3868,7 +3868,7 @@ int sdvo_is_multi_display_device(sdvo_device_context_t *p_ctx) static sdvo_status_t sdvo_reset_encoder(sdvo_device_context_t *p_ctx) { sdvo_status_t ret_stat; - if ((p_ctx->dev_cap.vendor_id == VENDOR_ID_OKI) + if ((p_ctx->dev_cap.vendor_id == VENDOR_ID_LAPIS) && (p_ctx->dev_cap.device_id == 0x1)){ pd_attr_t *p_attr_temp = diff --git a/drivers/emgd/pal/sdvo/sdvo_port.h b/drivers/emgd/pal/sdvo/sdvo_port.h index b06fc73..17a004f 100644 --- a/drivers/emgd/pal/sdvo/sdvo_port.h +++ b/drivers/emgd/pal/sdvo/sdvo_port.h @@ -64,8 +64,8 @@ unsigned char sdvo_read_i2c_reg(sdvo_device_context_t *p_Ctx, unsigned char offs int sdvo_is_multi_display_device(sdvo_device_context_t *p_ctx); -/*OKI Workaround*/ -#define VENDOR_ID_OKI 0x81 +/*LAPIS Workaround*/ +#define VENDOR_ID_LAPIS 0x81 #endif /* _SDVO_PORT_H_ */ diff --git a/drivers/emgd/state/reg/plb/reg_plb.c b/drivers/emgd/state/reg/plb/reg_plb.c index 5e11ac8..9c36ae4 100644 --- a/drivers/emgd/state/reg/plb/reg_plb.c +++ b/drivers/emgd/state/reg/plb/reg_plb.c @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: reg_plb.c - * $Revision: 1.15 $ + * $Revision: 1.14.82.1 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2010, Intel Corporation. * diff --git a/drivers/emgd/state/reg/tnc/reg_tnc.c b/drivers/emgd/state/reg/tnc/reg_tnc.c index 13263e5..271d5bb 100644 --- a/drivers/emgd/state/reg/tnc/reg_tnc.c +++ b/drivers/emgd/state/reg/tnc/reg_tnc.c @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: reg_tnc.c - * $Revision: 1.19 $ + * $Revision: 1.18.60.1 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2010, Intel Corporation. * @@ -1033,7 +1033,7 @@ int reg_restore_tnc(igd_context_t *context, unsigned long lbb; int i; - platform_context_tnc_t *platform_context; + platform_context_tnc_t *platform_context; platform_context = (platform_context_tnc_t *)context->platform_context; EMGD_DEBUG("Entry - reg_restore"); diff --git a/drivers/emgd/video/msvdx/msvdx.c b/drivers/emgd/video/msvdx/msvdx.c index 87b1105..650edb1 100644 --- a/drivers/emgd/video/msvdx/msvdx.c +++ b/drivers/emgd/video/msvdx/msvdx.c @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: msvdx.c - * $Revision: 1.28 $ + * $Revision: 1.27 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2010, Intel Corporation. * @@ -146,9 +146,9 @@ unsigned long populate_fence_id(igd_context_t *context, unsigned long *mtx_msgs, unsigned long mtx_msg_cnt) { platform_context_plb_t *platform; - unsigned long submit_size; - unsigned long submit_id; - unsigned long context_id; + unsigned long submit_size = 0; + unsigned long submit_id = 0; + unsigned long context_id = 0; unsigned int msg; platform = (platform_context_plb_t *)context->platform_context; @@ -181,39 +181,44 @@ int process_mtx_messages(igd_context_t *context, unsigned long *mtx_msgs, unsigned long mtx_msg_cnt, unsigned long fence) { - unsigned char *mmio = context->device_context.virt_mmadr; platform_context_plb_t *platform; unsigned long submit_size; unsigned long submit_id; unsigned int msg; unsigned long skipped_msg_cnt; - unsigned long msvdx_status; + unsigned long msvdx_status; EMGD_TRACE_ENTER; platform = (platform_context_plb_t *)context->platform_context; // message processing is about to start .. set the flag=bit 2 - spin_lock(&platform->msvdx_init_plb); - platform->msvdx_status = platform->msvdx_status | 2; - msvdx_status = platform->msvdx_status; - spin_unlock(&platform->msvdx_init_plb); - - if (msvdx_status & 1) - { - // OOPS: reset/fw load in progress ... return from here - spin_lock(&platform->msvdx_init_plb); - platform->msvdx_status = platform->msvdx_status & ~2; // unset message processing status. - spin_unlock(&platform->msvdx_init_plb); - - return 0; - } + spin_lock(&platform->msvdx_init_plb); + platform->msvdx_status = platform->msvdx_status | 2; + msvdx_status = platform->msvdx_status; + spin_unlock(&platform->msvdx_init_plb); + + if (msvdx_status & 1) + { + // OOPS: reset/fw load in progress ... return from here + spin_lock(&platform->msvdx_init_plb); + platform->msvdx_status = platform->msvdx_status & ~2; // unset message processing status. + spin_unlock(&platform->msvdx_init_plb); + + return 0; + } save_msg = mtx_msgs; save_msg_cnt = mtx_msg_cnt; skipped_msg_cnt = 0; for (msg = 0; msg < mtx_msg_cnt; msg++) { + + if(!mtx_msgs) { + printk(KERN_ERR "Invalid message"); + return -IGD_ERROR_INVAL; + } + submit_size = (mtx_msgs[0] & 0x000000ff); submit_id = (mtx_msgs[0] & 0x0000ff00) >> 8; @@ -224,6 +229,11 @@ int process_mtx_messages(igd_context_t *context, continue; } + if(!(mtx_msgs + sizeof(unsigned long))) { + printk(KERN_ERR "Invalid message"); + return -IGD_ERROR_INVAL; + } + /* reuse the sgx phy PD */ mtx_msgs[1] = platform->psb_cr_bif_dir_list_base1 | 1; @@ -244,10 +254,10 @@ int process_mtx_messages(igd_context_t *context, } } - // We are done processing messages .. unset the flag + // We are done processing messages .. unset the flag spin_lock(&platform->msvdx_init_plb); - platform->msvdx_status = platform->msvdx_status & ~2; - spin_unlock(&platform->msvdx_init_plb); + platform->msvdx_status = platform->msvdx_status & ~2; + spin_unlock(&platform->msvdx_init_plb); EMGD_TRACE_EXIT; if (skipped_msg_cnt == mtx_msg_cnt) { diff --git a/drivers/emgd/video/msvdx/msvdx_init.c b/drivers/emgd/video/msvdx/msvdx_init.c index c3b550d..0998a00 100644 --- a/drivers/emgd/video/msvdx/msvdx_init.c +++ b/drivers/emgd/video/msvdx/msvdx_init.c @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: msvdx_init.c - * $Revision: 1.32 $ + * $Revision: 1.31 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2010, Intel Corporation. * @@ -262,6 +262,8 @@ unsigned long LastClockState; #define MSVDX_CORE_CR_BE_MSVDX_WDT_COMPAREMATCH_BE_WDT_CM0_SHIFT (0) /*watch dog end*/ +#define MAX_FW_SIZE 16 * 1024 + enum { MSVDX_DMAC_BSWAP_NO_SWAP = 0x0, /* No byte swapping will be performed */ MSVDX_DMAC_BSWAP_REVERSE = 0x1, /* Byte order will be reversed */ @@ -378,6 +380,24 @@ static int msvdx_map_fw(uint32_t size) /* Round up as DMA's can overrun a page */ alloc_size = (size + 8192) & ~0x0fff; + /* Verify there is enough memory for the firmware text */ + if( ((priv_fw->fw_text_size * 4) <= 0) || + ((priv_fw->fw_text_size * 4) > size) ) { + return -EINVAL; + } + + if( ((priv_fw->fw_data_location - MTX_DATA_BASE) <=0) || + ((priv_fw->fw_data_location - MTX_DATA_BASE) > size) ) { + return -EINVAL; + } + + /* Verify there is enough memory for the firmware data */ + if( ((priv_fw->fw_data_size * 4) <= 0) || + ((priv_fw->fw_data_size * 4) > (size - + (priv_fw->fw_data_location - MTX_DATA_BASE))) ) { + return -EINVAL; + } + mem_info = platform->msvdx_pvr->fw_mem_info; if (!mem_info) { mem_info = msvdx_pvr_alloc_devmem(alloc_size, "MSVDX firmware"); @@ -543,7 +563,7 @@ static int msvdx_upload_fw_dma(uint32_t address) return -ENODEV; } - count_reg = MSVDX_DMAC_VALUE_COUNT(MSVDX_DMAC_BSWAP_NO_SWAP, + count_reg = MSVDX_DMAC_VALUE_COUNT(MSVDX_DMAC_BSWAP_NO_SWAP, 0, /* 32 bits */ MSVDX_DMAC_DIR_MEM_TO_PERIPH, 0, @@ -621,7 +641,6 @@ static int msvdx_upload_fw(void) /* * Get the ram bank size * The banks size seems to be a 4 bit value in the MTX debug register. - * Where this is documented other than the UMG code is not clear. */ ram_bank = EMGD_READ32(mmio + PSB_MSVDX_MTX_RAM_BANK); bank_size = (ram_bank & 0x000f0000) >> 16; @@ -821,14 +840,15 @@ int msvdx_init_plb(unsigned long base0, unsigned long base1, // return back if firmware is already loaded if (init_msvdx_first_time) { - spin_lock_init(&platform->msvdx_init_plb); + spin_lock_init(&platform->msvdx_init_plb); } else if(!reset_flag){ - if (context_count == 0) { - spin_lock_irqsave(&platform->msvdx_lock, irq_flags); - INIT_LIST_HEAD(&platform->msvdx_queue); // empty the list. - spin_unlock_irqrestore(&platform->msvdx_lock, irq_flags); - } - return ret; + if (context_count == 0) { + spin_lock_irqsave(&platform->msvdx_lock, irq_flags); + INIT_LIST_HEAD(&platform->msvdx_queue); // empty the list. + spin_unlock_irqrestore(&platform->msvdx_lock, irq_flags); + } + + return ret; } // Set the status for firmware loading @@ -848,7 +868,31 @@ int msvdx_init_plb(unsigned long base0, unsigned long base1, if (!priv_fw && msvdx_fw) { fw = (msvdx_fw_t *) msvdx_fw; + + if((fw->fw_version_size <= 0) || (fw->fw_version_size > 64 )) { + ret = 1; + goto cleanup; + } + + fw_size = sizeof(unsigned long) * fw->fw_text_size; + if((fw_size == 0) || (fw_size > MAX_FW_SIZE)) { + ret = 1; + goto cleanup; + } + + fw_size = sizeof(unsigned long) * fw->fw_data_size; + if((fw_size == 0) || (fw_size > MAX_FW_SIZE)) { + ret = 1; + goto cleanup; + } + priv_fw = kzalloc(sizeof(msvdx_fw_t), GFP_KERNEL); + if (priv_fw == NULL) { + printk(KERN_ERR "MSVDX: Out of memory\n"); + ret = -ENOMEM; + goto cleanup; + } + priv_fw->fw_text_size = fw->fw_text_size; priv_fw->fw_data_size = fw->fw_data_size; priv_fw->fw_version_size = fw->fw_version_size; @@ -856,21 +900,50 @@ int msvdx_init_plb(unsigned long base0, unsigned long base1, fw_size = sizeof(unsigned long) * fw->fw_text_size; priv_fw->fw_text = kmalloc(fw_size, GFP_KERNEL); + if (priv_fw->fw_text == NULL) { + kfree (priv_fw); + priv_fw = NULL; + printk(KERN_ERR "MSVDX: Out of memory\n"); + ret = -ENOMEM; + goto cleanup; + } memcpy(priv_fw->fw_text, (void *) ((unsigned long) msvdx_fw) + ((unsigned long) fw->fw_text), fw_size); fw_size = sizeof(unsigned long) * fw->fw_data_size; priv_fw->fw_data = kmalloc(fw_size, GFP_KERNEL); + if (priv_fw->fw_data == NULL) { + kfree (priv_fw->fw_text); + priv_fw->fw_text = NULL; + kfree (priv_fw); + priv_fw = NULL; + printk(KERN_ERR "MSVDX: Out of memory\n"); + ret = -ENOMEM; + goto cleanup; + } memcpy(priv_fw->fw_data, (void *) ((unsigned long) msvdx_fw) + ((unsigned long) fw->fw_data), fw_size); priv_fw->fw_version = kzalloc(priv_fw->fw_version_size, GFP_KERNEL); - strcpy(priv_fw->fw_version, (char *) (((unsigned long) msvdx_fw) + - ((unsigned long) fw->fw_version))); + if (priv_fw->fw_version == NULL) { + kfree (priv_fw->fw_text); + kfree (priv_fw->fw_data); + priv_fw->fw_text = NULL; + priv_fw->fw_data = NULL; + kfree(priv_fw); + priv_fw = NULL; + printk(KERN_ERR "MSVDX: Out of memory\n"); + ret = -ENOMEM; + goto cleanup; + } + + strncpy(priv_fw->fw_version, (char *) (((unsigned long) msvdx_fw) + + ((unsigned long) fw->fw_version)), priv_fw->fw_version_size); + } else if (!priv_fw) { printk(KERN_INFO "Kernel firmware is not loaded"); if(init_msvdx_first_time) { - printk(KERN_ERR "ALAN!!! !priv_fw at msvdx init 1st"); + printk(KERN_ERR "!priv_fw at msvdx init 1st"); } ret = 1; goto cleanup; @@ -935,7 +1008,7 @@ int msvdx_init_plb(unsigned long base0, unsigned long base1, REGIO_WRITE_FIELD(reg_val, MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL, FE_WDT_ACTION0, 1); REGIO_WRITE_FIELD(reg_val, MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL, FE_WDT_CLEAR_SELECT, 1); REGIO_WRITE_FIELD(reg_val, MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL, FE_WDT_CLKDIV_SELECT, 7); - printk(KERN_INFO "CTL_MSG: WDT Control value = 0x%x", reg_val); + printk(KERN_INFO "CTL_MSG: WDT Control value = 0x%lx", reg_val); EMGD_WRITE32(0, mmio + MSVDX_CORE_CR_FE_MSVDX_WDT_COMPAREMATCH_OFFSET); EMGD_WRITE32(reg_val, mmio + MSVDX_CORE_CR_FE_MSVDX_WDT_CONTROL_OFFSET); @@ -945,7 +1018,7 @@ int msvdx_init_plb(unsigned long base0, unsigned long base1, REGIO_WRITE_FIELD(reg_val, MSVDX_CORE_CR_BE_MSVDX_WDT_CONTROL, BE_WDT_ACTION0, 1); REGIO_WRITE_FIELD(reg_val, MSVDX_CORE_CR_BE_MSVDX_WDT_CONTROL, BE_WDT_CLEAR_SELECT, 0xd); REGIO_WRITE_FIELD(reg_val, MSVDX_CORE_CR_BE_MSVDX_WDT_CONTROL, BE_WDT_CLKDIV_SELECT, 7); - printk(KERN_INFO "CTL_MSG: WDT Control value = 0x%x", reg_val); + printk(KERN_INFO "CTL_MSG: WDT Control value = 0x%lx", reg_val); EMGD_WRITE32(0, mmio + MSVDX_CORE_CR_BE_MSVDX_WDT_COMPAREMATCH_OFFSET); EMGD_WRITE32(reg_val, mmio + MSVDX_CORE_CR_BE_MSVDX_WDT_CONTROL_OFFSET); @@ -1256,6 +1329,10 @@ int msvdx_create_context(igd_context_t *context, void * drm_file_priv, unsigned int i = 0, ret = 0; EMGD_TRACE_ENTER; + if(!drm_file_priv) { + return -EINVAL; + } + for (i = 0; i < MSVDX_MAXIMUM_CONTEXT; ++i) { if (msvdx_contexts[i].drm_file_priv == NULL) { msvdx_contexts[i].drm_file_priv = drm_file_priv; @@ -1294,27 +1371,36 @@ void msvdx_postclose_check(igd_context_t *context, void *drm_file_priv) int process_video_decode_plb(igd_context_t *context, unsigned long offset, void *virt_addr, unsigned long *fence_id) { unsigned long *mtx_buf; - unsigned long *mtx_msgs; - unsigned long mtx_offset; - unsigned long mtx_msg_cnt; - unsigned long irq_flags; + unsigned long *mtx_msgs; + unsigned long mtx_offset; + unsigned long mtx_msg_cnt; + unsigned long irq_flags; int ret = 0; platform_context_plb_t *platform; EMGD_TRACE_ENTER; + if(!virt_addr || !fence_id) { + printk(KERN_ERR "Invalid message"); + return -EINVAL; + } - platform = (platform_context_plb_t *)context->platform_context; + platform = (platform_context_plb_t *)context->platform_context; mtx_buf = (unsigned long *) virt_addr; - mtx_offset = mtx_buf[0]; - mtx_msg_cnt = mtx_buf[1]; + mtx_offset = mtx_buf[0]; + mtx_msg_cnt = mtx_buf[1]; - if (mtx_msg_cnt > 0x20) { - printk(KERN_ERR "Message count too big at %ld\n", mtx_msg_cnt); - return -EINVAL; - } + if (mtx_msg_cnt > 0x20) { + printk(KERN_ERR "Message count too big at %ld\n", mtx_msg_cnt); + return -EINVAL; + } + + mtx_msgs = mtx_buf + (mtx_offset / sizeof (unsigned long)); + if(!mtx_msgs) { + printk(KERN_ERR "Invalid message"); + return -EINVAL; + } - mtx_msgs = mtx_buf + (mtx_offset / sizeof (unsigned long)); if (mtx_msg_cnt > 0) { //if ((mtx_buf[0] != 0x8) || (mtx_buf[2] != 0x8504)) { @@ -1325,7 +1411,6 @@ int process_video_decode_plb(igd_context_t *context, unsigned long offset, void platform->msvdx_busy = 1; spin_unlock_irqrestore(&platform->msvdx_lock, irq_flags); - if (platform->msvdx_needs_reset) { msvdx_reset_plb(context); msvdx_init_plb(0, 0, NULL, 0, 1); @@ -1338,11 +1423,9 @@ int process_video_decode_plb(igd_context_t *context, unsigned long offset, void if (ret) { ret = -EINVAL; - } } else { struct msvdx_cmd_queue *msvdx_cmd; - spin_unlock_irqrestore(&platform->msvdx_lock, irq_flags); msvdx_cmd = kzalloc(sizeof(struct msvdx_cmd_queue), GFP_KERNEL); @@ -1359,9 +1442,9 @@ int process_video_decode_plb(igd_context_t *context, unsigned long offset, void * and needing to be reset. */ if ((jiffies_at_last_dequeue != 0) && - ((jiffies - jiffies_at_last_dequeue) > 1000)) { + ((jiffies - jiffies_at_last_dequeue) > 1000)) { printk(KERN_ERR "Video decode hardware appears to be hung; " - "resetting\n"); + "resetting\n"); platform->msvdx_needs_reset = 1; } if (platform->msvdx_needs_reset) { @@ -1397,6 +1480,10 @@ int msvdx_get_fence_id(igd_context_t *context, unsigned long *fence_id) int ret = 0; platform_context_plb_t *platform; + if(!fence_id) { + return -EINVAL; + } + platform = (platform_context_plb_t *)context->platform_context; *fence_id = platform->mtx_completed; diff --git a/drivers/emgd/video/msvdx/msvdx_pvr.c b/drivers/emgd/video/msvdx/msvdx_pvr.c index 2b56e9d..ee948da 100644 --- a/drivers/emgd/video/msvdx/msvdx_pvr.c +++ b/drivers/emgd/video/msvdx/msvdx_pvr.c @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: msvdx_pvr.c - * $Revision: 1.11 $ + * $Revision: 1.10 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2010, Intel Corporation. * diff --git a/drivers/emgd/video/overlay/cmn/igd_ovl.c b/drivers/emgd/video/overlay/cmn/igd_ovl.c index 299c781..95bf3fc 100644 --- a/drivers/emgd/video/overlay/cmn/igd_ovl.c +++ b/drivers/emgd/video/overlay/cmn/igd_ovl.c @@ -272,17 +272,31 @@ static int igd_query_ovl(igd_display_h display_h, } } - for (cur_ovl = 0; cur_ovl < OVL_MAX_HW; cur_ovl++) { - if (ovl_displays[cur_ovl] != NULL) { - ret = ovl_dispatch[cur_ovl].query_ovl( - (igd_display_h)(ovl_displays[cur_ovl]), - (flags & IGD_OVL_QUERY_MASK)); - if (ret == FALSE) { - /* Can only return TRUE (event has occured and capability - * is available) if it is TRUE for all displays */ - return FALSE; - } - } + /* NOTE: As with alter_ovl2, user mode driver should decide which ovl + * to flip. Instead of having a duplicate logic here to check for clone, + * just flip the ovl bound to the display handle. This prevents a condition + * in clone mode, where the user mode driver does 2 query_ovl calls for + * each ovl plane, that translates into 4 query_ovl calls in kernel. + */ + + /* Determine which display this overlay belongs to */ + if(display == ovl_displays[OVL_PRIMARY]) { + cur_ovl = 0; + } else if (display == ovl_displays[OVL_SECONDARY]) { + cur_ovl = 1; + } else { + /* shouldn't get here. */ + EMGD_TRACE_EXIT; + return -IGD_ERROR_INVAL; + } + + ret = ovl_dispatch[cur_ovl].query_ovl( + (igd_display_h)(ovl_displays[cur_ovl]), + (flags & IGD_OVL_QUERY_MASK)); + if (ret == FALSE) { + /* Can only return TRUE (event has occured and capability + * is available) if it is TRUE for all displays */ + return FALSE; } return ret; diff --git a/drivers/emgd/video/overlay/tnc/ovl2_tnc.c b/drivers/emgd/video/overlay/tnc/ovl2_tnc.c index c73d2b5..030483c 100644 --- a/drivers/emgd/video/overlay/tnc/ovl2_tnc.c +++ b/drivers/emgd/video/overlay/tnc/ovl2_tnc.c @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: ovl2_tnc.c - * $Revision: 1.23 $ + * $Revision: 1.21.26.1 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2010, Intel Corporation. * @@ -265,7 +265,7 @@ unsigned int ovl2_send_instr_tnc( unsigned int flags) { unsigned char *mmio = MMIO(display); - unsigned long tmp, pipe_reg, pipe_num; + unsigned long tmp, pipe_num, pipe_reg; inter_module_dispatch_t *md; platform_context_tnc_t * platform; diff --git a/drivers/emgd/video/overlay/tnc/ovl_tnc.c b/drivers/emgd/video/overlay/tnc/ovl_tnc.c index 116489c..e28b4f5 100644 --- a/drivers/emgd/video/overlay/tnc/ovl_tnc.c +++ b/drivers/emgd/video/overlay/tnc/ovl_tnc.c @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: ovl_tnc.c - * $Revision: 1.30 $ + * $Revision: 1.30.16.2 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2010, Intel Corporation. * @@ -45,6 +45,7 @@ #include "../cmn/ovl_coeff.h" #include "ovl2_tnc.h" +#define OVL_DOWNSCALE_X_WORKAROUND /*----------------------------------------------------------------------------- * Common dispatch functions @@ -100,6 +101,16 @@ static ovl_chipset_tnc_t ovl_chipset_tnc[] = { (PF_DEPTH_8 | PF_TYPE_YUV_PLANAR), 1920, 1088}, {OVL_CONFIG_NO_LINE_BUFF, 0, 0, 0} }; +/* for Direct Display */ +typedef struct _dd_context_tnc { + igd_dd_context_t bridge; + igd_surface_t surf; + igd_ovl_info_t ovl; +} dd_context_tnc_t; + +/* Pointers to allocated memory for the Direct Display context info */ +static dd_context_tnc_t *dd_context_ovl; +static dd_context_tnc_t *dd_context_ovl2; #ifdef DEBUG_BUILD_TYPE static void ovl_dump_regs_tnc( @@ -2126,3 +2137,290 @@ static int query_max_size_ovl_tnc( EMGD_TRACE_EXIT; return IGD_SUCCESS; } + +/* + * enable_direct_display_tnc(): Enables direct display of video DMA input + * buffers on the Overlay or Sprite C plane of the specified screen. + */ +int enable_direct_display_tnc(void *arg, igd_dd_context_t dd_context) +{ + igd_display_context_t *display = (igd_display_context_t *)arg; + dd_context_tnc_t *dd_context_ptr; +#ifdef OVL_DOWNSCALE_X_WORKAROUND + int src_w, dest_w, scale, rem, fix_needed; +#endif + + EMGD_TRACE_ENTER; + + /* Ensure the display context has been set */ + if (display == NULL) { + printk(KERN_ERR "display context (arg) cannot be NULL !\n"); + return -EINVAL; + } + /* Ensure the igd context has been set */ + if (display->context == NULL) { + printk(KERN_INFO "igd context cannot be NULL !\n"); + return -EINVAL; + } + switch (dd_context.usage) { + case IGD_PLANE_OVERLAY_VIDEO: + /* Check to see if direct display on Overlay plane is available */ + if (dd_context_ovl) { + printk(KERN_ERR "Overlay direct display already enabled !\n"); + return -EBUSY; + } + break; + case IGD_PLANE_SPRITE_VIDEO: + /* Check to see if direct display on Sprite C plane is available */ + if (dd_context_ovl2) { + printk(KERN_ERR "Overlay direct display already enabled !\n"); + return -EBUSY; + } + break; + default: + printk(KERN_ERR "Invalid direct display usage type (%d) !\n", + dd_context.usage); + return -EINVAL; + } + /* Attempt to allocate the direct display context block */ + dd_context_ptr = OS_ALLOC(sizeof(dd_context_tnc_t)); + if (dd_context_ptr == NULL) { + printk(KERN_ERR "Unable to allocate DD context block !\n"); + return -ENOMEM; + } + /* Clear the DD context block and then copy the bridge data into it */ + OS_MEMSET(dd_context_ptr, 0, sizeof(dd_context_tnc_t)); + dd_context_ptr->bridge = dd_context; + + /* Initialize color keying, video quality, and gamma */ + dd_context_ptr->ovl.color_key.src_lo = 0x00000000; + dd_context_ptr->ovl.color_key.src_hi = 0x00000000; + dd_context_ptr->ovl.color_key.dest = 0xFF00FF; /* customer specified */ + dd_context_ptr->ovl.color_key.flags = IGD_OVL_DST_COLOR_KEY_DISABLE; + dd_context_ptr->ovl.video_quality.contrast = 0x8000; + dd_context_ptr->ovl.video_quality.brightness = 0x8000; + dd_context_ptr->ovl.video_quality.saturation = 0x8000; + dd_context_ptr->ovl.gamma.red = 0x100; + dd_context_ptr->ovl.gamma.green = 0x100; + dd_context_ptr->ovl.gamma.blue = 0x100; + dd_context_ptr->ovl.gamma.flags = IGD_OVL_GAMMA_DISABLE; + + /* Ensure source rectangle starts on even coordinates */ + dd_context_ptr->bridge.src.x1 = (dd_context_ptr->bridge.src.x1 + 1) & ~1; + dd_context_ptr->bridge.src.y1 = (dd_context_ptr->bridge.src.y1 + 1) & ~1; + + /* Ensure destination rectangle starts on even coordinates */ + dd_context_ptr->bridge.dest.x1 = (dd_context_ptr->bridge.dest.x1 + 1) & ~1; + dd_context_ptr->bridge.dest.y1 = (dd_context_ptr->bridge.dest.y1 + 1) & ~1; + + /* Initialize the generic rendering surface attributes */ + dd_context_ptr->surf.width = dd_context_ptr->bridge.src.x2 - + dd_context_ptr->bridge.src.x1 + 1; + dd_context_ptr->surf.height = dd_context_ptr->bridge.src.y2 - + dd_context_ptr->bridge.src.y1 + 1; + dd_context_ptr->surf.flags = IGD_OVL_ALTER_ON; + dd_context_ptr->surf.pitch = dd_context.video_pitch; + +#ifdef OVL_DOWNSCALE_X_WORKAROUND + src_w = dd_context_ptr->surf.width; + dest_w = dd_context_ptr->bridge.dest.x2 - dd_context_ptr->bridge.dest.x1 + 1; + scale = src_w / dest_w; + rem = src_w % dest_w; + fix_needed = 0; + + /* + * If downscaling along the X dimension we need to avoid scale factors + * that are greater than 4 and less than 9, and greater than 12. The + * issue is with the destination rectangle, so we leave the source + * rectangle as specified, and expand the destination rectangle to be + * exactly 4 or 12 times smaller. We have to adjust the start and/or + * end position accordingly, so that it fits within the screen bounds. + */ + if (src_w > dest_w) { + if ((scale > 4 && scale < 9) || (scale == 4 && rem)) { + /* Force a scale factor of 4 here */ + dest_w = src_w / 4; + fix_needed = 1; + } else if ((scale > 12) || (scale == 12 && rem)) { + /* Force a scale factor of 12 here */ + dest_w = src_w / 12; + fix_needed = 1; + } + if (fix_needed) { + /* Adjust the destination X endpoint */ + dd_context_ptr->bridge.dest.x2 = + dd_context_ptr->bridge.dest.x1 + dest_w - 1; + + /* Ensure rectangle X coordinates fit on screen */ + if (dd_context_ptr->bridge.dest.x2 >= + dd_context_ptr->bridge.screen_w) { + /* Adjust X end position to screen edge */ + dd_context_ptr->bridge.dest.x2 = + dd_context_ptr->bridge.screen_w - 1; + /* Adjust X start position according to width */ + dd_context_ptr->bridge.dest.x1 = + dd_context_ptr->bridge.dest.x2 - dest_w + 1; + } + } + } +#endif + if (dd_context.usage == IGD_PLANE_OVERLAY_VIDEO) { + /* Initialize the YUV422-specific surface attributes */ + dd_context_ptr->surf.pixel_format = IGD_PF_YUV422_PACKED_UYVY; + + /* Save this pointer as our Overlay context */ + dd_context_ovl = dd_context_ptr; + } else { + /* Initialize the RGB565-specific surface attributes */ + dd_context_ptr->surf.pixel_format = IGD_PF_RGB16_565; + dd_context_ptr->surf.pitch *= 2; /* RGB565 = 2 Bpp */ + + /* Save this pointer as our Overlay 2 (Sprite C) context */ + dd_context_ovl2 = dd_context_ptr; + } + EMGD_TRACE_EXIT; + return 0; +} +EXPORT_SYMBOL(enable_direct_display_tnc); + + +/* + * disable_direct_display_tnc(): Disables direct display of video on the + * Overlay plane or Sprite C plane. + */ +int disable_direct_display_tnc(void *arg, int usage) +{ + igd_display_context_t *display = (igd_display_context_t *)arg; + dd_context_tnc_t *dd_context_ptr; + int ret; + + EMGD_TRACE_ENTER; + + /* Ensure the display context has been set */ + if (display == NULL) { + printk(KERN_ERR "Display context (arg) cannot be NULL !\n"); + return -EINVAL; + } + /* Set the direct display context pointer according to the usage arg */ + dd_context_ptr = + (usage == IGD_PLANE_OVERLAY_VIDEO) ? dd_context_ovl : dd_context_ovl2; + + /* Ensure this direct display context pointer is set */ + if (dd_context_ptr == NULL) { + printk(KERN_ERR "%s direct display not currently enabled !\n", + (usage == IGD_PLANE_OVERLAY_VIDEO) ? "Overlay" : "Sprite C"); + return -EINVAL; + } + /* Set the flag to turn Overlay/Sprite C off */ + dd_context_ptr->surf.flags = IGD_OVL_ALTER_OFF; + + /* Check the DD context being referenced */ + if (usage == IGD_PLANE_OVERLAY_VIDEO) { + /* Disable the display of the Overlay plane */ + ret = alter_ovl_tnc(display, &dd_context_ovl->surf, + &dd_context_ovl->bridge.src, &dd_context_ovl->bridge.dest, + &dd_context_ovl->ovl, dd_context_ovl->surf.flags); + + /* Mark the Overlay direct display context as invalid */ + dd_context_ovl = NULL; + } else { + /* Disable the display of the Sprite C plane */ + ret = alter_ovl2_tnc(display, &dd_context_ovl2->surf, + &dd_context_ovl2->bridge.src, &dd_context_ovl2->bridge.dest, + &dd_context_ovl2->ovl, dd_context_ovl2->surf.flags); + + /* Mark the Sprite C direct display context as invalid */ + dd_context_ovl2 = NULL; + } + /* Deallocate the DD context block for the direct display plane */ + OS_FREE(dd_context_ptr); + + EMGD_TRACE_EXIT; + return ret; +} +EXPORT_SYMBOL(disable_direct_display_tnc); + + +/* + * direct_display_frame_tnc(): Performs the direct display of the new frame + * of video data on the Overlay plane or Sprite C plane. + */ +int direct_display_frame_tnc(void *arg, int usage, unsigned long offset) +{ + igd_display_context_t *display = (igd_display_context_t *)arg; + dd_context_tnc_t *dd_context_ptr; + int ret; + + EMGD_TRACE_ENTER; + + /* Ensure the display context is set */ + if (display == NULL) { + printk(KERN_ERR "display context cannot be NULL !!!\n"); + return -EINVAL; + } + /* Set the direct display context pointer according to the usage arg */ + dd_context_ptr = + (usage == IGD_PLANE_OVERLAY_VIDEO) ? dd_context_ovl : dd_context_ovl2; + + /* Ensure this direct display context pointer is set */ + if (dd_context_ptr == NULL) { + printk(KERN_ERR "%s direct display context not set !\n", + (usage == IGD_PLANE_OVERLAY_VIDEO) ? "Overlay" : "Sprite C"); + return -EINVAL; + } + + /* Update the surface offset corresponding to this new frame */ + dd_context_ptr->surf.offset = offset; + + if (usage == IGD_PLANE_OVERLAY_VIDEO) { + /* display the new video frame on the Overlay plane */ + ret = alter_ovl_tnc(display, &dd_context_ovl->surf, + &dd_context_ovl->bridge.src, &dd_context_ovl->bridge.dest, + &dd_context_ovl->ovl, dd_context_ovl->surf.flags); + } else { + /* display the new video frame on the Sprite C plane */ + ret = alter_ovl2_tnc(display, &dd_context_ovl2->surf, + &dd_context_ovl2->bridge.src, &dd_context_ovl2->bridge.dest, + &dd_context_ovl2->ovl, dd_context_ovl2->surf.flags); + } + EMGD_TRACE_EXIT; + return ret; +} +EXPORT_SYMBOL(direct_display_frame_tnc); +/* + * ovl_set_dest_colorkey_tnc(): Performs the enable or disable colorkey on the Overlay plane. + */ +int ovl_set_dest_colorkey_tnc(igd_dd_context_t dd_context, igd_ovl_color_key_info_t *color_key) +{ + EMGD_TRACE_ENTER; + switch (dd_context.usage) { + case IGD_PLANE_OVERLAY_VIDEO: + /* Check to see if direct display on Overlay plane is available */ + if (!dd_context_ovl) { + printk(KERN_ERR "Overlay direct display = NULL !\n"); + return -EINVAL; + } + + dd_context_ovl->ovl.color_key.dest = color_key->dest; + dd_context_ovl->ovl.color_key.flags = color_key->flags; + break; + case IGD_PLANE_SPRITE_VIDEO: + /* Check to see if direct display on Sprite C plane is available */ + if (!dd_context_ovl2) { + printk(KERN_ERR "Overlay direct display2 = NULL !\n"); + return -EINVAL; + } + + dd_context_ovl2->ovl.color_key.dest = color_key->dest; + dd_context_ovl2->ovl.color_key.flags = color_key->flags; + break; + default: + printk(KERN_ERR "Invalid direct display usage type (%d) !\n", + dd_context.usage); + return -EINVAL; + } + + EMGD_TRACE_EXIT; + return 0; +} +EXPORT_SYMBOL(ovl_set_dest_colorkey_tnc); diff --git a/drivers/emgd/video/overlay/tnc/ovl_tnc_cache.c b/drivers/emgd/video/overlay/tnc/ovl_tnc_cache.c index f3d162e..8b73366 100644 --- a/drivers/emgd/video/overlay/tnc/ovl_tnc_cache.c +++ b/drivers/emgd/video/overlay/tnc/ovl_tnc_cache.c @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: ovl_tnc_cache.c - * $Revision: 1.7 $ + * $Revision: 1.5.102.2 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2010, Intel Corporation. * diff --git a/drivers/emgd/video/topaz/topaz.c b/drivers/emgd/video/topaz/topaz.c index f710ff2..89b8fcf 100644 --- a/drivers/emgd/video/topaz/topaz.c +++ b/drivers/emgd/video/topaz/topaz.c @@ -48,6 +48,9 @@ #include #include +#define MAX_CURRENT_TOPAZ_CMD_SIZE 5 +#define MAX_TOPAZ_CMD_SIZE 0x20 + void write_mtx_mem_multiple_setup(igd_context_t *context, unsigned long addr) { @@ -131,7 +134,7 @@ int mtx_send_tnc(igd_context_t *context, unsigned long *msg) if (ret == 0) { topaz_priv->topaz_cmd_windex = 0; } else { - EMGD_ERROR("TOPAZ: poll rindex timeout\n"); + printk(KERN_ERR "TOPAZ: poll rindex timeout\n"); return ret; /* HW may hang, need reset */ } EMGD_DEBUG("TOPAZ: -------wrap CCB was done.\n"); @@ -229,7 +232,7 @@ int process_encode_mtx_messages(igd_context_t *context, unsigned long size) { unsigned long *command = (unsigned long *) mtx_buf; - unsigned long cmd_size = size; + unsigned long cmd_size = 0; int ret = 0; struct topaz_cmd_header *cur_cmd_header; unsigned long cur_cmd_size, cur_cmd_id; @@ -241,9 +244,21 @@ int process_encode_mtx_messages(igd_context_t *context, topaz_priv = &platform->tpz_private_data; cur_cmd_header = (struct topaz_cmd_header *) command; + + if(!cur_cmd_header) { + printk(KERN_ERR "TOPAZ: Invalid Command\n"); + return -IGD_ERROR_INVAL; + } + cur_cmd_size = cur_cmd_header->size; cur_cmd_id = cur_cmd_header->id; + /* Verify the incoming current command size */ + if((cur_cmd_size == 0) || (cur_cmd_size > MAX_CURRENT_TOPAZ_CMD_SIZE)) { + printk(KERN_ERR "TOPAZ: Invalid Command Size\n"); + return -IGD_ERROR_INVAL; + } + while (cur_cmd_id != MTX_CMDID_NULL) { switch (cur_cmd_id) { @@ -251,7 +266,7 @@ int process_encode_mtx_messages(igd_context_t *context, codec = *((unsigned long *) mtx_buf + 1); EMGD_DEBUG("TOPAZ: setup new codec %ld\n", codec); if (topaz_setup_fw(context, codec)) { - EMGD_ERROR("TOPAZ: upload FW to HW failed\n"); + printk(KERN_ERR "TOPAZ: upload FW to HW failed\n"); return -IGD_ERROR_INVAL; } topaz_priv->topaz_cur_codec = codec; @@ -271,28 +286,55 @@ int process_encode_mtx_messages(igd_context_t *context, *(command + cur_cmd_size - 1)); /* strip the QP parameter (it's software arg) */ cur_cmd_header->size--; - default: + case MTX_CMDID_DO_HEADER: + case MTX_CMDID_ENCODE_SLICE: + case MTX_CMDID_END_PIC: + case MTX_CMDID_SYNC: + case MTX_CMDID_ENCODE_ONE_ROW: + case MTX_CMDID_FLUSH: + cur_cmd_header->seq = 0x7fff & topaz_priv->topaz_cmd_seq++; EMGD_DEBUG("TOPAZ: %ld: size(%ld), seq (0x%04x)\n", cur_cmd_id, cur_cmd_size, cur_cmd_header->seq); ret = mtx_send_tnc(context, command); if (ret) { - EMGD_ERROR("TOPAZ: error -- ret(%d)\n", ret); + printk(KERN_ERR "TOPAZ: error -- ret(%d)\n", ret); return -IGD_ERROR_INVAL; } break; + default: + printk(KERN_ERR "TOPAZ: Invalid Command\n"); + return -IGD_ERROR_INVAL; } - /* save frame skip flag for query */ - /*topaz_priv->topaz_frame_skip = 0; CCB_CTRL_FRAMESKIP(context);*/ - /* current command done */ + + /* current command done */ command += cur_cmd_size; - cmd_size -= cur_cmd_size; + cmd_size += cur_cmd_size; + + /* Verify that the incoming commands are of reasonable size */ + if((cmd_size >= MAX_TOPAZ_CMD_SIZE)) { + printk(KERN_ERR "TOPAZ: Invalid Command Size\n"); + return -IGD_ERROR_INVAL; + } /* Get next command */ cur_cmd_header = (struct topaz_cmd_header *) command; + + if(!cur_cmd_header) { + printk(KERN_ERR "TOPAZ: Invalid Command\n"); + return -IGD_ERROR_INVAL; + } + cur_cmd_size = cur_cmd_header->size; cur_cmd_id = cur_cmd_header->id; + + /* Verify the incoming current command size */ + if((cur_cmd_size == 0) || (cur_cmd_size > MAX_CURRENT_TOPAZ_CMD_SIZE)) { + printk(KERN_ERR "TOPAZ: Invalid Command Size\n"); + return -IGD_ERROR_INVAL; + } + } topaz_sync_tnc(context); diff --git a/drivers/emgd/video/topaz/topaz_init.c b/drivers/emgd/video/topaz/topaz_init.c index 4401b69..b73e411 100644 --- a/drivers/emgd/video/topaz/topaz_init.c +++ b/drivers/emgd/video/topaz/topaz_init.c @@ -89,7 +89,6 @@ void get_mtx_control_from_dash(igd_context_t *context); void release_mtx_control_from_dash(igd_context_t *context); -/* According to UMG code this define is important */ #define RAM_SIZE (1024 * 24) /* register default values */ @@ -409,6 +408,10 @@ int topaz_init_tnc(unsigned long wb_offset, void *wb_addr, void *firmware_addr) context = priv->context; mmio = context->device_context.virt_mmadr; + if(!wb_addr || !firmware_addr) { + return -EINVAL; + } + /* Only support Atom E6xx */ if ((PCI_DEVICE_ID_VGA_TNC != context->device_context.did)|| (context->device_context.bid == PCI_DEVICE_ID_BRIDGE_TNC_ULP)) { @@ -513,6 +516,9 @@ int topaz_setup_fw(igd_context_t *context, enum tnc_topaz_encode_fw codec) /* topaz_upload_fw */ /* Point to request firmware */ + if((codec < 1) || (codec > 9)) { + return 1; + } curr_fw = &firmware[codec]; upload_firmware(context, curr_fw); @@ -904,6 +910,10 @@ int process_video_encode_tnc(igd_context_t *context, unsigned long offset, void EMGD_TRACE_ENTER; + if(!virt_addr || !fence_id) { + return -EINVAL; + } + platform = (platform_context_plb_t *)context->platform_context; topaz_priv = &platform->tpz_private_data; mtx_buf = (unsigned long *) virt_addr; @@ -915,8 +925,8 @@ int process_video_encode_tnc(igd_context_t *context, unsigned long offset, void ret = process_encode_mtx_messages(context, mtx_buf, size); if (ret){ printk(KERN_INFO "Invalid topaz encode cmd"); - ret = -EINVAL; - } + ret = -EINVAL; + } *fence_id = topaz_priv->topaz_sync_id; platform->topaz_busy = 0; @@ -961,6 +971,10 @@ int topaz_get_frame_skip(igd_context_t *context, unsigned long *frame_skip) tnc_topaz_priv_t *topaz_priv; platform_context_tnc_t *platform; + if(!frame_skip) { + return -EINVAL; + } + platform = (platform_context_tnc_t *)context->platform_context; topaz_priv = &platform->tpz_private_data; *frame_skip = topaz_priv->topaz_frame_skip; @@ -975,6 +989,10 @@ int topaz_get_fence_id(igd_context_t *context, unsigned long *fence_id) unsigned long *sync_p; platform_context_tnc_t *platform; + if(!fence_id) { + return -EINVAL; + } + platform = (platform_context_tnc_t *)context->platform_context; topaz_priv = &platform->tpz_private_data; sync_p = (unsigned long *)topaz_priv->topaz_sync_addr; diff --git a/drivers/include/emgd_drm.h b/drivers/include/emgd_drm.h index d4a8df8..0a06591 100644 --- a/drivers/include/emgd_drm.h +++ b/drivers/include/emgd_drm.h @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: emgd_drm.h - * $Revision: 1.64 $ + * $Revision: 1.63.12.3 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2010, Intel Corporation. * @@ -32,7 +32,7 @@ #define _EMGD_DRM_H_ #include -#include +#include #include #include #include @@ -479,6 +479,10 @@ typedef struct _kdrm_query_max_size_ovl { unsigned int max_height; /* (UP) */ } emgd_drm_query_max_size_ovl_t; +typedef struct _kdrm_framebuffer_info { + int rtn; /* (UP) - return value of HAL procedure */ + igd_framebuffer_info_t fb_info; /* (UP) */ +} emgd_drm_framebuffer_info_t; typedef struct _kdrm_query_ovl { int rtn; /* (UP) - return value of HAL procedure */ @@ -652,6 +656,20 @@ typedef struct _kdrm_query_2d_caps_hwhint { unsigned long *status; /* (UP) */ } emgd_drm_query_2d_caps_hwhint_t; + +typedef struct _kdrm_cfg_bufs_t { + int rtn; /* (UP) - return value of HAL procedure */ + igd_display_h primary; /* (DOWN) - primary display handle */ + igd_display_h secondary; /* (DOWN) - secondary display handle */ + igd_buffer_config_t buf_cfg[2][3];/* (DOWN) - pri & sec buffer config */ +} emgd_drm_cfg_bufs_t; + +typedef struct _kdrm_switch_hz { + int rtn; /* (UP) - return value of HAL procedure */ + int hz; /* (DOWN) - The hertz that need to be changed */ + int pipe; /* (DOWN) - Pipe to change for */ +} emgd_drm_switch_hz; + /* For Buffer Class FCB #17711*/ typedef struct _kdrm_bc_ts { int rtn; @@ -666,8 +684,15 @@ typedef struct _kdrm_bc_ts { unsigned long pixel_format; unsigned long phyaddr; unsigned long virtaddr; + unsigned int mapped; } emgd_drm_bc_ts_t; +typedef struct _kdrm_unlock_planes { + int rtn; /* (UP) - return value of HAL procedure */ + igd_display_h display_handle; /* (DOWN) - an "opaque handle" */ + unsigned int screen_num; /*primary=0, secondary=1 */ +} emgd_drm_unlock_planes_t; + /* * This is where all the IOCTL's used by the egd DRM interface are * defined. This information is shared between the user space code and @@ -707,6 +732,10 @@ typedef struct _kdrm_bc_ts { #define DRM_IGD_QUERY_2D_CAPS_HWHINT 0x35 #define DRM_IGD_DIHCLONE_SET_SURFACE 0x36 #define DRM_IGD_SET_OVERLAY_DISPLAY 0x37 +#define DRM_IGD_GET_2ND_FB 0x3A +#define DRM_IGD_CONFIG_BUFFS 0x3B +#define DRM_IGD_SWITCH_HZ 0x3C + #define DRM_IGD_WAIT_VBLANK 0x40 /* @@ -753,6 +782,8 @@ typedef struct _kdrm_bc_ts { #define DRM_IGD_GET_CHIPSET_INFO 0x30 #define DRM_IGD_GET_DISPLAY_INFO 0x38 #define DRM_IGD_PREINIT_MMU 0x39 +#define DRM_IGD_UNLOCK_PLANES 0x47 + /* For Buffer Class of Texture Stream */ #define DRM_IGD_BC_TS_INIT 0x40 #define DRM_IGD_BC_TS_UNINIT 0x41 @@ -848,6 +879,8 @@ typedef struct _kdrm_bc_ts { emgd_drm_control_plane_format_t) #define DRM_IOCTL_IGD_SET_OVERLAY_DISPLAY DRM_IOWR(DRM_IGD_SET_OVERLAY_DISPLAY + BASE,\ emgd_drm_set_overlay_display_t) +#define DRM_IOCTL_IGD_GET_2ND_FB DRM_IOWR(DRM_IGD_GET_2ND_FB + BASE,\ + emgd_drm_framebuffer_info_t) #define DRM_IOCTL_IGD_SET_ATTRS DRM_IOWR(DRM_IGD_SET_ATTRS + BASE,\ emgd_drm_set_attrs_t) #define DRM_IOCTL_IGD_SET_PALETTE_ENTRY DRM_IOWR(DRM_IGD_SET_PALETTE_ENTRY +\ @@ -881,6 +914,12 @@ typedef struct _kdrm_bc_ts { #define DRM_IOCTL_IGD_WAIT_VBLANK DRM_IOWR(DRM_IGD_WAIT_VBLANK + BASE,\ emgd_drm_driver_set_sync_refresh_t) +#define DRM_IOCTL_IGD_CONFIG_BUFFS DRM_IOWR(DRM_IGD_CONFIG_BUFFS + BASE,\ + emgd_drm_cfg_bufs_t) +#define DRM_IOCTL_IGD_SWITCH_HZ DRM_IOWR(DRM_IGD_SWITCH_HZ + BASE,\ + emgd_drm_switch_hz) + + /* From pvr_bridge.h */ #define DRM_IOCTL_IGD_RESERVED_1 DRM_IOW(DRM_IGD_RESERVED_1 + BASE, \ @@ -907,6 +946,8 @@ typedef struct _kdrm_bc_ts { emgd_drm_video_flush_tlb_t) #define DRM_IOCTL_IGD_PREINIT_MMU DRM_IOR(DRM_IGD_PREINIT_MMU + BASE,\ emgd_drm_preinit_mmu_t) +#define DRM_IOCTL_IGD_UNLOCK_PLANES DRM_IOR(DRM_IGD_UNLOCK_PLANES + BASE,\ + emgd_drm_unlock_planes_t) #define DRM_IOCTL_IGD_GET_DISPLAY_INFO DRM_IOR(DRM_IGD_GET_DISPLAY_INFO + BASE,\ emgd_drm_get_display_info_t) /* For Buffer Class of Texture Stream */ diff --git a/drivers/include/emgd_shared.h b/drivers/include/emgd_shared.h index fe576ed..f74a2d4 100644 --- a/drivers/include/emgd_shared.h +++ b/drivers/include/emgd_shared.h @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: emgd_shared.h - * $Revision: 1.14 $ + * $Revision: 1.14.102.1 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2010, Intel Corporation. * @@ -59,6 +59,60 @@ #define DRM_PVR_RESERVED6 0x1E +/*! + * @name Surface Alignment Flags + * @anchor surface_info_flags + * + * Surface Alignment Flags are passed to the _igd_dispatch::gmm_alloc_surface() + * function as an indicator for how the surface will be used. + * + * - IGD_SURFACE_RENDER The surface may be used as a rendering target, + * this must be set for all color buffers. + * - IGD_SURFACE_TEXTURE The surface may be used as a texture input. + * - IGD_SURFACE_CURSOR Surface may be used as a cursor + * - IGD_SURFACE_OVERLAY Surface may be used with the overlay + * - IGD_SURFACE_DISPLAY This surface is suitable for use with the display + * engine. This flag must be set for any render target that may later + * be flipped to the front buffer. + * - IGD_SURFACE_DEPTH The surface may be used as a depth (Z) buffer. + * + * - IGD_SURFACE_YMAJOR If the surface is tiled, it is tiled with the + * walk in the YMajor direction. This flag is output only unless the + * allocation type is Fixed TF. + * - IGD_SURFACE_XMAJOR If the surface is tiled, it is tiled with the + * walk in the YMajor direction. This flag is output only unless the + * allocation type is Fixed TF. + * - IGD_SURFACE_TILED Surface is tiled. This flag is output only unless + * the allocation type is Fixed TF. + * - IGD_SURFACE_FENCED Surface is fenced. This flaf is output only unless + * the allocation type is Fixed TF. + * + * Additionally all FB flags can be populated + * See: @ref fb_info_flags + * + * @{ + */ +#define IGD_SURFACE_RENDER 0x00000001 +#define IGD_SURFACE_TEXTURE 0x00000002 +#define IGD_SURFACE_CURSOR 0x00000004 +#define IGD_SURFACE_OVERLAY 0x00000008 +#define IGD_SURFACE_DISPLAY 0x00000010 +#define IGD_SURFACE_DEPTH 0x00000020 +#define IGD_SURFACE_VIDEO 0x00000040 +#define IGD_SURFACE_VIDEO_ENCODE 0x00000080 + +#define IGD_SURFACE_WALK_MASK 0x00001000 +#define IGD_SURFACE_YMAJOR 0x00001000 +#define IGD_SURFACE_XMAJOR 0x00000000 +#define IGD_SURFACE_TILED 0x00002000 +#define IGD_SURFACE_FENCED 0x00004000 +#define IGD_SURFACE_SYS_MEM 0x00008000 +#define IGD_SURFACE_PHYS_PTR 0x00010000 +#define IGD_SURFACE_DRM_OWN 0x00020000 +#define IGD_SURFACE_X_OWN 0x00040000 + +#define IGD_DONT_REINIT_PVR 0x00000001 + /* * The following typedefs support the ability of non-HAL software to have a * function called when a VBlank interrupt occurs. diff --git a/drivers/include/igd.h b/drivers/include/igd.h index 2c81c51..e859f2e 100644 --- a/drivers/include/igd.h +++ b/drivers/include/igd.h @@ -1442,6 +1442,9 @@ typedef struct _igd_dispatch { int (*query_ovl)(igd_display_h display_h, unsigned int flags); + /* User mode only query_ovl */ + int (*query_ovl2)(igd_display_h display_h, + unsigned int flags); /*! * Query the overlay for the maximum width and height given the input * src video pixel format. @@ -1620,6 +1623,8 @@ typedef struct _igd_dispatch { * Get MSVDX status. */ int (*msvdx_status)(igd_driver_h driver_handle, unsigned long *queue_status, unsigned long *mtx_msg_status); + /* show_desktop calls this function so, the planes now show the desktop instead of the splas screen */ + int (*unlock_planes)(igd_display_h display_handle , unsigned int scrn_num); } igd_dispatch_t; #endif diff --git a/drivers/include/igd_gmm.h b/drivers/include/igd_gmm.h index b262a14..341efca 100644 --- a/drivers/include/igd_gmm.h +++ b/drivers/include/igd_gmm.h @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: igd_gmm.h - * $Revision: 1.13 $ + * $Revision: 1.13.26.2 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2010, Intel Corporation. * @@ -106,6 +106,7 @@ #define IGD_SURFACE_PHYS_PTR 0x00010000 #define IGD_SURFACE_CI 0x00020000 #define IGD_SURFACE_CI_V4L2_MAP 0x00040000 /*will be set when map_method=0 without WA*/ +#define IGD_SURFACE_CI_TEXTSTREAM 0x00080000 /* * Mipmap flags are only valid on mipmap surfaces. * Planes flags are only valid on volume surfaces. @@ -249,7 +250,13 @@ typedef struct _igd_memstat { } igd_memstat_t; - +struct emgd_ci_meminfo_t{ + unsigned long v4l2_offset; + unsigned long virt; + unsigned long size; + unsigned int used; + unsigned long vbufqueue_handle; +}; /*! * @name GMM Alloc Cached Flags * @anchor gmm_alloc_cached_flags diff --git a/drivers/include/igd_mode.h b/drivers/include/igd_mode.h index 6fc61a7..4ca9497 100644 --- a/drivers/include/igd_mode.h +++ b/drivers/include/igd_mode.h @@ -564,10 +564,11 @@ typedef struct _igd_framebuffer_info { unsigned long visible_offset; /* this is the offset that will be restored when swithcing back to dih mode from - * dihclone mode + * dihclone mode and also when unlock_plane is called. */ unsigned long saved_offset; + unsigned int lock; /*! * @brief pixel format of the fb. See @ref pixel_formats * diff --git a/drivers/include/igd_pd.h b/drivers/include/igd_pd.h index 2c36267..649b43d 100644 --- a/drivers/include/igd_pd.h +++ b/drivers/include/igd_pd.h @@ -52,6 +52,8 @@ #define FALSE 0 #endif +#define POW2( X ) (unsigned long)1<<(X) + /*! * @addtogroup display_group * diff --git a/drivers/include/igd_render.h b/drivers/include/igd_render.h index c492918..b89d0bf 100644 --- a/drivers/include/igd_render.h +++ b/drivers/include/igd_render.h @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: igd_render.h - * $Revision: 1.18 $ + * $Revision: 1.18.12.1 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2010, Intel Corporation. * @@ -112,6 +112,47 @@ typedef struct _igd_rect { unsigned int y2; } igd_rect_t, *pigd_rect_t; +/* + * Direct Display context for video-to-graphics bridge. + * (Added here for compatibility between User & Kernel space) + * Note: This structure must match EMGDHmiVideoContext. + */ +typedef struct _igd_dd_context { + unsigned int usage; /* requested display plane */ + unsigned int screen; /* screen index for video output */ + unsigned int screen_w; /* width of display screen */ + unsigned int screen_h; /* height of display screen */ + unsigned int video_w; /* width of IOH video frame */ + unsigned int video_h; /* height of IOH video frame */ + unsigned int video_pitch; /* pitch of IOH video frame */ + igd_rect_t src; /* video input source rectangle */ + igd_rect_t dest; /* display output dest rectangle */ +} igd_dd_context_t, *pigd_dd_context_t; + +/* planes where reconfiguration and Z-ordering is supported */ +typedef enum _igd_plane_usage { + IGD_PLANE_NONE, + IGD_PLANE_HMI, + IGD_PLANE_X11, + IGD_PLANE_OVERLAY_VIDEO, + IGD_PLANE_OVERLAY_POPUP, + IGD_PLANE_SPRITE_VIDEO, + IGD_PLANE_SPRITE_POPUP, +} igd_plane_usage_t; + +typedef struct _igd_buffer_config { + igd_plane_usage_t plane; /* usage/ownership of this plane */ + unsigned long offset; /* surface's GTT offset */ + int stride; /* surface's stride (in bytes) */ + igd_rect_t src; /* input source rectangle */ + igd_rect_t dest; /* display destination rectangle */ + int extended_screen; + int alpha_ena; /* enables/disables constant alpha */ + int alpha_val; /* constant alpha opacity value */ + int ckey_ena; /* enables/disables color keying */ + int ckey_val; /* source color key value */ +} igd_buffer_config_t, *pigd_buffer_config_t; + typedef struct _igd_surface { unsigned long offset; unsigned int pitch; @@ -161,8 +202,13 @@ typedef struct _igd_surface { } igd_surface_t, *pigd_surface_t; typedef struct _igd_surface_list { - unsigned long offset; - unsigned long size; + unsigned long offset; + unsigned long size; + unsigned long flags; + unsigned long pitch; + unsigned long width; + unsigned long height; + unsigned long pixel_format; } igd_surface_list_t, *pigd_surface_list_t; /*! diff --git a/drivers/include/igd_version.h b/drivers/include/igd_version.h index 55cfb0b..a90a590 100644 --- a/drivers/include/igd_version.h +++ b/drivers/include/igd_version.h @@ -1,7 +1,7 @@ /* *----------------------------------------------------------------------------- * Filename: igd_version.h - * $Revision: 1.233 $ + * $Revision: 1.221.4.27 $ *----------------------------------------------------------------------------- * Copyright (c) 2002-2010, Intel Corporation. * @@ -34,8 +34,8 @@ #define _IGD_VERSION_H #define IGD_MAJOR_NUM 1 -#define IGD_MINOR_NUM 14 -#define IGD_BUILD_NUM 2667 +#define IGD_MINOR_NUM 16 +#define IGD_BUILD_NUM 3104 #define IGD_PCF_VERSION 0x00000400 #endif diff --git a/drivers/pvr/services4/3rdparty/emgd_bufferclass/emgd_bc.c b/drivers/pvr/services4/3rdparty/emgd_bufferclass/emgd_bc.c index 55a791e..0fcd349 100644 --- a/drivers/pvr/services4/3rdparty/emgd_bufferclass/emgd_bc.c +++ b/drivers/pvr/services4/3rdparty/emgd_bufferclass/emgd_bc.c @@ -189,10 +189,16 @@ GetBCBufferAddr (IMG_HANDLE hDevice, if (NULL == hDevice || NULL == hBuffer){ return (PVRSRV_ERROR_INVALID_PARAMS); } + psBuffer = (BC_BUFFER *)hBuffer; + if (IMG_NULL != pbMapped) { - *pbMapped = IMG_TRUE; + + if(psBuffer->mapped) + *pbMapped = IMG_TRUE; + else + *pbMapped = IMG_FALSE; } - psBuffer = (BC_BUFFER *)hBuffer; + EMGD_DEBUG("Buffer 0x%lx", (IMG_UINT32)psBuffer); if (NULL != ppsSysAddr) { diff --git a/drivers/pvr/services4/3rdparty/emgd_bufferclass/emgd_bc.h b/drivers/pvr/services4/3rdparty/emgd_bufferclass/emgd_bc.h index 7d5b5e3..c9d5d46 100644 --- a/drivers/pvr/services4/3rdparty/emgd_bufferclass/emgd_bc.h +++ b/drivers/pvr/services4/3rdparty/emgd_bufferclass/emgd_bc.h @@ -99,6 +99,7 @@ extern "C" IMG_UINT32 sBufferHandle; IMG_BOOL is_conti_addr; IMG_UINT32 tag; /* Buffer Tag. -- Surface ID*/ + IMG_BOOL mapped; } BC_BUFFER; typedef struct BC_DEVINFO_TAG diff --git a/drivers/pvr/services4/3rdparty/emgd_bufferclass/emgd_bc_linux.c b/drivers/pvr/services4/3rdparty/emgd_bufferclass/emgd_bc_linux.c index ca987b9..152877c 100644 --- a/drivers/pvr/services4/3rdparty/emgd_bufferclass/emgd_bc_linux.c +++ b/drivers/pvr/services4/3rdparty/emgd_bufferclass/emgd_bc_linux.c @@ -44,7 +44,7 @@ #include "io.h" #include "pvrmodule.h" #include "emgd_drm.h" - +#include "igd_gmm.h" #include "emgd_bc.h" #if 0 #define DEVNAME "bc_video" @@ -57,6 +57,9 @@ #define BC_PIX_FMT_UYVY BC_FOURCC('U', 'Y', 'V', 'Y') /*YUV 4:2:2 */ #define BC_PIX_FMT_YUYV BC_FOURCC('Y', 'U', 'Y', 'V') /*YUV 4:2:2 */ #define BC_PIX_FMT_RGB565 BC_FOURCC('R', 'G', 'B', 'P') /*RGB 5:6:5 */ +#define BC_PIX_FMT_ARGB BC_FOURCC('A','R', 'G', 'B') /*ARGB*/ +#define BC_PIX_FMT_xRGB BC_FOURCC('x','R', 'G', 'B') /*xRGB*/ +#define BC_PIX_FMT_RGB4 BC_FOURCC('R', 'G', 'B', '4') /*RGB4*/ #if 0 #if defined(BCE_USE_SET_MEMORY) #undef BCE_USE_SET_MEMORY @@ -340,6 +343,9 @@ BCE_ERROR BCAllocContigMemory (unsigned long ulSize, int iError; pvLinAddr = kmalloc(ulAlignedSize, GFP_KERNEL); + if(!pvLinAddr) { + return (BCE_ERROR_OUT_OF_MEMORY); + } BUG_ON (((unsigned long) pvLinAddr) & ~PAGE_MASK); iError = set_memory_wc((unsigned long) pvLinAddr, iPages); @@ -426,7 +432,7 @@ emgd_error_t BCGetLibFuncAddr (BCE_HANDLE unref__ hExtDrv, char *szFunctionName, } int BC_CreateBuffers(BC_DEVINFO *psDevInfo, bc_buf_params_t *p, IMG_BOOL is_conti_addr) { - IMG_UINT32 i = 0; + IMG_UINT32 i = 0, j = 0; IMG_UINT32 stride = 0; IMG_UINT32 size = 0; PVRSRV_PIXEL_FORMAT pixel_fmt = 0; @@ -438,9 +444,17 @@ int BC_CreateBuffers(BC_DEVINFO *psDevInfo, bc_buf_params_t *p, IMG_BOOL is_cont return -1; } - if (p->width <= 1 || p->height <= 1) { - return -1; - } + if (p->count > BUFCLASS_BUFFER_MAX) { + return -1; + } + + if (p->width <= 1 || p->height <= 1 || p->stride <=1 ) { + return -1; + } + + if (p->width > 2048 || p->height > 1536 || p->stride >2048*4) { + return -1; + } switch (p->fourcc) { case BC_PIX_FMT_NV12: @@ -456,6 +470,13 @@ int BC_CreateBuffers(BC_DEVINFO *psDevInfo, bc_buf_params_t *p, IMG_BOOL is_cont case BC_PIX_FMT_YUYV: pixel_fmt = PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YUYV; break; + case BC_PIX_FMT_ARGB: + case BC_PIX_FMT_RGB4: + pixel_fmt = PVRSRV_PIXEL_FORMAT_ARGB8888; + break; + case BC_PIX_FMT_xRGB: + pixel_fmt = PVRSRV_PIXEL_FORMAT_XRGB8888; + break; default: return -1; break; @@ -475,7 +496,8 @@ int BC_CreateBuffers(BC_DEVINFO *psDevInfo, bc_buf_params_t *p, IMG_BOOL is_cont return -1; } } else { - if ((psDevInfo->sBufferInfo.ui32BufferCount + p->count) >= BUFCLASS_BUFFER_MAX) { + + if ((psDevInfo->sBufferInfo.ui32BufferCount + p->count) > BUFCLASS_BUFFER_MAX) { EMGD_ERROR("No avaiable Buffers"); return -1; } @@ -519,11 +541,17 @@ int BC_CreateBuffers(BC_DEVINFO *psDevInfo, bc_buf_params_t *p, IMG_BOOL is_cont if (is_conti_addr){ bufnode->psSysAddr = (IMG_SYS_PHYADDR *)BCAllocKernelMem (sizeof(IMG_SYS_PHYADDR)); if (NULL == bufnode->psSysAddr) { - return EMGD_ERROR_OUT_OF_MEMORY; - } + /* Free the previously successfully allocated memeory */ + for(j=0;jpsSystemBuffer[psDevInfo->sBufferInfo.ui32BufferCount + j]); + bc_ts_free_bcbuffer(bufnode); + } + return EMGD_ERROR_OUT_OF_MEMORY; + } memset(bufnode->psSysAddr, 0, sizeof(IMG_SYS_PHYADDR)); } else { - return EMGD_ERROR_INVALID_PARAMS; + return EMGD_ERROR_INVALID_PARAMS; } } @@ -557,9 +585,15 @@ int BC_DestroyBuffers(void *psDevInfo) { DevInfo = (BC_DEVINFO *)psDevInfo; EMGD_DEBUG("To Free %lu buffers", DevInfo->sBufferInfo.ui32BufferCount); + if (DevInfo->sBufferInfo.ui32BufferCount > BUFCLASS_BUFFER_MAX) { + EMGD_ERROR("Wrong number of buffers"); + } + for (i = 0; i < DevInfo->sBufferInfo.ui32BufferCount; i++) { - bufnode = &(DevInfo->psSystemBuffer[i]); - bc_ts_free_bcbuffer(bufnode); + if(i < BUFCLASS_BUFFER_MAX) { + bufnode = &(DevInfo->psSystemBuffer[i]); + bc_ts_free_bcbuffer(bufnode); + } } BCFreeKernelMem(DevInfo->psSystemBuffer); DevInfo->psSystemBuffer = NULL; @@ -627,8 +661,8 @@ static __inline int emgd_bc_ts_bridge_init(struct drm_device *drv, void* arg, st } } - if (BUFCLASS_DEVICE_MAX_ID == i) { - EMGD_ERROR("Do you really need to run more than 5 video simulateously."); + if (BUFCLASS_DEVICE_MAX_ID == i) { + EMGD_ERROR("Do you really need to run more than 6 video simulateously."); } EMGD_TRACE_EXIT; @@ -651,6 +685,10 @@ static __inline int emgd_bc_ts_bridge_uninit(struct drm_device *drv, void* arg, } psDevInfo = (BC_DEVINFO *)GetAnchorPtr(psBridge->dev_id); + if (NULL == psDevInfo) { + EMGD_ERROR("System Error"); + return err; + } /* To disable buffer class device*/ emgd_bc_ts_set_state(psDevInfo, 0); @@ -755,7 +793,7 @@ static __inline int emgd_bc_ts_bridge_set_buffer_info(struct drm_device *drv, vo emgd_drm_bc_ts_t *psBridge = (emgd_drm_bc_ts_t *) arg; BC_DEVINFO *devinfo = IMG_NULL; BC_BUFFER *bcBuf = NULL; - + unsigned long virt=0; EMGD_TRACE_ENTER; if (NULL == psBridge) { @@ -811,9 +849,27 @@ static __inline int emgd_bc_ts_bridge_set_buffer_info(struct drm_device *drv, vo if (IMG_FALSE == bcBuf->is_conti_addr) { EMGD_ERROR("Only support conti. memory!"); } else { - bcBuf->psSysAddr[0].uiAddr = psBridge->phyaddr; - } + if(!psBridge->mapped){ + if(!psBridge->virtaddr) { + EMGD_ERROR("Invalid bridge address"); + return err; + } + /*The CPU device will be registerd into PVR later*/ + virt=((struct emgd_ci_meminfo_t *)(psBridge->virtaddr))->virt; + if(!virt) { + EMGD_ERROR("Invalid CPU address"); + return err; + } + bcBuf->sCPUVAddr = virt; + printk(KERN_ERR"virt=0x%08lx\n",virt); + bcBuf->psSysAddr[0].uiAddr = virt_to_phys(virt); + + }else{ + bcBuf->psSysAddr[0].uiAddr = psBridge->phyaddr; + } + } + bcBuf->mapped = psBridge->mapped; SUCCESS_OK: psBridge->rtn = 0; diff --git a/drivers/pvr/services4/srvkm/bridged/sgx/bridged_sgx_bridge.c b/drivers/pvr/services4/srvkm/bridged/sgx/bridged_sgx_bridge.c index de4e697..6527488 100644 --- a/drivers/pvr/services4/srvkm/bridged/sgx/bridged_sgx_bridge.c +++ b/drivers/pvr/services4/srvkm/bridged/sgx/bridged_sgx_bridge.c @@ -2455,6 +2455,30 @@ SGXPDumpHWPerfCBBW(IMG_UINT32 ui32BridgeID, #endif +/* LGE HACK: SGX reset*/ +IMG_VOID HWRecoveryResetSGX (PVRSRV_DEVICE_NODE *psDeviceNode, + IMG_UINT32 ui32Component, + IMG_UINT32 ui32CallerID); + + +IMG_INT +DummyBW2(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_MAPPHYSTOUSERSPACE *psBridgeIn, + PVRSRV_BRIDGE_OUT_MAPPHYSTOUSERSPACE *psBridgeOut, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + + PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, + psBridgeIn->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + + printk("[%s %d]HWRecoveryResetSGX\n",__FUNCTION__,__LINE__); + HWRecoveryResetSGX(hDevCookieInt, 0, KERNEL_ID); + + return 0; +} IMG_VOID SetSGXDispatchTableEntry(IMG_VOID) { @@ -2463,7 +2487,7 @@ IMG_VOID SetSGXDispatchTableEntry(IMG_VOID) SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO, SGXReleaseClientInfoBW); SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO, SGXGetInternalDevInfoBW); SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_DOKICK, SGXDoKickBW); - SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETPHYSPAGEADDR, DummyBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETPHYSPAGEADDR, DummyBW2); SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READREGISTRYDWORD, DummyBW); SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE, SGX2DQueryBlitsCompleteBW); diff --git a/drivers/pvr/services4/srvkm/devices/sgx/sgxinit.c b/drivers/pvr/services4/srvkm/devices/sgx/sgxinit.c index 45c16dc..a76f817 100644 --- a/drivers/pvr/services4/srvkm/devices/sgx/sgxinit.c +++ b/drivers/pvr/services4/srvkm/devices/sgx/sgxinit.c @@ -950,7 +950,6 @@ IMG_VOID SGXDumpDebugInfo (PVRSRV_DEVICE_NODE *psDeviceNode, #if defined(SYS_USING_INTERRUPTS) || defined(SUPPORT_HW_RECOVERY) -static IMG_VOID HWRecoveryResetSGX (PVRSRV_DEVICE_NODE *psDeviceNode, IMG_UINT32 ui32Component, IMG_UINT32 ui32CallerID) -- 2.7.4