aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/emgd/emgd/video/overlay/plb/ovl_plb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/emgd/emgd/video/overlay/plb/ovl_plb.c')
-rw-r--r--drivers/gpu/drm/emgd/emgd/video/overlay/plb/ovl_plb.c2165
1 files changed, 0 insertions, 2165 deletions
diff --git a/drivers/gpu/drm/emgd/emgd/video/overlay/plb/ovl_plb.c b/drivers/gpu/drm/emgd/emgd/video/overlay/plb/ovl_plb.c
deleted file mode 100644
index 80e014e528c8..000000000000
--- a/drivers/gpu/drm/emgd/emgd/video/overlay/plb/ovl_plb.c
+++ /dev/null
@@ -1,2165 +0,0 @@
-/* -*- pse-c -*-
- *-----------------------------------------------------------------------------
- * Filename: ovl_plb.c
- * $Revision: 1.22 $
- *-----------------------------------------------------------------------------
- * Copyright © 2002-2010, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *-----------------------------------------------------------------------------
- * Description:
- * This file contains function that actually programs the overlay
- * register back buffer with the bits to properly configure
- * the overlay
- * Also includes functions to execute the overlay flip instruction,
- * and query the overlay flip status.
- * Also contains some hardware capabilities querrying functions
- * for upper overlay layer to get this chips overlay capabilities
- *-----------------------------------------------------------------------------
- */
-
-#define MODULE_NAME hal.overlay
-
-#include <math_fix.h>
-#include <plb/cmd.h>
-#include "ovl_plb_cache.h"
-#include "../cmn/ovl_dispatch.h"
-#include "../cmn/ovl_virt.h"
-#include "../cmn/ovl_coeff.h"
-#include "ovl2_plb.h"
-
-/*-----------------------------------------------------------------------------
- * Common dispatch functions
- *---------------------------------------------------------------------------*/
-static int alter_ovl_plb(igd_display_context_t *display,
- igd_surface_t *src_surf,
- igd_rect_t *src_rect,
- igd_rect_t *dest_rect,
- igd_ovl_info_t *ovl_info,
- unsigned int flags);
-static int query_ovl_plb(igd_display_h display_h,
- unsigned int flags);
-static int query_max_size_ovl_plb(igd_display_h display_h,
- unsigned long pf,
- unsigned int *max_width,
- unsigned int *max_height);
-
-
-ovl_dispatch_t ovl_dispatch_plb[] = {
- /* Dispatch for the hardware overlay */
- {
- NULL, /*blend_surf_needed_plb,*/
- alter_ovl_plb,
- query_ovl_plb,
- query_max_size_ovl_plb,
- },
- /* Dispatch for the software overlay */
- {
- NULL, /*blend2_surf_needed_plb,*/
- alter_ovl2_plb,
- query_ovl2_plb,
- query_max_size_ovl2_plb,
- },
-};
-
-
-typedef struct _ovl_chipset_plb {
- unsigned int num_linebuf;
- unsigned int pixel_format;
- unsigned int max_width;
- unsigned int max_height;
-} ovl_chipset_plb_t;
-
-static ovl_chipset_plb_t ovl_chipset_plb[] = {
- {OVL_CONFIG_THREE_LINE_BUFF,
- (PF_DEPTH_16 | PF_TYPE_YUV_PACKED), 1280, 1080},
- {OVL_CONFIG_THREE_LINE_BUFF,
- (PF_DEPTH_8 | PF_TYPE_YUV_PLANAR), 1024, 1080},
- {OVL_CONFIG_THREE_LINE_BUFF,
- (PF_DEPTH_32 | PF_TYPE_ARGB), 640, 1080},
- {OVL_CONFIG_THREE_LINE_BUFF,
- (PF_DEPTH_32 | PF_TYPE_RGB), 640, 1080},
-
- {OVL_CONFIG_TWO_LINE_BUFF,
- (PF_DEPTH_16 | PF_TYPE_YUV_PACKED), 1920, 1088},
- {OVL_CONFIG_TWO_LINE_BUFF,
- (PF_DEPTH_8 | PF_TYPE_YUV_PLANAR), 1920, 1088},
- {OVL_CONFIG_TWO_LINE_BUFF,
- (PF_DEPTH_32 | PF_TYPE_ARGB), 960, 1080},
- {OVL_CONFIG_TWO_LINE_BUFF,
- (PF_DEPTH_32 | PF_TYPE_RGB), 960, 1080},
- {OVL_CONFIG_NO_LINE_BUFF, 0, 0, 0}
-};
-
-#ifdef DEBUG_BUILD_TYPE
-
-static void ovl_dump_regs_plb(
- ovl_reg_image_plb_t *ovl_regs_plb)
-{
- return;
-
- printk (KERN_ERR "************************************************\n");
- printk (KERN_ERR "OVERLAY REGISTER LISTING\n");
-
- printk (KERN_ERR "OVL REGS AT = 0x%x \n", (unsigned int)ovl_regs_plb);
- if(ovl_regs_plb->buffer0_yrgb_ptr)
- printk (KERN_ERR "RGB POINTER 0 = 0x%x \n",
- ovl_regs_plb->buffer0_yrgb_ptr);
- if(ovl_regs_plb->buffer1_yrgb_ptr)
- printk (KERN_ERR "RGB POINTER 1 = 0x%x \n",
- ovl_regs_plb->buffer1_yrgb_ptr);
- if(ovl_regs_plb->buffer0_u_ptr)
- printk (KERN_ERR "U POINTER 0 = 0x%x \n",
- ovl_regs_plb->buffer0_u_ptr);
- if(ovl_regs_plb->buffer0_v_ptr)
- printk (KERN_ERR "V POINTER 0 = 0x%x \n",
- ovl_regs_plb->buffer0_v_ptr);
- if(ovl_regs_plb->buffer1_u_ptr)
- printk (KERN_ERR "U POINTER 1 = 0x%x \n",
- ovl_regs_plb->buffer1_u_ptr);
- if(ovl_regs_plb->buffer1_v_ptr)
- printk (KERN_ERR "V POINTER 1 = 0x%x \n",
- ovl_regs_plb->buffer1_v_ptr);
-
- printk (KERN_ERR "RGB STRIDE = 0x%x \n",
- ovl_regs_plb->yrgb_stride);
- printk (KERN_ERR "UV STRIDE = 0x%x \n",
- ovl_regs_plb->uv_stride);
- printk (KERN_ERR "DST POS X = %d \n",
- ovl_regs_plb->dest_pos_x_left);
- printk (KERN_ERR "DST POS Y = %d \n",
- ovl_regs_plb->dest_pos_y_top);
- printk (KERN_ERR "DST WIDTH = %d \n",
- ovl_regs_plb->dest_width_x);
- printk (KERN_ERR "DST HEIGHT = %d \n",
- ovl_regs_plb->dest_height_y);
- printk (KERN_ERR "SRC WIDTH = %d \n",
- ovl_regs_plb->source_yrgb_width);
- printk (KERN_ERR "SRC SWWIDTH = 0x%x \n",
- ovl_regs_plb->source_yrgb_width_swords);
- printk (KERN_ERR "SRC HEIGHT = %d \n",
- ovl_regs_plb->source_yrgb_height);
- printk (KERN_ERR "UV SRC WIDTH = %d \n",
- ovl_regs_plb->source_uv_width);
- printk (KERN_ERR "UV SRC SWWIDTH = %d \n",
- ovl_regs_plb->source_uv_width_swords);
- printk (KERN_ERR "UV SRC HEIGHT = %d \n",
- ovl_regs_plb->source_uv_height);
- printk (KERN_ERR "RGB SCALE = 0x%x \n",
- ovl_regs_plb->yrgb_scale);
- printk (KERN_ERR "UV SCALE = 0x%x \n",
- ovl_regs_plb->uv_scale);
- printk (KERN_ERR "COL CTL BRT CON = 0x%x \n",
- ovl_regs_plb->col_ctl_brt_con);
- printk (KERN_ERR "COL CTL SAT HUE = 0x%x \n",
- ovl_regs_plb->col_ctl_sat_hue);
- printk (KERN_ERR "DST COLOR KEY = 0x%x \n",
- ovl_regs_plb->dest_ckey_val);
- printk (KERN_ERR "DST COLOR KEY MASK = 0x%x \n",
- ovl_regs_plb->dest_ckey_mask);
- printk (KERN_ERR "SRC COLOR KEY HI = 0x%x \n",
- ovl_regs_plb->source_ckey_high);
- printk (KERN_ERR "SRC COLOR KEY LO = 0x%x \n",
- ovl_regs_plb->source_ckey_low);
- printk (KERN_ERR "SRC COLOR KEY MASK = 0x%x \n",
- ovl_regs_plb->source_ckey_mask);
- printk (KERN_ERR "OVL CONFIG = 0x%x \n", ovl_regs_plb->config);
- printk (KERN_ERR "OVL CMD = 0x%x \n", ovl_regs_plb->command);
- printk (KERN_ERR "FAST_V_DSCALE = 0x%x \n",
- ovl_regs_plb->vert_downscale);
- printk (KERN_ERR "************************************************\n");
-}
-#endif
-
-/*----------------------------------------------------------------------
- * Function: ovl_check_pf_plb()
- * Parameters: unsigned int requested_pixel_format -
- * according to definitions in igd_mode.h
- *
- * Description:
- *
- * Returns:
- * TRUE on Success
- * FALSE on The first pixel format that is supported
- *----------------------------------------------------------------------*/
-static unsigned int ovl_check_pf_plb(
- igd_display_context_t *display,
- unsigned int requested_pixel_format)
-{
- unsigned long *overlay_pfs;
- int temp_loop = 0;
-
- display->context->dispatch.get_pixelformats(
- (igd_display_h)display, NULL, NULL, &overlay_pfs, NULL, NULL);
-
- while(overlay_pfs[temp_loop]) {
- if(overlay_pfs[temp_loop] == requested_pixel_format) {
- return TRUE;
- }
- ++temp_loop;
- }
-
- return FALSE;
-}
-
-static unsigned int get_uv_shift_x (unsigned long pf)
-{
-
- switch(pf) {
- case IGD_PF_YUV422_PACKED_YUY2:
- case IGD_PF_YUV422_PACKED_UYVY:
- case IGD_PF_YUV420_PLANAR_I420: /* same as IYUV */
- case IGD_PF_YUV420_PLANAR_YV12:
- case IGD_PF_YUV420_PLANAR_NV12:
- return 1;
- break;
- case IGD_PF_YUV410_PLANAR_YVU9:
- return 2;
- break;
- default:
- return 0;
- }
-
-}
-
-static unsigned int get_uv_shift_y (unsigned long pf)
-{
-
- switch(pf) {
- case IGD_PF_YUV420_PLANAR_I420: /* same as IYUV */
- case IGD_PF_YUV420_PLANAR_YV12:
- case IGD_PF_YUV420_PLANAR_NV12:
- return 1;
- break;
- case IGD_PF_YUV410_PLANAR_YVU9:
- return 2;
- break;
- default:
- return 0;
- }
-
-}
-
-static unsigned int ovl_check_plb(igd_display_context_t *display,
- igd_surface_t *src_surf,
- igd_rect_t *src_rect,
- igd_rect_t *dest_rect,
- igd_ovl_info_t *ovl_info,
- unsigned int flags)
-{
- igd_timing_info_t *timing;
- ovl_chipset_plb_t *ovl_chip;
- unsigned int min_w, min_h;
-
- EMGD_TRACE_ENTER;
-
- if (!display){
- EMGD_ERROR_EXIT("display is null");
- return -IGD_ERROR_INVAL;
- }
- if (!PIPE(display)){
- EMGD_ERROR_EXIT("PIPE(display) is null");
- return -IGD_ERROR_INVAL;
- }
-
- timing = PIPE(display)->timing;
-
- /* DCT-PC99TA crashes with dotclock > 300MHz */
- if(timing->dclk >= 340000){
- EMGD_ERROR_EXIT("Cannot support dotclock > 340MHz for this SKU");
- return -IGD_ERROR_HWERROR;
- }
-
- /* The following parameters are only valid if the overlay is on, so
- * return success if the overlay is being turned off. */
- if ((flags & IGD_OVL_ALTER_ON) == IGD_OVL_ALTER_OFF) {
- EMGD_TRACE_EXIT;
- return IGD_SUCCESS;
- }
-
- /*************************************************************************
- * Ensure the overlay surface is ok and can be properly displayed.
- * This ensures the following is valid:
- * - Ensure x1, x2, y1, y2 are pixel aligned
- * - 2 pixels or greater in width and height
- * - Pixel format is supported by the overlay
- * - Pitch is <= 8KB
- * - Based on the pixel format, the width is supported
- *************************************************************************/
- if (!src_surf){
- EMGD_ERROR_EXIT("src_surf is null");
- return -IGD_ERROR_INVAL;
- }
- if (!src_rect){
- EMGD_ERROR_EXIT("src_rect is null");
- return -IGD_ERROR_INVAL;
- }
-
- /* Get the minimum size of 1 pixel in width and height for y, u, and v.
- */
- min_w = 1 << get_uv_shift_x(src_surf->pixel_format);
- min_h = 1 << get_uv_shift_y(src_surf->pixel_format);
-
- if (((src_rect->x2 - src_rect->x1) < min_w*2) ||
- ((src_rect->y2 - src_rect->y1) < min_h*2)) {
- EMGD_ERROR_EXIT(
- "Overlay source width or height is < 2 pixels (%dx%d)\n",
- src_rect->x2 - src_rect->x1, src_rect->y2 - src_rect->y1);
- return -IGD_ERROR_INVAL;
- }
-
- if (FALSE == ovl_check_pf_plb(display, src_surf->pixel_format)) {
- EMGD_ERROR_EXIT("Overlay source pixel format unsupported (pf:0x%lx)",
- src_surf->pixel_format);
- return -IGD_ERROR_HWERROR;
- }
-
- if (src_surf->pitch > 8192) {
- EMGD_ERROR_EXIT("Overlay source pitch (%d) > 8KB",
- src_surf->pitch);
- return -IGD_ERROR_HWERROR;
- }
-
- ovl_chip = ovl_chipset_plb;
- while(ovl_chip->num_linebuf != OVL_CONFIG_NO_LINE_BUFF){
- if(((src_surf->pixel_format & IGD_PF_MASK) ==
- ovl_chip->pixel_format) &&
- (src_surf->width <= ovl_chip->max_width)) {
- break;
- }
- ovl_chip++;
- }
- if (ovl_chip->num_linebuf == OVL_CONFIG_NO_LINE_BUFF) {
- EMGD_ERROR_EXIT("Overlay source width (%d) > max supported",
- src_surf->width);
- return -IGD_ERROR_HWERROR;
- }
-
- /*************************************************************************
- * Ensure the location on the framebuffer is ok and can be properly
- * displayed
- * This ensures the following is valid:
- * - Greater than 1 pixel width and height
- * - Will be displayed on screen (not panned off)
- *************************************************************************/
- if (!dest_rect){
- EMGD_ERROR_EXIT("dest_rect is null");
- return -IGD_ERROR_INVAL;
- }
- if (((dest_rect->x2 - dest_rect->x1) <= 1) ||
- ((dest_rect->y2 - dest_rect->y1) <= 1)) {
- EMGD_ERROR_EXIT(
- "Overlay dest width or height is single pixel (%dx%d)\n",
- dest_rect->x2 - dest_rect->x1, dest_rect->y2 - dest_rect->y1);
- return -IGD_ERROR_INVAL;
- }
-
- if ((dest_rect->x1 >= timing->width) ||
- (dest_rect->y1 >= timing->height)) {
- EMGD_ERROR_EXIT(
- "Overlay dest is panned off the screen (%d,%d)\n",
- dest_rect->x1, dest_rect->y1);
- return -IGD_ERROR_INVAL;
- }
-
- EMGD_TRACE_EXIT;
- return IGD_SUCCESS;
-}
-
-
-
-static unsigned int ovl_update_src_plb(igd_display_context_t *display,
- ovl_reg_image_plb_t *ovl_regs_plb,
- igd_surface_t *src_surf,
- igd_rect_t *src_rect)
-{
- ovl_chipset_plb_t *ovl_chip;
- unsigned int src_Bpp;
- unsigned int src_uv_shift_x, src_uv_shift_y;
- unsigned short src_w;
- unsigned short src_h;
-
- EMGD_TRACE_ENTER;
-
- /* This is in Bytes per pixel */
- src_Bpp = IGD_PF_BPP(src_surf->pixel_format)/8;
-
- src_uv_shift_x = get_uv_shift_x(src_surf->pixel_format);
- src_uv_shift_y = get_uv_shift_y(src_surf->pixel_format);
-
- src_w = src_rect->x2 - src_rect->x1;
- src_h = src_rect->y2 - src_rect->y1;
-
- ovl_regs_plb->yrgb_stride = (unsigned short)src_surf->pitch;
- ovl_regs_plb->uv_stride = (unsigned short)src_surf->u_pitch;
-
- /* src width */
- ovl_regs_plb->source_yrgb_width = src_w;
- ovl_regs_plb->source_uv_width = src_w >> src_uv_shift_x;
-
- /* src width swords - This equation follows the B-Spec */
- ovl_regs_plb->source_yrgb_width_swords =
- ((((((ovl_regs_plb->buffer0_yrgb_ptr +
- (ovl_regs_plb->source_yrgb_width * src_Bpp) +
- 0x3F) >> 6) -
- (ovl_regs_plb->buffer0_yrgb_ptr >> 6)) << 1) - 1) << 2);
- ovl_regs_plb->source_uv_width_swords =
- ((((((ovl_regs_plb->buffer0_u_ptr +
- (ovl_regs_plb->source_uv_width * src_Bpp) +
- 0x3F) >> 6) -
- (ovl_regs_plb->buffer0_u_ptr >> 6)) << 1) - 1) << 2 );
-
-
- /* src height */
- ovl_regs_plb->source_yrgb_height = src_h;
- ovl_regs_plb->source_uv_height = src_h >> src_uv_shift_y;
-
- /* src pixel format */
- switch(src_surf->pixel_format){
- case IGD_PF_YUV422_PACKED_YUY2:
- ovl_regs_plb->command |= OVL_CMD_YUV_422;
- break;
- case IGD_PF_YUV422_PACKED_UYVY:
- ovl_regs_plb->command |= OVL_CMD_YUV_422 | OVL_CMD_Y_SWAP;
- break;
- case IGD_PF_YUV420_PLANAR_I420: /* same as IYUV */
- ovl_regs_plb->command |= OVL_CMD_YUV_420P;
- break;
- case IGD_PF_YUV420_PLANAR_YV12:
- ovl_regs_plb->command |= OVL_CMD_YUV_420P | OVL_CMD_UV_SWAP;
- break;
- case IGD_PF_YUV420_PLANAR_NV12:
- ovl_regs_plb->command |= OVL_CMD_YUV_NV12;
- break;
- case IGD_PF_YUV410_PLANAR_YVU9:
- ovl_regs_plb->command |= OVL_CMD_YUV_410P;
- break;
- case IGD_PF_ARGB32_8888:
- case IGD_PF_xRGB32_8888:
- ovl_regs_plb->command |= OVL_CMD_RGB_8888;
- break;
- case IGD_PF_RGB16_565:
- ovl_regs_plb->command |= OVL_CMD_RGB_565;
- break;
- case IGD_PF_xRGB16_555:
- case IGD_PF_ARGB16_1555:
- ovl_regs_plb->command |= OVL_CMD_RGB_555;
- break;
- default:
- EMGD_ERROR_EXIT("Invalid pixel format: 0x%lx", src_surf->pixel_format);
- return -IGD_ERROR_HWERROR;
- }
-
- /* Turn off YUV to RGB conversion if the src is RGB */
- if (!(src_surf->pixel_format & PF_TYPE_YUV)) {
- ovl_regs_plb->config |= (1<<4);
- }
-
- ovl_chip = ovl_chipset_plb;
- ovl_regs_plb->config &= ~OVL_CONFIG_LINE_BUFF_MASK;
- while(ovl_chip->num_linebuf != OVL_CONFIG_NO_LINE_BUFF){
- if(((src_surf->pixel_format & IGD_PF_MASK) ==
- ovl_chip->pixel_format) &&
- (src_w <= ovl_chip->max_width)) {
- ovl_regs_plb->config |= ovl_chip->num_linebuf;
- break;
- }
- ovl_chip++;
- }
-
- EMGD_TRACE_EXIT;
- return IGD_SUCCESS;
-}
-
-
-static unsigned int ovl_update_src_ptr_plb(igd_display_context_t *display,
- ovl_reg_image_plb_t *ovl_regs_plb,
- igd_surface_t *src_surf,
- igd_rect_t *src_rect)
-{
- unsigned int src_Bpp;
- unsigned int src_uv_shift_x, src_uv_shift_y;
-
- EMGD_TRACE_ENTER;
-
- /* This is in Bytes per pixel */
- src_Bpp = IGD_PF_BPP(src_surf->pixel_format)/8;
- src_uv_shift_x = get_uv_shift_x(src_surf->pixel_format);
- src_uv_shift_y = get_uv_shift_y(src_surf->pixel_format);
-
- /* src surface */
- ovl_regs_plb->buffer0_yrgb_ptr =
- ovl_regs_plb->buffer1_yrgb_ptr =
- src_surf->offset +
- (src_rect->y1 * src_surf->pitch) + (src_rect->x1 * src_Bpp);
-
- /*
- * The NV12 format has the UV pixels interleaved so the total
- * width of the UV portion of the surface is the same as the
- * Y width. Thus, don't do any shifting of the UV plane in the
- * X direction.
- */
- if (src_surf->pixel_format == IGD_PF_YUV420_PLANAR_NV12) {
- ovl_regs_plb->buffer0_u_ptr =
- ovl_regs_plb->buffer1_u_ptr =
- src_surf->u_offset +
- ((src_rect->y1>>src_uv_shift_y) * src_surf->u_pitch) +
- src_rect->x1;
-
- ovl_regs_plb->buffer0_v_ptr =
- ovl_regs_plb->buffer1_v_ptr =
- src_surf->v_offset +
- ((src_rect->y1>>src_uv_shift_y) * src_surf->v_pitch) +
- src_rect->x1;
- } else {
- ovl_regs_plb->buffer0_u_ptr =
- ovl_regs_plb->buffer1_u_ptr =
- src_surf->u_offset +
- ((src_rect->y1>>src_uv_shift_y) * src_surf->u_pitch) +
- (src_rect->x1>>src_uv_shift_x);
-
- ovl_regs_plb->buffer0_v_ptr =
- ovl_regs_plb->buffer1_v_ptr =
- src_surf->v_offset +
- ((src_rect->y1>>src_uv_shift_y) * src_surf->v_pitch) +
- (src_rect->x1>>src_uv_shift_x);
- }
-
-
- EMGD_TRACE_EXIT;
- return IGD_SUCCESS;
-}
-
-
-static unsigned int ovl_update_phase_plb(
- ovl_reg_image_plb_t *ovl_regs_plb,
- igd_surface_t *src_surf,
- igd_rect_t *src_rect)
-{
-
- EMGD_TRACE_ENTER;
-
- /*
- * Set the Vertical/Horizontal Phase Registers. Both Field0
- * and Field1 are set, although Field1 is only used when
- * interleaved.
- */
- switch (src_surf->pixel_format) {
- case IGD_PF_YUV422_PACKED_YUY2:
- case IGD_PF_YUV422_PACKED_UYVY:
- /* YUV 422 */
- ovl_regs_plb->init_phase_shift = 0;
-
- /* Vertical Phase */
- if (ovl_regs_plb->config & OVL_CONFIG_THREE_LINE_BUFF) {
- ovl_regs_plb->yrgb_vert_phase_field0 = 0;
- ovl_regs_plb->yrgb_vert_phase_field1 = 0;
- ovl_regs_plb->uv_vert_phase_field0 = 0;
- ovl_regs_plb->uv_vert_phase_field1 = 0;
- } else {
- ovl_regs_plb->yrgb_vert_phase_field0 = 0x8000; /*.5*/
- ovl_regs_plb->yrgb_vert_phase_field1 = 0x8000; /*.5*/
- ovl_regs_plb->uv_vert_phase_field0 = 0x8000; /*.5*/
- ovl_regs_plb->uv_vert_phase_field1 = 0x8000; /*.5*/
- }
-
- /* Horizontal Phase */
- if (!(src_rect->x1 & 1)) {
- ovl_regs_plb->yrgb_hphase = 0;
- ovl_regs_plb->uv_hphase = 0;
- } else {
- ovl_regs_plb->init_phase_shift |= Y_HPP_PLUS1;
- ovl_regs_plb->yrgb_hphase = 0; /*1*/
- ovl_regs_plb->uv_hphase = 0x8000; /*.5*/
- }
- break;
-
- case IGD_PF_YUV420_PLANAR_I420:
- case IGD_PF_YUV420_PLANAR_YV12:
- case IGD_PF_YUV420_PLANAR_NV12:
- /* YUV 420 */
- ovl_regs_plb->init_phase_shift = 0;
-
- /* Vertical Phase */
- if (ovl_regs_plb->config & OVL_CONFIG_THREE_LINE_BUFF) {
- if (!(src_rect->y1 & 1)) {
- ovl_regs_plb->yrgb_vert_phase_field0 = 0; /*0*/
- ovl_regs_plb->init_phase_shift |= Y_VPP_FLD1_PLUS1;
- ovl_regs_plb->yrgb_vert_phase_field1 = 0;/*1*/
-
- ovl_regs_plb->init_phase_shift |= UV_VPP_FLD0_MINUS1;
- ovl_regs_plb->uv_vert_phase_field0 = 0xc000; /*-.25*/
- ovl_regs_plb->uv_vert_phase_field1 = 0x4000; /*.25*/
- } else {
- ovl_regs_plb->init_phase_shift |= Y_VPP_FLD0_PLUS1;
- ovl_regs_plb->yrgb_vert_phase_field0 = 0; /*1*/
- ovl_regs_plb->yrgb_vert_phase_field1 = 0;/*0*/
-
- ovl_regs_plb->uv_vert_phase_field0 = 0x4000; /*.25*/
- ovl_regs_plb->init_phase_shift |= UV_VPP_FLD1_MINUS1;
- ovl_regs_plb->uv_vert_phase_field1 = 0xc000; /*-.25*/
- }
- } else {
- if (!(src_rect->y1 & 1)) {
- ovl_regs_plb->yrgb_vert_phase_field0 = 0x8000; /*.5*/
- ovl_regs_plb->init_phase_shift |= Y_VPP_FLD1_PLUS1;
- ovl_regs_plb->yrgb_vert_phase_field1 = 0x8000;/*1.5*/
-
- ovl_regs_plb->uv_vert_phase_field0 = 0x4000; /*.25*/
- ovl_regs_plb->uv_vert_phase_field1 = 0xc000; /*.75*/
- } else {
- ovl_regs_plb->init_phase_shift |= Y_VPP_FLD0_PLUS1;
- ovl_regs_plb->yrgb_vert_phase_field0 = 0x8000;/*1.5*/
- ovl_regs_plb->yrgb_vert_phase_field1 = 0x8000; /*.5*/
-
- ovl_regs_plb->uv_vert_phase_field0 = 0xc000; /*.75*/
- ovl_regs_plb->uv_vert_phase_field1 = 0x4000; /*.25*/
- }
- }
-
- /* Horizontal Phase */
- if (!(src_rect->x1 & 1)) {
- ovl_regs_plb->yrgb_hphase = 0;
- ovl_regs_plb->uv_hphase = 0;
- } else {
- ovl_regs_plb->init_phase_shift |= Y_HPP_PLUS1;
- ovl_regs_plb->yrgb_hphase = 0; /*1*/
- ovl_regs_plb->uv_hphase = 0x8000; /*.5*/
- }
- break;
-
- case IGD_PF_YUV410_PLANAR_YVU9:
- /* YUV 410 */
- ovl_regs_plb->init_phase_shift = 0;
-
- /* Vertical Phase */
- if (ovl_regs_plb->config & OVL_CONFIG_THREE_LINE_BUFF) {
- switch (src_rect->y1 & 3) {
- default:
- case 0:
- ovl_regs_plb->yrgb_vert_phase_field0 = 0; /*0*/
- ovl_regs_plb->init_phase_shift |= Y_VPP_FLD1_PLUS1;
- ovl_regs_plb->yrgb_vert_phase_field1 = 0;/*1*/
-
- ovl_regs_plb->init_phase_shift |= UV_VPP_FLD0_MINUS1;
- ovl_regs_plb->uv_vert_phase_field0 = 0xa000; /*-.375*/
- ovl_regs_plb->init_phase_shift |= UV_VPP_FLD1_MINUS1;
- ovl_regs_plb->uv_vert_phase_field1 = 0xe000; /*-.125*/
- break;
-
- case 1:
- ovl_regs_plb->init_phase_shift |= Y_VPP_FLD0_PLUS1;
- ovl_regs_plb->yrgb_vert_phase_field0 = 0; /*1*/
- ovl_regs_plb->init_phase_shift |= Y_VPP_FLD1_PLUS1;
- ovl_regs_plb->yrgb_vert_phase_field1 = 0;/*1*/
-
- ovl_regs_plb->init_phase_shift |= UV_VPP_FLD0_MINUS1;
- ovl_regs_plb->uv_vert_phase_field0 = 0xe000; /*-.125*/
- ovl_regs_plb->uv_vert_phase_field1 = 0x2000; /*.125*/
- break;
-
- case 2:
- ovl_regs_plb->init_phase_shift |= Y_VPP_FLD0_PLUS1;
- ovl_regs_plb->yrgb_vert_phase_field0 = 0; /*1*/
- ovl_regs_plb->init_phase_shift |= Y_VPP_FLD1_PLUS1;
- ovl_regs_plb->yrgb_vert_phase_field1 = 0;/*1*/
-
- ovl_regs_plb->uv_vert_phase_field0 = 0x2000; /*.125*/
- ovl_regs_plb->uv_vert_phase_field1 = 0x6000; /*.375*/
- break;
-
- case 3:
- ovl_regs_plb->init_phase_shift |= Y_VPP_FLD0_PLUS1;
- ovl_regs_plb->yrgb_vert_phase_field0 = 0; /*1*/
- ovl_regs_plb->yrgb_vert_phase_field1 = 0;/*0*/
-
- ovl_regs_plb->uv_vert_phase_field0 = 0x6000; /*.375*/
- ovl_regs_plb->init_phase_shift |= UV_VPP_FLD1_MINUS1;
- ovl_regs_plb->uv_vert_phase_field1 = 0xa000; /*-.375*/
- break;
- }
- } else {
- switch (src_rect->y1 & 3) {
- default:
- case 0:
- ovl_regs_plb->yrgb_vert_phase_field0 = 0x8000; /*.5*/
- ovl_regs_plb->init_phase_shift |= Y_VPP_FLD1_PLUS1;
- ovl_regs_plb->yrgb_vert_phase_field1 = 0x8000;/*1.5*/
-
- ovl_regs_plb->init_phase_shift |= UV_VPP_FLD0_MINUS1;
- ovl_regs_plb->uv_vert_phase_field0 = 0xc000; /*-.25*/
- ovl_regs_plb->uv_vert_phase_field1 = 0; /*0*/
- break;
-
- case 1:
- ovl_regs_plb->init_phase_shift |= Y_VPP_FLD0_PLUS1;
- ovl_regs_plb->yrgb_vert_phase_field0 = 0x8000;/*1.5*/
- ovl_regs_plb->init_phase_shift |= Y_VPP_FLD1_PLUS1;
- ovl_regs_plb->yrgb_vert_phase_field1 = 0x8000; /*1.5*/
-
- ovl_regs_plb->uv_vert_phase_field0 = 0x0; /*0*/
- ovl_regs_plb->uv_vert_phase_field1 = 0x4000; /*.25*/
- break;
-
- case 2:
- ovl_regs_plb->init_phase_shift |= Y_VPP_FLD0_PLUS1;
- ovl_regs_plb->yrgb_vert_phase_field0 = 0x8000;/*1.5*/
- ovl_regs_plb->init_phase_shift |= Y_VPP_FLD1_PLUS1;
- ovl_regs_plb->yrgb_vert_phase_field1 = 0x8000; /*1.5*/
-
- ovl_regs_plb->uv_vert_phase_field0 = 0x4000; /*.25*/
- ovl_regs_plb->uv_vert_phase_field1 = 0x8000; /*.5*/
- break;
-
- case 3:
- ovl_regs_plb->init_phase_shift |= Y_VPP_FLD0_PLUS1;
- ovl_regs_plb->yrgb_vert_phase_field0 = 0x8000;/*1.5*/
- ovl_regs_plb->yrgb_vert_phase_field1 = 0x8000; /*.5*/
-
- ovl_regs_plb->uv_vert_phase_field0 = 0x8000; /*.5*/
- ovl_regs_plb->init_phase_shift |= UV_VPP_FLD1_MINUS1;
- ovl_regs_plb->uv_vert_phase_field1 = 0xc000; /*-.25*/
- break;
- }
- }
-
- /* Horizontal Phase */
- switch (src_rect->x1 & 3) {
- default:
- case 0:
- ovl_regs_plb->yrgb_hphase = 0;
- ovl_regs_plb->init_phase_shift |= UV_HPP_MINUS1;
- ovl_regs_plb->uv_hphase = 0xa000; /*-.375*/
- break;
-
- case 1:
- ovl_regs_plb->init_phase_shift |= Y_HPP_PLUS1;
- ovl_regs_plb->yrgb_hphase = 0; /*1*/
- ovl_regs_plb->init_phase_shift |= UV_HPP_MINUS1;
- ovl_regs_plb->uv_hphase = 0xe000; /*-.125*/
- break;
-
- case 2:
- ovl_regs_plb->init_phase_shift |= Y_HPP_PLUS2;
- ovl_regs_plb->yrgb_hphase = 0; /*2*/
- ovl_regs_plb->uv_hphase = 0x2000; /*.125*/
- break;
-
- case 3:
- ovl_regs_plb->init_phase_shift |= Y_HPP_PLUS2;
- ovl_regs_plb->yrgb_hphase = 0xffff; /*3*/
- ovl_regs_plb->uv_hphase = 0x6000; /*.375*/
- break;
- }
- break;
-
- default:
- /* RGB format */
- ovl_regs_plb->init_phase_shift = 0;
-
- /* Vertical Phase */
- if (ovl_regs_plb->config & OVL_CONFIG_THREE_LINE_BUFF) {
- ovl_regs_plb->yrgb_vert_phase_field0 = 0;
- ovl_regs_plb->yrgb_vert_phase_field1 = 0;
- ovl_regs_plb->uv_vert_phase_field0 = 0;
- ovl_regs_plb->uv_vert_phase_field1 = 0;
- } else {
- ovl_regs_plb->yrgb_vert_phase_field0 = 0x8000;
- ovl_regs_plb->yrgb_vert_phase_field1 = 0x8000;
- ovl_regs_plb->uv_vert_phase_field0 = 0x8000;
- ovl_regs_plb->uv_vert_phase_field1 = 0x8000;
- }
-
- /* Horizontal Phase */
- ovl_regs_plb->yrgb_hphase = 0;
- ovl_regs_plb->uv_hphase = 0;
- break;
- }
-
- EMGD_TRACE_EXIT;
- return IGD_SUCCESS;
-}
-
-
-
-/*----------------------------------------------------------------------
- * Function: ovl_update_scale_plb()
- *
- * Description: Will update only the scaling registers for the plb core
- *
- * Returns:
- * N/A
- *----------------------------------------------------------------------*/
-
-static unsigned int ovl_update_scale_plb(
- ovl_reg_image_plb_t *ovl_regs_plb,
- igd_surface_t *src_surf,
- igd_rect_t *src_rect,
- igd_rect_t *dest_rect,
- unsigned int flags)
-{
- unsigned int uv_shift;
- unsigned int xscale, xscale_int, xscale_fract;
- unsigned int yscale, yscale_int, yscale_fract;
- unsigned int xscale_int_uv, xscale_fract_uv;
- unsigned int yscale_int_uv, yscale_fract_uv;
-
- EMGD_TRACE_ENTER;
-
- xscale = ((src_rect->x2 - src_rect->x1)<<12) /
- (dest_rect->x2 - dest_rect->x1);
- yscale = ((src_rect->y2 - src_rect->y1)<<12) /
- (dest_rect->y2 - dest_rect->y1);
-
- /* In interleaved mode, the y scale is /2 */
- if (flags & IGD_OVL_ALTER_INTERLEAVED) {
- yscale >>= 1;
- }
-
- xscale_int = (xscale & 0x3000) >> 12;
- xscale_fract = xscale & 0xfff;
- yscale_int = (yscale & 0x7ff000) >> 12;
- yscale_fract = yscale & 0xfff;
-
- uv_shift = get_uv_shift_x(src_surf->pixel_format);
- xscale_int_uv = ((xscale>>uv_shift) & 0x3000) >> 12;
- xscale_fract_uv = (xscale>>uv_shift) & 0xfff;
-
- uv_shift = get_uv_shift_y(src_surf->pixel_format);
- yscale_int_uv = ((yscale>>uv_shift) & 0x7ff000) >> 12;
- yscale_fract_uv = (yscale>>uv_shift) & 0xfff;
-
- ovl_regs_plb->yrgb_scale =
- (yscale_fract << 20) | /* Vert Scale Fraction */
- (xscale_int << 16) | /* Horiz Scale Int */
- (xscale_fract << 3); /* Horiz Scale Fraction */
-
- ovl_regs_plb->uv_scale =
- (yscale_fract_uv << 20) | /* UV Vert Scale Fraction */
- (xscale_int_uv << 16) | /* UV Horiz Scale Int */
- (xscale_fract_uv << 3 ); /* UV Horiz Scale Fraction */
- ovl_regs_plb->vert_downscale =
- (yscale_int << 16) | /* Vert Scale Factor */
- yscale_int_uv; /* UV Vert Scale Factor */
-
- EMGD_TRACE_EXIT;
- return IGD_SUCCESS;
-}
-
-
-
-/*----------------------------------------------------------------------
- * Function: ovl_update_video_quality_plb()
- *
- * Description:
- * This function updates the contrast, brightness, and saturation of
- * the overlay using the values specified in overlay_info.
- *
- * Returns:
- * != 0 on Error
- * 0 on Success
- *----------------------------------------------------------------------*/
-
-static int ovl_update_video_quality_plb(
- ovl_reg_image_plb_t *ovl_regs_plb,
- igd_surface_t *src_surf,
- igd_ovl_video_quality_info_t *video_quality)
-{
- int calc_brightness_tmp = 0;
- int calc_brightness = 0;
- unsigned int calc_contrast_tmp = 0;
- unsigned int calc_contrast = 0;
- unsigned int calc_saturation_tmp = 0;
- unsigned int calc_saturation = 0;
-
- EMGD_TRACE_ENTER;
-
- /* If the src_surf pixel format is RGB, then brightness, contrast,
- * and saturation should all be set to the exact default */
- if (src_surf->pixel_format & PF_TYPE_RGB) {
- if (video_quality->brightness != 0x8000) {
- EMGD_DEBUG("RGB surfaces must set brightness to default");
- }
- if (video_quality->contrast != 0x8000) {
- EMGD_DEBUG("RGB surfaces must set contrast to default");
- }
- if (video_quality->saturation != 0x8000) {
- EMGD_DEBUG("RGB surfaces must set saturation to default");
- }
-
- ovl_regs_plb->col_ctl_brt_con = OVL_RGB_COLOR_DEF_CONT_BRGHT;
- ovl_regs_plb->col_ctl_sat_hue = OVL_RGB_COLOR_DEF_SATN_HUE;
-
- EMGD_TRACE_EXIT;
- return IGD_SUCCESS;
- }
-
- /*************************************************************************
- * Brightness
- *************************************************************************/
- if (0x8000 == video_quality->brightness) {
- calc_brightness = MID_BRIGHTNESS_YUV;
- } else if (video_quality->brightness < 0x8000) {
- /*
- * we have here a brightness that is less than the default
- * mid point
- */
- calc_brightness_tmp = 0x8000 - video_quality->brightness;
- calc_brightness_tmp <<= 14;
- calc_brightness_tmp /= 0x8000;
- calc_brightness = -128 - MID_BRIGHTNESS_YUV;
- /*
- * more range if the midpoint is positive but less range
- * if midpoint is negative
- */
-
- calc_brightness *= calc_brightness_tmp;
- calc_brightness += BIT13;
- calc_brightness >>= 14;
-
- if (calc_brightness < -128) {
- calc_brightness = -128;
- }
- if (calc_brightness > MID_BRIGHTNESS_YUV) {
- calc_brightness = MID_BRIGHTNESS_YUV;
- }
- } else {
- /*
- * we have here a brightness that is more than the default
- * mid point
- */
- calc_brightness_tmp = video_quality->brightness - 0x8000;
- calc_brightness_tmp <<= 14;
- calc_brightness_tmp /= 0x8000;
- calc_brightness = 127 - MID_BRIGHTNESS_YUV;
- /*
- * less range if the midpoint is positive but more range
- * if midpoint is negative
- */
- calc_brightness *= calc_brightness_tmp;
- calc_brightness += BIT13;
- calc_brightness >>= 14;
-
- if (calc_brightness > 127) {
- calc_brightness = 127;
- }
- if (calc_brightness < MID_BRIGHTNESS_YUV) {
- calc_brightness = MID_BRIGHTNESS_YUV;
- }
- }
-
- ovl_regs_plb->col_ctl_brt_con =
- (ovl_regs_plb->col_ctl_brt_con & 0xFFFFFF00) |
- (calc_brightness & 0xFF);
-
- /*************************************************************************
- * Contrast
- *************************************************************************/
- if (0x8000 == video_quality->contrast ){
- calc_contrast = MID_CONTRAST_YUV;
- } else if (video_quality->contrast < 0x8000) {
- /* we have here a contrast that is less than the
- * default mid point */
- calc_contrast_tmp = video_quality->contrast;
- calc_contrast_tmp <<= 12;
- calc_contrast_tmp /= 0x8000;
- calc_contrast = MID_CONTRAST_YUV;
- calc_contrast *= calc_contrast_tmp;
- calc_contrast += BIT11;
- calc_contrast >>= 12;
- if (calc_contrast > 0x3F) {
- calc_contrast = 0x3F;
- }
- } else {
- /* we have here a contrast that is more than the
- * default mid point */
- calc_contrast_tmp = video_quality->contrast - 0x8000;
- calc_contrast_tmp <<= 12;
- calc_contrast_tmp /= 0x8000;
- calc_contrast = (0x1FF - MID_CONTRAST_YUV);
- calc_contrast *= calc_contrast_tmp;
- calc_contrast += BIT11;
- calc_contrast >>= 12;
- calc_contrast += MID_CONTRAST_YUV;
- if (calc_contrast > 0x1FF) {
- calc_contrast = 0x1FF;
- }
- }
-
- ovl_regs_plb->col_ctl_brt_con =
- (ovl_regs_plb->col_ctl_brt_con & 0xF803FFFF) |
- ((calc_contrast & 0x1FF) << 18);
-
- /*************************************************************************
- * Saturation
- *************************************************************************/
- if (video_quality->saturation == 0x8000) {
- calc_saturation = MID_SATURATION_YUV;
- } else if (video_quality->saturation < 0x8000) {
- /* we have here a saturation that is less than the default
- * mid point */
- calc_saturation_tmp = video_quality->saturation;
- calc_saturation_tmp <<= 12;
- calc_saturation_tmp /= 0x8000;
- calc_saturation = MID_SATURATION_YUV;
- calc_saturation *= calc_saturation_tmp;
- calc_saturation += BIT11;
- calc_saturation >>= 12;
- if (calc_saturation > 0x7F) {
- calc_saturation = 0x7F;
- }
- } else {
- /* we have here a saturation that is more than the default
- * mid point*/
- calc_saturation_tmp = video_quality->saturation - 0x8000;
- calc_saturation_tmp <<= 12;
- calc_saturation_tmp /= 0x8000;
- calc_saturation = (0x3FF - MID_SATURATION_YUV);
- calc_saturation *= calc_saturation_tmp;
- calc_saturation += BIT11;
- calc_saturation >>= 12;
- calc_saturation += MID_SATURATION_YUV;
-
- if (calc_saturation > 0x3FF) {
- calc_saturation = 0x3FF;
- }
- }
-
- ovl_regs_plb->col_ctl_sat_hue =
- (ovl_regs_plb->col_ctl_sat_hue & 0xFFFFFC00) |
- (calc_saturation & 0x3FF);
-
- /*************************************************************************
- * Hue
- *************************************************************************/
- /* Hue is always set to the default value. It is based on the saturation
- * value, and having a separate hue is of minimal value. */
- ovl_regs_plb->col_ctl_sat_hue =
- (ovl_regs_plb->col_ctl_sat_hue & 0xF800FFFF);
-
- EMGD_TRACE_EXIT;
- return IGD_SUCCESS;
-}
-
-
-
-static void check_gamma(unsigned int *gamma)
-{
-
- if (*gamma < IGD_OVL_GAMMA_MIN) {
- EMGD_ERROR("Gamma to small (0x%x in 24i.8f format), "
- "changing to Min Gamma (0.6)",
- *gamma);
- *gamma = IGD_OVL_GAMMA_MIN;
- }
- if (*gamma > IGD_OVL_GAMMA_MAX) {
- EMGD_ERROR("Gamma to large (0x%x in 24i.8f format), "
- "changing to Max Gamma (6.0)",
- *gamma);
- *gamma = IGD_OVL_GAMMA_MAX;
- }
-
- return;
-}
-
-
-
-/*-----------------------------------------------------------------------------
- * Function: ovl_update_gamma_plb()
- *
- * Description:
- * This function sets the gamma correction values for the overlays.
- *
- * Returns:
- * != 0 on Error
- * IGD_SUCCESS on Success
- *---------------------------------------------------------------------------*/
-static int ovl_update_gamma_plb(
- igd_display_context_t *display,
- igd_ovl_gamma_info_t * ovl_gamma)
-{
- const int gamma_reg_input[OVL_TOTAL_GAMMA_REG] = {8, 16, 32, 64, 128, 192};
- const int gamma_reg_offset[OVL_TOTAL_GAMMA_REG] = {
- OVL_REG_ADDR_GAMMA0,
- OVL_REG_ADDR_GAMMA1,
- OVL_REG_ADDR_GAMMA2,
- OVL_REG_ADDR_GAMMA3,
- OVL_REG_ADDR_GAMMA4,
- OVL_REG_ADDR_GAMMA5
- };
- const unsigned int gamma_def[OVL_TOTAL_GAMMA_REG] = {
- 0x00080808,
- 0x00101010,
- 0x00202020,
- 0x00404040,
- 0x00808080,
- 0x00c0c0c0
- };
- unsigned int new_gamma_red_24i_8f, new_gamma_green_24i_8f;
- unsigned int new_gamma_blue_24i_8f;
- unsigned int gamma_normal_r_24i_8f;
- unsigned int gamma_normal_g_24i_8f;
- unsigned int gamma_normal_b_24i_8f;
- unsigned int gamma_reg, gamma_reg_24i_8f;
- unsigned int i;
-
- EMGD_TRACE_ENTER;
-
- /* FIXME: The gamma values are re-written for every alter_ovl call.
- * This may cause issues or may be to slow? If so, store the previous
- * values and only re-write when they change. */
-
- /* If the overlay gamma is disabled, set it to the default */
- if ((ovl_gamma->flags & IGD_OVL_GAMMA_ENABLE) == IGD_OVL_GAMMA_DISABLE) {
- for (i = 0; i < OVL_TOTAL_GAMMA_REG; i++) {
- /* program register */
- EMGD_WRITE32(gamma_def[i], MMIO(display) + gamma_reg_offset[i]);
- }
- EMGD_TRACE_EXIT;
- return IGD_SUCCESS;
- }
-
- /* It is assumed that the input value is a 24-bit number */
- new_gamma_red_24i_8f = ovl_gamma->red;
- new_gamma_green_24i_8f = ovl_gamma->green;
- new_gamma_blue_24i_8f = ovl_gamma->blue;
-
- /* Ensure the gamma values are between MIN and MAX */
- check_gamma(&new_gamma_red_24i_8f);
- check_gamma(&new_gamma_green_24i_8f);
- check_gamma(&new_gamma_blue_24i_8f);
-
- /*
- * Program RGB for each of the 6 gamma registers
- */
-
- /* Since the OS_POW_FIX function can only take an integer base,
- * we need to normalize the result by gamma_normal_x
- */
- gamma_normal_r_24i_8f = OS_POW_FIX(255, (1<<16)/new_gamma_red_24i_8f);
- gamma_normal_g_24i_8f = OS_POW_FIX(255, (1<<16)/new_gamma_green_24i_8f);
- gamma_normal_b_24i_8f = OS_POW_FIX(255, (1<<16)/new_gamma_blue_24i_8f);
-
- for( i = 0; i < OVL_TOTAL_GAMMA_REG; i++ )
- {
- /* red */
- gamma_reg_24i_8f = OS_POW_FIX(gamma_reg_input[i],
- (1<<16)/new_gamma_red_24i_8f);
- gamma_reg =
- ((255 * gamma_reg_24i_8f) / gamma_normal_r_24i_8f) << 16;
-
- /* green */
- gamma_reg_24i_8f = OS_POW_FIX(gamma_reg_input[i],
- (1<<16)/new_gamma_green_24i_8f);
- gamma_reg |=
- ((255 * gamma_reg_24i_8f) / gamma_normal_g_24i_8f) << 8;
-
- /* blue */
- gamma_reg_24i_8f = OS_POW_FIX(gamma_reg_input[i],
- (1<<16)/new_gamma_blue_24i_8f);
- gamma_reg |=
- ((255 * gamma_reg_24i_8f) / gamma_normal_b_24i_8f);
-
- /* turn overlay off (TBD) */
-
- /* program register */
- EMGD_WRITE32(gamma_reg, MMIO(display) + gamma_reg_offset[i]);
-
- /* turn overlay on (TBD) */
- }
-
- EMGD_TRACE_EXIT;
- return IGD_SUCCESS;
-}
-
-
-
-/*----------------------------------------------------------------------
- * Function: ovl_update_coeff_plb()
- * Description: Function to calculate the filter coeffcient
- * registers for plb
- * Notes in Usage:
- *
- *----------------------------------------------------------------------*/
-static unsigned int ovl_update_coeff_plb(
- ovl_reg_image_plb_t *ovl_regs_plb,
- igd_surface_t *src_surf,
- igd_rect_t *src_rect,
- igd_rect_t *dest_rect,
- unsigned int flags)
-{
- unsigned int scale_int, scale_fpint;
-
- unsigned int dest_h = dest_rect->y2 - dest_rect->y1;
- unsigned int dest_w = dest_rect->x2 - dest_rect->x1;
- unsigned int src_h = src_rect->y2 - src_rect->y1;
- unsigned int src_w = src_rect->x2 - src_rect->x1;
-
- EMGD_TRACE_ENTER;
-
- /* FIXME: The coeff values are re-written for every alter_ovl call.
- * This may cause issues or may be to slow? If so, store the previous
- * values and only re-write when they change. */
-
- /* In interleaved mode, the src_h is /2 */
- if (flags & IGD_OVL_ALTER_INTERLEAVED) {
- src_h >>= 1;
- }
-
- /* Y Horizontal */
- scale_int = ((ovl_regs_plb->yrgb_scale) >> 16) & 0x7;
-
- if (!scale_int) {
- /* upscale - clamp to 1.0 */
- scale_fpint = 1<<20;
- } else {
- scale_fpint = ((src_w << 20) / dest_w) / scale_int;
- }
- ovl_update_coeff_regs(5, scale_fpint, 1, 1,
- (unsigned short *)ovl_regs_plb->y_horz_coeff_single);
-
- /* Y Vertical */
- scale_int = ((ovl_regs_plb->vert_downscale) >> 16) & 0x7ff;
- if (!scale_int) {
- /* upscale - clamp to 1.0 */
- scale_fpint = 1<<20;
- } else {
- scale_fpint = ((src_h << 20) / dest_h) / scale_int;
- }
- ovl_update_coeff_regs(3, scale_fpint, 0, 1,
- (unsigned short *)ovl_regs_plb->y_vert_coeff_single);
-
- /* UV Horizontal */
- scale_int = ((ovl_regs_plb->uv_scale) >> 16) & 0x7;
- if (!scale_int) {
- /* upscale - clamp to 1.0 */
- scale_fpint = 1<<20;
- } else {
- scale_fpint = ((src_w << 20) / dest_w) / scale_int;
- scale_fpint >>= get_uv_shift_x(src_surf->pixel_format);
- }
- ovl_update_coeff_regs(3, scale_fpint , 1, 0,
- (unsigned short *)ovl_regs_plb->uv_horz_coeff_single);
-
- /* UV Vertical */
- scale_int = (ovl_regs_plb->vert_downscale) & 0x7ff;
- if (!scale_int) {
- /* upscale - clamp to 1.0 */
- scale_fpint = 1<<20;
- } else {
- scale_fpint = ((src_h << 20) / dest_h) / scale_int;
- scale_fpint >>= get_uv_shift_y(src_surf->pixel_format);
- }
- ovl_update_coeff_regs(3, scale_fpint, 0, 0,
- (unsigned short *)ovl_regs_plb->uv_vert_coeff_single);
-
- /* Adjust for 2-line Vertical Buffer */
- if((ovl_regs_plb->config & OVL_CONFIG_LINE_BUFF_MASK)==
- OVL_CONFIG_TWO_LINE_BUFF){
- ovl_update_coeff_regs(2, 0x10, 0, 1,
- (unsigned short *)ovl_regs_plb->y_vert_coeff_single);
- ovl_update_coeff_regs(2, 0x10, 0, 0,
- (unsigned short *)ovl_regs_plb->uv_vert_coeff_single);
- }
-
- EMGD_TRACE_EXIT;
- return IGD_SUCCESS;
-}
-
-static unsigned int convert_color_key_to_hw (
- unsigned long pf,
- unsigned int input)
-{
- unsigned int output;
-
- switch (pf) {
- case IGD_PF_ARGB32:
- case IGD_PF_xRGB32:
- case IGD_PF_ARGB8_INDEXED:
- default:
- output = input;
- break;
- case IGD_PF_RGB16_565:
- output =
- ((((input & 0xf800)>>11)<<3)<<16) |
- ((((input & 0x07e0)>>5 )<<2)<<8 ) |
- ((((input & 0x001f)>>0 )<<3)<<0 );
- break;
- case IGD_PF_ARGB16_1555:
- output =
- ((((input & 0x7c00)>>10)<<3)<<16) |
- ((((input & 0x03e0)>>5 )<<3)<<8 ) |
- ((((input & 0x001f)>>0 )<<3)<<0 );
- break;
- }
-
- return output;
-}
-static unsigned int convert_color_key_to_mask (
- unsigned long pf,
- unsigned int input)
-{
- unsigned int output;
-
- switch (pf) {
- case IGD_PF_ARGB32:
- case IGD_PF_xRGB32:
- default:
- output = 0x00000000;
- break;
- case IGD_PF_RGB16_565:
- output = 0x00070307;
- break;
- case IGD_PF_ARGB16_1555:
- output = 0x00070707;
- break;
- case IGD_PF_ARGB8_INDEXED:
- output = 0x00ffff00;
- break;
- }
-
- return output;
-}
-
-/* Convert RGB to GBR for 32bpp and 16bpp pixel formats.
- * Do not convert YUV surfaces or RGB indexed pixel formats */
-static unsigned int rgb_to_gbr(
- unsigned long pf,
- unsigned int input)
-{
- unsigned int output;
-
- if (((pf & IGD_PF_TYPE_MASK) == PF_TYPE_ARGB) &&
- ((pf & IGD_PF_DEPTH_MASK) != PF_DEPTH_8)) {
- output =
- ((input & 0x00ff0000) >> 16) |
- ((input & 0x0000ff00) << 8) |
- ((input & 0x000000ff) << 8);
- } else {
- output = input;
- }
-
- return output;
-}
-
-
-#ifndef OVL_PLB_CACHE_QUICK_SWAP /* If no OVL_PLB_CACHE_QUICK_SWAP */
-
-static unsigned int ovl_update_regs_plb(
- igd_display_context_t *display,
- igd_surface_t *src_surf,
- igd_rect_t *src_rect,
- igd_rect_t *dest_rect,
- igd_ovl_info_t *ovl_info,
- unsigned int flags)
-{
- ovl_reg_image_plb_t *ovl_regs_plb, *ovl_cache_plb ;
- int ret;
-
- EMGD_TRACE_ENTER;
-
- ovl_regs_plb = phys_to_virt(ovl_context->reg_update_phys);
- ovl_cache_plb = OS_ALLOC(sizeof(ovl_reg_image_plb_t));
- OS_MEMSET(ovl_cache_plb, 0, sizeof(ovl_reg_image_plb_t));
-
- if ((flags & IGD_OVL_ALTER_ON) == IGD_OVL_ALTER_OFF) {
- /* Turn the overlay Off */
- ovl_regs_plb->command = 0;
- /* Always use buf 0 when turning the overlay off. */
- ovl_context->ovl_buff = 0;
- OS_FREE(ovl_cache_plb);
- EMGD_TRACE_EXIT;
- return IGD_SUCCESS;
- }
-
- /* Force value of y1 to even due hardware expects even number */
- dest_rect->y1 &= ~1;
- dest_rect->y2 = (dest_rect->y2 + 1) & ~1;
- dest_rect->x1 &= ~1;
- dest_rect->x2 = (dest_rect->x2 + 1) & ~1;
-
- /*************************************************************************
- * Copy the information passed in to the HW overlay structure
- *************************************************************************/
- /* Zero the config and command, since they will be OR'ed in with data
- * below */
- ovl_cache_plb->config = 0;
- ovl_cache_plb->command = 0;
-
- /* Set overlay to the proper pipe */
- if (1 == PIPE(display)->pipe_num) {
- /* This is pipe B */
- ovl_cache_plb->config |= 1 << 18;
- }
-
- /* Interleaved/progressive and Odd/Even if interleaved */
- if (flags & IGD_OVL_ALTER_INTERLEAVED) {
- ovl_cache_plb->command |= OVL_CMD_FIELD_MODE;
- /* Need to enable FIELD SYNC OVERLAY FLIP in field mode. */
- ovl_cache_plb->command |= OVL_CMD_FIELD_SYNC_FLIP;
- if (flags & IGD_OVL_ALTER_FLIP_ODD) {
- ovl_cache_plb->command |= OVL_CMD_ACT_FLD1;
- } else {
- ovl_cache_plb->command |= OVL_CMD_ACT_FLD0;
- }
- } else {
- ovl_cache_plb->command |= OVL_CMD_FRAME_MODE;
- }
-
- /* Dest rect information */
- ovl_cache_plb->dest_pos_x_left = (unsigned short)dest_rect->x1;
- ovl_cache_plb->dest_pos_y_top = (unsigned short)dest_rect->y1;
- ovl_cache_plb->dest_width_x =
- (unsigned short)(dest_rect->x2 - dest_rect->x1);
- ovl_cache_plb->dest_height_y =
- (unsigned short)(dest_rect->y2 - dest_rect->y1);
-
- /* Src rect and surface information */
-
- ret = ovl_update_src_ptr_plb(display, ovl_cache_plb, src_surf, src_rect);
- if (ret) {
- OS_FREE(ovl_cache_plb);
- EMGD_ERROR_EXIT("Overlay updating src pointers failed");
- return ret;
- }
-
- ret = ovl_update_src_plb(display, ovl_cache_plb, src_surf, src_rect);
- if (ret) {
- OS_FREE(ovl_cache_plb);
- EMGD_ERROR_EXIT("Overlay updating src failed");
- return ret;
- }
-
- /* Scaling information including Vertical downscaling.
- * Scaling should be guaranteed to work, since if the scale is not
- * supported, it should have already been blended to a supported scale. */
- ret = ovl_update_scale_plb(ovl_cache_plb, src_surf, src_rect, dest_rect,
- flags);
- if (ret) {
- OS_FREE(ovl_cache_plb);
- EMGD_ERROR_EXIT("Overlay updating scaling failed");
- return ret;
- }
-
- /* Color control information */
- ret = ovl_update_video_quality_plb(ovl_cache_plb, src_surf,
- &ovl_info->video_quality);
- if (ret) {
- OS_FREE(ovl_cache_plb);
- EMGD_ERROR_EXIT("Overlay video quality failed");
- return ret;
- }
- ret = ovl_update_gamma_plb(display, &ovl_info->gamma);
- if (ret) {
- OS_FREE(ovl_cache_plb);
- EMGD_ERROR_EXIT("Overlay gamma failed");
- return ret;
- }
-
- /* Destination color key */
- EMGD_DEBUG("Color key.flags: 0x%lx", ovl_info->color_key.flags);
- if (ovl_info->color_key.flags & IGD_OVL_DST_COLOR_KEY_ENABLE) {
- EMGD_DEBUG("Overlay Enable Dest Color Key");
- /* The mask and color key are different for the different
- * pixel formats */
- ovl_cache_plb->dest_ckey_val = convert_color_key_to_hw(
- PLANE(display)->fb_info->pixel_format,
- ovl_info->color_key.dest);
- ovl_cache_plb->dest_ckey_mask = convert_color_key_to_mask(
- PLANE(display)->fb_info->pixel_format,
- ovl_info->color_key.dest);
- ovl_cache_plb->dest_ckey_mask |= 0x80000000;
- } else {
- EMGD_DEBUG("Overlay Disable Dest Color Key");
- ovl_cache_plb->dest_ckey_mask = 0x00000000;
- }
-
- /* Source Color key */
- if (ovl_info->color_key.flags & IGD_OVL_SRC_COLOR_KEY_ENABLE) {
- EMGD_DEBUG("Overlay Enable Src Color Key");
- ovl_cache_plb->source_ckey_high = convert_color_key_to_hw(
- src_surf->pixel_format,
- ovl_info->color_key.src_hi);
- ovl_cache_plb->source_ckey_high = rgb_to_gbr(
- src_surf->pixel_format,
- ovl_cache_plb->source_ckey_high);
-
- ovl_cache_plb->source_ckey_low = convert_color_key_to_hw(
- src_surf->pixel_format,
- ovl_info->color_key.src_lo);
- ovl_cache_plb->source_ckey_low = rgb_to_gbr(
- src_surf->pixel_format,
- ovl_cache_plb->source_ckey_low);
-
- ovl_cache_plb->source_ckey_mask = 0x07000000;
- } else {
- EMGD_DEBUG("Overlay Disable Src Color Key");
- ovl_cache_plb->source_ckey_mask = 0x00000000;
- }
-
- /* Coefficients - Must be after Scaling */
- ret = ovl_update_coeff_plb(ovl_cache_plb, src_surf, src_rect, dest_rect, flags);
- if (ret) {
- OS_FREE(ovl_cache_plb);
- EMGD_ERROR_EXIT("Overlay updating coefficient failed");
- return ret;
- }
-
- /* Phase information - Must be after Coefficients */
- ret = ovl_update_phase_plb(ovl_cache_plb, src_surf, src_rect);
- if (ret) {
- OS_FREE(ovl_cache_plb);
- EMGD_ERROR_EXIT("Overlay updating phase failed");
- return ret;
- }
-
- /* General overlay information. Turn the overlay on and alternate
- * between Buffer 0 and Buffer 1. */
- ovl_cache_plb->command = (ovl_cache_plb->command & 0xfffffff3) |
- ovl_context->ovl_buff | 1;
- ovl_context->ovl_buff ^= OVL_CMD_ACT_BUF1;
-
- /* Dump out the Overlay Update Registers if debugging */
- EMGD_VERBOSE(hal.dump_overlay_regs, ovl_dump_regs_plb(ovl_regs_plb));
-
- OS_MEMCPY(ovl_regs_plb, ovl_cache_plb, sizeof(ovl_reg_image_plb_t));
- OS_FREE(ovl_cache_plb);
- EMGD_TRACE_EXIT;
- return IGD_SUCCESS;
-}
-
-#else /* Else OVL_PLB_CACHE_QUICK_SWAP */
-
-/* Poulsbo overlay cache structure */
-static ovl_plb_cache_t ovl_cache;
-
-/* Flag to signal the cache is invalid and needs
- * to be re-initialized */
-static int ovl_cache_needs_init = TRUE;
-
-static unsigned int ovl_update_regs_plb(
- igd_display_context_t *display,
- igd_surface_t *src_surf,
- igd_rect_t *src_rect,
- igd_rect_t *dest_rect,
- igd_ovl_info_t *ovl_info,
- unsigned int flags)
-{
- ovl_reg_image_plb_t *ovl_regs_plb,
- *ovl_cache_regs;
- unsigned int cache_changed;
- int ret;
-
- EMGD_TRACE_ENTER;
-
- /* get the pointers to the real regs, and our cached copy of them */
- ovl_regs_plb = phys_to_virt(ovl_context->reg_update_phys);
- ovl_cache_regs = &ovl_cache.ovl_regs;
-
- /* Fast path for turning off overlay. No need for cache */
- if ((flags & IGD_OVL_ALTER_ON) == IGD_OVL_ALTER_OFF) {
-
- /* Turn the overlay Off */
- ovl_regs_plb->command = 0;
-
- /* if we were using the cache, turn it off there too */
- if (!ovl_cache_needs_init) {
- ovl_cache.ovl_regs.command = 0;
- }
-
- /* Reset the cache */
- ovl_cache_needs_init = TRUE;
-
- /* Always use buf 0 when turning the overlay off. */
- ovl_context->ovl_buff = 0;
- EMGD_TRACE_EXIT;
- return IGD_SUCCESS;
- }
-
- /* Force value to even due hardware expects even number */
- dest_rect->y1 &= ~1;
- dest_rect->y2 = (dest_rect->y2 + 1) & ~1;
- dest_rect->x1 &= ~1;
- dest_rect->x2 = (dest_rect->x2 + 1) & ~1;
-
- /* Init the cache if necessary */
- if (ovl_cache_needs_init) {
-
-
- /* Force every cache check to miss */
- OS_MEMSET(&ovl_cache, 0, sizeof(ovl_plb_cache_t));
-
- /* We just set our cached flags to 0, which might accidently
- * match up with "OFF" for some important incoming flag
- * bits, causing us to think we already handled them when
- * we didn't. So set our cached flags to the exact
- * opposite of the incoming flags, which will force
- * us to test and handle every single bit, regardless
- * of whether it is on or off. */
- ovl_cache.flags = ~flags;
-
- /* init our cached registers */
- OS_MEMCPY(ovl_cache_regs,
- ovl_regs_plb,
- sizeof(ovl_reg_image_plb_t));
-
- /* initialization complete */
- ovl_cache_needs_init = FALSE;
- }
-
- /* See what has changed in the cache */
- cache_changed = get_cache_changes_plb (src_surf,
- src_rect,
- dest_rect,
- ovl_info,
- flags,
- &ovl_cache);
-
- /* Perhaps the biggest challenge of caching the overlay
- * state is what to do with the command and config regs.
- * Normally we would clear command and config to 0 here,
- * and let the update process set only the bits that are
- * needed. But doing this would invalidate our cache.
- * Instead we are relying on the above call to
- * get_cache_changes() to clear those bits in command
- * and config that will be changing */
-
- /* Set overlay to the proper pipe */
- /* it is cheaper to just set this, than to test it and set it. */
- if (1 == PIPE(display)->pipe_num) {
- /* This is pipe B */
- ovl_cache_regs->config |= 1 << 18;
- } else {
- ovl_cache_regs->config &= ~(1 << 18);
- }
-
- if (cache_changed & IGD_OVL_PLB_UPDATE_FLAGS) {
-
- /* Interleaved/progressive and Odd/Even if interleaved. */
- if (flags & IGD_OVL_ALTER_INTERLEAVED) {
- ovl_cache_regs->command |= OVL_CMD_FIELD_MODE;
- /* enable FIELD SYNC OVERLAY FLIP in field mode. */
- ovl_cache_regs->command |= OVL_CMD_FIELD_SYNC_FLIP;
- if (flags & IGD_OVL_ALTER_FLIP_ODD) {
- ovl_cache_regs->command |= OVL_CMD_ACT_FLD1;
- } else {
- ovl_cache_regs->command |= OVL_CMD_ACT_FLD0;
- }
- } else {
- ovl_cache_regs->command |= OVL_CMD_FRAME_MODE;
- }
- }
-
- /* Has our destination rectangle changed? */
- if (cache_changed & IGD_OVL_PLB_UPDATE_DEST) {
- ovl_cache_regs->dest_pos_x_left =
- (unsigned short) dest_rect->x1;
- ovl_cache_regs->dest_pos_y_top =
- (unsigned short) dest_rect->y1;
- ovl_cache_regs->dest_width_x =
- (unsigned short) (dest_rect->x2 - dest_rect->x1);
- ovl_cache_regs->dest_height_y =
- (unsigned short) (dest_rect->y2 - dest_rect->y1);
-
- }
-
- /* Always update the source pointers every frame */
- ret = ovl_update_src_ptr_plb(display,
- ovl_cache_regs,
- src_surf,
- src_rect);
- if (ret) {
- /* Not good. Invalidate the entire cache and bail. */
- ovl_cache_needs_init = TRUE;
- EMGD_ERROR_EXIT("Overlay updating src pointers failed");
- return ret;
- }
-
- /* Did either the Src rect or surface change? */
- if (cache_changed & (IGD_OVL_PLB_UPDATE_SURF |
- IGD_OVL_PLB_UPDATE_SRC ) ) {
-
- ret = ovl_update_src_plb(display,
- ovl_cache_regs,
- src_surf,
- src_rect);
- if (ret) {
- /* Not good. Invalidate the entire cache and bail. */
- ovl_cache_needs_init = TRUE;
- EMGD_ERROR_EXIT("Overlay updating src failed");
- return ret;
- }
- }
-
- /* Scaling information including Vertical downscaling.
- * Scaling should be guaranteed to work, since if the scale
- * is not supported, it should have already been blended
- * to a supported scale. */
- if ( cache_changed & (IGD_OVL_PLB_UPDATE_SRC |
- IGD_OVL_PLB_UPDATE_SURF |
- IGD_OVL_PLB_UPDATE_DEST |
- IGD_OVL_PLB_UPDATE_FLAGS) ) {
-
- ret = ovl_update_scale_plb(ovl_cache_regs,
- src_surf,
- src_rect,
- dest_rect,
- flags);
- if (ret) {
- /* Not good. Invalidate the entire cache and bail. */
- ovl_cache_needs_init = TRUE;
- EMGD_ERROR_EXIT("Overlay updating scaling failed");
- return ret;
- }
- }
-
- /* Did video quality change? */
- if (cache_changed & (IGD_OVL_PLB_UPDATE_VQ |
- IGD_OVL_PLB_UPDATE_SURF ) ) {
- /* Color control information */
-
- ret = ovl_update_video_quality_plb(ovl_cache_regs, src_surf,
- &ovl_info->video_quality);
- if (ret) {
- /* Not good. Invalidate the entire cache and bail. */
- ovl_cache_needs_init = TRUE;
- EMGD_ERROR_EXIT("Overlay video quality failed");
- return ret;
- }
- }
-
- /* Did gamma change? */
- if (cache_changed & IGD_OVL_PLB_UPDATE_GAMMA) {
-
- ret = ovl_update_gamma_plb(display, &ovl_info->gamma);
- if (ret) {
- /* Not good. Invalidate the entire cache and bail. */
- ovl_cache_needs_init = TRUE;
- EMGD_ERROR_EXIT("Overlay gamma failed");
- return ret;
- }
- }
-
- /* Did color key change? */
- if (cache_changed & IGD_OVL_PLB_UPDATE_COLORKEY) {
-
- /* Destination color key */
- EMGD_DEBUG("Color key.flags: 0x%lx", ovl_info->color_key.flags);
- if (ovl_info->color_key.flags & IGD_OVL_DST_COLOR_KEY_ENABLE) {
-
- EMGD_DEBUG("Overlay Enable Dest Color Key");
- /* The mask and color key are different for the
- * different pixel formats */
- ovl_cache_regs->dest_ckey_val =
- convert_color_key_to_hw(
- PLANE(display)->fb_info->pixel_format,
- ovl_info->color_key.dest);
- ovl_cache_regs->dest_ckey_mask =
- convert_color_key_to_mask(
- PLANE(display)->fb_info->pixel_format,
- ovl_info->color_key.dest);
- ovl_cache_regs->dest_ckey_mask |= 0x80000000;
- } else {
- EMGD_DEBUG("Overlay Disable Dest Color Key");
- ovl_cache_regs->dest_ckey_mask = 0x00000000;
- }
-
- /* Source Color key */
- if (ovl_info->color_key.flags & IGD_OVL_SRC_COLOR_KEY_ENABLE) {
-
- EMGD_DEBUG("Overlay Enable Src Color Key");
- ovl_cache_regs->source_ckey_high =
- convert_color_key_to_hw(
- src_surf->pixel_format,
- ovl_info->color_key.src_hi);
- ovl_cache_regs->source_ckey_high =
- rgb_to_gbr(src_surf->pixel_format,
- ovl_cache_regs->source_ckey_high);
-
- ovl_cache_regs->source_ckey_low =
- convert_color_key_to_hw(
- src_surf->pixel_format,
- ovl_info->color_key.src_lo);
- ovl_cache_regs->source_ckey_low =
- rgb_to_gbr(src_surf->pixel_format,
- ovl_cache_regs->source_ckey_low);
-
- ovl_cache_regs->source_ckey_mask = 0x07000000;
- } else {
- EMGD_DEBUG("Overlay Disable Src Color Key");
- ovl_cache_regs->source_ckey_mask = 0x00000000;
- }
- } /* end color key changes */
-
-
- /* Coefficients - Must be after Scaling */
- if (cache_changed & (IGD_OVL_PLB_UPDATE_SRC |
- IGD_OVL_PLB_UPDATE_SURF |
- IGD_OVL_PLB_UPDATE_DEST |
- IGD_OVL_PLB_UPDATE_FLAGS ) ) {
-
- ret = ovl_update_coeff_plb(ovl_cache_regs,
- src_surf,
- src_rect,
- dest_rect,
- flags);
- if (ret) {
- /* Not good. Invalidate entire cache and bail. */
- ovl_cache_needs_init = TRUE;
- EMGD_ERROR_EXIT("Overlay update coefficient failed");
- return ret;
- }
- }
-
- /* Phase information - Must be after Coefficients */
- if (cache_changed & (IGD_OVL_PLB_UPDATE_SRC |
- IGD_OVL_PLB_UPDATE_SURF ) ) {
-
- ret = ovl_update_phase_plb(ovl_cache_regs,
- src_surf,
- src_rect);
- if (ret) {
- /* Not good. Invalidate entire cache and bail. */
- ovl_cache_needs_init = TRUE;
- EMGD_ERROR_EXIT("Overlay updating phase failed");
- return ret;
- }
- }
-
- /* General overlay information. Turn the overlay on and alternate
- * between Buffer 0 and Buffer 1. */
- ovl_cache_regs->command = (ovl_cache_regs->command & 0xfffffff3) |
- ovl_context->ovl_buff | 1;
- ovl_context->ovl_buff ^= OVL_CMD_ACT_BUF1;
-
- /* Dump out the Overlay Update Registers if debugging */
- EMGD_VERBOSE(hal.dump_overlay_regs, ovl_dump_regs_plb(ovl_regs_plb));
-
- /* Finally, transfer the cached regs to the real regs */
- OS_MEMCPY(ovl_regs_plb,
- ovl_cache_regs,
- sizeof(ovl_reg_image_plb_t));
-
- EMGD_TRACE_EXIT;
- return IGD_SUCCESS;
-}
-
-#endif /* End if OVL_PLB_CACHE_QUICK_SWAP */
-
-static unsigned int ovl_send_instr_plb(
- igd_display_context_t *display,
- unsigned int flags)
-{
- unsigned char * mmio = MMIO(display);
- unsigned long tmp;
-
- EMGD_TRACE_ENTER;
-
- if ((flags & IGD_OVL_ALTER_ON) == IGD_OVL_ALTER_ON) {
-
- ovl_context->state = OVL_STATE_ON;
- /*
- * If Overlay + FB Blend is requested and the FB is xRGB
- * turn on the ARGB format.
- */
- if(ovl_context->fb_blend_ovl) {
- tmp = EMGD_READ32(mmio + PLANE(display)->plane_reg);
- if((tmp & 0x3c000000) == 0x18000000) {
- EMGD_WRITE32(tmp | 0x1c000000, mmio + PLANE(display)->plane_reg);
- tmp = EMGD_READ32(mmio + PLANE(display)->plane_reg + 4);
- EMGD_WRITE32(tmp, mmio + PLANE(display)->plane_reg + 4);
- }
- }
-
- } else {
-
- if(ovl_context->fb_blend_ovl) {
- tmp = EMGD_READ32(mmio + PLANE(display)->plane_reg);
- if((tmp & 0x3c000000) == 0x1c000000) {
- tmp = tmp & 0xc3FFFFFF;
- EMGD_WRITE32(tmp | 0x18000000, mmio + PLANE(display)->plane_reg);
- tmp = EMGD_READ32(mmio + PLANE(display)->plane_reg + 4);
- EMGD_WRITE32(tmp, mmio + PLANE(display)->plane_reg + 4);
- OS_SLEEP(100);
- }
- }
-
- OS_SLEEP(1);
-
- /* if overlay is being turned OFF - ensure it's ON first */
- if (ovl_context->state == OVL_STATE_OFF) {
- /* Overlay is already off, no need to turn it off again */
- EMGD_TRACE_EXIT;
- return IGD_SUCCESS;
- }
-
- ovl_context->state = OVL_STATE_OFF;
- }
-
- /* Write the address of the memory buffer to the Overlay Update
- * Address Register causes the HW to load the new values from the
- * memory on the next VBLANK */
- EMGD_WRITE32((ovl_context->reg_update_phys | 0x1), mmio + 0x30000);
-
- ovl_context->sync = 0;
-
- display->context->dispatch.sync(display,
- IGD_PRIORITY_NORMAL,
- &ovl_context->sync,
- IGD_SYNC_NONBLOCK);
-
- EMGD_TRACE_EXIT;
- return IGD_SUCCESS;
-}
-
-
-
-
-static int alter_ovl_plb(igd_display_context_t *display,
- igd_surface_t *src_surf,
- igd_rect_t *src_rect,
- igd_rect_t *dest_rect,
- igd_ovl_info_t *ovl_info,
- unsigned int flags)
-{
- int ret;
-
- EMGD_TRACE_ENTER;
- /* Dump overlay parameters for debugging */
- /*
- printk (KERN_ERR " alter_ovl_plb Entry."
- "offset=0x%X "
- "pitch=%d "
- "width=%d "
- "height=%d \n"
- "pixel_format=0x%X "
- "flags=0x%X "
- "virt_addr=0x%X "
- "pvr2d_mem_info=0x%X "
- "pvr2d_context_h=0x%X "
- "hPVR2DFlipChain=0x%X \n"
- "src_x1=%d "
- "src_x2=%d "
- "src_y1=%d "
- "src_y2=%d "
- "src width=%d "
- "src height=%d \n"
- "dest_x1=%d "
- "dest_x2=%d "
- "dest_y1=%d "
- "dest_y2=%d "
- "dest width=%d "
- "dest height=%d \n"
- "color_key.src_lo=0x%X "
- "color_key.src_hi=0x%X "
- "color_key.dest=0x%X "
- "color_key.flags=0x%X "
- "flags=0x%X "
- ,
- (unsigned int) src_surf->offset ,
- (unsigned int) src_surf->pitch ,
- (unsigned int) src_surf->width ,
- (unsigned int) src_surf->height ,
- (unsigned int) src_surf->pixel_format ,
- (unsigned int) src_surf->flags ,
- (unsigned int) src_surf->virt_addr ,
- (unsigned int) src_surf->pvr2d_mem_info ,
- (unsigned int) src_surf->pvr2d_context_h ,
- (unsigned int) src_surf->hPVR2DFlipChain ,
- (unsigned int) src_rect->x1,
- (unsigned int) src_rect->x2,
- (unsigned int) src_rect->y1,
- (unsigned int) src_rect->y2,
- (unsigned int) (src_rect->x2 - src_rect->x1),
- (unsigned int) (src_rect->y2 - src_rect->y1),
- (unsigned int) dest_rect->x1,
- (unsigned int) dest_rect->x2,
- (unsigned int) dest_rect->y1,
- (unsigned int) dest_rect->y2,
- (unsigned int) (dest_rect->x2 - dest_rect->x1),
- (unsigned int) (dest_rect->y2 - dest_rect->y1),
- (unsigned int) ovl_info->color_key.src_lo,
- (unsigned int) ovl_info->color_key.src_hi,
- (unsigned int) ovl_info->color_key.dest,
- (unsigned int) ovl_info->color_key.flags,
- (unsigned int) flags
- );
- */
- /* Dump overlay surface contents, for debugging */
- /*
- if (flags & IGD_OVL_ALTER_ON)
- {
- int i;
- unsigned char *ptr = src_surf->virt_addr;
-
- for (i = 0; i<10; ++i) {
- printk(KERN_ERR
- "%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X"
- "%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X"
- "%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X"
- "%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X",
- ptr[0],ptr[1],ptr[2],ptr[3],ptr[4],
- ptr[5],ptr[6],ptr[7],ptr[8],ptr[9],
- ptr[10],ptr[11],ptr[12],ptr[13],ptr[14],
- ptr[15],ptr[16],ptr[17],ptr[18],ptr[19],
- ptr[20],ptr[21],ptr[22],ptr[23],ptr[24],
- ptr[25],ptr[26],ptr[27],ptr[28],ptr[29],
- ptr[30],ptr[31],ptr[32],ptr[33],ptr[34],
- ptr[35],ptr[36],ptr[37],ptr[38],ptr[39]);
- ptr += src_surf->pitch;
- }
- }
- */
-
- /* Check to ensure the overlay can be used given the current mode as
- * well as what the IAL is asking for. If not return an error. */
- ret = ovl_check_plb(display, src_surf, src_rect, dest_rect, ovl_info,
- flags);
- if (ret) {
- EMGD_ERROR_EXIT("Overlay Check failed");
- return ret;
- }
-
- /* Check if last flip is still pending.
- * This is necessary for the following reasons:
- * - If the previous instructions have not been processed, then the
- * ovl_regs_plb is still in use and can not be overwritten.
- */
- if ((FALSE == query_ovl_plb(
- (igd_display_h)display,
- IGD_OVL_QUERY_WAIT_LAST_FLIP_DONE)) &&
- (flags & IGD_OVL_ALTER_ON)) {
- /* Only return an error if the overlay is on. If turning it off,
- * allow it to continue, since something may have failed and we
- * should try our best to turn the overlay off. */
- EMGD_ERROR_EXIT("Query Overlay failed");
- return -IGD_ERROR_HWERROR;
- }
-
- /* Update all Overlay Update Registers */
- ret = ovl_update_regs_plb(display, src_surf, src_rect,
- dest_rect, ovl_info,
- flags);
- if (ret) {
- EMGD_ERROR_EXIT("Overlay Update Registers failed");
- return ret;
- }
-
- /* Send the instructions to the command queue */
- ret = ovl_send_instr_plb(display, flags);
-
- EMGD_TRACE_EXIT;
- return ret;
-}
-
-
-
-static int query_ovl_plb(igd_display_h display_h,
- unsigned int flags)
-{
- igd_display_context_t *display = (igd_display_context_t *)display_h;
- os_alarm_t timeout;
-
- EMGD_TRACE_ENTER;
-
- switch (flags) {
-
- case IGD_OVL_QUERY_IS_HW_SUPPORTED:
- /* This is the first overlay, so HW overlay is supported */
- break;
-
- case IGD_OVL_QUERY_IS_LAST_FLIP_DONE:
- /* If there no sync to wait on, then the last flip is done, and the
- * Register Update has occured, simply return TRUE (Flip done).
- */
- /*if (!(ovl_context->sync)) {
- return TRUE;
- }*/
-
- /* Check to see if the last flip instruction has been executed. If not
- * return FALSE (Flip not done). */
- /*if(display->context->dispatch.sync(
- display,
- IGD_PRIORITY_NORMAL,
- &ovl_context->sync,
- IGD_SYNC_NONBLOCK)) {
- EMGD_DEBUG("Overlay Sync Check - Flip not done");
- return FALSE;
- }*/
-
- /* Check to see if the register update is complete. If not return
- * FALSE (Flip not done). */
- if(!(EMGD_READ32(MMIO(display) + 0x30008) & 0x80000000)) {
- EMGD_DEBUG("Overlay Status Check - Register Update not done");
- return FALSE;
- }
-
- /* Now that we know the last flip is done and the register update is
- * complete, set the sync to 0 and return TRUE (Flip done). */
- ovl_context->sync = 0;
- break;
-
- case IGD_OVL_QUERY_WAIT_LAST_FLIP_DONE:
- /* Wait for 200 milliseconds for the last flip to complete. If not
- * done in that time, there is likely a hardware problem so return
- * FALSE. */
- timeout = OS_SET_ALARM(200);
- do {
- if (TRUE ==
- query_ovl_plb(display_h, IGD_OVL_QUERY_IS_LAST_FLIP_DONE)) {
- EMGD_TRACE_EXIT;
- return TRUE;
- }
- } while (!OS_TEST_ALARM(timeout));
- EMGD_ERROR_EXIT("Timeout waiting for last flip done");
- return FALSE;
- break;
- case IGD_OVL_QUERY_IS_GAMMA_SUPPORTED:
- return TRUE;
- break;
- case IGD_OVL_QUERY_IS_VIDEO_PARAM_SUPPORTED:
- return TRUE;
- break;
- }
-
- EMGD_TRACE_EXIT;
- return TRUE;
-}
-
-static int query_max_size_ovl_plb(
- igd_display_h display_h,
- unsigned long pf,
- unsigned int *max_width,
- unsigned int *max_height)
-{
- ovl_chipset_plb_t *ovl_chip;
-
- EMGD_TRACE_ENTER;
-
- ovl_chip = ovl_chipset_plb;
- *max_width = 0;
- *max_height = 0;
- while(ovl_chip->num_linebuf != OVL_CONFIG_NO_LINE_BUFF){
- if(((pf & IGD_PF_MASK) == ovl_chip->pixel_format) &&
- (ovl_chip->max_width > *max_width)) {
- *max_width = ovl_chip->max_width;
- *max_height = ovl_chip->max_height;
- }
- ovl_chip++;
- }
-
- EMGD_TRACE_EXIT;
- return IGD_SUCCESS;
-}