aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/msm/mdp4_overlay.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/msm/mdp4_overlay.c')
-rw-r--r--drivers/staging/msm/mdp4_overlay.c1259
1 files changed, 0 insertions, 1259 deletions
diff --git a/drivers/staging/msm/mdp4_overlay.c b/drivers/staging/msm/mdp4_overlay.c
deleted file mode 100644
index b9acf5299297..000000000000
--- a/drivers/staging/msm/mdp4_overlay.c
+++ /dev/null
@@ -1,1259 +0,0 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/time.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/hrtimer.h>
-#include <linux/clk.h>
-#include <mach/hardware.h>
-#include <linux/io.h>
-#include <linux/debugfs.h>
-#include <linux/fb.h>
-#include <msm_mdp.h>
-#include <linux/file.h>
-#include "android_pmem.h"
-#include <linux/major.h>
-#include <asm/system.h>
-#include <asm/mach-types.h>
-#include <linux/semaphore.h>
-#include <linux/uaccess.h>
-#include <linux/mutex.h>
-
-#include "mdp.h"
-#include "msm_fb.h"
-#include "mdp4.h"
-
-
-struct mdp4_overlay_ctrl {
- struct mdp4_overlay_pipe plist[MDP4_MAX_OVERLAY_PIPE];
- struct mdp4_overlay_pipe *stage[MDP4_MAX_MIXER][MDP4_MAX_STAGE];
-} mdp4_overlay_db;
-
-static struct mdp4_overlay_ctrl *ctrl = &mdp4_overlay_db;
-
-
-void mdp4_overlay_dmap_cfg(struct msm_fb_data_type *mfd, int lcdc)
-{
- uint32 dma2_cfg_reg;
-
- dma2_cfg_reg = DMA_DITHER_EN;
-
- if (mfd->fb_imgType == MDP_BGR_565)
- dma2_cfg_reg |= DMA_PACK_PATTERN_BGR;
- else
- dma2_cfg_reg |= DMA_PACK_PATTERN_RGB;
-
-
- if (mfd->panel_info.bpp == 18) {
- dma2_cfg_reg |= DMA_DSTC0G_6BITS | /* 666 18BPP */
- DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
- } else if (mfd->panel_info.bpp == 16) {
- dma2_cfg_reg |= DMA_DSTC0G_6BITS | /* 565 16BPP */
- DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
- } else {
- dma2_cfg_reg |= DMA_DSTC0G_8BITS | /* 888 16BPP */
- DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS;
- }
-
- if (lcdc)
- dma2_cfg_reg |= DMA_PACK_ALIGN_MSB;
-
- /* dma2 config register */
- MDP_OUTP(MDP_BASE + 0x90000, dma2_cfg_reg);
-
-}
-
-void mdp4_overlay_dmap_xy(struct mdp4_overlay_pipe *pipe)
-{
-
- /* dma_p source */
- MDP_OUTP(MDP_BASE + 0x90004,
- (pipe->src_height << 16 | pipe->src_width));
- MDP_OUTP(MDP_BASE + 0x90008, pipe->srcp0_addr);
- MDP_OUTP(MDP_BASE + 0x9000c, pipe->srcp0_ystride);
-
- /* dma_p dest */
- MDP_OUTP(MDP_BASE + 0x90010, (pipe->dst_y << 16 | pipe->dst_x));
-}
-
-#define MDP4_VG_PHASE_STEP_DEFAULT 0x20000000
-#define MDP4_VG_PHASE_STEP_SHIFT 29
-
-static int mdp4_leading_0(uint32 num)
-{
- uint32 bit = 0x80000000;
- int i;
-
- for (i = 0; i < 32; i++) {
- if (bit & num)
- return i;
- bit >>= 1;
- }
-
- return i;
-}
-
-static uint32 mdp4_scale_phase_step(int f_num, uint32 src, uint32 dst)
-{
- uint32 val;
- int n;
-
- n = mdp4_leading_0(src);
- if (n > f_num)
- n = f_num;
- val = src << n; /* maximum to reduce lose of resolution */
- val /= dst;
- if (n < f_num) {
- n = f_num - n;
- val <<= n;
- }
-
- return val;
-}
-
-static void mdp4_scale_setup(struct mdp4_overlay_pipe *pipe)
-{
-
- pipe->phasex_step = MDP4_VG_PHASE_STEP_DEFAULT;
- pipe->phasey_step = MDP4_VG_PHASE_STEP_DEFAULT;
-
- if (pipe->dst_h && pipe->src_h != pipe->dst_h) {
- if (pipe->dst_h >= pipe->src_h * 8) /* too much */
- return;
- pipe->op_mode |= MDP4_OP_SCALEY_EN;
-
- if (pipe->pipe_type == OVERLAY_TYPE_VG) {
- if (pipe->dst_h <= (pipe->src_h / 4))
- pipe->op_mode |= MDP4_OP_SCALEY_MN_PHASE;
- else
- pipe->op_mode |= MDP4_OP_SCALEY_FIR;
- }
-
- pipe->phasey_step = mdp4_scale_phase_step(29,
- pipe->src_h, pipe->dst_h);
- }
-
- if (pipe->dst_w && pipe->src_w != pipe->dst_w) {
- if (pipe->dst_w >= pipe->src_w * 8) /* too much */
- return;
- pipe->op_mode |= MDP4_OP_SCALEX_EN;
-
- if (pipe->pipe_type == OVERLAY_TYPE_VG) {
- if (pipe->dst_w <= (pipe->src_w / 4))
- pipe->op_mode |= MDP4_OP_SCALEY_MN_PHASE;
- else
- pipe->op_mode |= MDP4_OP_SCALEY_FIR;
- }
-
- pipe->phasex_step = mdp4_scale_phase_step(29,
- pipe->src_w, pipe->dst_w);
- }
-}
-
-void mdp4_overlay_rgb_setup(struct mdp4_overlay_pipe *pipe)
-{
- char *rgb_base;
- uint32 src_size, src_xy, dst_size, dst_xy;
- uint32 format, pattern;
-
- rgb_base = MDP_BASE + MDP4_RGB_BASE;
- rgb_base += (MDP4_RGB_OFF * pipe->pipe_num);
-
- src_size = ((pipe->src_h << 16) | pipe->src_w);
- src_xy = ((pipe->src_y << 16) | pipe->src_x);
- dst_size = ((pipe->dst_h << 16) | pipe->dst_w);
- dst_xy = ((pipe->dst_y << 16) | pipe->dst_x);
-
- format = mdp4_overlay_format(pipe);
- pattern = mdp4_overlay_unpack_pattern(pipe);
-
- pipe->op_mode |= MDP4_OP_IGC_LUT_EN;
-
- mdp4_scale_setup(pipe);
-
- outpdw(rgb_base + 0x0000, src_size); /* MDP_RGB_SRC_SIZE */
- outpdw(rgb_base + 0x0004, src_xy); /* MDP_RGB_SRC_XY */
- outpdw(rgb_base + 0x0008, dst_size); /* MDP_RGB_DST_SIZE */
- outpdw(rgb_base + 0x000c, dst_xy); /* MDP_RGB_DST_XY */
-
- outpdw(rgb_base + 0x0010, pipe->srcp0_addr);
- outpdw(rgb_base + 0x0040, pipe->srcp0_ystride);
-
- outpdw(rgb_base + 0x0050, format);/* MDP_RGB_SRC_FORMAT */
- outpdw(rgb_base + 0x0054, pattern);/* MDP_RGB_SRC_UNPACK_PATTERN */
- outpdw(rgb_base + 0x0058, pipe->op_mode);/* MDP_RGB_OP_MODE */
- outpdw(rgb_base + 0x005c, pipe->phasex_step);
- outpdw(rgb_base + 0x0060, pipe->phasey_step);
-
- /* 16 bytes-burst x 3 req <= 48 bytes */
- outpdw(rgb_base + 0x1004, 0xc2); /* MDP_RGB_FETCH_CFG */
-}
-
-void mdp4_overlay_vg_setup(struct mdp4_overlay_pipe *pipe)
-{
- char *vg_base;
- uint32 frame_size, src_size, src_xy, dst_size, dst_xy;
- uint32 format, pattern;
-
- vg_base = MDP_BASE + MDP4_VIDEO_BASE;
- vg_base += (MDP4_VIDEO_OFF * pipe->pipe_num);
-
- frame_size = ((pipe->src_height << 16) | pipe->src_width);
- src_size = ((pipe->src_h << 16) | pipe->src_w);
- src_xy = ((pipe->src_y << 16) | pipe->src_x);
- dst_size = ((pipe->dst_h << 16) | pipe->dst_w);
- dst_xy = ((pipe->dst_y << 16) | pipe->dst_x);
-
- format = mdp4_overlay_format(pipe);
- pattern = mdp4_overlay_unpack_pattern(pipe);
-
- pipe->op_mode |= (MDP4_OP_CSC_EN | MDP4_OP_SRC_DATA_YCBCR |
- MDP4_OP_IGC_LUT_EN);
-
- mdp4_scale_setup(pipe);
-
- outpdw(vg_base + 0x0000, src_size); /* MDP_RGB_SRC_SIZE */
- outpdw(vg_base + 0x0004, src_xy); /* MDP_RGB_SRC_XY */
- outpdw(vg_base + 0x0008, dst_size); /* MDP_RGB_DST_SIZE */
- outpdw(vg_base + 0x000c, dst_xy); /* MDP_RGB_DST_XY */
- outpdw(vg_base + 0x0048, frame_size); /* TILE frame size */
-
- /* luma component plane */
- outpdw(vg_base + 0x0010, pipe->srcp0_addr);
-
- /* chroma component plane */
- outpdw(vg_base + 0x0014, pipe->srcp1_addr);
-
- outpdw(vg_base + 0x0040,
- pipe->srcp1_ystride << 16 | pipe->srcp0_ystride);
-
- outpdw(vg_base + 0x0050, format); /* MDP_RGB_SRC_FORMAT */
- outpdw(vg_base + 0x0054, pattern); /* MDP_RGB_SRC_UNPACK_PATTERN */
- outpdw(vg_base + 0x0058, pipe->op_mode);/* MDP_RGB_OP_MODE */
- outpdw(vg_base + 0x005c, pipe->phasex_step);
- outpdw(vg_base + 0x0060, pipe->phasey_step);
-
- if (pipe->op_mode & MDP4_OP_DITHER_EN) {
- outpdw(vg_base + 0x0068,
- pipe->r_bit << 4 | pipe->b_bit << 2 | pipe->g_bit);
- }
-
- /* 16 bytes-burst x 3 req <= 48 bytes */
- outpdw(vg_base + 0x1004, 0xc2); /* MDP_VG_FETCH_CFG */
-}
-
-int mdp4_overlay_format2type(uint32 format)
-{
- switch (format) {
- case MDP_RGB_565:
- case MDP_RGB_888:
- case MDP_BGR_565:
- case MDP_ARGB_8888:
- case MDP_RGBA_8888:
- case MDP_BGRA_8888:
- return OVERLAY_TYPE_RGB;
- case MDP_YCRYCB_H2V1:
- case MDP_Y_CRCB_H2V1:
- case MDP_Y_CBCR_H2V1:
- case MDP_Y_CRCB_H2V2:
- case MDP_Y_CBCR_H2V2:
- case MDP_Y_CBCR_H2V2_TILE:
- case MDP_Y_CRCB_H2V2_TILE:
- return OVERLAY_TYPE_VG;
- default:
- return -ERANGE;
- }
-
-}
-
-#define C3_ALPHA 3 /* alpha */
-#define C2_R_Cr 2 /* R/Cr */
-#define C1_B_Cb 1 /* B/Cb */
-#define C0_G_Y 0 /* G/luma */
-
-int mdp4_overlay_format2pipe(struct mdp4_overlay_pipe *pipe)
-{
- switch (pipe->src_format) {
- case MDP_RGB_565:
- pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
- pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
- pipe->a_bit = 0;
- pipe->r_bit = 1; /* R, 5 bits */
- pipe->b_bit = 1; /* B, 5 bits */
- pipe->g_bit = 2; /* G, 6 bits */
- pipe->alpha_enable = 0;
- pipe->unpack_tight = 1;
- pipe->unpack_align_msb = 0;
- pipe->unpack_count = 2;
- pipe->element2 = C2_R_Cr; /* R */
- pipe->element1 = C0_G_Y; /* G */
- pipe->element0 = C1_B_Cb; /* B */
- pipe->bpp = 2; /* 2 bpp */
- break;
- case MDP_RGB_888:
- pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
- pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
- pipe->a_bit = 0;
- pipe->r_bit = 3; /* R, 8 bits */
- pipe->b_bit = 3; /* B, 8 bits */
- pipe->g_bit = 3; /* G, 8 bits */
- pipe->alpha_enable = 0;
- pipe->unpack_tight = 1;
- pipe->unpack_align_msb = 0;
- pipe->unpack_count = 2;
- pipe->element2 = C2_R_Cr; /* R */
- pipe->element1 = C0_G_Y; /* G */
- pipe->element0 = C1_B_Cb; /* B */
- pipe->bpp = 3; /* 3 bpp */
- break;
- case MDP_BGR_565:
- pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
- pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
- pipe->a_bit = 0;
- pipe->r_bit = 1; /* R, 5 bits */
- pipe->b_bit = 1; /* B, 5 bits */
- pipe->g_bit = 2; /* G, 6 bits */
- pipe->alpha_enable = 0;
- pipe->unpack_tight = 1;
- pipe->unpack_align_msb = 0;
- pipe->unpack_count = 2;
- pipe->element2 = C1_B_Cb; /* B */
- pipe->element1 = C0_G_Y; /* G */
- pipe->element0 = C2_R_Cr; /* R */
- pipe->bpp = 2; /* 2 bpp */
- break;
- case MDP_ARGB_8888:
- pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
- pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
- pipe->a_bit = 3; /* alpha, 4 bits */
- pipe->r_bit = 3; /* R, 8 bits */
- pipe->b_bit = 3; /* B, 8 bits */
- pipe->g_bit = 3; /* G, 8 bits */
- pipe->alpha_enable = 1;
- pipe->unpack_tight = 1;
- pipe->unpack_align_msb = 0;
- pipe->unpack_count = 3;
- pipe->element3 = C3_ALPHA; /* alpha */
- pipe->element2 = C2_R_Cr; /* R */
- pipe->element1 = C0_G_Y; /* G */
- pipe->element0 = C1_B_Cb; /* B */
- pipe->bpp = 4; /* 4 bpp */
- break;
- case MDP_RGBA_8888:
- pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
- pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
- pipe->a_bit = 3; /* alpha, 4 bits */
- pipe->r_bit = 3; /* R, 8 bits */
- pipe->b_bit = 3; /* B, 8 bits */
- pipe->g_bit = 3; /* G, 8 bits */
- pipe->alpha_enable = 1;
- pipe->unpack_tight = 1;
- pipe->unpack_align_msb = 0;
- pipe->unpack_count = 3;
- pipe->element3 = C2_R_Cr; /* R */
- pipe->element2 = C0_G_Y; /* G */
- pipe->element1 = C1_B_Cb; /* B */
- pipe->element0 = C3_ALPHA; /* alpha */
- pipe->bpp = 4; /* 4 bpp */
- break;
- case MDP_BGRA_8888:
- pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
- pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
- pipe->a_bit = 3; /* alpha, 4 bits */
- pipe->r_bit = 3; /* R, 8 bits */
- pipe->b_bit = 3; /* B, 8 bits */
- pipe->g_bit = 3; /* G, 8 bits */
- pipe->alpha_enable = 1;
- pipe->unpack_tight = 1;
- pipe->unpack_align_msb = 0;
- pipe->unpack_count = 3;
- pipe->element3 = C1_B_Cb; /* B */
- pipe->element2 = C0_G_Y; /* G */
- pipe->element1 = C2_R_Cr; /* R */
- pipe->element0 = C3_ALPHA; /* alpha */
- pipe->bpp = 4; /* 4 bpp */
- break;
- case MDP_YCRYCB_H2V1:
- pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
- pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
- pipe->a_bit = 0; /* alpha, 4 bits */
- pipe->r_bit = 3; /* R, 8 bits */
- pipe->b_bit = 3; /* B, 8 bits */
- pipe->g_bit = 3; /* G, 8 bits */
- pipe->alpha_enable = 0;
- pipe->unpack_tight = 1;
- pipe->unpack_align_msb = 0;
- pipe->unpack_count = 3;
- pipe->element3 = C0_G_Y; /* G */
- pipe->element2 = C2_R_Cr; /* R */
- pipe->element1 = C0_G_Y; /* G */
- pipe->element0 = C1_B_Cb; /* B */
- pipe->bpp = 2; /* 2 bpp */
- pipe->chroma_sample = MDP4_CHROMA_H2V1;
- break;
- case MDP_Y_CRCB_H2V1:
- case MDP_Y_CBCR_H2V1:
- case MDP_Y_CRCB_H2V2:
- case MDP_Y_CBCR_H2V2:
- pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
- pipe->fetch_plane = OVERLAY_PLANE_PSEUDO_PLANAR;
- pipe->a_bit = 0;
- pipe->r_bit = 3; /* R, 8 bits */
- pipe->b_bit = 3; /* B, 8 bits */
- pipe->g_bit = 3; /* G, 8 bits */
- pipe->alpha_enable = 0;
- pipe->unpack_tight = 1;
- pipe->unpack_align_msb = 0;
- pipe->unpack_count = 1; /* 2 */
- pipe->element3 = C0_G_Y; /* not used */
- pipe->element2 = C0_G_Y; /* not used */
- if (pipe->src_format == MDP_Y_CRCB_H2V1) {
- pipe->element1 = C2_R_Cr; /* R */
- pipe->element0 = C1_B_Cb; /* B */
- pipe->chroma_sample = MDP4_CHROMA_H2V1;
- } else if (pipe->src_format == MDP_Y_CBCR_H2V1) {
- pipe->element1 = C1_B_Cb; /* B */
- pipe->element0 = C2_R_Cr; /* R */
- pipe->chroma_sample = MDP4_CHROMA_H2V1;
- } else if (pipe->src_format == MDP_Y_CRCB_H2V2) {
- pipe->element1 = C2_R_Cr; /* R */
- pipe->element0 = C1_B_Cb; /* B */
- pipe->chroma_sample = MDP4_CHROMA_420;
- } else if (pipe->src_format == MDP_Y_CBCR_H2V2) {
- pipe->element1 = C1_B_Cb; /* B */
- pipe->element0 = C2_R_Cr; /* R */
- pipe->chroma_sample = MDP4_CHROMA_420;
- }
- pipe->bpp = 2; /* 2 bpp */
- break;
- case MDP_Y_CBCR_H2V2_TILE:
- case MDP_Y_CRCB_H2V2_TILE:
- pipe->frame_format = MDP4_FRAME_FORMAT_VIDEO_SUPERTILE;
- pipe->fetch_plane = OVERLAY_PLANE_PSEUDO_PLANAR;
- pipe->a_bit = 0;
- pipe->r_bit = 3; /* R, 8 bits */
- pipe->b_bit = 3; /* B, 8 bits */
- pipe->g_bit = 3; /* G, 8 bits */
- pipe->alpha_enable = 0;
- pipe->unpack_tight = 1;
- pipe->unpack_align_msb = 0;
- pipe->unpack_count = 1; /* 2 */
- pipe->element3 = C0_G_Y; /* not used */
- pipe->element2 = C0_G_Y; /* not used */
- if (pipe->src_format == MDP_Y_CRCB_H2V2_TILE) {
- pipe->element1 = C2_R_Cr; /* R */
- pipe->element0 = C1_B_Cb; /* B */
- pipe->chroma_sample = MDP4_CHROMA_420;
- } else if (pipe->src_format == MDP_Y_CBCR_H2V2_TILE) {
- pipe->element1 = C1_B_Cb; /* B */
- pipe->element0 = C2_R_Cr; /* R */
- pipe->chroma_sample = MDP4_CHROMA_420;
- }
- pipe->bpp = 2; /* 2 bpp */
- break;
- default:
- /* not likely */
- return -ERANGE;
- }
-
- return 0;
-}
-
-/*
- * color_key_convert: output with 12 bits color key
- */
-static uint32 color_key_convert(int start, int num, uint32 color)
-{
-
- uint32 data;
-
- data = (color >> start) & ((1 << num) - 1);
-
- if (num == 5)
- data = (data << 7) + (data << 2) + (data >> 3);
- else if (num == 6)
- data = (data << 6) + data;
- else /* 8 bits */
- data = (data << 4) + (data >> 4);
-
- return data;
-
-}
-
-void transp_color_key(int format, uint32 transp,
- uint32 *c0, uint32 *c1, uint32 *c2)
-{
- int b_start, g_start, r_start;
- int b_num, g_num, r_num;
-
- switch (format) {
- case MDP_RGB_565:
- b_start = 0;
- g_start = 5;
- r_start = 11;
- r_num = 5;
- g_num = 6;
- b_num = 5;
- break;
- case MDP_RGB_888:
- case MDP_XRGB_8888:
- case MDP_ARGB_8888:
- b_start = 0;
- g_start = 8;
- r_start = 16;
- r_num = 8;
- g_num = 8;
- b_num = 8;
- break;
- case MDP_BGR_565:
- b_start = 11;
- g_start = 5;
- r_start = 0;
- r_num = 5;
- g_num = 6;
- b_num = 5;
- break;
- case MDP_Y_CBCR_H2V2:
- case MDP_Y_CBCR_H2V1:
- b_start = 8;
- g_start = 16;
- r_start = 0;
- r_num = 8;
- g_num = 8;
- b_num = 8;
- break;
- case MDP_Y_CRCB_H2V2:
- case MDP_Y_CRCB_H2V1:
- b_start = 0;
- g_start = 16;
- r_start = 8;
- r_num = 8;
- g_num = 8;
- b_num = 8;
- break;
- default:
- b_start = 0;
- g_start = 8;
- r_start = 16;
- r_num = 8;
- g_num = 8;
- b_num = 8;
- break;
- }
-
- *c0 = color_key_convert(g_start, g_num, transp);
- *c1 = color_key_convert(b_start, b_num, transp);
- *c2 = color_key_convert(r_start, r_num, transp);
-}
-
-uint32 mdp4_overlay_format(struct mdp4_overlay_pipe *pipe)
-{
- uint32 format;
-
- format = 0;
-
- if (pipe->solid_fill)
- format |= MDP4_FORMAT_SOLID_FILL;
-
- if (pipe->unpack_align_msb)
- format |= MDP4_FORMAT_UNPACK_ALIGN_MSB;
-
- if (pipe->unpack_tight)
- format |= MDP4_FORMAT_UNPACK_TIGHT;
-
- if (pipe->alpha_enable)
- format |= MDP4_FORMAT_ALPHA_ENABLE;
-
- format |= (pipe->unpack_count << 13);
- format |= ((pipe->bpp - 1) << 9);
- format |= (pipe->a_bit << 6);
- format |= (pipe->r_bit << 4);
- format |= (pipe->b_bit << 2);
- format |= pipe->g_bit;
-
- format |= (pipe->frame_format << 29);
-
- if (pipe->fetch_plane == OVERLAY_PLANE_PSEUDO_PLANAR) {
- /* video/graphic */
- format |= (pipe->fetch_plane << 19);
- format |= (pipe->chroma_site << 28);
- format |= (pipe->chroma_sample << 26);
- }
-
- return format;
-}
-
-uint32 mdp4_overlay_unpack_pattern(struct mdp4_overlay_pipe *pipe)
-{
- return (pipe->element3 << 24) | (pipe->element2 << 16) |
- (pipe->element1 << 8) | pipe->element0;
-}
-
-void mdp4_overlayproc_cfg(struct mdp4_overlay_pipe *pipe)
-{
- uint32 data;
- char *overlay_base;
-
- if (pipe->mixer_num == MDP4_MIXER1)
- overlay_base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
- else
- overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
-
- /* MDP_OVERLAYPROC_CFG */
- outpdw(overlay_base + 0x0004, 0x01); /* directout */
- data = pipe->src_height;
- data <<= 16;
- data |= pipe->src_width;
- outpdw(overlay_base + 0x0008, data); /* ROI, height + width */
- outpdw(overlay_base + 0x000c, pipe->srcp0_addr);
- outpdw(overlay_base + 0x0010, pipe->srcp0_ystride);
- outpdw(overlay_base + 0x0014, 0x4); /* GC_LUT_EN, 888 */
-}
-
-int mdp4_overlay_active(int mixer)
-{
- uint32 data, mask, i;
- int p1, p2;
-
- data = inpdw(MDP_BASE + 0x10100);
- p1 = 0;
- p2 = 0;
- for (i = 0; i < 8; i++) {
- mask = data & 0x0f;
- if (mask) {
- if (mask <= 4)
- p1++;
- else
- p2++;
- }
- data >>= 4;
- }
-
- if (mixer)
- return p2;
- else
- return p1;
-}
-
-void mdp4_mixer_stage_up(struct mdp4_overlay_pipe *pipe)
-{
- uint32 data, mask, snum, stage, mixer;
-
- stage = pipe->mixer_stage;
- mixer = pipe->mixer_num;
-
- /* MDP_LAYERMIXER_IN_CFG, shard by both mixer 0 and 1 */
- data = inpdw(MDP_BASE + 0x10100);
-
- if (mixer == MDP4_MIXER1)
- stage += 8;
-
- if (pipe->pipe_type == OVERLAY_TYPE_VG) {/* VG1 and VG2 */
- snum = 0;
- snum += (4 * pipe->pipe_num);
- } else {
- snum = 8;
- snum += (4 * pipe->pipe_num); /* RGB1 and RGB2 */
- }
-
- mask = 0x0f;
- mask <<= snum;
- stage <<= snum;
- data &= ~mask; /* clear old bits */
-
- data |= stage;
-
- outpdw(MDP_BASE + 0x10100, data); /* MDP_LAYERMIXER_IN_CFG */
-
- data = inpdw(MDP_BASE + 0x10100);
-
- ctrl->stage[pipe->mixer_num][pipe->mixer_stage] = pipe; /* keep it */
-}
-
-void mdp4_mixer_stage_down(struct mdp4_overlay_pipe *pipe)
-{
- uint32 data, mask, snum, stage, mixer;
-
- stage = pipe->mixer_stage;
- mixer = pipe->mixer_num;
-
- if (pipe != ctrl->stage[mixer][stage]) /* not running */
- return;
-
- /* MDP_LAYERMIXER_IN_CFG, shard by both mixer 0 and 1 */
- data = inpdw(MDP_BASE + 0x10100);
-
- if (mixer == MDP4_MIXER1)
- stage += 8;
-
- if (pipe->pipe_type == OVERLAY_TYPE_VG) {/* VG1 and VG2 */
- snum = 0;
- snum += (4 * pipe->pipe_num);
- } else {
- snum = 8;
- snum += (4 * pipe->pipe_num); /* RGB1 and RGB2 */
- }
-
- mask = 0x0f;
- mask <<= snum;
- data &= ~mask; /* clear old bits */
-
- outpdw(MDP_BASE + 0x10100, data); /* MDP_LAYERMIXER_IN_CFG */
-
- data = inpdw(MDP_BASE + 0x10100);
-
- ctrl->stage[pipe->mixer_num][pipe->mixer_stage] = NULL; /* clear it */
-}
-
-void mdp4_mixer_blend_setup(struct mdp4_overlay_pipe *pipe)
-{
- unsigned char *overlay_base;
- uint32 c0, c1, c2, blend_op;
- int off;
-
- if (pipe->mixer_num) /* mixer number, /dev/fb0, /dev/fb1 */
- overlay_base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
- else
- overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
-
- /* stage 0 to stage 2 */
- off = 0x20 * (pipe->mixer_stage - MDP4_MIXER_STAGE0);
-
- blend_op = 0;
- if (pipe->alpha_enable) /* ARGB */
- blend_op = MDP4_BLEND_FG_ALPHA_FG_PIXEL |
- MDP4_BLEND_BG_ALPHA_FG_PIXEL;
- else
- blend_op = (MDP4_BLEND_BG_ALPHA_BG_CONST |
- MDP4_BLEND_FG_ALPHA_FG_CONST);
-
-
- if (pipe->alpha_enable == 0) { /* not ARGB */
- if (pipe->is_fg) {
- outpdw(overlay_base + off + 0x108, pipe->alpha);
- outpdw(overlay_base + off + 0x10c, 0xff - pipe->alpha);
- } else {
- outpdw(overlay_base + off + 0x108, 0xff - pipe->alpha);
- outpdw(overlay_base + off + 0x10c, pipe->alpha);
- }
- }
-
- if (pipe->transp != MDP_TRANSP_NOP) {
- transp_color_key(pipe->src_format, pipe->transp, &c0, &c1, &c2);
- if (pipe->is_fg) {
- blend_op |= MDP4_BLEND_FG_TRANSP_EN; /* Fg blocked */
- /* lower limit */
- if (c0 > 0x10)
- c0 -= 0x10;
- if (c1 > 0x10)
- c1 -= 0x10;
- if (c2 > 0x10)
- c2 -= 0x10;
- outpdw(overlay_base + off + 0x110,
- (c1 << 16 | c0));/* low */
- outpdw(overlay_base + off + 0x114, c2);/* low */
- /* upper limit */
- if ((c0 + 0x20) < 0x0fff)
- c0 += 0x20;
- else
- c0 = 0x0fff;
- if ((c1 + 0x20) < 0x0fff)
- c1 += 0x20;
- else
- c1 = 0x0fff;
- if ((c2 + 0x20) < 0x0fff)
- c2 += 0x20;
- else
- c2 = 0x0fff;
- outpdw(overlay_base + off + 0x118,
- (c1 << 16 | c0));/* high */
- outpdw(overlay_base + off + 0x11c, c2);/* high */
- } else {
- blend_op |= MDP4_BLEND_BG_TRANSP_EN; /* bg blocked */
- /* lower limit */
- if (c0 > 0x10)
- c0 -= 0x10;
- if (c1 > 0x10)
- c1 -= 0x10;
- if (c2 > 0x10)
- c2 -= 0x10;
- outpdw(overlay_base + 0x180,
- (c1 << 16 | c0));/* low */
- outpdw(overlay_base + 0x184, c2);/* low */
- /* upper limit */
- if ((c0 + 0x20) < 0x0fff)
- c0 += 0x20;
- else
- c0 = 0x0fff;
- if ((c1 + 0x20) < 0x0fff)
- c1 += 0x20;
- else
- c1 = 0x0fff;
- if ((c2 + 0x20) < 0x0fff)
- c2 += 0x20;
- else
- c2 = 0x0fff;
- outpdw(overlay_base + 0x188,
- (c1 << 16 | c0));/* high */
- outpdw(overlay_base + 0x18c, c2);/* high */
- }
- }
- outpdw(overlay_base + off + 0x104, blend_op);
-}
-
-void mdp4_overlay_reg_flush(struct mdp4_overlay_pipe *pipe, int all)
-{
- uint32 bits = 0;
-
- if (pipe->mixer_num == MDP4_MIXER1)
- bits |= 0x02;
- else
- bits |= 0x01;
-
- if (all) {
- if (pipe->pipe_type == OVERLAY_TYPE_RGB) {
- if (pipe->pipe_num == OVERLAY_PIPE_RGB2)
- bits |= 0x20;
- else
- bits |= 0x10;
- } else {
- if (pipe->pipe_num == OVERLAY_PIPE_VG2)
- bits |= 0x08;
- else
- bits |= 0x04;
- }
- }
-
- outpdw(MDP_BASE + 0x18000, bits); /* MDP_OVERLAY_REG_FLUSH */
-
- while (inpdw(MDP_BASE + 0x18000) & bits) /* self clear when complete */
- ;
-}
-
-struct mdp4_overlay_pipe *mdp4_overlay_ndx2pipe(int ndx)
-{
- struct mdp4_overlay_pipe *pipe;
-
- if (ndx == 0 || ndx >= MDP4_MAX_OVERLAY_PIPE)
- return NULL;
-
- pipe = &ctrl->plist[ndx - 1]; /* ndx start from 1 */
-
- if (pipe->pipe_ndx == 0)
- return NULL;
-
- return pipe;
-}
-
-struct mdp4_overlay_pipe *mdp4_overlay_pipe_alloc(void)
-{
- int i;
- struct mdp4_overlay_pipe *pipe;
-
- pipe = &ctrl->plist[0];
- for (i = 0; i < MDP4_MAX_OVERLAY_PIPE; i++) {
- if (pipe->pipe_ndx == 0) {
- pipe->pipe_ndx = i + 1; /* start from 1 */
- init_completion(&pipe->comp);
- printk(KERN_INFO "mdp4_overlay_pipe_alloc: pipe=%p ndx=%d\n",
- pipe, pipe->pipe_ndx);
- return pipe;
- }
- pipe++;
- }
-
- return NULL;
-}
-
-
-void mdp4_overlay_pipe_free(struct mdp4_overlay_pipe *pipe)
-{
- printk(KERN_INFO "mdp4_overlay_pipe_free: pipe=%p ndx=%d\n",
- pipe, pipe->pipe_ndx);
- memset(pipe, 0, sizeof(*pipe));
-}
-
-static int get_pipe_num(int ptype, int stage)
-{
- if (ptype == OVERLAY_TYPE_RGB) {
- if (stage == MDP4_MIXER_STAGE_BASE)
- return OVERLAY_PIPE_RGB1;
- else
- return OVERLAY_PIPE_RGB2;
- } else {
- if (stage == MDP4_MIXER_STAGE0)
- return OVERLAY_PIPE_VG1;
- else
- return OVERLAY_PIPE_VG2;
- }
-}
-
-int mdp4_overlay_req_check(uint32 id, uint32 z_order, uint32 mixer)
-{
- struct mdp4_overlay_pipe *pipe;
-
- pipe = ctrl->stage[mixer][z_order];
-
- if (pipe == NULL)
- return 0;
-
- if (pipe->pipe_ndx == id) /* same req, recycle */
- return 0;
-
- return -EPERM;
-}
-
-static int mdp4_overlay_req2pipe(struct mdp_overlay *req, int mixer,
- struct mdp4_overlay_pipe **ppipe)
-{
- struct mdp4_overlay_pipe *pipe;
- int ret, ptype;
-
- if (mixer >= MDP4_MAX_MIXER) {
- printk(KERN_ERR "mpd_overlay_req2pipe: mixer out of range!\n");
- return -ERANGE;
- }
-
- if (req->z_order < 0 || req->z_order > 2) {
- printk(KERN_ERR "mpd_overlay_req2pipe: z_order=%d out of range!\n",
- req->z_order);
- return -ERANGE;
- }
-
- if (req->src_rect.h == 0 || req->src_rect.w == 0) {
- printk(KERN_ERR "mpd_overlay_req2pipe: src img of zero size!\n");
- return -EINVAL;
- }
-
- ret = mdp4_overlay_req_check(req->id, req->z_order, mixer);
- if (ret < 0)
- return ret;
-
- ptype = mdp4_overlay_format2type(req->src.format);
- if (ptype < 0)
- return ptype;
-
- if (req->id == MSMFB_NEW_REQUEST) /* new request */
- pipe = mdp4_overlay_pipe_alloc();
- else
- pipe = mdp4_overlay_ndx2pipe(req->id);
-
- if (pipe == NULL)
- return -ENOMEM;
-
- pipe->src_format = req->src.format;
- ret = mdp4_overlay_format2pipe(pipe);
-
- if (ret < 0)
- return ret;
-
- /*
- * base layer == 1, reserved for frame buffer
- * zorder 0 == stage 0 == 2
- * zorder 1 == stage 1 == 3
- * zorder 2 == stage 2 == 4
- */
- if (req->id == MSMFB_NEW_REQUEST) { /* new request */
- pipe->mixer_stage = req->z_order + MDP4_MIXER_STAGE0;
- pipe->pipe_type = ptype;
- pipe->pipe_num = get_pipe_num(ptype, pipe->mixer_stage);
- printk(KERN_INFO "mpd4_overlay_req2pipe: zorder=%d pipe_num=%d\n",
- req->z_order, pipe->pipe_num);
- }
-
- pipe->src_width = req->src.width & 0x07ff; /* source img width */
- pipe->src_height = req->src.height & 0x07ff; /* source img height */
- pipe->src_h = req->src_rect.h & 0x07ff;
- pipe->src_w = req->src_rect.w & 0x07ff;
- pipe->src_y = req->src_rect.y & 0x07ff;
- pipe->src_x = req->src_rect.x & 0x07ff;
- pipe->dst_h = req->dst_rect.h & 0x07ff;
- pipe->dst_w = req->dst_rect.w & 0x07ff;
- pipe->dst_y = req->dst_rect.y & 0x07ff;
- pipe->dst_x = req->dst_rect.x & 0x07ff;
-
- if (req->flags & MDP_FLIP_LR)
- pipe->op_mode |= MDP4_OP_FLIP_LR;
-
- if (req->flags & MDP_FLIP_UD)
- pipe->op_mode |= MDP4_OP_FLIP_UD;
-
- if (req->flags & MDP_DITHER)
- pipe->op_mode |= MDP4_OP_DITHER_EN;
-
- if (req->flags & MDP_DEINTERLACE)
- pipe->op_mode |= MDP4_OP_DEINT_ODD_REF;
-
- pipe->is_fg = req->is_fg;/* control alpha and color key */
-
- pipe->alpha = req->alpha & 0x0ff;
-
- pipe->transp = req->transp_mask;
-
- *ppipe = pipe;
-
- return 0;
-}
-
-int get_img(struct msmfb_data *img, struct fb_info *info,
- unsigned long *start, unsigned long *len, struct file **pp_file)
-{
- int put_needed, ret = 0;
- struct file *file;
-#ifdef CONFIG_ANDROID_PMEM
- unsigned long vstart;
-#endif
-
-#ifdef CONFIG_ANDROID_PMEM
- if (!get_pmem_file(img->memory_id, start, &vstart, len, pp_file))
- return 0;
-#endif
- file = fget_light(img->memory_id, &put_needed);
- if (file == NULL)
- return -1;
-
- if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
- *start = info->fix.smem_start;
- *len = info->fix.smem_len;
- *pp_file = file;
- } else {
- ret = -1;
- fput_light(file, put_needed);
- }
- return ret;
-}
-int mdp4_overlay_get(struct fb_info *info, struct mdp_overlay *req)
-{
- struct mdp4_overlay_pipe *pipe;
-
- pipe = mdp4_overlay_ndx2pipe(req->id);
- if (pipe == NULL)
- return -ENODEV;
-
- *req = pipe->req_data;
-
- return 0;
-}
-
-int mdp4_overlay_set(struct fb_info *info, struct mdp_overlay *req)
-{
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
- int ret, mixer;
- struct mdp4_overlay_pipe *pipe;
- int lcdc;
-
- if (mfd == NULL)
- return -ENODEV;
-
- if (req->src.format == MDP_FB_FORMAT)
- req->src.format = mfd->fb_imgType;
-
- if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
- return -EINTR;
-
- mixer = info->node; /* minor number of char device */
-
- ret = mdp4_overlay_req2pipe(req, mixer, &pipe);
- if (ret < 0) {
- mutex_unlock(&mfd->dma->ov_mutex);
- return ret;
- }
-
- lcdc = inpdw(MDP_BASE + 0xc0000);
-
- if (lcdc == 0) { /* mddi */
- /* MDP cmd block enable */
- mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
- }
-
- /* return id back to user */
- req->id = pipe->pipe_ndx; /* pipe_ndx start from 1 */
- pipe->req_data = *req; /* keep original req */
-
- mutex_unlock(&mfd->dma->ov_mutex);
-
- return 0;
-}
-
-int mdp4_overlay_unset(struct fb_info *info, int ndx)
-{
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
- struct mdp4_overlay_pipe *pipe;
- int lcdc;
-
- if (mfd == NULL)
- return -ENODEV;
-
- if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
- return -EINTR;
-
- pipe = mdp4_overlay_ndx2pipe(ndx);
-
- if (pipe == NULL) {
- mutex_unlock(&mfd->dma->ov_mutex);
- return -ENODEV;
- }
-
- lcdc = inpdw(MDP_BASE + 0xc0000);
-
- mdp4_mixer_stage_down(pipe);
-
- if (lcdc == 0) { /* mddi */
- /* MDP cmd block disable */
- mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
- }
-
- if (lcdc) /* LCDC mode */
- mdp4_overlay_reg_flush(pipe, 0);
-
- mdp4_overlay_pipe_free(pipe);
-
- if (lcdc == 0) { /* mddi */
- mdp4_mddi_overlay_restore();
- }
-
- mutex_unlock(&mfd->dma->ov_mutex);
-
- return 0;
-}
-
-struct tile_desc {
- uint32 width; /* tile's width */
- uint32 height; /* tile's height */
- uint32 row_tile_w; /* tiles per row's width */
- uint32 row_tile_h; /* tiles per row's height */
-};
-
-void tile_samsung(struct tile_desc *tp)
-{
- /*
- * each row of samsung tile consists of two tiles in height
- * and two tiles in width which means width should align to
- * 64 x 2 bytes and height should align to 32 x 2 bytes.
- * video decoder generate two tiles in width and one tile
- * in height which ends up height align to 32 X 1 bytes.
- */
- tp->width = 64; /* 64 bytes */
- tp->row_tile_w = 2; /* 2 tiles per row's width */
- tp->height = 32; /* 32 bytes */
- tp->row_tile_h = 1; /* 1 tiles per row's height */
-}
-
-uint32 tile_mem_size(struct mdp4_overlay_pipe *pipe, struct tile_desc *tp)
-{
- uint32 tile_w, tile_h;
- uint32 row_num_w, row_num_h;
-
-
- tile_w = tp->width * tp->row_tile_w;
- tile_h = tp->height * tp->row_tile_h;
-
- row_num_w = (pipe->src_width + tile_w - 1) / tile_w;
- row_num_h = (pipe->src_height + tile_h - 1) / tile_h;
-
- return row_num_w * row_num_h * tile_w * tile_h;
-}
-
-int mdp4_overlay_play(struct fb_info *info, struct msmfb_overlay_data *req,
- struct file **pp_src_file)
-{
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
- struct msmfb_data *img;
- struct mdp4_overlay_pipe *pipe;
- ulong start, addr;
- ulong len = 0;
- struct file *p_src_file = 0;
- int lcdc;
-
- if (mfd == NULL)
- return -ENODEV;
-
- pipe = mdp4_overlay_ndx2pipe(req->id);
- if (pipe == NULL)
- return -ENODEV;
-
- if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
- return -EINTR;
-
- img = &req->data;
- get_img(img, info, &start, &len, &p_src_file);
- if (len == 0) {
- mutex_unlock(&mfd->dma->ov_mutex);
- printk(KERN_ERR "mdp_overlay_play: could not retrieve"
- " image from memory\n");
- return -1;
- }
- *pp_src_file = p_src_file;
-
- addr = start + img->offset;
- pipe->srcp0_addr = addr;
- pipe->srcp0_ystride = pipe->src_width * pipe->bpp;
-
- if (pipe->fetch_plane == OVERLAY_PLANE_PSEUDO_PLANAR) {
- if (pipe->frame_format == MDP4_FRAME_FORMAT_VIDEO_SUPERTILE) {
- struct tile_desc tile;
-
- tile_samsung(&tile);
- pipe->srcp1_addr = addr + tile_mem_size(pipe, &tile);
- } else
- pipe->srcp1_addr = addr +
- pipe->src_width * pipe->src_height;
-
- pipe->srcp0_ystride = pipe->src_width;
- pipe->srcp1_ystride = pipe->src_width;
- }
-
- lcdc = inpdw(MDP_BASE + 0xc0000);
- lcdc &= 0x01; /* LCDC mode */
-
- if (pipe->pipe_type == OVERLAY_TYPE_VG)
- mdp4_overlay_vg_setup(pipe); /* video/graphic pipe */
- else
- mdp4_overlay_rgb_setup(pipe); /* rgb pipe */
-
- mdp4_mixer_blend_setup(pipe);
- mdp4_mixer_stage_up(pipe);
-
- if (lcdc) { /* LCDC mode */
- mdp4_overlay_reg_flush(pipe, 1);
- }
-
- if (lcdc) { /* LCDC mode */
- if (pipe->mixer_stage != MDP4_MIXER_STAGE_BASE) { /* done */
- mutex_unlock(&mfd->dma->ov_mutex);
- return 0;
- }
- }
-
- if (lcdc == 0) { /* MDDI mode */
-#ifdef MDP4_NONBLOCKING
- if (mfd->panel_power_on)
-#else
- if (!mfd->dma->busy && mfd->panel_power_on)
-#endif
- mdp4_mddi_overlay_kickoff(mfd, pipe);
- }
-
- mutex_unlock(&mfd->dma->ov_mutex);
-
- return 0;
-}