Staging: msm: delete the driver

It doesn't build anymore, no one is working on it, and, according to the
developers, there's a different one that is working and in the real part
of the kernel already.

Acked-by: David Brown <davidb@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Greg Kroah-Hartman 2011-07-06 16:34:27 -07:00
parent 0435f9337f
commit 8eb26942ae
66 changed files with 0 additions and 29601 deletions

View file

@ -118,8 +118,6 @@ source "drivers/staging/cxt1e1/Kconfig"
source "drivers/staging/xgifb/Kconfig"
source "drivers/staging/msm/Kconfig"
source "drivers/staging/lirc/Kconfig"
source "drivers/staging/easycap/Kconfig"

View file

@ -51,7 +51,6 @@ obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/
obj-$(CONFIG_CRYSTALHD) += crystalhd/
obj-$(CONFIG_CXT1E1) += cxt1e1/
obj-$(CONFIG_FB_XGI) += xgifb/
obj-$(CONFIG_MSM_STAGING) += msm/
obj-$(CONFIG_EASYCAP) += easycap/
obj-$(CONFIG_SOLO6X10) += solo6x10/
obj-$(CONFIG_TIDSPBRIDGE) += tidspbridge/

View file

@ -1,124 +0,0 @@
config MSM_STAGING
tristate "MSM Frame Buffer Support"
depends on FB && ARCH_MSM && !FB_MSM
select FB_BACKLIGHT if FB_MSM_BACKLIGHT
select NEW_LEDS
select LEDS_CLASS
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
---help---
Support for MSM Framebuffer.
if MSM_STAGING
config FB_MSM_LCDC_HW
bool
default n
choice
prompt "MDP HW version"
default FB_MSM_MDP31
config FB_MSM_MDP31
select FB_MSM_LCDC_HW
bool "MDP HW ver3.1"
---help---
Support for MSM MDP HW revision 3.1
Say Y here if this is msm8x50 variant platform.
endchoice
config FB_MSM_LCDC
bool
default n
config FB_MSM_TVOUT
bool
default n
config FB_MSM_LCDC_PANEL
bool
select FB_MSM_LCDC
default n
config FB_MSM_LCDC_PRISM_WVGA
bool
select FB_MSM_LCDC_PANEL
default n
config FB_MSM_LCDC_ST15_WXGA
bool
select FB_MSM_LCDC_PANEL
default n
choice
prompt "LCD Panel"
default FB_MSM_LCDC_ST15_PANEL
config FB_MSM_LCDC_PRISM_WVGA_PANEL
depends on FB_MSM_LCDC_HW
bool "LCDC Prism WVGA Panel"
select FB_MSM_LCDC_PRISM_WVGA
---help---
Support for LCDC Prism WVGA (800x480) panel
config FB_MSM_LCDC_ST15_PANEL
depends on FB_MSM_LCDC_HW
bool "LCDC ST1.5 Panel"
select FB_MSM_LCDC_ST15_WXGA
---help---
Support for ST1.5 WXGA (1366x768) panel
config FB_MSM_PANEL_NONE
bool "NONE"
---help---
This will disable LCD panel
endchoice
choice
prompt "Secondary LCD Panel"
depends on FB_MSM_MDP31
default FB_MSM_SECONDARY_PANEL_NONE
config FB_MSM_SECONDARY_PANEL_NONE
bool "NONE"
---help---
No secondary panel
endchoice
config FB_MSM_TVOUT_NTSC
bool
select FB_MSM_TVOUT
default n
config FB_MSM_TVOUT_PAL
bool
select FB_MSM_TVOUT
default n
choice
depends on (FB_MSM_MDP22 || FB_MSM_MDP31)
prompt "TVOut Region"
default FB_MSM_TVOUT_NTSC_M
config FB_MSM_TVOUT_NTSC_M
bool "NTSC M"
select FB_MSM_TVOUT_NTSC
---help---
Support for NTSC M region (North American and Korea)
config FB_MSM_TVOUT_NONE
bool "NONE"
---help---
This will disable TV Out functionality.
endchoice
config PMEM_KERNEL_SIZE
int "PMEM for kernel components (in MB)"
default 2
depends on ARCH_QSD8X50
help
Configures the amount of PMEM for use by kernel components
(in MB; minimum 2MB)
endif

View file

@ -1,88 +0,0 @@
obj-y := msm_fb.o staging-devices.o memory.o
obj-$(CONFIG_FB_MSM_LOGO) += logo.o
obj-$(CONFIG_FB_BACKLIGHT) += msm_fb_bl.o
# MDP
obj-y += mdp.o
ifeq ($(CONFIG_FB_MSM_MDP40),y)
obj-y += mdp4_util.o
obj-$(CONFIG_DEBUG_FS) += mdp4_debugfs.o
else
obj-y += mdp_hw_init.o
obj-y += mdp_ppp.o
ifeq ($(CONFIG_FB_MSM_MDP31),y)
obj-y += mdp_ppp_v31.o
obj-$(CONFIG_MDP_PPP_ASYNC_OP) += mdp_ppp_dq.o
else
obj-y += mdp_ppp_v20.o
endif
endif
ifeq ($(CONFIG_FB_MSM_OVERLAY),y)
obj-y += mdp4_overlay.o
obj-y += mdp4_overlay_lcdc.o
obj-y += mdp4_overlay_mddi.o
else
obj-y += mdp_dma_lcdc.o
endif
obj-y += mdp_dma.o
obj-y += mdp_dma_s.o
obj-y += mdp_vsync.o
obj-y += mdp_cursor.o
obj-y += mdp_dma_tv.o
# EBI2
obj-$(CONFIG_FB_MSM_EBI2) += ebi2_lcd.o
# LCDC
obj-$(CONFIG_FB_MSM_LCDC) += lcdc.o
# MDDI
msm_mddi-y := mddi.o mddihost.o mddihosti.o
obj-$(CONFIG_FB_MSM_MDDI) += msm_mddi.o
# External MDDI
msm_mddi_ext-y := mddihost_e.o mddi_ext.o
obj-$(CONFIG_FB_MSM_EXTMDDI) += msm_mddi_ext.o
# TVEnc
obj-$(CONFIG_FB_MSM_TVOUT) += tvenc.o
# MSM FB Panel
obj-y += msm_fb_panel.o
obj-$(CONFIG_FB_MSM_EBI2_TMD_QVGA_EPSON_QCIF) += ebi2_tmd20.o
obj-$(CONFIG_FB_MSM_EBI2_TMD_QVGA_EPSON_QCIF) += ebi2_l2f.o
ifeq ($(CONFIG_FB_MSM_MDDI_AUTO_DETECT),y)
obj-y += mddi_prism.o
obj-y += mddi_toshiba.o
obj-y += mddi_toshiba_vga.o
obj-y += mddi_toshiba_wvga_pt.o
obj-y += mddi_sharp.o
else
obj-$(CONFIG_FB_MSM_MDDI_PRISM_WVGA) += mddi_prism.o
obj-$(CONFIG_FB_MSM_MDDI_TOSHIBA_COMMON) += mddi_toshiba.o
obj-$(CONFIG_FB_MSM_MDDI_TOSHIBA_COMMON_VGA) += mddi_toshiba_vga.o
obj-$(CONFIG_FB_MSM_MDDI_TOSHIBA_WVGA_PORTRAIT) += mddi_toshiba_wvga_pt.o
obj-$(CONFIG_FB_MSM_MDDI_SHARP_QVGA_128x128) += mddi_sharp.o
endif
obj-$(CONFIG_FB_MSM_LCDC_PANEL) += lcdc_panel.o
obj-$(CONFIG_FB_MSM_LCDC_PRISM_WVGA) += lcdc_prism.o
obj-$(CONFIG_FB_MSM_LCDC_EXTERNAL_WXGA) += lcdc_external.o
obj-$(CONFIG_FB_MSM_LCDC_GORDON_VGA) += lcdc_gordon.o
obj-$(CONFIG_FB_MSM_LCDC_TOSHIBA_WVGA_PT) += lcdc_toshiba_wvga_pt.o
obj-$(CONFIG_FB_MSM_LCDC_SHARP_WVGA_PT) += lcdc_sharp_wvga_pt.o
obj-$(CONFIG_FB_MSM_LCDC_ST15_WXGA) += lcdc_st15.o
obj-$(CONFIG_FB_MSM_HDMI_SII_EXTERNAL_720P) += hdmi_sii9022.o
obj-$(CONFIG_FB_MSM_TVOUT_NTSC) += tv_ntsc.o
obj-$(CONFIG_FB_MSM_TVOUT_PAL) += tv_pal.o
obj-$(CONFIG_FB_MSM_EXTMDDI_SVGA) += mddi_ext_lcd.o
clean:
rm *.o .*cmd

View file

@ -1,3 +0,0 @@
- Merge this code with the existing MSM framebuffer
- General style clean ups.

View file

@ -1,569 +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 "msm_fb.h"
#include <linux/memory.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <mach/hardware.h>
#include <linux/io.h>
#include <asm/system.h>
#include <asm/mach-types.h>
/* The following are for MSM5100 on Gator
*/
#ifdef FEATURE_PM1000
#include "pm1000.h"
#endif /* FEATURE_PM1000 */
/* The following are for MSM6050 on Bambi
*/
#ifdef FEATURE_PMIC_LCDKBD_LED_DRIVER
#include "pm.h"
#endif /* FEATURE_PMIC_LCDKBD_LED_DRIVER */
#ifdef DISP_DEVICE_18BPP
#undef DISP_DEVICE_18BPP
#define DISP_DEVICE_16BPP
#endif
#define QCIF_WIDTH 176
#define QCIF_HEIGHT 220
static void *DISP_CMD_PORT;
static void *DISP_DATA_PORT;
#define DISP_CMD_DISON 0xaf
#define DISP_CMD_DISOFF 0xae
#define DISP_CMD_DISNOR 0xa6
#define DISP_CMD_DISINV 0xa7
#define DISP_CMD_DISCTL 0xca
#define DISP_CMD_GCP64 0xcb
#define DISP_CMD_GCP16 0xcc
#define DISP_CMD_GSSET 0xcd
#define DISP_GS_2 0x02
#define DISP_GS_16 0x01
#define DISP_GS_64 0x00
#define DISP_CMD_SLPIN 0x95
#define DISP_CMD_SLPOUT 0x94
#define DISP_CMD_SD_PSET 0x75
#define DISP_CMD_MD_PSET 0x76
#define DISP_CMD_SD_CSET 0x15
#define DISP_CMD_MD_CSET 0x16
#define DISP_CMD_DATCTL 0xbc
#define DISP_DATCTL_666 0x08
#define DISP_DATCTL_565 0x28
#define DISP_DATCTL_444 0x38
#define DISP_CMD_RAMWR 0x5c
#define DISP_CMD_RAMRD 0x5d
#define DISP_CMD_PTLIN 0xa8
#define DISP_CMD_PTLOUT 0xa9
#define DISP_CMD_ASCSET 0xaa
#define DISP_CMD_SCSTART 0xab
#define DISP_CMD_VOLCTL 0xc6
#define DISP_VOLCTL_TONE 0x80
#define DISP_CMD_NOp 0x25
#define DISP_CMD_OSSEL 0xd0
#define DISP_CMD_3500KSET 0xd1
#define DISP_CMD_3500KEND 0xd2
#define DISP_CMD_14MSET 0xd3
#define DISP_CMD_14MEND 0xd4
#define DISP_CMD_OUT(cmd) outpw(DISP_CMD_PORT, cmd);
#define DISP_DATA_OUT(data) outpw(DISP_DATA_PORT, data);
#define DISP_DATA_IN() inpw(DISP_DATA_PORT);
/* Epson device column number starts at 2
*/
#define DISP_SET_RECT(ulhc_row, lrhc_row, ulhc_col, lrhc_col) \
DISP_CMD_OUT(DISP_CMD_SD_PSET) \
DISP_DATA_OUT((ulhc_row) & 0xFF) \
DISP_DATA_OUT((ulhc_row) >> 8) \
DISP_DATA_OUT((lrhc_row) & 0xFF) \
DISP_DATA_OUT((lrhc_row) >> 8) \
DISP_CMD_OUT(DISP_CMD_SD_CSET) \
DISP_DATA_OUT(((ulhc_col)+2) & 0xFF) \
DISP_DATA_OUT(((ulhc_col)+2) >> 8) \
DISP_DATA_OUT(((lrhc_col)+2) & 0xFF) \
DISP_DATA_OUT(((lrhc_col)+2) >> 8)
#define DISP_MIN_CONTRAST 0
#define DISP_MAX_CONTRAST 127
#define DISP_DEFAULT_CONTRAST 80
#define DISP_MIN_BACKLIGHT 0
#define DISP_MAX_BACKLIGHT 15
#define DISP_DEFAULT_BACKLIGHT 2
#define WAIT_SEC(sec) mdelay((sec)/1000)
static word disp_area_start_row;
static word disp_area_end_row;
static byte disp_contrast = DISP_DEFAULT_CONTRAST;
static boolean disp_powered_up;
static boolean disp_initialized = FALSE;
/* For some reason the contrast set at init time is not good. Need to do
* it again
*/
static boolean display_on = FALSE;
static void epsonQcif_disp_init(struct platform_device *pdev);
static void epsonQcif_disp_set_contrast(word contrast);
static void epsonQcif_disp_set_display_area(word start_row, word end_row);
static int epsonQcif_disp_off(struct platform_device *pdev);
static int epsonQcif_disp_on(struct platform_device *pdev);
static void epsonQcif_disp_set_rect(int x, int y, int xres, int yres);
volatile word databack;
static void epsonQcif_disp_init(struct platform_device *pdev)
{
struct msm_fb_data_type *mfd;
int i;
if (disp_initialized)
return;
mfd = platform_get_drvdata(pdev);
DISP_CMD_PORT = mfd->cmd_port;
DISP_DATA_PORT = mfd->data_port;
/* Sleep in */
DISP_CMD_OUT(DISP_CMD_SLPIN);
/* Display off */
DISP_CMD_OUT(DISP_CMD_DISOFF);
/* Display normal */
DISP_CMD_OUT(DISP_CMD_DISNOR);
/* Set data mode */
DISP_CMD_OUT(DISP_CMD_DATCTL);
DISP_DATA_OUT(DISP_DATCTL_565);
/* Set display timing */
DISP_CMD_OUT(DISP_CMD_DISCTL);
DISP_DATA_OUT(0x1c); /* p1 */
DISP_DATA_OUT(0x02); /* p1 */
DISP_DATA_OUT(0x82); /* p2 */
DISP_DATA_OUT(0x00); /* p3 */
DISP_DATA_OUT(0x00); /* p4 */
DISP_DATA_OUT(0xe0); /* p5 */
DISP_DATA_OUT(0x00); /* p5 */
DISP_DATA_OUT(0xdc); /* p6 */
DISP_DATA_OUT(0x00); /* p6 */
DISP_DATA_OUT(0x02); /* p7 */
DISP_DATA_OUT(0x00); /* p8 */
/* Set 64 gray scale level */
DISP_CMD_OUT(DISP_CMD_GCP64);
DISP_DATA_OUT(0x08); /* p01 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0x2a); /* p02 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0x4e); /* p03 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0x6b); /* p04 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0x88); /* p05 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0xa3); /* p06 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0xba); /* p07 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0xd1); /* p08 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0xe5); /* p09 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0xf3); /* p10 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0x03); /* p11 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x13); /* p12 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x22); /* p13 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x2f); /* p14 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x3b); /* p15 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x46); /* p16 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x51); /* p17 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x5b); /* p18 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x64); /* p19 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x6c); /* p20 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x74); /* p21 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x7c); /* p22 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x83); /* p23 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x8a); /* p24 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x91); /* p25 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x98); /* p26 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x9f); /* p27 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xa6); /* p28 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xac); /* p29 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xb2); /* p30 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xb7); /* p31 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xbc); /* p32 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xc1); /* p33 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xc6); /* p34 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xcb); /* p35 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xd0); /* p36 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xd4); /* p37 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xd8); /* p38 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xdc); /* p39 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xe0); /* p40 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xe4); /* p41 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xe8); /* p42 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xec); /* p43 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xf0); /* p44 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xf4); /* p45 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xf8); /* p46 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xfb); /* p47 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xfe); /* p48 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x01); /* p49 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x03); /* p50 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x05); /* p51 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x07); /* p52 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x09); /* p53 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x0b); /* p54 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x0d); /* p55 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x0f); /* p56 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x11); /* p57 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x13); /* p58 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x15); /* p59 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x17); /* p60 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x19); /* p61 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x1b); /* p62 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x1c); /* p63 */
DISP_DATA_OUT(0x02);
/* Set 16 gray scale level */
DISP_CMD_OUT(DISP_CMD_GCP16);
DISP_DATA_OUT(0x1a); /* p01 */
DISP_DATA_OUT(0x32); /* p02 */
DISP_DATA_OUT(0x42); /* p03 */
DISP_DATA_OUT(0x4c); /* p04 */
DISP_DATA_OUT(0x58); /* p05 */
DISP_DATA_OUT(0x5f); /* p06 */
DISP_DATA_OUT(0x66); /* p07 */
DISP_DATA_OUT(0x6b); /* p08 */
DISP_DATA_OUT(0x70); /* p09 */
DISP_DATA_OUT(0x74); /* p10 */
DISP_DATA_OUT(0x78); /* p11 */
DISP_DATA_OUT(0x7b); /* p12 */
DISP_DATA_OUT(0x7e); /* p13 */
DISP_DATA_OUT(0x80); /* p14 */
DISP_DATA_OUT(0x82); /* p15 */
/* Set DSP column */
DISP_CMD_OUT(DISP_CMD_MD_CSET);
DISP_DATA_OUT(0xff);
DISP_DATA_OUT(0x03);
DISP_DATA_OUT(0xff);
DISP_DATA_OUT(0x03);
/* Set DSP page */
DISP_CMD_OUT(DISP_CMD_MD_PSET);
DISP_DATA_OUT(0xff);
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xff);
DISP_DATA_OUT(0x01);
/* Set ARM column */
DISP_CMD_OUT(DISP_CMD_SD_CSET);
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x00);
DISP_DATA_OUT((QCIF_WIDTH + 1) & 0xFF);
DISP_DATA_OUT((QCIF_WIDTH + 1) >> 8);
/* Set ARM page */
DISP_CMD_OUT(DISP_CMD_SD_PSET);
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0x00);
DISP_DATA_OUT((QCIF_HEIGHT - 1) & 0xFF);
DISP_DATA_OUT((QCIF_HEIGHT - 1) >> 8);
/* Set 64 gray scales */
DISP_CMD_OUT(DISP_CMD_GSSET);
DISP_DATA_OUT(DISP_GS_64);
DISP_CMD_OUT(DISP_CMD_OSSEL);
DISP_DATA_OUT(0);
/* Sleep out */
DISP_CMD_OUT(DISP_CMD_SLPOUT);
WAIT_SEC(40000);
/* Initialize power IC */
DISP_CMD_OUT(DISP_CMD_VOLCTL);
DISP_DATA_OUT(DISP_VOLCTL_TONE);
WAIT_SEC(40000);
/* Set electronic volume, d'xx */
DISP_CMD_OUT(DISP_CMD_VOLCTL);
DISP_DATA_OUT(DISP_DEFAULT_CONTRAST); /* value from 0 to 127 */
/* Initialize display data */
DISP_SET_RECT(0, (QCIF_HEIGHT - 1), 0, (QCIF_WIDTH - 1));
DISP_CMD_OUT(DISP_CMD_RAMWR);
for (i = 0; i < QCIF_HEIGHT * QCIF_WIDTH; i++)
DISP_DATA_OUT(0xffff);
DISP_CMD_OUT(DISP_CMD_RAMRD);
databack = DISP_DATA_IN();
databack = DISP_DATA_IN();
databack = DISP_DATA_IN();
databack = DISP_DATA_IN();
WAIT_SEC(80000);
DISP_CMD_OUT(DISP_CMD_DISON);
disp_area_start_row = 0;
disp_area_end_row = QCIF_HEIGHT - 1;
disp_powered_up = TRUE;
disp_initialized = TRUE;
epsonQcif_disp_set_display_area(0, QCIF_HEIGHT - 1);
display_on = TRUE;
}
static void epsonQcif_disp_set_rect(int x, int y, int xres, int yres)
{
if (!disp_initialized)
return;
DISP_SET_RECT(y, y + yres - 1, x, x + xres - 1);
DISP_CMD_OUT(DISP_CMD_RAMWR);
}
static void epsonQcif_disp_set_display_area(word start_row, word end_row)
{
if (!disp_initialized)
return;
if ((start_row == disp_area_start_row)
&& (end_row == disp_area_end_row))
return;
disp_area_start_row = start_row;
disp_area_end_row = end_row;
/* Range checking
*/
if (end_row >= QCIF_HEIGHT)
end_row = QCIF_HEIGHT - 1;
if (start_row > end_row)
start_row = end_row;
/* When display is not the full screen, gray scale is set to
** 2; otherwise it is set to 64.
*/
if ((start_row == 0) && (end_row == (QCIF_HEIGHT - 1))) {
/* The whole screen */
DISP_CMD_OUT(DISP_CMD_PTLOUT);
WAIT_SEC(10000);
DISP_CMD_OUT(DISP_CMD_DISOFF);
WAIT_SEC(100000);
DISP_CMD_OUT(DISP_CMD_GSSET);
DISP_DATA_OUT(DISP_GS_64);
WAIT_SEC(100000);
DISP_CMD_OUT(DISP_CMD_DISON);
} else {
/* partial screen */
DISP_CMD_OUT(DISP_CMD_PTLIN);
DISP_DATA_OUT(start_row);
DISP_DATA_OUT(start_row >> 8);
DISP_DATA_OUT(end_row);
DISP_DATA_OUT(end_row >> 8);
DISP_CMD_OUT(DISP_CMD_GSSET);
DISP_DATA_OUT(DISP_GS_2);
}
}
static int epsonQcif_disp_off(struct platform_device *pdev)
{
if (!disp_initialized)
epsonQcif_disp_init(pdev);
if (display_on) {
DISP_CMD_OUT(DISP_CMD_DISOFF);
DISP_CMD_OUT(DISP_CMD_SLPIN);
display_on = FALSE;
}
return 0;
}
static int epsonQcif_disp_on(struct platform_device *pdev)
{
if (!disp_initialized)
epsonQcif_disp_init(pdev);
if (!display_on) {
DISP_CMD_OUT(DISP_CMD_SLPOUT);
WAIT_SEC(40000);
DISP_CMD_OUT(DISP_CMD_DISON);
epsonQcif_disp_set_contrast(disp_contrast);
display_on = TRUE;
}
return 0;
}
static void epsonQcif_disp_set_contrast(word contrast)
{
if (!disp_initialized)
return;
/* Initialize power IC, d'24 */
DISP_CMD_OUT(DISP_CMD_VOLCTL);
DISP_DATA_OUT(DISP_VOLCTL_TONE);
WAIT_SEC(40000);
/* Set electronic volume, d'xx */
DISP_CMD_OUT(DISP_CMD_VOLCTL);
if (contrast > 127)
contrast = 127;
DISP_DATA_OUT(contrast); /* value from 0 to 127 */
disp_contrast = (byte) contrast;
} /* End disp_set_contrast */
static void epsonQcif_disp_clear_screen_area(
word start_row, word end_row, word start_column, word end_column) {
int32 i;
/* Clear the display screen */
DISP_SET_RECT(start_row, end_row, start_column, end_column);
DISP_CMD_OUT(DISP_CMD_RAMWR);
i = (end_row - start_row + 1) * (end_column - start_column + 1);
for (; i > 0; i--)
DISP_DATA_OUT(0xffff);
}
static int __init epsonQcif_probe(struct platform_device *pdev)
{
msm_fb_add_device(pdev);
return 0;
}
static struct platform_driver this_driver = {
.probe = epsonQcif_probe,
.driver = {
.name = "ebi2_epson_qcif",
},
};
static struct msm_fb_panel_data epsonQcif_panel_data = {
.on = epsonQcif_disp_on,
.off = epsonQcif_disp_off,
.set_rect = epsonQcif_disp_set_rect,
};
static struct platform_device this_device = {
.name = "ebi2_epson_qcif",
.id = 0,
.dev = {
.platform_data = &epsonQcif_panel_data,
}
};
static int __init epsonQcif_init(void)
{
int ret;
struct msm_panel_info *pinfo;
ret = platform_driver_register(&this_driver);
if (!ret) {
pinfo = &epsonQcif_panel_data.panel_info;
pinfo->xres = QCIF_WIDTH;
pinfo->yres = QCIF_HEIGHT;
pinfo->type = EBI2_PANEL;
pinfo->pdest = DISPLAY_2;
pinfo->wait_cycle = 0x808000;
pinfo->bpp = 16;
pinfo->fb_num = 2;
pinfo->lcd.vsync_enable = FALSE;
ret = platform_device_register(&this_device);
if (ret)
platform_driver_unregister(&this_driver);
}
return ret;
}
module_init(epsonQcif_init);

View file

@ -1,249 +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/moduleparam.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/uaccess.h>
#include <linux/workqueue.h>
#include <linux/string.h>
#include <linux/proc_fs.h>
#include <linux/vmalloc.h>
#include <linux/debugfs.h>
#include "msm_fb.h"
static int ebi2_lcd_probe(struct platform_device *pdev);
static int ebi2_lcd_remove(struct platform_device *pdev);
static struct platform_driver ebi2_lcd_driver = {
.probe = ebi2_lcd_probe,
.remove = ebi2_lcd_remove,
.suspend = NULL,
.suspend_late = NULL,
.resume_early = NULL,
.resume = NULL,
.shutdown = NULL,
.driver = {
.name = "ebi2_lcd",
},
};
static void *ebi2_base;
static void *ebi2_lcd_cfg0;
static void *ebi2_lcd_cfg1;
static void __iomem *lcd01_base;
static void __iomem *lcd02_base;
static int ebi2_lcd_resource_initialized;
static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
static int pdev_list_cnt;
static int ebi2_lcd_probe(struct platform_device *pdev)
{
struct msm_fb_data_type *mfd;
struct platform_device *mdp_dev = NULL;
struct msm_fb_panel_data *pdata = NULL;
int rc, i;
if (pdev->id == 0) {
for (i = 0; i < pdev->num_resources; i++) {
if (!strncmp(pdev->resource[i].name, "base", 4)) {
ebi2_base = ioremap(pdev->resource[i].start,
pdev->resource[i].end -
pdev->resource[i].start + 1);
if (!ebi2_base) {
printk(KERN_ERR
"ebi2_base ioremap failed!\n");
return -ENOMEM;
}
ebi2_lcd_cfg0 = (void *)(ebi2_base + 0x20);
ebi2_lcd_cfg1 = (void *)(ebi2_base + 0x24);
} else if (!strncmp(pdev->resource[i].name,
"lcd01", 5)) {
lcd01_base = ioremap(pdev->resource[i].start,
pdev->resource[i].end -
pdev->resource[i].start + 1);
if (!lcd01_base) {
printk(KERN_ERR
"lcd01_base ioremap failed!\n");
return -ENOMEM;
}
} else if (!strncmp(pdev->resource[i].name,
"lcd02", 5)) {
lcd02_base = ioremap(pdev->resource[i].start,
pdev->resource[i].end -
pdev->resource[i].start + 1);
if (!lcd02_base) {
printk(KERN_ERR
"lcd02_base ioremap failed!\n");
return -ENOMEM;
}
}
}
ebi2_lcd_resource_initialized = 1;
return 0;
}
if (!ebi2_lcd_resource_initialized)
return -EPERM;
mfd = platform_get_drvdata(pdev);
if (!mfd)
return -ENODEV;
if (mfd->key != MFD_KEY)
return -EINVAL;
if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
return -ENOMEM;
if (ebi2_base == NULL)
return -ENOMEM;
mdp_dev = platform_device_alloc("mdp", pdev->id);
if (!mdp_dev)
return -ENOMEM;
/* link to the latest pdev */
mfd->pdev = mdp_dev;
mfd->dest = DISPLAY_LCD;
/* add panel data */
if (platform_device_add_data
(mdp_dev, pdev->dev.platform_data,
sizeof(struct msm_fb_panel_data))) {
printk(KERN_ERR "ebi2_lcd_probe: platform_device_add_data failed!\n");
platform_device_put(mdp_dev);
return -ENOMEM;
}
/* data chain */
pdata = mdp_dev->dev.platform_data;
pdata->on = panel_next_on;
pdata->off = panel_next_off;
pdata->next = pdev;
/* get/set panel specific fb info */
mfd->panel_info = pdata->panel_info;
if (mfd->panel_info.bpp == 24)
mfd->fb_imgType = MDP_RGB_888;
else
mfd->fb_imgType = MDP_RGB_565;
/* config msm ebi2 lcd register */
if (mfd->panel_info.pdest == DISPLAY_1) {
outp32(ebi2_base,
(inp32(ebi2_base) & (~(EBI2_PRIM_LCD_CLR))) |
EBI2_PRIM_LCD_SEL);
/*
* current design has one set of cfg0/1 register to control
* both EBI2 channels. so, we're using the PRIM channel to
* configure both.
*/
outp32(ebi2_lcd_cfg0, mfd->panel_info.wait_cycle);
if (mfd->panel_info.bpp == 18)
outp32(ebi2_lcd_cfg1, 0x01000000);
else
outp32(ebi2_lcd_cfg1, 0x0);
} else {
#ifdef DEBUG_EBI2_LCD
/*
* confliting with QCOM SURF FPGA CS.
* OEM should enable below for their CS mapping
*/
outp32(ebi2_base, (inp32(ebi2_base)&(~(EBI2_SECD_LCD_CLR)))
|EBI2_SECD_LCD_SEL);
#endif
}
/*
* map cs (chip select) address
*/
if (mfd->panel_info.pdest == DISPLAY_1) {
mfd->cmd_port = lcd01_base;
mfd->data_port =
(void *)((uint32) mfd->cmd_port + EBI2_PRIM_LCD_RS_PIN);
mfd->data_port_phys =
(void *)(LCD_PRIM_BASE_PHYS + EBI2_PRIM_LCD_RS_PIN);
} else {
mfd->cmd_port = lcd01_base;
mfd->data_port =
(void *)((uint32) mfd->cmd_port + EBI2_SECD_LCD_RS_PIN);
mfd->data_port_phys =
(void *)(LCD_SECD_BASE_PHYS + EBI2_SECD_LCD_RS_PIN);
}
/*
* set driver data
*/
platform_set_drvdata(mdp_dev, mfd);
/*
* register in mdp driver
*/
rc = platform_device_add(mdp_dev);
if (rc) {
goto ebi2_lcd_probe_err;
}
pdev_list[pdev_list_cnt++] = pdev;
return 0;
ebi2_lcd_probe_err:
platform_device_put(mdp_dev);
return rc;
}
static int ebi2_lcd_remove(struct platform_device *pdev)
{
struct msm_fb_data_type *mfd;
mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
if (!mfd)
return 0;
if (mfd->key != MFD_KEY)
return 0;
iounmap(mfd->cmd_port);
return 0;
}
static int ebi2_lcd_register_driver(void)
{
return platform_driver_register(&ebi2_lcd_driver);
}
static int __init ebi2_lcd_driver_init(void)
{
return ebi2_lcd_register_driver();
}
module_init(ebi2_lcd_driver_init);

File diff suppressed because it is too large Load diff

View file

@ -1,248 +0,0 @@
/* Copyright (c) 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/i2c.h>
#include <linux/delay.h>
#include "msm_fb.h"
#define DEVICE_NAME "sii9022"
#define SII9022_DEVICE_ID 0xB0
struct sii9022_i2c_addr_data{
u8 addr;
u8 data;
};
/* video mode data */
static u8 video_mode_data[] = {
0x00,
0xF9, 0x1C, 0x70, 0x17, 0x72, 0x06, 0xEE, 0x02,
};
static u8 avi_io_format[] = {
0x09,
0x00, 0x00,
};
/* power state */
static struct sii9022_i2c_addr_data regset0[] = {
{ 0x60, 0x04 },
{ 0x63, 0x00 },
{ 0x1E, 0x00 },
};
static u8 video_infoframe[] = {
0x0C,
0xF0, 0x00, 0x68, 0x00, 0x04, 0x00, 0x19, 0x00,
0xE9, 0x02, 0x04, 0x01, 0x04, 0x06,
};
/* configure audio */
static struct sii9022_i2c_addr_data regset1[] = {
{ 0x26, 0x90 },
{ 0x20, 0x90 },
{ 0x1F, 0x80 },
{ 0x26, 0x80 },
{ 0x24, 0x02 },
{ 0x25, 0x0B },
{ 0xBC, 0x02 },
{ 0xBD, 0x24 },
{ 0xBE, 0x02 },
};
/* enable audio */
static u8 misc_infoframe[] = {
0xBF,
0xC2, 0x84, 0x01, 0x0A, 0x6F, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
/* set HDMI, active */
static struct sii9022_i2c_addr_data regset2[] = {
{ 0x1A, 0x01 },
{ 0x3D, 0x00 },
};
static int send_i2c_data(struct i2c_client *client,
struct sii9022_i2c_addr_data *regset,
int size)
{
int i;
int rc = 0;
for (i = 0; i < size; i++) {
rc = i2c_smbus_write_byte_data(
client,
regset[i].addr, regset[i].data);
if (rc)
break;
}
return rc;
}
static int hdmi_sii_enable(struct i2c_client *client)
{
int rc;
int retries = 10;
int count;
rc = i2c_smbus_write_byte_data(client, 0xC7, 0x00);
if (rc)
goto enable_exit;
do {
msleep(1);
rc = i2c_smbus_read_byte_data(client, 0x1B);
} while ((rc != SII9022_DEVICE_ID) && retries--);
if (rc != SII9022_DEVICE_ID)
return -ENODEV;
rc = i2c_smbus_write_byte_data(client, 0x1A, 0x11);
if (rc)
goto enable_exit;
count = ARRAY_SIZE(video_mode_data);
rc = i2c_master_send(client, video_mode_data, count);
if (rc != count) {
rc = -EIO;
goto enable_exit;
}
rc = i2c_smbus_write_byte_data(client, 0x08, 0x20);
if (rc)
goto enable_exit;
count = ARRAY_SIZE(avi_io_format);
rc = i2c_master_send(client, avi_io_format, count);
if (rc != count) {
rc = -EIO;
goto enable_exit;
}
rc = send_i2c_data(client, regset0, ARRAY_SIZE(regset0));
if (rc)
goto enable_exit;
count = ARRAY_SIZE(video_infoframe);
rc = i2c_master_send(client, video_infoframe, count);
if (rc != count) {
rc = -EIO;
goto enable_exit;
}
rc = send_i2c_data(client, regset1, ARRAY_SIZE(regset1));
if (rc)
goto enable_exit;
count = ARRAY_SIZE(misc_infoframe);
rc = i2c_master_send(client, misc_infoframe, count);
if (rc != count) {
rc = -EIO;
goto enable_exit;
}
rc = send_i2c_data(client, regset2, ARRAY_SIZE(regset2));
if (rc)
goto enable_exit;
return 0;
enable_exit:
printk(KERN_ERR "%s: exited rc=%d\n", __func__, rc);
return rc;
}
static const struct i2c_device_id hmdi_sii_id[] = {
{ DEVICE_NAME, 0 },
{ }
};
static int hdmi_sii_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int rc;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C))
return -ENODEV;
rc = hdmi_sii_enable(client);
return rc;
}
static struct i2c_driver hdmi_sii_i2c_driver = {
.driver = {
.name = DEVICE_NAME,
.owner = THIS_MODULE,
},
.probe = hdmi_sii_probe,
.remove = __exit_p(hdmi_sii_remove),
.id_table = hmdi_sii_id,
};
static int __init hdmi_sii_init(void)
{
int ret;
struct msm_panel_info pinfo;
if (msm_fb_detect_client("hdmi_sii9022"))
return 0;
pinfo.xres = 1280;
pinfo.yres = 720;
pinfo.type = HDMI_PANEL;
pinfo.pdest = DISPLAY_1;
pinfo.wait_cycle = 0;
pinfo.bpp = 24;
pinfo.fb_num = 2;
pinfo.clk_rate = 74250000;
pinfo.lcdc.h_back_porch = 124;
pinfo.lcdc.h_front_porch = 110;
pinfo.lcdc.h_pulse_width = 136;
pinfo.lcdc.v_back_porch = 19;
pinfo.lcdc.v_front_porch = 5;
pinfo.lcdc.v_pulse_width = 6;
pinfo.lcdc.border_clr = 0;
pinfo.lcdc.underflow_clr = 0xff;
pinfo.lcdc.hsync_skew = 0;
ret = lcdc_device_register(&pinfo);
if (ret) {
printk(KERN_ERR "%s: failed to register device\n", __func__);
goto init_exit;
}
ret = i2c_add_driver(&hdmi_sii_i2c_driver);
if (ret)
printk(KERN_ERR "%s: failed to add i2c driver\n", __func__);
init_exit:
return ret;
}
static void __exit hdmi_sii_exit(void)
{
i2c_del_driver(&hdmi_sii_i2c_driver);
}
module_init(hdmi_sii_init);
module_exit(hdmi_sii_exit);
MODULE_LICENSE("GPL v2");
MODULE_VERSION("0.1");
MODULE_AUTHOR("Qualcomm Innovation Center, Inc.");
MODULE_DESCRIPTION("SiI9022 HDMI driver");
MODULE_ALIAS("platform:hdmi-sii9022");

View file

@ -1,239 +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/delay.h>
#include <mach/hardware.h>
#include <linux/io.h>
#include <asm/system.h>
#include <asm/mach-types.h>
#include <linux/semaphore.h>
#include <linux/uaccess.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/pm_qos_params.h>
#include "msm_fb.h"
static int lcdc_probe(struct platform_device *pdev);
static int lcdc_remove(struct platform_device *pdev);
static int lcdc_off(struct platform_device *pdev);
static int lcdc_on(struct platform_device *pdev);
static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
static int pdev_list_cnt;
static struct clk *mdp_lcdc_pclk_clk;
static struct clk *mdp_lcdc_pad_pclk_clk;
int mdp_lcdc_pclk_clk_rate;
int mdp_lcdc_pad_pclk_clk_rate;
static struct platform_driver lcdc_driver = {
.probe = lcdc_probe,
.remove = lcdc_remove,
.suspend = NULL,
.resume = NULL,
.shutdown = NULL,
.driver = {
.name = "lcdc",
},
};
static struct lcdc_platform_data *lcdc_pdata;
static int lcdc_off(struct platform_device *pdev)
{
int ret = 0;
ret = panel_next_off(pdev);
clk_disable(mdp_lcdc_pclk_clk);
clk_disable(mdp_lcdc_pad_pclk_clk);
if (lcdc_pdata && lcdc_pdata->lcdc_power_save)
lcdc_pdata->lcdc_power_save(0);
if (lcdc_pdata && lcdc_pdata->lcdc_gpio_config)
ret = lcdc_pdata->lcdc_gpio_config(0);
// pm_qos_update_requirement(PM_QOS_SYSTEM_BUS_FREQ , "lcdc",
// PM_QOS_DEFAULT_VALUE);
return ret;
}
static int lcdc_on(struct platform_device *pdev)
{
int ret = 0;
struct msm_fb_data_type *mfd;
unsigned long panel_pixclock_freq , pm_qos_freq;
mfd = platform_get_drvdata(pdev);
panel_pixclock_freq = mfd->fbi->var.pixclock;
if (panel_pixclock_freq > 58000000)
/* pm_qos_freq should be in Khz */
pm_qos_freq = panel_pixclock_freq / 1000 ;
else
pm_qos_freq = 58000;
// pm_qos_update_requirement(PM_QOS_SYSTEM_BUS_FREQ , "lcdc",
// pm_qos_freq);
mfd = platform_get_drvdata(pdev);
clk_enable(mdp_lcdc_pclk_clk);
clk_enable(mdp_lcdc_pad_pclk_clk);
if (lcdc_pdata && lcdc_pdata->lcdc_power_save)
lcdc_pdata->lcdc_power_save(1);
if (lcdc_pdata && lcdc_pdata->lcdc_gpio_config)
ret = lcdc_pdata->lcdc_gpio_config(1);
clk_set_rate(mdp_lcdc_pclk_clk, mfd->fbi->var.pixclock);
clk_set_rate(mdp_lcdc_pad_pclk_clk, mfd->fbi->var.pixclock);
mdp_lcdc_pclk_clk_rate = clk_get_rate(mdp_lcdc_pclk_clk);
mdp_lcdc_pad_pclk_clk_rate = clk_get_rate(mdp_lcdc_pad_pclk_clk);
ret = panel_next_on(pdev);
return ret;
}
static int lcdc_probe(struct platform_device *pdev)
{
struct msm_fb_data_type *mfd;
struct fb_info *fbi;
struct platform_device *mdp_dev = NULL;
struct msm_fb_panel_data *pdata = NULL;
int rc;
if (pdev->id == 0) {
lcdc_pdata = pdev->dev.platform_data;
return 0;
}
mfd = platform_get_drvdata(pdev);
if (!mfd)
return -ENODEV;
if (mfd->key != MFD_KEY)
return -EINVAL;
if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
return -ENOMEM;
mdp_dev = platform_device_alloc("mdp", pdev->id);
if (!mdp_dev)
return -ENOMEM;
/*
* link to the latest pdev
*/
mfd->pdev = mdp_dev;
mfd->dest = DISPLAY_LCDC;
/*
* alloc panel device data
*/
if (platform_device_add_data
(mdp_dev, pdev->dev.platform_data,
sizeof(struct msm_fb_panel_data))) {
printk(KERN_ERR "lcdc_probe: platform_device_add_data failed!\n");
platform_device_put(mdp_dev);
return -ENOMEM;
}
/*
* data chain
*/
pdata = (struct msm_fb_panel_data *)mdp_dev->dev.platform_data;
pdata->on = lcdc_on;
pdata->off = lcdc_off;
pdata->next = pdev;
/*
* get/set panel specific fb info
*/
mfd->panel_info = pdata->panel_info;
mfd->fb_imgType = MDP_RGB_565;
fbi = mfd->fbi;
fbi->var.pixclock = mfd->panel_info.clk_rate;
fbi->var.left_margin = mfd->panel_info.lcdc.h_back_porch;
fbi->var.right_margin = mfd->panel_info.lcdc.h_front_porch;
fbi->var.upper_margin = mfd->panel_info.lcdc.v_back_porch;
fbi->var.lower_margin = mfd->panel_info.lcdc.v_front_porch;
fbi->var.hsync_len = mfd->panel_info.lcdc.h_pulse_width;
fbi->var.vsync_len = mfd->panel_info.lcdc.v_pulse_width;
/*
* set driver data
*/
platform_set_drvdata(mdp_dev, mfd);
/*
* register in mdp driver
*/
rc = platform_device_add(mdp_dev);
if (rc)
goto lcdc_probe_err;
pdev_list[pdev_list_cnt++] = pdev;
return 0;
lcdc_probe_err:
platform_device_put(mdp_dev);
return rc;
}
static int lcdc_remove(struct platform_device *pdev)
{
// pm_qos_remove_requirement(PM_QOS_SYSTEM_BUS_FREQ , "lcdc");
return 0;
}
static int lcdc_register_driver(void)
{
return platform_driver_register(&lcdc_driver);
}
static int __init lcdc_driver_init(void)
{
mdp_lcdc_pclk_clk = clk_get(NULL, "mdp_lcdc_pclk_clk");
if (IS_ERR(mdp_lcdc_pclk_clk)) {
printk(KERN_ERR "error: can't get mdp_lcdc_pclk_clk!\n");
return PTR_ERR(mdp_lcdc_pclk_clk);
}
mdp_lcdc_pad_pclk_clk = clk_get(NULL, "mdp_lcdc_pad_pclk_clk");
if (IS_ERR(mdp_lcdc_pad_pclk_clk)) {
printk(KERN_ERR "error: can't get mdp_lcdc_pad_pclk_clk!\n");
return PTR_ERR(mdp_lcdc_pad_pclk_clk);
}
// pm_qos_add_requirement(PM_QOS_SYSTEM_BUS_FREQ , "lcdc",
// PM_QOS_DEFAULT_VALUE);
return lcdc_register_driver();
}
module_init(lcdc_driver_init);

View file

@ -1,54 +0,0 @@
/* Copyright (c) 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 "msm_fb.h"
static int __init lcdc_external_init(void)
{
int ret;
struct msm_panel_info pinfo;
if (msm_fb_detect_client("lcdc_external"))
return 0;
pinfo.xres = 1280;
pinfo.yres = 720;
pinfo.type = LCDC_PANEL;
pinfo.pdest = DISPLAY_1;
pinfo.wait_cycle = 0;
pinfo.bpp = 24;
pinfo.fb_num = 2;
pinfo.clk_rate = 74250000;
pinfo.lcdc.h_back_porch = 124;
pinfo.lcdc.h_front_porch = 110;
pinfo.lcdc.h_pulse_width = 136;
pinfo.lcdc.v_back_porch = 19;
pinfo.lcdc.v_front_porch = 5;
pinfo.lcdc.v_pulse_width = 6;
pinfo.lcdc.border_clr = 0; /* blk */
pinfo.lcdc.underflow_clr = 0xff; /* blue */
pinfo.lcdc.hsync_skew = 0;
ret = lcdc_device_register(&pinfo);
if (ret)
printk(KERN_ERR "%s: failed to register device!\n", __func__);
return ret;
}
module_init(lcdc_external_init);

View file

@ -1,446 +0,0 @@
/* Copyright (c) 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/delay.h>
#include <mach/gpio.h>
#include "msm_fb.h"
/* registers */
#define GORDON_REG_NOP 0x00
#define GORDON_REG_IMGCTL1 0x10
#define GORDON_REG_IMGCTL2 0x11
#define GORDON_REG_IMGSET1 0x12
#define GORDON_REG_IMGSET2 0x13
#define GORDON_REG_IVBP1 0x14
#define GORDON_REG_IHBP1 0x15
#define GORDON_REG_IVNUM1 0x16
#define GORDON_REG_IHNUM1 0x17
#define GORDON_REG_IVBP2 0x18
#define GORDON_REG_IHBP2 0x19
#define GORDON_REG_IVNUM2 0x1A
#define GORDON_REG_IHNUM2 0x1B
#define GORDON_REG_LCDIFCTL1 0x30
#define GORDON_REG_VALTRAN 0x31
#define GORDON_REG_AVCTL 0x33
#define GORDON_REG_LCDIFCTL2 0x34
#define GORDON_REG_LCDIFCTL3 0x35
#define GORDON_REG_LCDIFSET1 0x36
#define GORDON_REG_PCCTL 0x3C
#define GORDON_REG_TPARAM1 0x40
#define GORDON_REG_TLCDIF1 0x41
#define GORDON_REG_TSSPB_ST1 0x42
#define GORDON_REG_TSSPB_ED1 0x43
#define GORDON_REG_TSCK_ST1 0x44
#define GORDON_REG_TSCK_WD1 0x45
#define GORDON_REG_TGSPB_VST1 0x46
#define GORDON_REG_TGSPB_VED1 0x47
#define GORDON_REG_TGSPB_CH1 0x48
#define GORDON_REG_TGCK_ST1 0x49
#define GORDON_REG_TGCK_ED1 0x4A
#define GORDON_REG_TPCTL_ST1 0x4B
#define GORDON_REG_TPCTL_ED1 0x4C
#define GORDON_REG_TPCHG_ED1 0x4D
#define GORDON_REG_TCOM_CH1 0x4E
#define GORDON_REG_THBP1 0x4F
#define GORDON_REG_TPHCTL1 0x50
#define GORDON_REG_EVPH1 0x51
#define GORDON_REG_EVPL1 0x52
#define GORDON_REG_EVNH1 0x53
#define GORDON_REG_EVNL1 0x54
#define GORDON_REG_TBIAS1 0x55
#define GORDON_REG_TPARAM2 0x56
#define GORDON_REG_TLCDIF2 0x57
#define GORDON_REG_TSSPB_ST2 0x58
#define GORDON_REG_TSSPB_ED2 0x59
#define GORDON_REG_TSCK_ST2 0x5A
#define GORDON_REG_TSCK_WD2 0x5B
#define GORDON_REG_TGSPB_VST2 0x5C
#define GORDON_REG_TGSPB_VED2 0x5D
#define GORDON_REG_TGSPB_CH2 0x5E
#define GORDON_REG_TGCK_ST2 0x5F
#define GORDON_REG_TGCK_ED2 0x60
#define GORDON_REG_TPCTL_ST2 0x61
#define GORDON_REG_TPCTL_ED2 0x62
#define GORDON_REG_TPCHG_ED2 0x63
#define GORDON_REG_TCOM_CH2 0x64
#define GORDON_REG_THBP2 0x65
#define GORDON_REG_TPHCTL2 0x66
#define GORDON_REG_POWCTL 0x80
static int lcdc_gordon_panel_off(struct platform_device *pdev);
static int spi_cs;
static int spi_sclk;
static int spi_sdo;
static int spi_sdi;
static int spi_dac;
static unsigned char bit_shift[8] = { (1 << 7), /* MSB */
(1 << 6),
(1 << 5),
(1 << 4),
(1 << 3),
(1 << 2),
(1 << 1),
(1 << 0) /* LSB */
};
struct gordon_state_type{
boolean disp_initialized;
boolean display_on;
boolean disp_powered_up;
};
static struct gordon_state_type gordon_state = { 0 };
static struct msm_panel_common_pdata *lcdc_gordon_pdata;
static void serigo(uint16 reg, uint8 data)
{
unsigned int tx_val = ((0x00FF & reg) << 8) | data;
unsigned char i, val = 0;
/* Enable the Chip Select */
gpio_set_value(spi_cs, 1);
udelay(33);
/* Transmit it in two parts, Higher Byte first, then Lower Byte */
val = (unsigned char)((tx_val & 0xFF00) >> 8);
/* Clock should be Low before entering ! */
for (i = 0; i < 8; i++) {
/* #1: Drive the Data (High or Low) */
if (val & bit_shift[i])
gpio_set_value(spi_sdi, 1);
else
gpio_set_value(spi_sdi, 0);
/* #2: Drive the Clk High and then Low */
udelay(33);
gpio_set_value(spi_sclk, 1);
udelay(33);
gpio_set_value(spi_sclk, 0);
}
/* Idle state of SDO (MOSI) is Low */
gpio_set_value(spi_sdi, 0);
/* ..then Lower Byte */
val = (uint8) (tx_val & 0x00FF);
/* Before we enter here the Clock should be Low ! */
for (i = 0; i < 8; i++) {
/* #1: Drive the Data (High or Low) */
if (val & bit_shift[i])
gpio_set_value(spi_sdi, 1);
else
gpio_set_value(spi_sdi, 0);
/* #2: Drive the Clk High and then Low */
udelay(33);
gpio_set_value(spi_sclk, 1);
udelay(33);
gpio_set_value(spi_sclk, 0);
}
/* Idle state of SDO (MOSI) is Low */
gpio_set_value(spi_sdi, 0);
/* Now Disable the Chip Select */
udelay(33);
gpio_set_value(spi_cs, 0);
}
static void spi_init(void)
{
/* Setting the Default GPIO's */
spi_sclk = *(lcdc_gordon_pdata->gpio_num);
spi_cs = *(lcdc_gordon_pdata->gpio_num + 1);
spi_sdi = *(lcdc_gordon_pdata->gpio_num + 2);
spi_sdo = *(lcdc_gordon_pdata->gpio_num + 3);
/* Set the output so that we dont disturb the slave device */
gpio_set_value(spi_sclk, 0);
gpio_set_value(spi_sdi, 0);
/* Set the Chip Select De-asserted */
gpio_set_value(spi_cs, 0);
}
static void gordon_disp_powerup(void)
{
if (!gordon_state.disp_powered_up && !gordon_state.display_on) {
/* Reset the hardware first */
/* Include DAC power up implementation here */
gordon_state.disp_powered_up = TRUE;
}
}
static void gordon_init(void)
{
/* Image interface settings */
serigo(GORDON_REG_IMGCTL2, 0x00);
serigo(GORDON_REG_IMGSET1, 0x00);
/* Exchange the RGB signal for J510(Softbank mobile) */
serigo(GORDON_REG_IMGSET2, 0x12);
serigo(GORDON_REG_LCDIFSET1, 0x00);
/* Pre-charge settings */
serigo(GORDON_REG_PCCTL, 0x09);
serigo(GORDON_REG_LCDIFCTL2, 0x7B);
mdelay(1);
}
static void gordon_disp_on(void)
{
if (gordon_state.disp_powered_up && !gordon_state.display_on) {
gordon_init();
mdelay(20);
/* gordon_dispmode setting */
serigo(GORDON_REG_TPARAM1, 0x30);
serigo(GORDON_REG_TLCDIF1, 0x00);
serigo(GORDON_REG_TSSPB_ST1, 0x8B);
serigo(GORDON_REG_TSSPB_ED1, 0x93);
serigo(GORDON_REG_TSCK_ST1, 0x88);
serigo(GORDON_REG_TSCK_WD1, 0x00);
serigo(GORDON_REG_TGSPB_VST1, 0x01);
serigo(GORDON_REG_TGSPB_VED1, 0x02);
serigo(GORDON_REG_TGSPB_CH1, 0x5E);
serigo(GORDON_REG_TGCK_ST1, 0x80);
serigo(GORDON_REG_TGCK_ED1, 0x3C);
serigo(GORDON_REG_TPCTL_ST1, 0x50);
serigo(GORDON_REG_TPCTL_ED1, 0x74);
serigo(GORDON_REG_TPCHG_ED1, 0x78);
serigo(GORDON_REG_TCOM_CH1, 0x50);
serigo(GORDON_REG_THBP1, 0x84);
serigo(GORDON_REG_TPHCTL1, 0x00);
serigo(GORDON_REG_EVPH1, 0x70);
serigo(GORDON_REG_EVPL1, 0x64);
serigo(GORDON_REG_EVNH1, 0x56);
serigo(GORDON_REG_EVNL1, 0x48);
serigo(GORDON_REG_TBIAS1, 0x88);
/* QVGA settings */
serigo(GORDON_REG_TPARAM2, 0x28);
serigo(GORDON_REG_TLCDIF2, 0x14);
serigo(GORDON_REG_TSSPB_ST2, 0x49);
serigo(GORDON_REG_TSSPB_ED2, 0x4B);
serigo(GORDON_REG_TSCK_ST2, 0x4A);
serigo(GORDON_REG_TSCK_WD2, 0x02);
serigo(GORDON_REG_TGSPB_VST2, 0x02);
serigo(GORDON_REG_TGSPB_VED2, 0x03);
serigo(GORDON_REG_TGSPB_CH2, 0x2F);
serigo(GORDON_REG_TGCK_ST2, 0x40);
serigo(GORDON_REG_TGCK_ED2, 0x1E);
serigo(GORDON_REG_TPCTL_ST2, 0x2C);
serigo(GORDON_REG_TPCTL_ED2, 0x3A);
serigo(GORDON_REG_TPCHG_ED2, 0x3C);
serigo(GORDON_REG_TCOM_CH2, 0x28);
serigo(GORDON_REG_THBP2, 0x4D);
serigo(GORDON_REG_TPHCTL2, 0x1A);
/* VGA settings */
serigo(GORDON_REG_IVBP1, 0x02);
serigo(GORDON_REG_IHBP1, 0x90);
serigo(GORDON_REG_IVNUM1, 0xA0);
serigo(GORDON_REG_IHNUM1, 0x78);
/* QVGA settings */
serigo(GORDON_REG_IVBP2, 0x02);
serigo(GORDON_REG_IHBP2, 0x48);
serigo(GORDON_REG_IVNUM2, 0x50);
serigo(GORDON_REG_IHNUM2, 0x3C);
/* Gordon Charge pump settings and ON */
serigo(GORDON_REG_POWCTL, 0x03);
mdelay(15);
serigo(GORDON_REG_POWCTL, 0x07);
mdelay(15);
serigo(GORDON_REG_POWCTL, 0x0F);
mdelay(15);
serigo(GORDON_REG_AVCTL, 0x03);
mdelay(15);
serigo(GORDON_REG_POWCTL, 0x1F);
mdelay(15);
serigo(GORDON_REG_POWCTL, 0x5F);
mdelay(15);
serigo(GORDON_REG_POWCTL, 0x7F);
mdelay(15);
serigo(GORDON_REG_LCDIFCTL1, 0x02);
mdelay(15);
serigo(GORDON_REG_IMGCTL1, 0x00);
mdelay(15);
serigo(GORDON_REG_LCDIFCTL3, 0x00);
mdelay(15);
serigo(GORDON_REG_VALTRAN, 0x01);
mdelay(15);
serigo(GORDON_REG_LCDIFCTL1, 0x03);
mdelay(1);
gordon_state.display_on = TRUE;
}
}
static int lcdc_gordon_panel_on(struct platform_device *pdev)
{
if (!gordon_state.disp_initialized) {
/* Configure reset GPIO that drives DAC */
lcdc_gordon_pdata->panel_config_gpio(1);
spi_dac = *(lcdc_gordon_pdata->gpio_num + 4);
gpio_set_value(spi_dac, 0);
udelay(15);
gpio_set_value(spi_dac, 1);
spi_init(); /* LCD needs SPI */
gordon_disp_powerup();
gordon_disp_on();
gordon_state.disp_initialized = TRUE;
}
return 0;
}
static int lcdc_gordon_panel_off(struct platform_device *pdev)
{
if (gordon_state.disp_powered_up && gordon_state.display_on) {
serigo(GORDON_REG_LCDIFCTL2, 0x7B);
serigo(GORDON_REG_VALTRAN, 0x01);
serigo(GORDON_REG_LCDIFCTL1, 0x02);
serigo(GORDON_REG_LCDIFCTL3, 0x01);
mdelay(20);
serigo(GORDON_REG_VALTRAN, 0x01);
serigo(GORDON_REG_IMGCTL1, 0x01);
serigo(GORDON_REG_LCDIFCTL1, 0x00);
mdelay(20);
serigo(GORDON_REG_POWCTL, 0x1F);
mdelay(40);
serigo(GORDON_REG_POWCTL, 0x07);
mdelay(40);
serigo(GORDON_REG_POWCTL, 0x03);
mdelay(40);
serigo(GORDON_REG_POWCTL, 0x00);
mdelay(40);
lcdc_gordon_pdata->panel_config_gpio(0);
gordon_state.display_on = FALSE;
gordon_state.disp_initialized = FALSE;
}
return 0;
}
static void lcdc_gordon_set_backlight(struct msm_fb_data_type *mfd)
{
int bl_level = mfd->bl_level;
if (bl_level <= 1) {
/* keep back light OFF */
serigo(GORDON_REG_LCDIFCTL2, 0x0B);
udelay(15);
serigo(GORDON_REG_VALTRAN, 0x01);
} else {
/* keep back light ON */
serigo(GORDON_REG_LCDIFCTL2, 0x7B);
udelay(15);
serigo(GORDON_REG_VALTRAN, 0x01);
}
}
static int __init gordon_probe(struct platform_device *pdev)
{
if (pdev->id == 0) {
lcdc_gordon_pdata = pdev->dev.platform_data;
return 0;
}
msm_fb_add_device(pdev);
return 0;
}
static struct platform_driver this_driver = {
.probe = gordon_probe,
.driver = {
.name = "lcdc_gordon_vga",
},
};
static struct msm_fb_panel_data gordon_panel_data = {
.on = lcdc_gordon_panel_on,
.off = lcdc_gordon_panel_off,
.set_backlight = lcdc_gordon_set_backlight,
};
static struct platform_device this_device = {
.name = "lcdc_gordon_vga",
.id = 1,
.dev = {
.platform_data = &gordon_panel_data,
}
};
static int __init lcdc_gordon_panel_init(void)
{
int ret;
struct msm_panel_info *pinfo;
#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
if (msm_fb_detect_client("lcdc_gordon_vga"))
return 0;
#endif
ret = platform_driver_register(&this_driver);
if (ret)
return ret;
pinfo = &gordon_panel_data.panel_info;
pinfo->xres = 480;
pinfo->yres = 640;
pinfo->type = LCDC_PANEL;
pinfo->pdest = DISPLAY_1;
pinfo->wait_cycle = 0;
pinfo->bpp = 24;
pinfo->fb_num = 2;
pinfo->clk_rate = 24500000;
pinfo->bl_max = 4;
pinfo->bl_min = 1;
pinfo->lcdc.h_back_porch = 84;
pinfo->lcdc.h_front_porch = 33;
pinfo->lcdc.h_pulse_width = 60;
pinfo->lcdc.v_back_porch = 0;
pinfo->lcdc.v_front_porch = 2;
pinfo->lcdc.v_pulse_width = 2;
pinfo->lcdc.border_clr = 0; /* blk */
pinfo->lcdc.underflow_clr = 0xff; /* blue */
pinfo->lcdc.hsync_skew = 0;
ret = platform_device_register(&this_device);
if (ret)
platform_driver_unregister(&this_driver);
return ret;
}
module_init(lcdc_gordon_panel_init);

View file

@ -1,88 +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 "msm_fb.h"
static int lcdc_panel_on(struct platform_device *pdev)
{
return 0;
}
static int lcdc_panel_off(struct platform_device *pdev)
{
return 0;
}
static int __init lcdc_panel_probe(struct platform_device *pdev)
{
msm_fb_add_device(pdev);
return 0;
}
static struct platform_driver this_driver = {
.probe = lcdc_panel_probe,
.driver = {
.name = "lcdc_panel",
},
};
static struct msm_fb_panel_data lcdc_panel_data = {
.on = lcdc_panel_on,
.off = lcdc_panel_off,
};
static int lcdc_dev_id;
int lcdc_device_register(struct msm_panel_info *pinfo)
{
struct platform_device *pdev = NULL;
int ret;
pdev = platform_device_alloc("lcdc_panel", ++lcdc_dev_id);
if (!pdev)
return -ENOMEM;
lcdc_panel_data.panel_info = *pinfo;
ret = platform_device_add_data(pdev, &lcdc_panel_data,
sizeof(lcdc_panel_data));
if (ret) {
printk(KERN_ERR
"%s: platform_device_add_data failed!\n", __func__);
goto err_device_put;
}
ret = platform_device_add(pdev);
if (ret) {
printk(KERN_ERR
"%s: platform_device_register failed!\n", __func__);
goto err_device_put;
}
return 0;
err_device_put:
platform_device_put(pdev);
return ret;
}
static int __init lcdc_panel_init(void)
{
return platform_driver_register(&this_driver);
}
module_init(lcdc_panel_init);

View file

@ -1,64 +0,0 @@
/* Copyright (c) 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 "msm_fb.h"
#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
#include "mddihosti.h"
#endif
static int __init lcdc_prism_init(void)
{
int ret;
struct msm_panel_info pinfo;
#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
ret = msm_fb_detect_client("lcdc_prism_wvga");
if (ret == -ENODEV)
return 0;
if (ret && (mddi_get_client_id() != 0))
return 0;
#endif
pinfo.xres = 800;
pinfo.yres = 480;
pinfo.type = LCDC_PANEL;
pinfo.pdest = DISPLAY_1;
pinfo.wait_cycle = 0;
pinfo.bpp = 24;
pinfo.fb_num = 2;
pinfo.clk_rate = 38460000;
pinfo.lcdc.h_back_porch = 21;
pinfo.lcdc.h_front_porch = 81;
pinfo.lcdc.h_pulse_width = 60;
pinfo.lcdc.v_back_porch = 18;
pinfo.lcdc.v_front_porch = 27;
pinfo.lcdc.v_pulse_width = 2;
pinfo.lcdc.border_clr = 0; /* blk */
pinfo.lcdc.underflow_clr = 0xff; /* blue */
pinfo.lcdc.hsync_skew = 0;
ret = lcdc_device_register(&pinfo);
if (ret)
printk(KERN_ERR "%s: failed to register device!\n", __func__);
return ret;
}
module_init(lcdc_prism_init);

View file

@ -1,290 +0,0 @@
/* Copyright (c) 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/delay.h>
#ifdef CONFIG_ARCH_MSM7X30
#include <linux/mfd/pmic8058.h>
#endif
#include <mach/gpio.h>
#include "msm_fb.h"
static int lcdc_sharp_panel_off(struct platform_device *pdev);
static int spi_cs;
static int spi_sclk;
static int spi_mosi;
static int spi_miso;
static unsigned char bit_shift[8] = { (1 << 7), /* MSB */
(1 << 6),
(1 << 5),
(1 << 4),
(1 << 3),
(1 << 2),
(1 << 1),
(1 << 0) /* LSB */
};
struct sharp_state_type {
boolean disp_initialized;
boolean display_on;
boolean disp_powered_up;
};
struct sharp_spi_data {
u8 addr;
u8 data;
};
static struct sharp_spi_data init_sequence[] = {
{ 15, 0x01 },
{ 5, 0x01 },
{ 7, 0x10 },
{ 9, 0x1E },
{ 10, 0x04 },
{ 17, 0xFF },
{ 21, 0x8A },
{ 22, 0x00 },
{ 23, 0x82 },
{ 24, 0x24 },
{ 25, 0x22 },
{ 26, 0x6D },
{ 27, 0xEB },
{ 28, 0xB9 },
{ 29, 0x3A },
{ 49, 0x1A },
{ 50, 0x16 },
{ 51, 0x05 },
{ 55, 0x7F },
{ 56, 0x15 },
{ 57, 0x7B },
{ 60, 0x05 },
{ 61, 0x0C },
{ 62, 0x80 },
{ 63, 0x00 },
{ 92, 0x90 },
{ 97, 0x01 },
{ 98, 0xFF },
{ 113, 0x11 },
{ 114, 0x02 },
{ 115, 0x08 },
{ 123, 0xAB },
{ 124, 0x04 },
{ 6, 0x02 },
{ 133, 0x00 },
{ 134, 0xFE },
{ 135, 0x22 },
{ 136, 0x0B },
{ 137, 0xFF },
{ 138, 0x0F },
{ 139, 0x00 },
{ 140, 0xFE },
{ 141, 0x22 },
{ 142, 0x0B },
{ 143, 0xFF },
{ 144, 0x0F },
{ 145, 0x00 },
{ 146, 0xFE },
{ 147, 0x22 },
{ 148, 0x0B },
{ 149, 0xFF },
{ 150, 0x0F },
{ 202, 0x30 },
{ 30, 0x01 },
{ 4, 0x01 },
{ 31, 0x41 },
};
static struct sharp_state_type sharp_state = { 0 };
static struct msm_panel_common_pdata *lcdc_sharp_pdata;
static void sharp_spi_write_byte(u8 val)
{
int i;
/* Clock should be Low before entering */
for (i = 0; i < 8; i++) {
/* #1: Drive the Data (High or Low) */
if (val & bit_shift[i])
gpio_set_value(spi_mosi, 1);
else
gpio_set_value(spi_mosi, 0);
/* #2: Drive the Clk High and then Low */
gpio_set_value(spi_sclk, 1);
gpio_set_value(spi_sclk, 0);
}
}
static void serigo(u8 reg, u8 data)
{
/* Enable the Chip Select - low */
gpio_set_value(spi_cs, 0);
udelay(1);
/* Transmit register address first, then data */
sharp_spi_write_byte(reg);
/* Idle state of MOSI is Low */
gpio_set_value(spi_mosi, 0);
udelay(1);
sharp_spi_write_byte(data);
gpio_set_value(spi_mosi, 0);
gpio_set_value(spi_cs, 1);
}
static void sharp_spi_init(void)
{
spi_sclk = *(lcdc_sharp_pdata->gpio_num);
spi_cs = *(lcdc_sharp_pdata->gpio_num + 1);
spi_mosi = *(lcdc_sharp_pdata->gpio_num + 2);
spi_miso = *(lcdc_sharp_pdata->gpio_num + 3);
/* Set the output so that we don't disturb the slave device */
gpio_set_value(spi_sclk, 0);
gpio_set_value(spi_mosi, 0);
/* Set the Chip Select deasserted (active low) */
gpio_set_value(spi_cs, 1);
}
static void sharp_disp_powerup(void)
{
if (!sharp_state.disp_powered_up && !sharp_state.display_on)
sharp_state.disp_powered_up = TRUE;
}
static void sharp_disp_on(void)
{
int i;
if (sharp_state.disp_powered_up && !sharp_state.display_on) {
for (i = 0; i < ARRAY_SIZE(init_sequence); i++) {
serigo(init_sequence[i].addr,
init_sequence[i].data);
}
mdelay(10);
serigo(31, 0xC1);
mdelay(10);
serigo(31, 0xD9);
serigo(31, 0xDF);
sharp_state.display_on = TRUE;
}
}
static int lcdc_sharp_panel_on(struct platform_device *pdev)
{
if (!sharp_state.disp_initialized) {
lcdc_sharp_pdata->panel_config_gpio(1);
sharp_spi_init();
sharp_disp_powerup();
sharp_disp_on();
sharp_state.disp_initialized = TRUE;
}
return 0;
}
static int lcdc_sharp_panel_off(struct platform_device *pdev)
{
if (sharp_state.disp_powered_up && sharp_state.display_on) {
serigo(4, 0x00);
mdelay(40);
serigo(31, 0xC1);
mdelay(40);
serigo(31, 0x00);
mdelay(100);
sharp_state.display_on = FALSE;
sharp_state.disp_initialized = FALSE;
}
return 0;
}
static int __init sharp_probe(struct platform_device *pdev)
{
if (pdev->id == 0) {
lcdc_sharp_pdata = pdev->dev.platform_data;
return 0;
}
msm_fb_add_device(pdev);
return 0;
}
static struct platform_driver this_driver = {
.probe = sharp_probe,
.driver = {
.name = "lcdc_sharp_wvga",
},
};
static struct msm_fb_panel_data sharp_panel_data = {
.on = lcdc_sharp_panel_on,
.off = lcdc_sharp_panel_off,
};
static struct platform_device this_device = {
.name = "lcdc_sharp_wvga",
.id = 1,
.dev = {
.platform_data = &sharp_panel_data,
}
};
static int __init lcdc_sharp_panel_init(void)
{
int ret;
struct msm_panel_info *pinfo;
#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
if (msm_fb_detect_client("lcdc_sharp_wvga_pt"))
return 0;
#endif
ret = platform_driver_register(&this_driver);
if (ret)
return ret;
pinfo = &sharp_panel_data.panel_info;
pinfo->xres = 480;
pinfo->yres = 800;
pinfo->type = LCDC_PANEL;
pinfo->pdest = DISPLAY_1;
pinfo->wait_cycle = 0;
pinfo->bpp = 18;
pinfo->fb_num = 2;
pinfo->clk_rate = 24500000;
pinfo->bl_max = 4;
pinfo->bl_min = 1;
pinfo->lcdc.h_back_porch = 20;
pinfo->lcdc.h_front_porch = 10;
pinfo->lcdc.h_pulse_width = 10;
pinfo->lcdc.v_back_porch = 2;
pinfo->lcdc.v_front_porch = 2;
pinfo->lcdc.v_pulse_width = 2;
pinfo->lcdc.border_clr = 0;
pinfo->lcdc.underflow_clr = 0xff;
pinfo->lcdc.hsync_skew = 0;
ret = platform_device_register(&this_device);
if (ret)
platform_driver_unregister(&this_driver);
return ret;
}
module_init(lcdc_sharp_panel_init);

View file

@ -1,237 +0,0 @@
/* Copyright (c) 2010, 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/i2c.h>
#include <linux/delay.h>
#include "msm_fb.h"
#define DEVICE_NAME "sii9022"
#define SII9022_DEVICE_ID 0xB0
struct sii9022_i2c_addr_data{
u8 addr;
u8 data;
};
/* video mode data */
static u8 video_mode_data[] = {
0x00,
0xF9, 0x1C, 0x70, 0x17, 0x72, 0x06, 0xEE, 0x02,
};
static u8 avi_io_format[] = {
0x09,
0x00, 0x00,
};
/* power state */
static struct sii9022_i2c_addr_data regset0[] = {
{ 0x60, 0x04 },
{ 0x63, 0x00 },
{ 0x1E, 0x00 },
};
static u8 video_infoframe[] = {
0x0C,
0xF0, 0x00, 0x68, 0x00, 0x04, 0x00, 0x19, 0x00,
0xE9, 0x02, 0x04, 0x01, 0x04, 0x06,
};
/* configure audio */
static struct sii9022_i2c_addr_data regset1[] = {
{ 0x26, 0x90 },
{ 0x20, 0x90 },
{ 0x1F, 0x80 },
{ 0x26, 0x80 },
{ 0x24, 0x02 },
{ 0x25, 0x0B },
{ 0xBC, 0x02 },
{ 0xBD, 0x24 },
{ 0xBE, 0x02 },
};
/* enable audio */
static u8 misc_infoframe[] = {
0xBF,
0xC2, 0x84, 0x01, 0x0A, 0x6F, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
/* set HDMI, active */
static struct sii9022_i2c_addr_data regset2[] = {
{ 0x1A, 0x01 },
{ 0x3D, 0x00 },
};
static int send_i2c_data(struct i2c_client *client,
struct sii9022_i2c_addr_data *regset,
int size)
{
int i;
int rc = 0;
for (i = 0; i < size; i++) {
rc = i2c_smbus_write_byte_data(
client,
regset[i].addr, regset[i].data);
if (rc)
break;
}
return rc;
}
static int hdmi_sii_enable(struct i2c_client *client)
{
int rc;
int retries = 10;
int count;
rc = i2c_smbus_write_byte_data(client, 0xC7, 0x00);
if (rc)
goto enable_exit;
do {
msleep(1);
rc = i2c_smbus_read_byte_data(client, 0x1B);
} while ((rc != SII9022_DEVICE_ID) && retries--);
if (rc != SII9022_DEVICE_ID)
return -ENODEV;
rc = i2c_smbus_write_byte_data(client, 0x1A, 0x11);
if (rc)
goto enable_exit;
count = ARRAY_SIZE(video_mode_data);
rc = i2c_master_send(client, video_mode_data, count);
if (rc != count) {
rc = -EIO;
goto enable_exit;
}
rc = i2c_smbus_write_byte_data(client, 0x08, 0x20);
if (rc)
goto enable_exit;
count = ARRAY_SIZE(avi_io_format);
rc = i2c_master_send(client, avi_io_format, count);
if (rc != count) {
rc = -EIO;
goto enable_exit;
}
rc = send_i2c_data(client, regset0, ARRAY_SIZE(regset0));
if (rc)
goto enable_exit;
count = ARRAY_SIZE(video_infoframe);
rc = i2c_master_send(client, video_infoframe, count);
if (rc != count) {
rc = -EIO;
goto enable_exit;
}
rc = send_i2c_data(client, regset1, ARRAY_SIZE(regset1));
if (rc)
goto enable_exit;
count = ARRAY_SIZE(misc_infoframe);
rc = i2c_master_send(client, misc_infoframe, count);
if (rc != count) {
rc = -EIO;
goto enable_exit;
}
rc = send_i2c_data(client, regset2, ARRAY_SIZE(regset2));
if (rc)
goto enable_exit;
return 0;
enable_exit:
printk(KERN_ERR "%s: exited rc=%d\n", __func__, rc);
return rc;
}
static const struct i2c_device_id hmdi_sii_id[] = {
{ DEVICE_NAME, 0 },
{ }
};
static int hdmi_sii_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int rc;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C))
return -ENODEV;
rc = hdmi_sii_enable(client);
return rc;
}
static struct i2c_driver hdmi_sii_i2c_driver = {
.driver = {
.name = DEVICE_NAME,
.owner = THIS_MODULE,
},
.probe = hdmi_sii_probe,
.remove = __exit_p(hdmi_sii_remove),
.id_table = hmdi_sii_id,
};
static int __init lcdc_st15_init(void)
{
int ret;
struct msm_panel_info pinfo;
if (msm_fb_detect_client("lcdc_st15"))
return 0;
pinfo.xres = 1366;
pinfo.yres = 768;
pinfo.type = LCDC_PANEL;
pinfo.pdest = DISPLAY_1;
pinfo.wait_cycle = 0;
pinfo.bpp = 24;
pinfo.fb_num = 2;
pinfo.clk_rate = 74250000;
pinfo.lcdc.h_back_porch = 120;
pinfo.lcdc.h_front_porch = 20;
pinfo.lcdc.h_pulse_width = 40;
pinfo.lcdc.v_back_porch = 25;
pinfo.lcdc.v_front_porch = 1;
pinfo.lcdc.v_pulse_width = 7;
pinfo.lcdc.border_clr = 0; /* blk */
pinfo.lcdc.underflow_clr = 0xff; /* blue */
pinfo.lcdc.hsync_skew = 0;
ret = lcdc_device_register(&pinfo);
if (ret) {
printk(KERN_ERR "%s: failed to register device!\n", __func__);
goto init_exit;
}
ret = i2c_add_driver(&hdmi_sii_i2c_driver);
if (ret)
printk(KERN_ERR "%s: failed to add i2c driver\n", __func__);
init_exit:
return ret;
}
module_init(lcdc_st15_init);

View file

@ -1,374 +0,0 @@
/* Copyright (c) 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/delay.h>
#include <linux/module.h>
#include <mach/gpio.h>
#include <mach/pmic.h>
#include "msm_fb.h"
#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
#include "mddihosti.h"
#endif
static int spi_cs;
static int spi_sclk;
static int spi_mosi;
static int spi_miso;
struct toshiba_state_type{
boolean disp_initialized;
boolean display_on;
boolean disp_powered_up;
};
static struct toshiba_state_type toshiba_state = { 0 };
static struct msm_panel_common_pdata *lcdc_toshiba_pdata;
static void toshiba_spi_write_byte(char dc, uint8 data)
{
uint32 bit;
int bnum;
gpio_set_value(spi_sclk, 0); /* clk low */
/* dc: 0 for command, 1 for parameter */
gpio_set_value(spi_mosi, dc);
udelay(1); /* at least 20 ns */
gpio_set_value(spi_sclk, 1); /* clk high */
udelay(1); /* at least 20 ns */
bnum = 8; /* 8 data bits */
bit = 0x80;
while (bnum) {
gpio_set_value(spi_sclk, 0); /* clk low */
if (data & bit)
gpio_set_value(spi_mosi, 1);
else
gpio_set_value(spi_mosi, 0);
udelay(1);
gpio_set_value(spi_sclk, 1); /* clk high */
udelay(1);
bit >>= 1;
bnum--;
}
}
static void toshiba_spi_write(char cmd, uint32 data, int num)
{
char *bp;
gpio_set_value(spi_cs, 1); /* cs high */
/* command byte first */
toshiba_spi_write_byte(0, cmd);
/* followed by parameter bytes */
if (num) {
bp = (char *)&data;
bp += (num - 1);
while (num) {
toshiba_spi_write_byte(1, *bp);
num--;
bp--;
}
}
gpio_set_value(spi_cs, 0); /* cs low */
udelay(1);
}
void toshiba_spi_read_bytes(char cmd, uint32 *data, int num)
{
uint32 dbit, bits;
int bnum;
gpio_set_value(spi_cs, 1); /* cs high */
/* command byte first */
toshiba_spi_write_byte(0, cmd);
if (num > 1) {
/* extra dc bit */
gpio_set_value(spi_sclk, 0); /* clk low */
udelay(1);
dbit = gpio_get_value(spi_miso);/* dc bit */
udelay(1);
gpio_set_value(spi_sclk, 1); /* clk high */
}
/* followed by data bytes */
bnum = num * 8; /* number of bits */
bits = 0;
while (bnum) {
bits <<= 1;
gpio_set_value(spi_sclk, 0); /* clk low */
udelay(1);
dbit = gpio_get_value(spi_miso);
udelay(1);
gpio_set_value(spi_sclk, 1); /* clk high */
bits |= dbit;
bnum--;
}
*data = bits;
udelay(1);
gpio_set_value(spi_cs, 0); /* cs low */
udelay(1);
}
static void spi_pin_assign(void)
{
/* Setting the Default GPIO's */
spi_sclk = *(lcdc_toshiba_pdata->gpio_num);
spi_cs = *(lcdc_toshiba_pdata->gpio_num + 1);
spi_mosi = *(lcdc_toshiba_pdata->gpio_num + 2);
spi_miso = *(lcdc_toshiba_pdata->gpio_num + 3);
}
static void toshiba_disp_powerup(void)
{
if (!toshiba_state.disp_powered_up && !toshiba_state.display_on) {
/* Reset the hardware first */
/* Include DAC power up implementation here */
toshiba_state.disp_powered_up = TRUE;
}
}
static void toshiba_disp_on(void)
{
uint32 data;
gpio_set_value(spi_cs, 0); /* low */
gpio_set_value(spi_sclk, 1); /* high */
gpio_set_value(spi_mosi, 0);
gpio_set_value(spi_miso, 0);
if (toshiba_state.disp_powered_up && !toshiba_state.display_on) {
toshiba_spi_write(0, 0, 0);
mdelay(7);
toshiba_spi_write(0, 0, 0);
mdelay(7);
toshiba_spi_write(0, 0, 0);
mdelay(7);
toshiba_spi_write(0xba, 0x11, 1);
toshiba_spi_write(0x36, 0x00, 1);
mdelay(1);
toshiba_spi_write(0x3a, 0x60, 1);
toshiba_spi_write(0xb1, 0x5d, 1);
mdelay(1);
toshiba_spi_write(0xb2, 0x33, 1);
toshiba_spi_write(0xb3, 0x22, 1);
mdelay(1);
toshiba_spi_write(0xb4, 0x02, 1);
toshiba_spi_write(0xb5, 0x1e, 1); /* vcs -- adjust brightness */
mdelay(1);
toshiba_spi_write(0xb6, 0x27, 1);
toshiba_spi_write(0xb7, 0x03, 1);
mdelay(1);
toshiba_spi_write(0xb9, 0x24, 1);
toshiba_spi_write(0xbd, 0xa1, 1);
mdelay(1);
toshiba_spi_write(0xbb, 0x00, 1);
toshiba_spi_write(0xbf, 0x01, 1);
mdelay(1);
toshiba_spi_write(0xbe, 0x00, 1);
toshiba_spi_write(0xc0, 0x11, 1);
mdelay(1);
toshiba_spi_write(0xc1, 0x11, 1);
toshiba_spi_write(0xc2, 0x11, 1);
mdelay(1);
toshiba_spi_write(0xc3, 0x3232, 2);
mdelay(1);
toshiba_spi_write(0xc4, 0x3232, 2);
mdelay(1);
toshiba_spi_write(0xc5, 0x3232, 2);
mdelay(1);
toshiba_spi_write(0xc6, 0x3232, 2);
mdelay(1);
toshiba_spi_write(0xc7, 0x6445, 2);
mdelay(1);
toshiba_spi_write(0xc8, 0x44, 1);
toshiba_spi_write(0xc9, 0x52, 1);
mdelay(1);
toshiba_spi_write(0xca, 0x00, 1);
mdelay(1);
toshiba_spi_write(0xec, 0x02a4, 2); /* 0x02a4 */
mdelay(1);
toshiba_spi_write(0xcf, 0x01, 1);
mdelay(1);
toshiba_spi_write(0xd0, 0xc003, 2); /* c003 */
mdelay(1);
toshiba_spi_write(0xd1, 0x01, 1);
mdelay(1);
toshiba_spi_write(0xd2, 0x0028, 2);
mdelay(1);
toshiba_spi_write(0xd3, 0x0028, 2);
mdelay(1);
toshiba_spi_write(0xd4, 0x26a4, 2);
mdelay(1);
toshiba_spi_write(0xd5, 0x20, 1);
mdelay(1);
toshiba_spi_write(0xef, 0x3200, 2);
mdelay(32);
toshiba_spi_write(0xbc, 0x80, 1); /* wvga pass through */
toshiba_spi_write(0x3b, 0x00, 1);
mdelay(1);
toshiba_spi_write(0xb0, 0x16, 1);
mdelay(1);
toshiba_spi_write(0xb8, 0xfff5, 2);
mdelay(1);
toshiba_spi_write(0x11, 0, 0);
mdelay(5);
toshiba_spi_write(0x29, 0, 0);
mdelay(5);
toshiba_state.display_on = TRUE;
}
data = 0;
toshiba_spi_read_bytes(0x04, &data, 3);
printk(KERN_INFO "toshiba_disp_on: id=%x\n", data);
}
static int lcdc_toshiba_panel_on(struct platform_device *pdev)
{
if (!toshiba_state.disp_initialized) {
/* Configure reset GPIO that drives DAC */
if (lcdc_toshiba_pdata->panel_config_gpio)
lcdc_toshiba_pdata->panel_config_gpio(1);
toshiba_disp_powerup();
toshiba_disp_on();
toshiba_state.disp_initialized = TRUE;
}
return 0;
}
static int lcdc_toshiba_panel_off(struct platform_device *pdev)
{
if (toshiba_state.disp_powered_up && toshiba_state.display_on) {
/* Main panel power off (Deep standby in) */
toshiba_spi_write(0x28, 0, 0); /* display off */
mdelay(1);
toshiba_spi_write(0xb8, 0x8002, 2); /* output control */
mdelay(1);
toshiba_spi_write(0x10, 0x00, 1); /* sleep mode in */
mdelay(85); /* wait 85 msec */
toshiba_spi_write(0xb0, 0x00, 1); /* deep standby in */
mdelay(1);
if (lcdc_toshiba_pdata->panel_config_gpio)
lcdc_toshiba_pdata->panel_config_gpio(0);
toshiba_state.display_on = FALSE;
toshiba_state.disp_initialized = FALSE;
}
return 0;
}
static void lcdc_toshiba_set_backlight(struct msm_fb_data_type *mfd)
{
int bl_level;
int ret = -EPERM;
bl_level = mfd->bl_level;
ret = pmic_set_led_intensity(LED_LCD, bl_level);
if (ret)
printk(KERN_WARNING "%s: can't set lcd backlight!\n",
__func__);
}
static int __init toshiba_probe(struct platform_device *pdev)
{
if (pdev->id == 0) {
lcdc_toshiba_pdata = pdev->dev.platform_data;
spi_pin_assign();
return 0;
}
msm_fb_add_device(pdev);
return 0;
}
static struct platform_driver this_driver = {
.probe = toshiba_probe,
.driver = {
.name = "lcdc_toshiba_wvga",
},
};
static struct msm_fb_panel_data toshiba_panel_data = {
.on = lcdc_toshiba_panel_on,
.off = lcdc_toshiba_panel_off,
.set_backlight = lcdc_toshiba_set_backlight,
};
static struct platform_device this_device = {
.name = "lcdc_toshiba_wvga",
.id = 1,
.dev = {
.platform_data = &toshiba_panel_data,
}
};
static int __init lcdc_toshiba_panel_init(void)
{
int ret;
struct msm_panel_info *pinfo;
#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
if (mddi_get_client_id() != 0)
return 0;
ret = msm_fb_detect_client("lcdc_toshiba_wvga_pt");
if (ret)
return 0;
#endif
ret = platform_driver_register(&this_driver);
if (ret)
return ret;
pinfo = &toshiba_panel_data.panel_info;
pinfo->xres = 480;
pinfo->yres = 800;
pinfo->type = LCDC_PANEL;
pinfo->pdest = DISPLAY_1;
pinfo->wait_cycle = 0;
pinfo->bpp = 18;
pinfo->fb_num = 2;
/* 30Mhz mdp_lcdc_pclk and mdp_lcdc_pad_pcl */
pinfo->clk_rate = 27648000;
pinfo->bl_max = 15;
pinfo->bl_min = 1;
pinfo->lcdc.h_back_porch = 184; /* hsw = 8 + hbp=184 */
pinfo->lcdc.h_front_porch = 4;
pinfo->lcdc.h_pulse_width = 8;
pinfo->lcdc.v_back_porch = 2; /* vsw=1 + vbp = 2 */
pinfo->lcdc.v_front_porch = 3;
pinfo->lcdc.v_pulse_width = 1;
pinfo->lcdc.border_clr = 0; /* blk */
pinfo->lcdc.underflow_clr = 0xff; /* blue */
pinfo->lcdc.hsync_skew = 0;
ret = platform_device_register(&this_device);
if (ret)
platform_driver_unregister(&this_driver);
return ret;
}
device_initcall(lcdc_toshiba_panel_init);

View file

@ -1,98 +0,0 @@
/* drivers/video/msm/logo.c
*
* Show Logo in RLE 565 format
*
* Copyright (C) 2008 Google Incorporated
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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.
*
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fb.h>
#include <linux/vt_kern.h>
#include <linux/unistd.h>
#include <linux/syscalls.h>
#include <linux/irq.h>
#include <asm/system.h>
#define fb_width(fb) ((fb)->var.xres)
#define fb_height(fb) ((fb)->var.yres)
#define fb_size(fb) ((fb)->var.xres * (fb)->var.yres * 2)
static void memset16(void *_ptr, unsigned short val, unsigned count)
{
unsigned short *ptr = _ptr;
count >>= 1;
while (count--)
*ptr++ = val;
}
/* 565RLE image format: [count(2 bytes), rle(2 bytes)] */
int load_565rle_image(char *filename)
{
struct fb_info *info;
int fd, err = 0;
unsigned count, max;
unsigned short *data, *bits, *ptr;
info = registered_fb[0];
if (!info) {
printk(KERN_WARNING "%s: Can not access framebuffer\n",
__func__);
return -ENODEV;
}
fd = sys_open(filename, O_RDONLY, 0);
if (fd < 0) {
printk(KERN_WARNING "%s: Can not open %s\n",
__func__, filename);
return -ENOENT;
}
count = (unsigned)sys_lseek(fd, (off_t)0, 2);
if (count == 0) {
sys_close(fd);
err = -EIO;
goto err_logo_close_file;
}
sys_lseek(fd, (off_t)0, 0);
data = kmalloc(count, GFP_KERNEL);
if (!data) {
printk(KERN_WARNING "%s: Can not alloc data\n", __func__);
err = -ENOMEM;
goto err_logo_close_file;
}
if ((unsigned)sys_read(fd, (char *)data, count) != count) {
err = -EIO;
goto err_logo_free_data;
}
max = fb_width(info) * fb_height(info);
ptr = data;
bits = (unsigned short *)(info->screen_base);
while (count > 3) {
unsigned n = ptr[0];
if (n > max)
break;
memset16(bits, ptr[1], n << 1);
bits += n;
max -= n;
ptr += 2;
count -= 4;
}
err_logo_free_data:
kfree(data);
err_logo_close_file:
sys_close(fd);
return err;
}
EXPORT_SYMBOL(load_565rle_image);

View file

@ -1,375 +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/delay.h>
#include <mach/hardware.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/mach-types.h>
#include <linux/semaphore.h>
#include <linux/uaccess.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include "msm_fb.h"
#include "mddihosti.h"
#include "mddihost.h"
#include <mach/gpio.h>
#include <mach/clk.h>
static int mddi_probe(struct platform_device *pdev);
static int mddi_remove(struct platform_device *pdev);
static int mddi_off(struct platform_device *pdev);
static int mddi_on(struct platform_device *pdev);
static int mddi_suspend(struct platform_device *pdev, pm_message_t state);
static int mddi_resume(struct platform_device *pdev);
#ifdef CONFIG_HAS_EARLYSUSPEND
static void mddi_early_suspend(struct early_suspend *h);
static void mddi_early_resume(struct early_suspend *h);
#endif
static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
static int pdev_list_cnt;
static struct clk *mddi_clk;
static struct clk *mddi_pclk;
static struct mddi_platform_data *mddi_pdata;
static struct platform_driver mddi_driver = {
.probe = mddi_probe,
.remove = mddi_remove,
#ifndef CONFIG_HAS_EARLYSUSPEND
#ifdef CONFIG_PM
.suspend = mddi_suspend,
.resume = mddi_resume,
#endif
#endif
.suspend_late = NULL,
.resume_early = NULL,
.shutdown = NULL,
.driver = {
.name = "mddi",
},
};
extern int int_mddi_pri_flag;
static int mddi_off(struct platform_device *pdev)
{
int ret = 0;
ret = panel_next_off(pdev);
if (mddi_pdata && mddi_pdata->mddi_power_save)
mddi_pdata->mddi_power_save(0);
return ret;
}
static int mddi_on(struct platform_device *pdev)
{
int ret = 0;
u32 clk_rate;
struct msm_fb_data_type *mfd;
mfd = platform_get_drvdata(pdev);
if (mddi_pdata && mddi_pdata->mddi_power_save)
mddi_pdata->mddi_power_save(1);
clk_rate = mfd->fbi->var.pixclock;
clk_rate = min(clk_rate, mfd->panel_info.clk_max);
if (mddi_pdata &&
mddi_pdata->mddi_sel_clk &&
mddi_pdata->mddi_sel_clk(&clk_rate))
printk(KERN_ERR
"%s: can't select mddi io clk targate rate = %d\n",
__func__, clk_rate);
if (clk_set_min_rate(mddi_clk, clk_rate) < 0)
printk(KERN_ERR "%s: clk_set_min_rate failed\n",
__func__);
ret = panel_next_on(pdev);
return ret;
}
static int mddi_resource_initialized;
static int mddi_probe(struct platform_device *pdev)
{
struct msm_fb_data_type *mfd;
struct platform_device *mdp_dev = NULL;
struct msm_fb_panel_data *pdata = NULL;
int rc;
resource_size_t size ;
u32 clk_rate;
if ((pdev->id == 0) && (pdev->num_resources >= 0)) {
mddi_pdata = pdev->dev.platform_data;
size = resource_size(&pdev->resource[0]);
msm_pmdh_base = ioremap(pdev->resource[0].start, size);
MSM_FB_INFO("primary mddi base phy_addr = 0x%x virt = 0x%x\n",
pdev->resource[0].start, (int) msm_pmdh_base);
if (unlikely(!msm_pmdh_base))
return -ENOMEM;
if (mddi_pdata && mddi_pdata->mddi_power_save)
mddi_pdata->mddi_power_save(1);
mddi_resource_initialized = 1;
return 0;
}
if (!mddi_resource_initialized)
return -EPERM;
mfd = platform_get_drvdata(pdev);
if (!mfd)
return -ENODEV;
if (mfd->key != MFD_KEY)
return -EINVAL;
if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
return -ENOMEM;
mdp_dev = platform_device_alloc("mdp", pdev->id);
if (!mdp_dev)
return -ENOMEM;
/*
* link to the latest pdev
*/
mfd->pdev = mdp_dev;
mfd->dest = DISPLAY_LCD;
/*
* alloc panel device data
*/
if (platform_device_add_data
(mdp_dev, pdev->dev.platform_data,
sizeof(struct msm_fb_panel_data))) {
printk(KERN_ERR "mddi_probe: platform_device_add_data failed!\n");
platform_device_put(mdp_dev);
return -ENOMEM;
}
/*
* data chain
*/
pdata = mdp_dev->dev.platform_data;
pdata->on = mddi_on;
pdata->off = mddi_off;
pdata->next = pdev;
/*
* get/set panel specific fb info
*/
mfd->panel_info = pdata->panel_info;
mfd->fb_imgType = MDP_RGB_565;
clk_rate = mfd->panel_info.clk_max;
if (mddi_pdata &&
mddi_pdata->mddi_sel_clk &&
mddi_pdata->mddi_sel_clk(&clk_rate))
printk(KERN_ERR
"%s: can't select mddi io clk targate rate = %d\n",
__func__, clk_rate);
if (clk_set_max_rate(mddi_clk, clk_rate) < 0)
printk(KERN_ERR "%s: clk_set_max_rate failed\n", __func__);
mfd->panel_info.clk_rate = mfd->panel_info.clk_min;
/*
* set driver data
*/
platform_set_drvdata(mdp_dev, mfd);
/*
* register in mdp driver
*/
rc = platform_device_add(mdp_dev);
if (rc)
goto mddi_probe_err;
pdev_list[pdev_list_cnt++] = pdev;
#ifdef CONFIG_HAS_EARLYSUSPEND
mfd->mddi_early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
mfd->mddi_early_suspend.suspend = mddi_early_suspend;
mfd->mddi_early_suspend.resume = mddi_early_resume;
register_early_suspend(&mfd->mddi_early_suspend);
#endif
return 0;
mddi_probe_err:
platform_device_put(mdp_dev);
return rc;
}
static int mddi_pad_ctrl;
static int mddi_power_locked;
static int mddi_is_in_suspend;
void mddi_disable(int lock)
{
mddi_host_type host_idx = MDDI_HOST_PRIM;
if (mddi_power_locked)
return;
if (lock)
mddi_power_locked = 1;
if (mddi_host_timer.function)
del_timer_sync(&mddi_host_timer);
mddi_pad_ctrl = mddi_host_reg_in(PAD_CTL);
mddi_host_reg_out(PAD_CTL, 0x0);
if (clk_set_min_rate(mddi_clk, 0) < 0)
printk(KERN_ERR "%s: clk_set_min_rate failed\n", __func__);
clk_disable(mddi_clk);
if (mddi_pclk)
clk_disable(mddi_pclk);
disable_irq(INT_MDDI_PRI);
if (mddi_pdata && mddi_pdata->mddi_power_save)
mddi_pdata->mddi_power_save(0);
}
static int mddi_suspend(struct platform_device *pdev, pm_message_t state)
{
if (mddi_is_in_suspend)
return 0;
mddi_is_in_suspend = 1;
mddi_disable(0);
return 0;
}
static int mddi_resume(struct platform_device *pdev)
{
mddi_host_type host_idx = MDDI_HOST_PRIM;
if (!mddi_is_in_suspend)
return 0;
mddi_is_in_suspend = 0;
if (mddi_power_locked)
return 0;
enable_irq(INT_MDDI_PRI);
clk_enable(mddi_clk);
if (mddi_pclk)
clk_enable(mddi_pclk);
mddi_host_reg_out(PAD_CTL, mddi_pad_ctrl);
if (mddi_host_timer.function)
mddi_host_timer_service(0);
return 0;
}
#ifdef CONFIG_HAS_EARLYSUSPEND
static void mddi_early_suspend(struct early_suspend *h)
{
pm_message_t state;
struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type,
mddi_early_suspend);
state.event = PM_EVENT_SUSPEND;
mddi_suspend(mfd->pdev, state);
}
static void mddi_early_resume(struct early_suspend *h)
{
struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type,
mddi_early_suspend);
mddi_resume(mfd->pdev);
}
#endif
static int mddi_remove(struct platform_device *pdev)
{
if (mddi_host_timer.function)
del_timer_sync(&mddi_host_timer);
iounmap(msm_pmdh_base);
return 0;
}
static int mddi_register_driver(void)
{
return platform_driver_register(&mddi_driver);
}
static int __init mddi_driver_init(void)
{
int ret;
mddi_clk = clk_get(NULL, "mddi_clk");
if (IS_ERR(mddi_clk)) {
printk(KERN_ERR "can't find mddi_clk \n");
return PTR_ERR(mddi_clk);
}
clk_enable(mddi_clk);
mddi_pclk = clk_get(NULL, "mddi_pclk");
if (IS_ERR(mddi_pclk))
mddi_pclk = NULL;
else
clk_enable(mddi_pclk);
ret = mddi_register_driver();
if (ret) {
clk_disable(mddi_clk);
clk_put(mddi_clk);
if (mddi_pclk) {
clk_disable(mddi_pclk);
clk_put(mddi_pclk);
}
printk(KERN_ERR "mddi_register_driver() failed!\n");
return ret;
}
mddi_init();
return ret;
}
module_init(mddi_driver_init);

View file

@ -1,320 +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/delay.h>
#include <mach/hardware.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/mach-types.h>
#include <linux/semaphore.h>
#include <linux/uaccess.h>
#include <linux/clk.h>
#include <mach/clk.h>
#include <linux/platform_device.h>
#include "msm_fb.h"
#include "mddihosti.h"
static int mddi_ext_probe(struct platform_device *pdev);
static int mddi_ext_remove(struct platform_device *pdev);
static int mddi_ext_off(struct platform_device *pdev);
static int mddi_ext_on(struct platform_device *pdev);
static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
static int pdev_list_cnt;
static int mddi_ext_suspend(struct platform_device *pdev, pm_message_t state);
static int mddi_ext_resume(struct platform_device *pdev);
#ifdef CONFIG_HAS_EARLYSUSPEND
static void mddi_ext_early_suspend(struct early_suspend *h);
static void mddi_ext_early_resume(struct early_suspend *h);
#endif
static struct platform_driver mddi_ext_driver = {
.probe = mddi_ext_probe,
.remove = mddi_ext_remove,
#ifndef CONFIG_HAS_EARLYSUSPEND
#ifdef CONFIG_PM
.suspend = mddi_ext_suspend,
.resume = mddi_ext_resume,
#endif
#endif
.resume_early = NULL,
.resume = NULL,
.shutdown = NULL,
.driver = {
.name = "mddi_ext",
},
};
static struct clk *mddi_ext_clk;
static struct mddi_platform_data *mddi_ext_pdata;
extern int int_mddi_ext_flag;
static int mddi_ext_off(struct platform_device *pdev)
{
int ret = 0;
ret = panel_next_off(pdev);
mddi_host_stop_ext_display();
return ret;
}
static int mddi_ext_on(struct platform_device *pdev)
{
int ret = 0;
u32 clk_rate;
struct msm_fb_data_type *mfd;
mfd = platform_get_drvdata(pdev);
clk_rate = mfd->fbi->var.pixclock;
clk_rate = min(clk_rate, mfd->panel_info.clk_max);
if (mddi_ext_pdata &&
mddi_ext_pdata->mddi_sel_clk &&
mddi_ext_pdata->mddi_sel_clk(&clk_rate))
printk(KERN_ERR
"%s: can't select mddi io clk targate rate = %d\n",
__func__, clk_rate);
if (clk_set_min_rate(mddi_ext_clk, clk_rate) < 0)
printk(KERN_ERR "%s: clk_set_min_rate failed\n",
__func__);
mddi_host_start_ext_display();
ret = panel_next_on(pdev);
return ret;
}
static int mddi_ext_resource_initialized;
static int mddi_ext_probe(struct platform_device *pdev)
{
struct msm_fb_data_type *mfd;
struct platform_device *mdp_dev = NULL;
struct msm_fb_panel_data *pdata = NULL;
int rc;
resource_size_t size ;
u32 clk_rate;
if ((pdev->id == 0) && (pdev->num_resources >= 0)) {
mddi_ext_pdata = pdev->dev.platform_data;
size = resource_size(&pdev->resource[0]);
msm_emdh_base = ioremap(pdev->resource[0].start, size);
MSM_FB_INFO("external mddi base address = 0x%x\n",
pdev->resource[0].start);
if (unlikely(!msm_emdh_base))
return -ENOMEM;
mddi_ext_resource_initialized = 1;
return 0;
}
if (!mddi_ext_resource_initialized)
return -EPERM;
mfd = platform_get_drvdata(pdev);
if (!mfd)
return -ENODEV;
if (mfd->key != MFD_KEY)
return -EINVAL;
if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
return -ENOMEM;
mdp_dev = platform_device_alloc("mdp", pdev->id);
if (!mdp_dev)
return -ENOMEM;
/*
* link to the latest pdev
*/
mfd->pdev = mdp_dev;
mfd->dest = DISPLAY_EXT_MDDI;
/*
* alloc panel device data
*/
if (platform_device_add_data
(mdp_dev, pdev->dev.platform_data,
sizeof(struct msm_fb_panel_data))) {
printk(KERN_ERR "mddi_ext_probe: platform_device_add_data failed!\n");
platform_device_put(mdp_dev);
return -ENOMEM;
}
/*
* data chain
*/
pdata = mdp_dev->dev.platform_data;
pdata->on = mddi_ext_on;
pdata->off = mddi_ext_off;
pdata->next = pdev;
/*
* get/set panel specific fb info
*/
mfd->panel_info = pdata->panel_info;
mfd->fb_imgType = MDP_RGB_565;
clk_rate = mfd->panel_info.clk_max;
if (mddi_ext_pdata &&
mddi_ext_pdata->mddi_sel_clk &&
mddi_ext_pdata->mddi_sel_clk(&clk_rate))
printk(KERN_ERR
"%s: can't select mddi io clk targate rate = %d\n",
__func__, clk_rate);
if (clk_set_max_rate(mddi_ext_clk, clk_rate) < 0)
printk(KERN_ERR "%s: clk_set_max_rate failed\n", __func__);
mfd->panel_info.clk_rate = mfd->panel_info.clk_min;
/*
* set driver data
*/
platform_set_drvdata(mdp_dev, mfd);
/*
* register in mdp driver
*/
rc = platform_device_add(mdp_dev);
if (rc)
goto mddi_ext_probe_err;
pdev_list[pdev_list_cnt++] = pdev;
#ifdef CONFIG_HAS_EARLYSUSPEND
mfd->mddi_ext_early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
mfd->mddi_ext_early_suspend.suspend = mddi_ext_early_suspend;
mfd->mddi_ext_early_suspend.resume = mddi_ext_early_resume;
register_early_suspend(&mfd->mddi_ext_early_suspend);
#endif
return 0;
mddi_ext_probe_err:
platform_device_put(mdp_dev);
return rc;
}
static int mddi_ext_is_in_suspend;
static int mddi_ext_suspend(struct platform_device *pdev, pm_message_t state)
{
if (mddi_ext_is_in_suspend)
return 0;
mddi_ext_is_in_suspend = 1;
if (clk_set_min_rate(mddi_ext_clk, 0) < 0)
printk(KERN_ERR "%s: clk_set_min_rate failed\n", __func__);
clk_disable(mddi_ext_clk);
disable_irq(INT_MDDI_EXT);
return 0;
}
static int mddi_ext_resume(struct platform_device *pdev)
{
struct msm_fb_data_type *mfd;
mfd = platform_get_drvdata(pdev);
if (!mddi_ext_is_in_suspend)
return 0;
mddi_ext_is_in_suspend = 0;
enable_irq(INT_MDDI_EXT);
clk_enable(mddi_ext_clk);
return 0;
}
#ifdef CONFIG_HAS_EARLYSUSPEND
static void mddi_ext_early_suspend(struct early_suspend *h)
{
pm_message_t state;
struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type,
mddi_ext_early_suspend);
state.event = PM_EVENT_SUSPEND;
mddi_ext_suspend(mfd->pdev, state);
}
static void mddi_ext_early_resume(struct early_suspend *h)
{
struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type,
mddi_ext_early_suspend);
mddi_ext_resume(mfd->pdev);
}
#endif
static int mddi_ext_remove(struct platform_device *pdev)
{
iounmap(msm_emdh_base);
return 0;
}
static int mddi_ext_register_driver(void)
{
return platform_driver_register(&mddi_ext_driver);
}
static int __init mddi_ext_driver_init(void)
{
int ret;
mddi_ext_clk = clk_get(NULL, "emdh_clk");
if (IS_ERR(mddi_ext_clk)) {
printk(KERN_ERR "can't find emdh_clk\n");
return PTR_ERR(mddi_ext_clk);
}
clk_enable(mddi_ext_clk);
ret = mddi_ext_register_driver();
if (ret) {
clk_disable(mddi_ext_clk);
clk_put(mddi_ext_clk);
printk(KERN_ERR "mddi_ext_register_driver() failed!\n");
return ret;
}
mddi_init();
return ret;
}
module_init(mddi_ext_driver_init);

View file

@ -1,91 +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 "msm_fb.h"
#include "mddihost.h"
#include "mddihosti.h"
static int mddi_ext_lcd_on(struct platform_device *pdev);
static int mddi_ext_lcd_off(struct platform_device *pdev);
static int mddi_ext_lcd_on(struct platform_device *pdev)
{
return 0;
}
static int mddi_ext_lcd_off(struct platform_device *pdev)
{
return 0;
}
static int __init mddi_ext_lcd_probe(struct platform_device *pdev)
{
msm_fb_add_device(pdev);
return 0;
}
static struct platform_driver this_driver = {
.probe = mddi_ext_lcd_probe,
.driver = {
.name = "extmddi_svga",
},
};
static struct msm_fb_panel_data mddi_ext_lcd_panel_data = {
.panel_info.xres = 800,
.panel_info.yres = 600,
.panel_info.type = EXT_MDDI_PANEL,
.panel_info.pdest = DISPLAY_1,
.panel_info.wait_cycle = 0,
.panel_info.bpp = 18,
.panel_info.fb_num = 2,
.panel_info.clk_rate = 122880000,
.panel_info.clk_min = 120000000,
.panel_info.clk_max = 125000000,
.on = mddi_ext_lcd_on,
.off = mddi_ext_lcd_off,
};
static struct platform_device this_device = {
.name = "extmddi_svga",
.id = 0,
.dev = {
.platform_data = &mddi_ext_lcd_panel_data,
}
};
static int __init mddi_ext_lcd_init(void)
{
int ret;
struct msm_panel_info *pinfo;
ret = platform_driver_register(&this_driver);
if (!ret) {
pinfo = &mddi_ext_lcd_panel_data.panel_info;
pinfo->lcd.vsync_enable = FALSE;
pinfo->mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR;
ret = platform_device_register(&this_device);
if (ret)
platform_driver_unregister(&this_driver);
}
return ret;
}
module_init(mddi_ext_lcd_init);

View file

@ -1,114 +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 "msm_fb.h"
#include "mddihost.h"
#include "mddihosti.h"
static int prism_lcd_on(struct platform_device *pdev);
static int prism_lcd_off(struct platform_device *pdev);
static int prism_lcd_on(struct platform_device *pdev)
{
/* Set the MDP pixel data attributes for Primary Display */
mddi_host_write_pix_attr_reg(0x00C3);
return 0;
}
static int prism_lcd_off(struct platform_device *pdev)
{
return 0;
}
static int __init prism_probe(struct platform_device *pdev)
{
msm_fb_add_device(pdev);
return 0;
}
static struct platform_driver this_driver = {
.probe = prism_probe,
.driver = {
.name = "mddi_prism_wvga",
},
};
static struct msm_fb_panel_data prism_panel_data = {
.on = prism_lcd_on,
.off = prism_lcd_off,
};
static struct platform_device this_device = {
.name = "mddi_prism_wvga",
.id = 0,
.dev = {
.platform_data = &prism_panel_data,
}
};
static int __init prism_init(void)
{
int ret;
struct msm_panel_info *pinfo;
#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
u32 id;
ret = msm_fb_detect_client("mddi_prism_wvga");
if (ret == -ENODEV)
return 0;
if (ret) {
id = mddi_get_client_id();
if (((id >> 16) != 0x4474) || ((id & 0xffff) == 0x8960))
return 0;
}
#endif
ret = platform_driver_register(&this_driver);
if (!ret) {
pinfo = &prism_panel_data.panel_info;
pinfo->xres = 800;
pinfo->yres = 480;
pinfo->type = MDDI_PANEL;
pinfo->pdest = DISPLAY_1;
pinfo->mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR;
pinfo->wait_cycle = 0;
pinfo->bpp = 18;
pinfo->fb_num = 2;
pinfo->clk_rate = 153600000;
pinfo->clk_min = 150000000;
pinfo->clk_max = 160000000;
pinfo->lcd.vsync_enable = TRUE;
pinfo->lcd.refx100 = 6050;
pinfo->lcd.v_back_porch = 23;
pinfo->lcd.v_front_porch = 20;
pinfo->lcd.v_pulse_width = 105;
pinfo->lcd.hw_vsync_mode = TRUE;
pinfo->lcd.vsync_notifier_period = 0;
ret = platform_device_register(&this_device);
if (ret)
platform_driver_unregister(&this_driver);
}
return ret;
}
module_init(prism_init);

View file

@ -1,892 +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 "msm_fb.h"
#include "mddihost.h"
#include "mddihosti.h"
#define SHARP_QVGA_PRIM 1
#define SHARP_128X128_SECD 2
extern uint32 mddi_host_core_version;
static boolean mddi_debug_prim_wait = FALSE;
static boolean mddi_sharp_vsync_wake = TRUE;
static boolean mddi_sharp_monitor_refresh_value = TRUE;
static boolean mddi_sharp_report_refresh_measurements = FALSE;
static uint32 mddi_sharp_rows_per_second = 13830; /* 5200000/376 */
static uint32 mddi_sharp_rows_per_refresh = 338;
static uint32 mddi_sharp_usecs_per_refresh = 24440; /* (376+338)/5200000 */
static boolean mddi_sharp_debug_60hz_refresh = FALSE;
extern mddi_gpio_info_type mddi_gpio;
extern boolean mddi_vsync_detect_enabled;
static msm_fb_vsync_handler_type mddi_sharp_vsync_handler;
static void *mddi_sharp_vsync_handler_arg;
static uint16 mddi_sharp_vsync_attempts;
static void mddi_sharp_prim_lcd_init(void);
static void mddi_sharp_sub_lcd_init(void);
static void mddi_sharp_lcd_set_backlight(struct msm_fb_data_type *mfd);
static void mddi_sharp_vsync_set_handler(msm_fb_vsync_handler_type handler,
void *);
static void mddi_sharp_lcd_vsync_detected(boolean detected);
static struct msm_panel_common_pdata *mddi_sharp_pdata;
#define REG_SYSCTL 0x0000
#define REG_INTR 0x0006
#define REG_CLKCNF 0x000C
#define REG_CLKDIV1 0x000E
#define REG_CLKDIV2 0x0010
#define REG_GIOD 0x0040
#define REG_GIOA 0x0042
#define REG_AGM 0x010A
#define REG_FLFT 0x0110
#define REG_FRGT 0x0112
#define REG_FTOP 0x0114
#define REG_FBTM 0x0116
#define REG_FSTRX 0x0118
#define REG_FSTRY 0x011A
#define REG_VRAM 0x0202
#define REG_SSDCTL 0x0330
#define REG_SSD0 0x0332
#define REG_PSTCTL1 0x0400
#define REG_PSTCTL2 0x0402
#define REG_PTGCTL 0x042A
#define REG_PTHP 0x042C
#define REG_PTHB 0x042E
#define REG_PTHW 0x0430
#define REG_PTHF 0x0432
#define REG_PTVP 0x0434
#define REG_PTVB 0x0436
#define REG_PTVW 0x0438
#define REG_PTVF 0x043A
#define REG_VBLKS 0x0458
#define REG_VBLKE 0x045A
#define REG_SUBCTL 0x0700
#define REG_SUBTCMD 0x0702
#define REG_SUBTCMDD 0x0704
#define REG_REVBYTE 0x0A02
#define REG_REVCNT 0x0A04
#define REG_REVATTR 0x0A06
#define REG_REVFMT 0x0A08
#define SHARP_SUB_UNKNOWN 0xffffffff
#define SHARP_SUB_HYNIX 1
#define SHARP_SUB_ROHM 2
static uint32 sharp_subpanel_type = SHARP_SUB_UNKNOWN;
static void sub_through_write(int sub_rs, uint32 sub_data)
{
mddi_queue_register_write(REG_SUBTCMDD, sub_data, FALSE, 0);
/* CS=1,RD=1,WE=1,RS=sub_rs */
mddi_queue_register_write(REG_SUBTCMD, 0x000e | sub_rs, FALSE, 0);
/* CS=0,RD=1,WE=1,RS=sub_rs */
mddi_queue_register_write(REG_SUBTCMD, 0x0006 | sub_rs, FALSE, 0);
/* CS=0,RD=1,WE=0,RS=sub_rs */
mddi_queue_register_write(REG_SUBTCMD, 0x0004 | sub_rs, FALSE, 0);
/* CS=0,RD=1,WE=1,RS=sub_rs */
mddi_queue_register_write(REG_SUBTCMD, 0x0006 | sub_rs, FALSE, 0);
/* CS=1,RD=1,WE=1,RS=sub_rs */
mddi_queue_register_write(REG_SUBTCMD, 0x000e | sub_rs, TRUE, 0);
}
static uint32 sub_through_read(int sub_rs)
{
uint32 sub_data;
/* CS=1,RD=1,WE=1,RS=sub_rs */
mddi_queue_register_write(REG_SUBTCMD, 0x000e | sub_rs, FALSE, 0);
/* CS=0,RD=1,WE=1,RS=sub_rs */
mddi_queue_register_write(REG_SUBTCMD, 0x0006 | sub_rs, FALSE, 0);
/* CS=0,RD=1,WE=0,RS=sub_rs */
mddi_queue_register_write(REG_SUBTCMD, 0x0002 | sub_rs, TRUE, 0);
mddi_queue_register_read(REG_SUBTCMDD, &sub_data, TRUE, 0);
/* CS=0,RD=1,WE=1,RS=sub_rs */
mddi_queue_register_write(REG_SUBTCMD, 0x0006 | sub_rs, FALSE, 0);
/* CS=1,RD=1,WE=1,RS=sub_rs */
mddi_queue_register_write(REG_SUBTCMD, 0x000e | sub_rs, TRUE, 0);
return sub_data;
}
static void serigo(uint32 ssd)
{
uint32 ssdctl;
mddi_queue_register_read(REG_SSDCTL, &ssdctl, TRUE, 0);
ssdctl = ((ssdctl & 0xE7) | 0x02);
mddi_queue_register_write(REG_SSD0, ssd, FALSE, 0);
mddi_queue_register_write(REG_SSDCTL, ssdctl, TRUE, 0);
do {
mddi_queue_register_read(REG_SSDCTL, &ssdctl, TRUE, 0);
} while ((ssdctl & 0x0002) != 0);
if (mddi_debug_prim_wait)
mddi_wait(2);
}
static void mddi_sharp_lcd_powerdown(void)
{
serigo(0x0131);
serigo(0x0300);
mddi_wait(40);
serigo(0x0135);
mddi_wait(20);
serigo(0x2122);
mddi_wait(20);
serigo(0x0201);
mddi_wait(20);
serigo(0x2100);
mddi_wait(20);
serigo(0x2000);
mddi_wait(20);
mddi_queue_register_write(REG_PSTCTL1, 0x1, TRUE, 0);
mddi_wait(100);
mddi_queue_register_write(REG_PSTCTL1, 0x0, TRUE, 0);
mddi_wait(2);
mddi_queue_register_write(REG_SYSCTL, 0x1, TRUE, 0);
mddi_wait(2);
mddi_queue_register_write(REG_CLKDIV1, 0x3, TRUE, 0);
mddi_wait(2);
mddi_queue_register_write(REG_SSDCTL, 0x0000, TRUE, 0); /* SSDRESET */
mddi_queue_register_write(REG_SYSCTL, 0x0, TRUE, 0);
mddi_wait(2);
}
static void mddi_sharp_lcd_set_backlight(struct msm_fb_data_type *mfd)
{
uint32 regdata;
int32 level;
int max = mfd->panel_info.bl_max;
int min = mfd->panel_info.bl_min;
if (mddi_sharp_pdata && mddi_sharp_pdata->backlight_level) {
level = mddi_sharp_pdata->backlight_level(mfd->bl_level,
max,
min);
if (level < 0)
return;
/* use Rodem GPIO(2:0) to give 8 levels of backlight (7-0) */
/* Set lower 3 GPIOs as Outputs (set to 0) */
mddi_queue_register_read(REG_GIOA, &regdata, TRUE, 0);
mddi_queue_register_write(REG_GIOA, regdata & 0xfff8, TRUE, 0);
/* Set lower 3 GPIOs as level */
mddi_queue_register_read(REG_GIOD, &regdata, TRUE, 0);
mddi_queue_register_write(REG_GIOD,
(regdata & 0xfff8) | (0x07 & level), TRUE, 0);
}
}
static void mddi_sharp_prim_lcd_init(void)
{
mddi_queue_register_write(REG_SYSCTL, 0x4000, TRUE, 0);
mddi_wait(1);
mddi_queue_register_write(REG_SYSCTL, 0x0000, TRUE, 0);
mddi_wait(5);
mddi_queue_register_write(REG_SYSCTL, 0x0001, FALSE, 0);
mddi_queue_register_write(REG_CLKDIV1, 0x000b, FALSE, 0);
/* new reg write below */
if (mddi_sharp_debug_60hz_refresh)
mddi_queue_register_write(REG_CLKCNF, 0x070d, FALSE, 0);
else
mddi_queue_register_write(REG_CLKCNF, 0x0708, FALSE, 0);
mddi_queue_register_write(REG_SYSCTL, 0x0201, FALSE, 0);
mddi_queue_register_write(REG_PTGCTL, 0x0010, FALSE, 0);
mddi_queue_register_write(REG_PTHP, 4, FALSE, 0);
mddi_queue_register_write(REG_PTHB, 40, FALSE, 0);
mddi_queue_register_write(REG_PTHW, 240, FALSE, 0);
if (mddi_sharp_debug_60hz_refresh)
mddi_queue_register_write(REG_PTHF, 12, FALSE, 0);
else
mddi_queue_register_write(REG_PTHF, 92, FALSE, 0);
mddi_wait(1);
mddi_queue_register_write(REG_PTVP, 1, FALSE, 0);
mddi_queue_register_write(REG_PTVB, 2, FALSE, 0);
mddi_queue_register_write(REG_PTVW, 320, FALSE, 0);
mddi_queue_register_write(REG_PTVF, 15, FALSE, 0);
mddi_wait(1);
/* vram_color set REG_AGM???? */
mddi_queue_register_write(REG_AGM, 0x0000, TRUE, 0);
mddi_queue_register_write(REG_SSDCTL, 0x0000, FALSE, 0);
mddi_queue_register_write(REG_SSDCTL, 0x0001, TRUE, 0);
mddi_wait(1);
mddi_queue_register_write(REG_PSTCTL1, 0x0001, TRUE, 0);
mddi_wait(10);
serigo(0x0701);
/* software reset */
mddi_wait(1);
/* Wait over 50us */
serigo(0x0400);
/* DCLK~ACHSYNC~ACVSYNC polarity setting */
serigo(0x2900);
/* EEPROM start read address setting */
serigo(0x2606);
/* EEPROM start read register setting */
mddi_wait(20);
/* Wait over 20ms */
serigo(0x0503);
/* Horizontal timing setting */
serigo(0x062C);
/* Veritical timing setting */
serigo(0x2001);
/* power initialize setting(VDC2) */
mddi_wait(20);
/* Wait over 20ms */
serigo(0x2120);
/* Initialize power setting(CPS) */
mddi_wait(20);
/* Wait over 20ms */
serigo(0x2130);
/* Initialize power setting(CPS) */
mddi_wait(20);
/* Wait over 20ms */
serigo(0x2132);
/* Initialize power setting(CPS) */
mddi_wait(10);
/* Wait over 10ms */
serigo(0x2133);
/* Initialize power setting(CPS) */
mddi_wait(20);
/* Wait over 20ms */
serigo(0x0200);
/* Panel initialize release(INIT) */
mddi_wait(1);
/* Wait over 1ms */
serigo(0x0131);
/* Panel setting(CPS) */
mddi_wait(1);
/* Wait over 1ms */
mddi_queue_register_write(REG_PSTCTL1, 0x0003, TRUE, 0);
/* if (FFA LCD is upside down) -> serigo(0x0100); */
serigo(0x0130);
/* Black mask release(display ON) */
mddi_wait(1);
/* Wait over 1ms */
if (mddi_sharp_vsync_wake) {
mddi_queue_register_write(REG_VBLKS, 0x1001, TRUE, 0);
mddi_queue_register_write(REG_VBLKE, 0x1002, TRUE, 0);
}
/* Set the MDP pixel data attributes for Primary Display */
mddi_host_write_pix_attr_reg(0x00C3);
return;
}
void mddi_sharp_sub_lcd_init(void)
{
mddi_queue_register_write(REG_SYSCTL, 0x4000, FALSE, 0);
mddi_queue_register_write(REG_SYSCTL, 0x0000, TRUE, 0);
mddi_wait(100);
mddi_queue_register_write(REG_SYSCTL, 0x0001, FALSE, 0);
mddi_queue_register_write(REG_CLKDIV1, 0x000b, FALSE, 0);
mddi_queue_register_write(REG_CLKCNF, 0x0708, FALSE, 0);
mddi_queue_register_write(REG_SYSCTL, 0x0201, FALSE, 0);
mddi_queue_register_write(REG_PTGCTL, 0x0010, FALSE, 0);
mddi_queue_register_write(REG_PTHP, 4, FALSE, 0);
mddi_queue_register_write(REG_PTHB, 40, FALSE, 0);
mddi_queue_register_write(REG_PTHW, 128, FALSE, 0);
mddi_queue_register_write(REG_PTHF, 92, FALSE, 0);
mddi_queue_register_write(REG_PTVP, 1, FALSE, 0);
mddi_queue_register_write(REG_PTVB, 2, FALSE, 0);
mddi_queue_register_write(REG_PTVW, 128, FALSE, 0);
mddi_queue_register_write(REG_PTVF, 15, FALSE, 0);
/* Now the sub display..... */
/* Reset High */
mddi_queue_register_write(REG_SUBCTL, 0x0200, FALSE, 0);
/* CS=1,RD=1,WE=1,RS=1 */
mddi_queue_register_write(REG_SUBTCMD, 0x000f, TRUE, 0);
mddi_wait(1);
/* Wait 5us */
if (sharp_subpanel_type == SHARP_SUB_UNKNOWN) {
uint32 data;
sub_through_write(1, 0x05);
sub_through_write(1, 0x6A);
sub_through_write(1, 0x1D);
sub_through_write(1, 0x05);
data = sub_through_read(1);
if (data == 0x6A) {
sharp_subpanel_type = SHARP_SUB_HYNIX;
} else {
sub_through_write(0, 0x36);
sub_through_write(1, 0xA8);
sub_through_write(0, 0x09);
data = sub_through_read(1);
data = sub_through_read(1);
if (data == 0x54) {
sub_through_write(0, 0x36);
sub_through_write(1, 0x00);
sharp_subpanel_type = SHARP_SUB_ROHM;
}
}
}
if (sharp_subpanel_type == SHARP_SUB_HYNIX) {
sub_through_write(1, 0x00); /* Display setting 1 */
sub_through_write(1, 0x04);
sub_through_write(1, 0x01);
sub_through_write(1, 0x05);
sub_through_write(1, 0x0280);
sub_through_write(1, 0x0301);
sub_through_write(1, 0x0402);
sub_through_write(1, 0x0500);
sub_through_write(1, 0x0681);
sub_through_write(1, 0x077F);
sub_through_write(1, 0x08C0);
sub_through_write(1, 0x0905);
sub_through_write(1, 0x0A02);
sub_through_write(1, 0x0B00);
sub_through_write(1, 0x0C00);
sub_through_write(1, 0x0D00);
sub_through_write(1, 0x0E00);
sub_through_write(1, 0x0F00);
sub_through_write(1, 0x100B); /* Display setting 2 */
sub_through_write(1, 0x1103);
sub_through_write(1, 0x1237);
sub_through_write(1, 0x1300);
sub_through_write(1, 0x1400);
sub_through_write(1, 0x1500);
sub_through_write(1, 0x1605);
sub_through_write(1, 0x1700);
sub_through_write(1, 0x1800);
sub_through_write(1, 0x192E);
sub_through_write(1, 0x1A00);
sub_through_write(1, 0x1B00);
sub_through_write(1, 0x1C00);
sub_through_write(1, 0x151A); /* Power setting */
sub_through_write(1, 0x2002); /* Gradation Palette setting */
sub_through_write(1, 0x2107);
sub_through_write(1, 0x220C);
sub_through_write(1, 0x2310);
sub_through_write(1, 0x2414);
sub_through_write(1, 0x2518);
sub_through_write(1, 0x261C);
sub_through_write(1, 0x2720);
sub_through_write(1, 0x2824);
sub_through_write(1, 0x2928);
sub_through_write(1, 0x2A2B);
sub_through_write(1, 0x2B2E);
sub_through_write(1, 0x2C31);
sub_through_write(1, 0x2D34);
sub_through_write(1, 0x2E37);
sub_through_write(1, 0x2F3A);
sub_through_write(1, 0x303C);
sub_through_write(1, 0x313E);
sub_through_write(1, 0x323F);
sub_through_write(1, 0x3340);
sub_through_write(1, 0x3441);
sub_through_write(1, 0x3543);
sub_through_write(1, 0x3646);
sub_through_write(1, 0x3749);
sub_through_write(1, 0x384C);
sub_through_write(1, 0x394F);
sub_through_write(1, 0x3A52);
sub_through_write(1, 0x3B59);
sub_through_write(1, 0x3C60);
sub_through_write(1, 0x3D67);
sub_through_write(1, 0x3E6E);
sub_through_write(1, 0x3F7F);
sub_through_write(1, 0x4001);
sub_through_write(1, 0x4107);
sub_through_write(1, 0x420C);
sub_through_write(1, 0x4310);
sub_through_write(1, 0x4414);
sub_through_write(1, 0x4518);
sub_through_write(1, 0x461C);
sub_through_write(1, 0x4720);
sub_through_write(1, 0x4824);
sub_through_write(1, 0x4928);
sub_through_write(1, 0x4A2B);
sub_through_write(1, 0x4B2E);
sub_through_write(1, 0x4C31);
sub_through_write(1, 0x4D34);
sub_through_write(1, 0x4E37);
sub_through_write(1, 0x4F3A);
sub_through_write(1, 0x503C);
sub_through_write(1, 0x513E);
sub_through_write(1, 0x523F);
sub_through_write(1, 0x5340);
sub_through_write(1, 0x5441);
sub_through_write(1, 0x5543);
sub_through_write(1, 0x5646);
sub_through_write(1, 0x5749);
sub_through_write(1, 0x584C);
sub_through_write(1, 0x594F);
sub_through_write(1, 0x5A52);
sub_through_write(1, 0x5B59);
sub_through_write(1, 0x5C60);
sub_through_write(1, 0x5D67);
sub_through_write(1, 0x5E6E);
sub_through_write(1, 0x5F7E);
sub_through_write(1, 0x6000);
sub_through_write(1, 0x6107);
sub_through_write(1, 0x620C);
sub_through_write(1, 0x6310);
sub_through_write(1, 0x6414);
sub_through_write(1, 0x6518);
sub_through_write(1, 0x661C);
sub_through_write(1, 0x6720);
sub_through_write(1, 0x6824);
sub_through_write(1, 0x6928);
sub_through_write(1, 0x6A2B);
sub_through_write(1, 0x6B2E);
sub_through_write(1, 0x6C31);
sub_through_write(1, 0x6D34);
sub_through_write(1, 0x6E37);
sub_through_write(1, 0x6F3A);
sub_through_write(1, 0x703C);
sub_through_write(1, 0x713E);
sub_through_write(1, 0x723F);
sub_through_write(1, 0x7340);
sub_through_write(1, 0x7441);
sub_through_write(1, 0x7543);
sub_through_write(1, 0x7646);
sub_through_write(1, 0x7749);
sub_through_write(1, 0x784C);
sub_through_write(1, 0x794F);
sub_through_write(1, 0x7A52);
sub_through_write(1, 0x7B59);
sub_through_write(1, 0x7C60);
sub_through_write(1, 0x7D67);
sub_through_write(1, 0x7E6E);
sub_through_write(1, 0x7F7D);
sub_through_write(1, 0x1851); /* Display on */
mddi_queue_register_write(REG_AGM, 0x0000, TRUE, 0);
/* 1 pixel / 1 post clock */
mddi_queue_register_write(REG_CLKDIV2, 0x3b00, FALSE, 0);
/* SUB LCD select */
mddi_queue_register_write(REG_PSTCTL2, 0x0080, FALSE, 0);
/* RS=0,command initiate number=0,select master mode */
mddi_queue_register_write(REG_SUBCTL, 0x0202, FALSE, 0);
/* Sub LCD Data transform start */
mddi_queue_register_write(REG_PSTCTL1, 0x0003, FALSE, 0);
} else if (sharp_subpanel_type == SHARP_SUB_ROHM) {
sub_through_write(0, 0x01); /* Display setting */
sub_through_write(1, 0x00);
mddi_wait(1);
/* Wait 100us <----- ******* Update 2005/01/24 */
sub_through_write(0, 0xB6);
sub_through_write(1, 0x0C);
sub_through_write(1, 0x4A);
sub_through_write(1, 0x20);
sub_through_write(0, 0x3A);
sub_through_write(1, 0x05);
sub_through_write(0, 0xB7);
sub_through_write(1, 0x01);
sub_through_write(0, 0xBA);
sub_through_write(1, 0x20);
sub_through_write(1, 0x02);
sub_through_write(0, 0x25);
sub_through_write(1, 0x4F);
sub_through_write(0, 0xBB);
sub_through_write(1, 0x00);
sub_through_write(0, 0x36);
sub_through_write(1, 0x00);
sub_through_write(0, 0xB1);
sub_through_write(1, 0x05);
sub_through_write(0, 0xBE);
sub_through_write(1, 0x80);
sub_through_write(0, 0x26);
sub_through_write(1, 0x01);
sub_through_write(0, 0x2A);
sub_through_write(1, 0x02);
sub_through_write(1, 0x81);
sub_through_write(0, 0x2B);
sub_through_write(1, 0x00);
sub_through_write(1, 0x7F);
sub_through_write(0, 0x2C);
sub_through_write(0, 0x11); /* Sleep mode off */
mddi_wait(1);
/* Wait 100 ms <----- ******* Update 2005/01/24 */
sub_through_write(0, 0x29); /* Display on */
sub_through_write(0, 0xB3);
sub_through_write(1, 0x20);
sub_through_write(1, 0xAA);
sub_through_write(1, 0xA0);
sub_through_write(1, 0x20);
sub_through_write(1, 0x30);
sub_through_write(1, 0xA6);
sub_through_write(1, 0xFF);
sub_through_write(1, 0x9A);
sub_through_write(1, 0x9F);
sub_through_write(1, 0xAF);
sub_through_write(1, 0xBC);
sub_through_write(1, 0xCF);
sub_through_write(1, 0xDF);
sub_through_write(1, 0x20);
sub_through_write(1, 0x9C);
sub_through_write(1, 0x8A);
sub_through_write(0, 0x002C); /* Display on */
/* 1 pixel / 2 post clock */
mddi_queue_register_write(REG_CLKDIV2, 0x7b00, FALSE, 0);
/* SUB LCD select */
mddi_queue_register_write(REG_PSTCTL2, 0x0080, FALSE, 0);
/* RS=1,command initiate number=0,select master mode */
mddi_queue_register_write(REG_SUBCTL, 0x0242, FALSE, 0);
/* Sub LCD Data transform start */
mddi_queue_register_write(REG_PSTCTL1, 0x0003, FALSE, 0);
}
/* Set the MDP pixel data attributes for Sub Display */
mddi_host_write_pix_attr_reg(0x00C0);
}
void mddi_sharp_lcd_vsync_detected(boolean detected)
{
/* static timetick_type start_time = 0; */
static struct timeval start_time;
static boolean first_time = TRUE;
/* uint32 mdp_cnt_val = 0; */
/* timetick_type elapsed_us; */
struct timeval now;
uint32 elapsed_us;
uint32 num_vsyncs;
if ((detected) || (mddi_sharp_vsync_attempts > 5)) {
if ((detected) && (mddi_sharp_monitor_refresh_value)) {
/* if (start_time != 0) */
if (!first_time) {
jiffies_to_timeval(jiffies, &now);
elapsed_us =
(now.tv_sec - start_time.tv_sec) * 1000000 +
now.tv_usec - start_time.tv_usec;
/*
* LCD is configured for a refresh every usecs,
* so to determine the number of vsyncs that
* have occurred since the last measurement add
* half that to the time difference and divide
* by the refresh rate.
*/
num_vsyncs = (elapsed_us +
(mddi_sharp_usecs_per_refresh >>
1)) /
mddi_sharp_usecs_per_refresh;
/*
* LCD is configured for * hsyncs (rows) per
* refresh cycle. Calculate new rows_per_second
* value based upon these new measurements.
* MDP can update with this new value.
*/
mddi_sharp_rows_per_second =
(mddi_sharp_rows_per_refresh * 1000 *
num_vsyncs) / (elapsed_us / 1000);
}
/* start_time = timetick_get(); */
first_time = FALSE;
jiffies_to_timeval(jiffies, &start_time);
if (mddi_sharp_report_refresh_measurements) {
/* mdp_cnt_val = MDP_LINE_COUNT; */
}
}
/* if detected = TRUE, client initiated wakeup was detected */
if (mddi_sharp_vsync_handler != NULL) {
(*mddi_sharp_vsync_handler)
(mddi_sharp_vsync_handler_arg);
mddi_sharp_vsync_handler = NULL;
}
mddi_vsync_detect_enabled = FALSE;
mddi_sharp_vsync_attempts = 0;
/* need to clear this vsync wakeup */
if (!mddi_queue_register_write_int(REG_INTR, 0x0000)) {
MDDI_MSG_ERR("Vsync interrupt clear failed!\n");
}
if (!detected) {
/* give up after 5 failed attempts but show error */
MDDI_MSG_NOTICE("Vsync detection failed!\n");
} else if ((mddi_sharp_monitor_refresh_value) &&
(mddi_sharp_report_refresh_measurements)) {
MDDI_MSG_NOTICE(" Lines Per Second=%d!\n",
mddi_sharp_rows_per_second);
}
} else
/* if detected = FALSE, we woke up from hibernation, but did not
* detect client initiated wakeup.
*/
mddi_sharp_vsync_attempts++;
}
/* ISR to be executed */
void mddi_sharp_vsync_set_handler(msm_fb_vsync_handler_type handler, void *arg)
{
boolean error = FALSE;
unsigned long flags;
/* Disable interrupts */
spin_lock_irqsave(&mddi_host_spin_lock, flags);
/* INTLOCK(); */
if (mddi_sharp_vsync_handler != NULL)
error = TRUE;
/* Register the handler for this particular GROUP interrupt source */
mddi_sharp_vsync_handler = handler;
mddi_sharp_vsync_handler_arg = arg;
/* Restore interrupts */
spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
/* INTFREE(); */
if (error)
MDDI_MSG_ERR("MDDI: Previous Vsync handler never called\n");
/* Enable the vsync wakeup */
mddi_queue_register_write(REG_INTR, 0x8100, FALSE, 0);
mddi_sharp_vsync_attempts = 1;
mddi_vsync_detect_enabled = TRUE;
} /* mddi_sharp_vsync_set_handler */
static int mddi_sharp_lcd_on(struct platform_device *pdev)
{
struct msm_fb_data_type *mfd;
mfd = platform_get_drvdata(pdev);
if (!mfd)
return -ENODEV;
if (mfd->key != MFD_KEY)
return -EINVAL;
if (mfd->panel.id == SHARP_QVGA_PRIM)
mddi_sharp_prim_lcd_init();
else
mddi_sharp_sub_lcd_init();
return 0;
}
static int mddi_sharp_lcd_off(struct platform_device *pdev)
{
mddi_sharp_lcd_powerdown();
return 0;
}
static int __init mddi_sharp_probe(struct platform_device *pdev)
{
if (pdev->id == 0) {
mddi_sharp_pdata = pdev->dev.platform_data;
return 0;
}
msm_fb_add_device(pdev);
return 0;
}
static struct platform_driver this_driver = {
.probe = mddi_sharp_probe,
.driver = {
.name = "mddi_sharp_qvga",
},
};
static struct msm_fb_panel_data mddi_sharp_panel_data0 = {
.on = mddi_sharp_lcd_on,
.off = mddi_sharp_lcd_off,
.set_backlight = mddi_sharp_lcd_set_backlight,
.set_vsync_notifier = mddi_sharp_vsync_set_handler,
};
static struct platform_device this_device_0 = {
.name = "mddi_sharp_qvga",
.id = SHARP_QVGA_PRIM,
.dev = {
.platform_data = &mddi_sharp_panel_data0,
}
};
static struct msm_fb_panel_data mddi_sharp_panel_data1 = {
.on = mddi_sharp_lcd_on,
.off = mddi_sharp_lcd_off,
};
static struct platform_device this_device_1 = {
.name = "mddi_sharp_qvga",
.id = SHARP_128X128_SECD,
.dev = {
.platform_data = &mddi_sharp_panel_data1,
}
};
static int __init mddi_sharp_init(void)
{
int ret;
struct msm_panel_info *pinfo;
#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
u32 id;
ret = msm_fb_detect_client("mddi_sharp_qvga");
if (ret == -ENODEV)
return 0;
if (ret) {
id = mddi_get_client_id();
if (((id >> 16) != 0x0) || ((id & 0xffff) != 0x8835))
return 0;
}
#endif
if (mddi_host_core_version > 8) {
/* can use faster refresh with newer hw revisions */
mddi_sharp_debug_60hz_refresh = TRUE;
/* Timing variables for tracking vsync */
/* dot_clock = 6.00MHz
* horizontal count = 296
* vertical count = 338
* refresh rate = 6000000/(296+338) = 60Hz
*/
mddi_sharp_rows_per_second = 20270; /* 6000000/296 */
mddi_sharp_rows_per_refresh = 338;
mddi_sharp_usecs_per_refresh = 16674; /* (296+338)/6000000 */
} else {
/* Timing variables for tracking vsync */
/* dot_clock = 5.20MHz
* horizontal count = 376
* vertical count = 338
* refresh rate = 5200000/(376+338) = 41Hz
*/
mddi_sharp_rows_per_second = 13830; /* 5200000/376 */
mddi_sharp_rows_per_refresh = 338;
mddi_sharp_usecs_per_refresh = 24440; /* (376+338)/5200000 */
}
ret = platform_driver_register(&this_driver);
if (!ret) {
pinfo = &mddi_sharp_panel_data0.panel_info;
pinfo->xres = 240;
pinfo->yres = 320;
pinfo->type = MDDI_PANEL;
pinfo->pdest = DISPLAY_1;
pinfo->mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR;
pinfo->wait_cycle = 0;
pinfo->bpp = 18;
pinfo->fb_num = 2;
pinfo->clk_rate = 122880000;
pinfo->clk_min = 120000000;
pinfo->clk_max = 125000000;
pinfo->lcd.vsync_enable = TRUE;
pinfo->lcd.refx100 =
(mddi_sharp_rows_per_second * 100) /
mddi_sharp_rows_per_refresh;
pinfo->lcd.v_back_porch = 12;
pinfo->lcd.v_front_porch = 6;
pinfo->lcd.v_pulse_width = 0;
pinfo->lcd.hw_vsync_mode = FALSE;
pinfo->lcd.vsync_notifier_period = (1 * HZ);
pinfo->bl_max = 7;
pinfo->bl_min = 1;
ret = platform_device_register(&this_device_0);
if (ret)
platform_driver_unregister(&this_driver);
pinfo = &mddi_sharp_panel_data1.panel_info;
pinfo->xres = 128;
pinfo->yres = 128;
pinfo->type = MDDI_PANEL;
pinfo->pdest = DISPLAY_2;
pinfo->mddi.vdopkt = 0x400;
pinfo->wait_cycle = 0;
pinfo->bpp = 18;
pinfo->clk_rate = 122880000;
pinfo->clk_min = 120000000;
pinfo->clk_max = 125000000;
pinfo->fb_num = 2;
ret = platform_device_register(&this_device_1);
if (ret) {
platform_device_unregister(&this_device_0);
platform_driver_unregister(&this_driver);
}
}
if (!ret)
mddi_lcd.vsync_detected = mddi_sharp_lcd_vsync_detected;
return ret;
}
module_init(mddi_sharp_init);

File diff suppressed because it is too large Load diff

View file

@ -1,36 +0,0 @@
/* Copyright (c) 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.
*/
#ifndef MDDI_TOSHIBA_H
#define MDDI_TOSHIBA_H
#define TOSHIBA_VGA_PRIM 1
#define TOSHIBA_VGA_SECD 2
#define LCD_TOSHIBA_2P4_VGA 0
#define LCD_TOSHIBA_2P4_WVGA 1
#define LCD_TOSHIBA_2P4_WVGA_PT 2
#define LCD_SHARP_2P4_VGA 3
#define GPIO_BLOCK_BASE 0x150000
#define SYSTEM_BLOCK2_BASE 0x170000
#define GPIODIR (GPIO_BLOCK_BASE|0x04)
#define GPIOSEL (SYSTEM_BLOCK2_BASE|0x00)
#define GPIOPC (GPIO_BLOCK_BASE|0x28)
#define GPIODATA (GPIO_BLOCK_BASE|0x00)
#define write_client_reg(__X, __Y, __Z) {\
mddi_queue_register_write(__X, __Y, TRUE, 0);\
}
#endif /* MDDI_TOSHIBA_H */

View file

@ -1,136 +0,0 @@
/* Copyright (c) 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 "msm_fb.h"
#include "mddihost.h"
#include "mddihosti.h"
#include "mddi_toshiba.h"
static uint32 read_client_reg(uint32 addr)
{
uint32 val;
mddi_queue_register_read(addr, &val, TRUE, 0);
return val;
}
static uint32 toshiba_lcd_gpio_read(void)
{
uint32 val;
write_client_reg(GPIODIR, 0x0000000C, TRUE);
write_client_reg(GPIOSEL, 0x00000000, TRUE);
write_client_reg(GPIOSEL, 0x00000000, TRUE);
write_client_reg(GPIOPC, 0x03CF00C0, TRUE);
val = read_client_reg(GPIODATA) & 0x2C0;
return val;
}
static u32 mddi_toshiba_panel_detect(void)
{
mddi_host_type host_idx = MDDI_HOST_PRIM;
uint32 lcd_gpio;
u32 mddi_toshiba_lcd = LCD_TOSHIBA_2P4_VGA;
/* Toshiba display requires larger drive_lo value */
mddi_host_reg_out(DRIVE_LO, 0x0050);
lcd_gpio = toshiba_lcd_gpio_read();
switch (lcd_gpio) {
case 0x0080:
mddi_toshiba_lcd = LCD_SHARP_2P4_VGA;
break;
case 0x00C0:
default:
mddi_toshiba_lcd = LCD_TOSHIBA_2P4_VGA;
break;
}
return mddi_toshiba_lcd;
}
static int __init mddi_toshiba_vga_init(void)
{
int ret;
struct msm_panel_info pinfo;
u32 panel;
#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
u32 id;
ret = msm_fb_detect_client("mddi_toshiba_vga");
if (ret == -ENODEV)
return 0;
if (ret) {
id = mddi_get_client_id();
if ((id >> 16) != 0xD263)
return 0;
}
#endif
panel = mddi_toshiba_panel_detect();
pinfo.xres = 480;
pinfo.yres = 640;
pinfo.type = MDDI_PANEL;
pinfo.pdest = DISPLAY_1;
pinfo.mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR;
pinfo.wait_cycle = 0;
pinfo.bpp = 18;
pinfo.lcd.vsync_enable = TRUE;
pinfo.lcd.refx100 = 6118;
pinfo.lcd.v_back_porch = 6;
pinfo.lcd.v_front_porch = 0;
pinfo.lcd.v_pulse_width = 0;
pinfo.lcd.hw_vsync_mode = FALSE;
pinfo.lcd.vsync_notifier_period = (1 * HZ);
pinfo.bl_max = 99;
pinfo.bl_min = 1;
pinfo.clk_rate = 122880000;
pinfo.clk_min = 120000000;
pinfo.clk_max = 200000000;
pinfo.fb_num = 2;
ret = mddi_toshiba_device_register(&pinfo, TOSHIBA_VGA_PRIM, panel);
if (ret) {
printk(KERN_ERR "%s: failed to register device!\n", __func__);
return ret;
}
pinfo.xres = 176;
pinfo.yres = 220;
pinfo.type = MDDI_PANEL;
pinfo.pdest = DISPLAY_2;
pinfo.mddi.vdopkt = 0x400;
pinfo.wait_cycle = 0;
pinfo.bpp = 18;
pinfo.clk_rate = 122880000;
pinfo.clk_min = 120000000;
pinfo.clk_max = 200000000;
pinfo.fb_num = 2;
ret = mddi_toshiba_device_register(&pinfo, TOSHIBA_VGA_SECD, panel);
if (ret)
printk(KERN_WARNING
"%s: failed to register device!\n", __func__);
return ret;
}
module_init(mddi_toshiba_vga_init);

View file

@ -1,64 +0,0 @@
/* Copyright (c) 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 "msm_fb.h"
#include "mddihost.h"
#include "mddihosti.h"
#include "mddi_toshiba.h"
static int __init mddi_toshiba_wvga_pt_init(void)
{
int ret;
struct msm_panel_info pinfo;
#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
uint id;
ret = msm_fb_detect_client("mddi_toshiba_wvga_pt");
if (ret == -ENODEV)
return 0;
if (ret) {
id = mddi_get_client_id();
if (id != 0xd2638722)
return 0;
}
#endif
pinfo.xres = 480;
pinfo.yres = 800;
pinfo.type = MDDI_PANEL;
pinfo.pdest = DISPLAY_1;
pinfo.mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR;
pinfo.wait_cycle = 0;
pinfo.bpp = 18;
pinfo.lcd.vsync_enable = FALSE;
pinfo.bl_max = 15;
pinfo.bl_min = 1;
pinfo.clk_rate = 192000000;
pinfo.clk_min = 190000000;
pinfo.clk_max = 200000000;
pinfo.fb_num = 2;
ret = mddi_toshiba_device_register(&pinfo, TOSHIBA_VGA_PRIM,
LCD_TOSHIBA_2P4_WVGA_PT);
if (ret)
printk(KERN_ERR "%s: failed to register device!\n", __func__);
return ret;
}
module_init(mddi_toshiba_wvga_pt_init);

View file

@ -1,377 +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/slab.h>
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include "msm_fb.h"
#include "mddihost.h"
#include "mddihosti.h"
#include <linux/clk.h>
#include <mach/clk.h>
struct semaphore mddi_host_mutex;
struct clk *mddi_io_clk;
static boolean mddi_host_powered = FALSE;
static boolean mddi_host_initialized = FALSE;
extern uint32 *mddi_reg_read_value_ptr;
mddi_lcd_func_type mddi_lcd;
extern mddi_client_capability_type mddi_client_capability_pkt;
#ifdef FEATURE_MDDI_HITACHI
extern void mddi_hitachi_window_adjust(uint16 x1,
uint16 x2, uint16 y1, uint16 y2);
#endif
extern void mddi_toshiba_lcd_init(void);
#ifdef FEATURE_MDDI_S6D0142
extern void mddi_s6d0142_lcd_init(void);
extern void mddi_s6d0142_window_adjust(uint16 x1,
uint16 x2,
uint16 y1,
uint16 y2,
mddi_llist_done_cb_type done_cb);
#endif
void mddi_init(void)
{
if (mddi_host_initialized)
return;
mddi_host_initialized = TRUE;
sema_init(&mddi_host_mutex, 1);
if (!mddi_host_powered) {
down(&mddi_host_mutex);
mddi_host_init(MDDI_HOST_PRIM);
mddi_host_powered = TRUE;
up(&mddi_host_mutex);
mdelay(10);
}
}
int mddi_host_register_read(uint32 reg_addr,
uint32 *reg_value_ptr, boolean wait, mddi_host_type host) {
mddi_linked_list_type *curr_llist_ptr;
mddi_register_access_packet_type *regacc_pkt_ptr;
uint16 curr_llist_idx;
int ret = 0;
if (in_interrupt())
MDDI_MSG_CRIT("Called from ISR context\n");
if (!mddi_host_powered) {
MDDI_MSG_ERR("MDDI powered down!\n");
mddi_init();
}
down(&mddi_host_mutex);
mddi_reg_read_value_ptr = reg_value_ptr;
curr_llist_idx = mddi_get_reg_read_llist_item(host, TRUE);
if (curr_llist_idx == UNASSIGNED_INDEX) {
up(&mddi_host_mutex);
/* need to change this to some sort of wait */
MDDI_MSG_ERR("Attempting to queue up more than 1 reg read\n");
return -EINVAL;
}
curr_llist_ptr = &llist_extern[host][curr_llist_idx];
curr_llist_ptr->link_controller_flags = 0x11;
curr_llist_ptr->packet_header_count = 14;
curr_llist_ptr->packet_data_count = 0;
curr_llist_ptr->next_packet_pointer = NULL;
curr_llist_ptr->packet_data_pointer = NULL;
curr_llist_ptr->reserved = 0;
regacc_pkt_ptr = &curr_llist_ptr->packet_header.register_pkt;
regacc_pkt_ptr->packet_length = curr_llist_ptr->packet_header_count;
regacc_pkt_ptr->packet_type = 146; /* register access packet */
regacc_pkt_ptr->bClient_ID = 0;
regacc_pkt_ptr->read_write_info = 0x8001;
regacc_pkt_ptr->register_address = reg_addr;
/* now adjust pointers */
mddi_queue_forward_packets(curr_llist_idx, curr_llist_idx, wait,
NULL, host);
/* need to check if we can write the pointer or not */
up(&mddi_host_mutex);
if (wait) {
int wait_ret;
mddi_linked_list_notify_type *llist_notify_ptr;
llist_notify_ptr = &llist_extern_notify[host][curr_llist_idx];
wait_ret = wait_for_completion_timeout(
&(llist_notify_ptr->done_comp), 5 * HZ);
if (wait_ret <= 0)
ret = -EBUSY;
if (wait_ret < 0)
printk(KERN_ERR "%s: failed to wait for completion!\n",
__func__);
else if (!wait_ret)
printk(KERN_ERR "%s: Timed out waiting!\n", __func__);
}
MDDI_MSG_DEBUG("Reg Read value=0x%x\n", *reg_value_ptr);
return ret;
} /* mddi_host_register_read */
int mddi_host_register_write(uint32 reg_addr,
uint32 reg_val, enum mddi_data_packet_size_type packet_size,
boolean wait, mddi_llist_done_cb_type done_cb, mddi_host_type host) {
mddi_linked_list_type *curr_llist_ptr;
mddi_linked_list_type *curr_llist_dma_ptr;
mddi_register_access_packet_type *regacc_pkt_ptr;
uint16 curr_llist_idx;
int ret = 0;
if (in_interrupt())
MDDI_MSG_CRIT("Called from ISR context\n");
if (!mddi_host_powered) {
MDDI_MSG_ERR("MDDI powered down!\n");
mddi_init();
}
down(&mddi_host_mutex);
curr_llist_idx = mddi_get_next_free_llist_item(host, TRUE);
curr_llist_ptr = &llist_extern[host][curr_llist_idx];
curr_llist_dma_ptr = &llist_dma_extern[host][curr_llist_idx];
curr_llist_ptr->link_controller_flags = 1;
curr_llist_ptr->packet_header_count = 14;
curr_llist_ptr->packet_data_count = 4;
curr_llist_ptr->next_packet_pointer = NULL;
curr_llist_ptr->reserved = 0;
regacc_pkt_ptr = &curr_llist_ptr->packet_header.register_pkt;
regacc_pkt_ptr->packet_length = curr_llist_ptr->packet_header_count +
(uint16)packet_size;
regacc_pkt_ptr->packet_type = 146; /* register access packet */
regacc_pkt_ptr->bClient_ID = 0;
regacc_pkt_ptr->read_write_info = 0x0001;
regacc_pkt_ptr->register_address = reg_addr;
regacc_pkt_ptr->register_data_list = reg_val;
MDDI_MSG_DEBUG("Reg Access write reg=0x%x, value=0x%x\n",
regacc_pkt_ptr->register_address,
regacc_pkt_ptr->register_data_list);
regacc_pkt_ptr = &curr_llist_dma_ptr->packet_header.register_pkt;
curr_llist_ptr->packet_data_pointer =
(void *)(&regacc_pkt_ptr->register_data_list);
/* now adjust pointers */
mddi_queue_forward_packets(curr_llist_idx, curr_llist_idx, wait,
done_cb, host);
up(&mddi_host_mutex);
if (wait) {
int wait_ret;
mddi_linked_list_notify_type *llist_notify_ptr;
llist_notify_ptr = &llist_extern_notify[host][curr_llist_idx];
wait_ret = wait_for_completion_timeout(
&(llist_notify_ptr->done_comp), 5 * HZ);
if (wait_ret <= 0)
ret = -EBUSY;
if (wait_ret < 0)
printk(KERN_ERR "%s: failed to wait for completion!\n",
__func__);
else if (!wait_ret)
printk(KERN_ERR "%s: Timed out waiting!\n", __func__);
}
return ret;
} /* mddi_host_register_write */
boolean mddi_host_register_read_int
(uint32 reg_addr, uint32 *reg_value_ptr, mddi_host_type host) {
mddi_linked_list_type *curr_llist_ptr;
mddi_register_access_packet_type *regacc_pkt_ptr;
uint16 curr_llist_idx;
if (!in_interrupt())
MDDI_MSG_CRIT("Called from TASK context\n");
if (!mddi_host_powered) {
MDDI_MSG_ERR("MDDI powered down!\n");
return FALSE;
}
if (down_trylock(&mddi_host_mutex) != 0)
return FALSE;
mddi_reg_read_value_ptr = reg_value_ptr;
curr_llist_idx = mddi_get_reg_read_llist_item(host, FALSE);
if (curr_llist_idx == UNASSIGNED_INDEX) {
up(&mddi_host_mutex);
return FALSE;
}
curr_llist_ptr = &llist_extern[host][curr_llist_idx];
curr_llist_ptr->link_controller_flags = 0x11;
curr_llist_ptr->packet_header_count = 14;
curr_llist_ptr->packet_data_count = 0;
curr_llist_ptr->next_packet_pointer = NULL;
curr_llist_ptr->packet_data_pointer = NULL;
curr_llist_ptr->reserved = 0;
regacc_pkt_ptr = &curr_llist_ptr->packet_header.register_pkt;
regacc_pkt_ptr->packet_length = curr_llist_ptr->packet_header_count;
regacc_pkt_ptr->packet_type = 146; /* register access packet */
regacc_pkt_ptr->bClient_ID = 0;
regacc_pkt_ptr->read_write_info = 0x8001;
regacc_pkt_ptr->register_address = reg_addr;
/* now adjust pointers */
mddi_queue_forward_packets(curr_llist_idx, curr_llist_idx, FALSE,
NULL, host);
/* need to check if we can write the pointer or not */
up(&mddi_host_mutex);
return TRUE;
} /* mddi_host_register_read */
boolean mddi_host_register_write_int
(uint32 reg_addr,
uint32 reg_val, mddi_llist_done_cb_type done_cb, mddi_host_type host) {
mddi_linked_list_type *curr_llist_ptr;
mddi_linked_list_type *curr_llist_dma_ptr;
mddi_register_access_packet_type *regacc_pkt_ptr;
uint16 curr_llist_idx;
if (!in_interrupt())
MDDI_MSG_CRIT("Called from TASK context\n");
if (!mddi_host_powered) {
MDDI_MSG_ERR("MDDI powered down!\n");
return FALSE;
}
if (down_trylock(&mddi_host_mutex) != 0)
return FALSE;
curr_llist_idx = mddi_get_next_free_llist_item(host, FALSE);
if (curr_llist_idx == UNASSIGNED_INDEX) {
up(&mddi_host_mutex);
return FALSE;
}
curr_llist_ptr = &llist_extern[host][curr_llist_idx];
curr_llist_dma_ptr = &llist_dma_extern[host][curr_llist_idx];
curr_llist_ptr->link_controller_flags = 1;
curr_llist_ptr->packet_header_count = 14;
curr_llist_ptr->packet_data_count = 4;
curr_llist_ptr->next_packet_pointer = NULL;
curr_llist_ptr->reserved = 0;
regacc_pkt_ptr = &curr_llist_ptr->packet_header.register_pkt;
regacc_pkt_ptr->packet_length = curr_llist_ptr->packet_header_count + 4;
regacc_pkt_ptr->packet_type = 146; /* register access packet */
regacc_pkt_ptr->bClient_ID = 0;
regacc_pkt_ptr->read_write_info = 0x0001;
regacc_pkt_ptr->register_address = reg_addr;
regacc_pkt_ptr->register_data_list = reg_val;
regacc_pkt_ptr = &curr_llist_dma_ptr->packet_header.register_pkt;
curr_llist_ptr->packet_data_pointer =
(void *)(&(regacc_pkt_ptr->register_data_list));
/* now adjust pointers */
mddi_queue_forward_packets(curr_llist_idx, curr_llist_idx, FALSE,
done_cb, host);
up(&mddi_host_mutex);
return TRUE;
} /* mddi_host_register_write */
void mddi_wait(uint16 time_ms)
{
mdelay(time_ms);
}
void mddi_client_lcd_vsync_detected(boolean detected)
{
if (mddi_lcd.vsync_detected)
(*mddi_lcd.vsync_detected) (detected);
}
/* extended version of function includes done callback */
void mddi_window_adjust_ext(struct msm_fb_data_type *mfd,
uint16 x1,
uint16 x2,
uint16 y1,
uint16 y2, mddi_llist_done_cb_type done_cb)
{
#ifdef FEATURE_MDDI_HITACHI
if (mfd->panel.id == HITACHI)
mddi_hitachi_window_adjust(x1, x2, y1, y2);
#elif defined(FEATURE_MDDI_S6D0142)
if (mfd->panel.id == MDDI_LCD_S6D0142)
mddi_s6d0142_window_adjust(x1, x2, y1, y2, done_cb);
#else
/* Do nothing then... except avoid lint/compiler warnings */
(void)x1;
(void)x2;
(void)y1;
(void)y2;
(void)done_cb;
#endif
}
void mddi_window_adjust(struct msm_fb_data_type *mfd,
uint16 x1, uint16 x2, uint16 y1, uint16 y2)
{
mddi_window_adjust_ext(mfd, x1, x2, y1, y2, NULL);
}

View file

@ -1,207 +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.
*/
#ifndef MDDIHOST_H
#define MDDIHOST_H
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/proc_fs.h>
#include <linux/types.h>
#include <linux/dma-mapping.h>
#include <linux/clk.h>
#include <mach/hardware.h>
#include <linux/io.h>
#include <asm/system.h>
#include <asm/mach-types.h>
#include "msm_fb_panel.h"
#undef FEATURE_MDDI_MC4
#undef FEATURE_MDDI_S6D0142
#undef FEATURE_MDDI_HITACHI
#define FEATURE_MDDI_SHARP
#define FEATURE_MDDI_TOSHIBA
#undef FEATURE_MDDI_E751
#define FEATURE_MDDI_CORONA
#define FEATURE_MDDI_PRISM
#define T_MSM7500
typedef enum {
format_16bpp,
format_18bpp,
format_24bpp
} mddi_video_format;
typedef enum {
MDDI_LCD_NONE = 0,
MDDI_LCD_MC4,
MDDI_LCD_S6D0142,
MDDI_LCD_SHARP,
MDDI_LCD_E751,
MDDI_LCD_CORONA,
MDDI_LCD_HITACHI,
MDDI_LCD_TOSHIBA,
MDDI_LCD_PRISM,
MDDI_LCD_TP2,
MDDI_NUM_LCD_TYPES,
MDDI_LCD_DEFAULT = MDDI_LCD_TOSHIBA
} mddi_lcd_type;
typedef enum {
MDDI_HOST_PRIM = 0,
MDDI_HOST_EXT,
MDDI_NUM_HOST_CORES
} mddi_host_type;
typedef enum {
MDDI_DRIVER_RESET, /* host core registers have not been written. */
MDDI_DRIVER_DISABLED, /* registers written, interrupts disabled. */
MDDI_DRIVER_ENABLED /* registers written, interrupts enabled. */
} mddi_host_driver_state_type;
typedef enum {
MDDI_GPIO_INT_0 = 0,
MDDI_GPIO_INT_1,
MDDI_GPIO_INT_2,
MDDI_GPIO_INT_3,
MDDI_GPIO_INT_4,
MDDI_GPIO_INT_5,
MDDI_GPIO_INT_6,
MDDI_GPIO_INT_7,
MDDI_GPIO_INT_8,
MDDI_GPIO_INT_9,
MDDI_GPIO_INT_10,
MDDI_GPIO_INT_11,
MDDI_GPIO_INT_12,
MDDI_GPIO_INT_13,
MDDI_GPIO_INT_14,
MDDI_GPIO_INT_15,
MDDI_GPIO_NUM_INTS
} mddi_gpio_int_type;
enum mddi_data_packet_size_type {
MDDI_DATA_PACKET_4_BYTES = 4,
MDDI_DATA_PACKET_8_BYTES = 8,
MDDI_DATA_PACKET_12_BYTES = 12,
MDDI_DATA_PACKET_16_BYTES = 16,
MDDI_DATA_PACKET_24_BYTES = 24
};
typedef struct {
uint32 addr;
uint32 value;
} mddi_reg_write_type;
boolean mddi_vsync_set_handler(msm_fb_vsync_handler_type handler, void *arg);
typedef void (*mddi_llist_done_cb_type) (void);
typedef void (*mddi_rev_handler_type) (void *);
boolean mddi_set_rev_handler(mddi_rev_handler_type handler, uint16 pkt_type);
#define MDDI_DEFAULT_PRIM_PIX_ATTR 0xC3
#define MDDI_DEFAULT_SECD_PIX_ATTR 0xC0
typedef int gpio_int_polarity_type;
typedef int gpio_int_handler_type;
typedef struct {
void (*vsync_detected) (boolean);
} mddi_lcd_func_type;
extern mddi_lcd_func_type mddi_lcd;
void mddi_init(void);
void mddi_powerdown(void);
void mddi_host_start_ext_display(void);
void mddi_host_stop_ext_display(void);
extern spinlock_t mddi_host_spin_lock;
#ifdef T_MSM7500
void mddi_reset(void);
#ifdef FEATURE_DUAL_PROC_MODEM_DISPLAY
void mddi_host_switch_proc_control(boolean on);
#endif
#endif
void mddi_host_exit_power_collapse(void);
void mddi_queue_splash_screen
(void *buf_ptr,
boolean clear_area,
int16 src_width,
int16 src_starting_row,
int16 src_starting_column,
int16 num_of_rows,
int16 num_of_columns, int16 dst_starting_row, int16 dst_starting_column);
void mddi_queue_image
(void *buf_ptr,
uint8 stereo_video,
boolean clear_area,
int16 src_width,
int16 src_starting_row,
int16 src_starting_column,
int16 num_of_rows,
int16 num_of_columns, int16 dst_starting_row, int16 dst_starting_column);
int mddi_host_register_read
(uint32 reg_addr,
uint32 *reg_value_ptr, boolean wait, mddi_host_type host_idx);
int mddi_host_register_write
(uint32 reg_addr, uint32 reg_val,
enum mddi_data_packet_size_type packet_size,
boolean wait, mddi_llist_done_cb_type done_cb, mddi_host_type host);
boolean mddi_host_register_write_int
(uint32 reg_addr,
uint32 reg_val, mddi_llist_done_cb_type done_cb, mddi_host_type host);
boolean mddi_host_register_read_int
(uint32 reg_addr, uint32 *reg_value_ptr, mddi_host_type host_idx);
void mddi_queue_register_write_static
(uint32 reg_addr,
uint32 reg_val, boolean wait, mddi_llist_done_cb_type done_cb);
void mddi_queue_static_window_adjust
(const mddi_reg_write_type *reg_write,
uint16 num_writes, mddi_llist_done_cb_type done_cb);
#define mddi_queue_register_read(reg, val_ptr, wait, sig) \
mddi_host_register_read(reg, val_ptr, wait, MDDI_HOST_PRIM)
#define mddi_queue_register_write(reg, val, wait, sig) \
mddi_host_register_write(reg, val, MDDI_DATA_PACKET_4_BYTES,\
wait, NULL, MDDI_HOST_PRIM)
#define mddi_queue_register_write_extn(reg, val, pkt_size, wait, sig) \
mddi_host_register_write(reg, val, pkt_size, \
wait, NULL, MDDI_HOST_PRIM)
#define mddi_queue_register_write_int(reg, val) \
mddi_host_register_write_int(reg, val, NULL, MDDI_HOST_PRIM)
#define mddi_queue_register_read_int(reg, val_ptr) \
mddi_host_register_read_int(reg, val_ptr, MDDI_HOST_PRIM)
#define mddi_queue_register_writes(reg_ptr, val, wait, sig) \
mddi_host_register_writes(reg_ptr, val, wait, sig, MDDI_HOST_PRIM)
void mddi_wait(uint16 time_ms);
void mddi_assign_max_pkt_dimensions(uint16 image_cols,
uint16 image_rows,
uint16 bpp,
uint16 *max_cols, uint16 * max_rows);
uint16 mddi_assign_pkt_height(uint16 pkt_width, uint16 pkt_height, uint16 bpp);
void mddi_queue_reverse_encapsulation(boolean wait);
void mddi_disable(int lock);
#endif /* MDDIHOST_H */

View file

@ -1,63 +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/slab.h>
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include "msm_fb.h"
#include "mddihost.h"
#include "mddihosti.h"
#include <linux/clk.h>
#include <mach/clk.h>
extern struct semaphore mddi_host_mutex;
static boolean mddi_host_ext_powered = FALSE;
void mddi_host_start_ext_display(void)
{
down(&mddi_host_mutex);
if (!mddi_host_ext_powered) {
mddi_host_init(MDDI_HOST_EXT);
mddi_host_ext_powered = TRUE;
}
up(&mddi_host_mutex);
}
void mddi_host_stop_ext_display(void)
{
down(&mddi_host_mutex);
if (mddi_host_ext_powered) {
mddi_host_powerdown(MDDI_HOST_EXT);
mddi_host_ext_powered = FALSE;
}
up(&mddi_host_mutex);
}

File diff suppressed because it is too large Load diff

View file

@ -1,531 +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.
*/
#ifndef MDDIHOSTI_H
#define MDDIHOSTI_H
#include "msm_fb.h"
#include "mddihost.h"
#include <linux/clk.h>
/* Register offsets in MDDI, applies to both msm_pmdh_base and
* (u32)msm_emdh_base. */
#define MDDI_CMD 0x0000
#define MDDI_VERSION 0x0004
#define MDDI_PRI_PTR 0x0008
#define MDDI_BPS 0x0010
#define MDDI_SPM 0x0014
#define MDDI_INT 0x0018
#define MDDI_INTEN 0x001c
#define MDDI_REV_PTR 0x0020
#define MDDI_REV_SIZE 0x0024
#define MDDI_STAT 0x0028
#define MDDI_REV_RATE_DIV 0x002c
#define MDDI_REV_CRC_ERR 0x0030
#define MDDI_TA1_LEN 0x0034
#define MDDI_TA2_LEN 0x0038
#define MDDI_TEST 0x0040
#define MDDI_REV_PKT_CNT 0x0044
#define MDDI_DRIVE_HI 0x0048
#define MDDI_DRIVE_LO 0x004c
#define MDDI_DISP_WAKE 0x0050
#define MDDI_REV_ENCAP_SZ 0x0054
#define MDDI_RTD_VAL 0x0058
#define MDDI_PAD_CTL 0x0068
#define MDDI_DRIVER_START_CNT 0x006c
#define MDDI_CORE_VER 0x008c
#define MDDI_FIFO_ALLOC 0x0090
#define MDDI_PAD_IO_CTL 0x00a0
#define MDDI_PAD_CAL 0x00a4
extern u32 mddi_msg_level;
/* No longer need to write to clear these registers */
#define xxxx_mddi_host_reg_outm(reg, mask, val) \
do { \
if (host_idx == MDDI_HOST_PRIM) \
mddi_host_reg_outm_pmdh(reg, mask, val); \
else \
mddi_host_reg_outm_emdh(reg, mask, val); \
} while (0)
#define mddi_host_reg_outm(reg, mask, val) \
do { \
unsigned long __addr; \
if (host_idx == MDDI_HOST_PRIM) \
__addr = (u32)msm_pmdh_base + MDDI_##reg; \
else \
__addr = (u32)msm_emdh_base + MDDI_##reg; \
writel((readl(__addr) & ~(mask)) | ((val) & (mask)), __addr); \
} while (0)
#define xxxx_mddi_host_reg_out(reg, val) \
do { \
if (host_idx == MDDI_HOST_PRIM) \
mddi_host_reg_out_pmdh(reg, val); \
else \
mddi_host_reg_out_emdh(reg, val); \
} while (0)
#define mddi_host_reg_out(reg, val) \
do { \
if (host_idx == MDDI_HOST_PRIM) \
writel(val, (u32)msm_pmdh_base + MDDI_##reg); \
else \
writel(val, (u32)msm_emdh_base + MDDI_##reg); \
} while (0)
#define xxxx_mddi_host_reg_in(reg) \
((host_idx) ? \
mddi_host_reg_in_emdh(reg) : mddi_host_reg_in_pmdh(reg));
#define mddi_host_reg_in(reg) \
((host_idx) ? \
readl((u32)msm_emdh_base + MDDI_##reg) : \
readl((u32)msm_pmdh_base + MDDI_##reg)) \
#define xxxx_mddi_host_reg_inm(reg, mask) \
((host_idx) ? \
mddi_host_reg_inm_emdh(reg, mask) : \
mddi_host_reg_inm_pmdh(reg, mask);)
#define mddi_host_reg_inm(reg, mask) \
((host_idx) ? \
readl((u32)msm_emdh_base + MDDI_##reg) & (mask) : \
readl((u32)msm_pmdh_base + MDDI_##reg) & (mask)) \
/* Using non-cacheable pmem, so do nothing */
#define mddi_invalidate_cache_lines(addr_start, num_bytes)
/*
* Using non-cacheable pmem, so do nothing with cache
* but, ensure write goes out to memory
*/
#define mddi_flush_cache_lines(addr_start, num_bytes) \
(void) addr_start; \
(void) num_bytes; \
memory_barrier()
/* Since this translates to Remote Procedure Calls to check on clock status
* just use a local variable to keep track of io_clock */
#define MDDI_HOST_IS_IO_CLOCK_ON mddi_host_io_clock_on
#define MDDI_HOST_ENABLE_IO_CLOCK
#define MDDI_HOST_DISABLE_IO_CLOCK
#define MDDI_HOST_IS_HCLK_ON mddi_host_hclk_on
#define MDDI_HOST_ENABLE_HCLK
#define MDDI_HOST_DISABLE_HCLK
#define FEATURE_MDDI_HOST_IO_CLOCK_CONTROL_DISABLE
#define FEATURE_MDDI_HOST_HCLK_CONTROL_DISABLE
#define TRAMP_MDDI_HOST_ISR TRAMP_MDDI_PRI_ISR
#define TRAMP_MDDI_HOST_EXT_ISR TRAMP_MDDI_EXT_ISR
#define MDP_LINE_COUNT_BMSK 0x3ff
#define MDP_SYNC_STATUS 0x000c
#define MDP_LINE_COUNT \
(readl(msm_mdp_base + MDP_SYNC_STATUS) & MDP_LINE_COUNT_BMSK)
/* MDP sends 256 pixel packets, so lower value hibernates more without
* significantly increasing latency of waiting for next subframe */
#define MDDI_HOST_BYTES_PER_SUBFRAME 0x3C00
#if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP40)
#define MDDI_HOST_TA2_LEN 0x001a
#define MDDI_HOST_REV_RATE_DIV 0x0004
#else
#define MDDI_HOST_TA2_LEN 0x000c
#define MDDI_HOST_REV_RATE_DIV 0x0002
#endif
#define MDDI_MSG_EMERG(msg, ...) \
if (mddi_msg_level > 0) \
printk(KERN_EMERG msg, ## __VA_ARGS__);
#define MDDI_MSG_ALERT(msg, ...) \
if (mddi_msg_level > 1) \
printk(KERN_ALERT msg, ## __VA_ARGS__);
#define MDDI_MSG_CRIT(msg, ...) \
if (mddi_msg_level > 2) \
printk(KERN_CRIT msg, ## __VA_ARGS__);
#define MDDI_MSG_ERR(msg, ...) \
if (mddi_msg_level > 3) \
printk(KERN_ERR msg, ## __VA_ARGS__);
#define MDDI_MSG_WARNING(msg, ...) \
if (mddi_msg_level > 4) \
printk(KERN_WARNING msg, ## __VA_ARGS__);
#define MDDI_MSG_NOTICE(msg, ...) \
if (mddi_msg_level > 5) \
printk(KERN_NOTICE msg, ## __VA_ARGS__);
#define MDDI_MSG_INFO(msg, ...) \
if (mddi_msg_level > 6) \
printk(KERN_INFO msg, ## __VA_ARGS__);
#define MDDI_MSG_DEBUG(msg, ...) \
if (mddi_msg_level > 7) \
printk(KERN_DEBUG msg, ## __VA_ARGS__);
#define GCC_PACKED __attribute__((packed))
typedef struct GCC_PACKED {
uint16 packet_length;
/* total # of bytes in the packet not including
the packet_length field. */
uint16 packet_type;
/* A Packet Type of 70 identifies the packet as
a Client status Packet. */
uint16 bClient_ID;
/* This field is reserved for future use and shall
be set to zero. */
} mddi_rev_packet_type;
typedef struct GCC_PACKED {
uint16 packet_length;
/* total # of bytes in the packet not including
the packet_length field. */
uint16 packet_type;
/* A Packet Type of 70 identifies the packet as
a Client status Packet. */
uint16 bClient_ID;
/* This field is reserved for future use and shall
be set to zero. */
uint16 reverse_link_request;
/* 16 bit unsigned integer with number of bytes client
needs in the * reverse encapsulation message
to transmit data. */
uint8 crc_error_count;
uint8 capability_change;
uint16 graphics_busy_flags;
uint16 parameter_CRC;
/* 16-bit CRC of all the bytes in the packet
including Packet Length. */
} mddi_client_status_type;
typedef struct GCC_PACKED {
uint16 packet_length;
/* total # of bytes in the packet not including
the packet_length field. */
uint16 packet_type;
/* A Packet Type of 66 identifies the packet as
a Client Capability Packet. */
uint16 bClient_ID;
/* This field is reserved for future use and
shall be set to zero. */
uint16 Protocol_Version;
uint16 Minimum_Protocol_Version;
uint16 Data_Rate_Capability;
uint8 Interface_Type_Capability;
uint8 Number_of_Alt_Displays;
uint16 PostCal_Data_Rate;
uint16 Bitmap_Width;
uint16 Bitmap_Height;
uint16 Display_Window_Width;
uint16 Display_Window_Height;
uint32 Color_Map_Size;
uint16 Color_Map_RGB_Width;
uint16 RGB_Capability;
uint8 Monochrome_Capability;
uint8 Reserved_1;
uint16 Y_Cb_Cr_Capability;
uint16 Bayer_Capability;
uint16 Alpha_Cursor_Image_Planes;
uint32 Client_Feature_Capability_Indicators;
uint8 Maximum_Video_Frame_Rate_Capability;
uint8 Minimum_Video_Frame_Rate_Capability;
uint16 Minimum_Sub_frame_Rate;
uint16 Audio_Buffer_Depth;
uint16 Audio_Channel_Capability;
uint16 Audio_Sample_Rate_Capability;
uint8 Audio_Sample_Resolution;
uint8 Mic_Audio_Sample_Resolution;
uint16 Mic_Sample_Rate_Capability;
uint8 Keyboard_Data_Format;
uint8 pointing_device_data_format;
uint16 content_protection_type;
uint16 Mfr_Name;
uint16 Product_Code;
uint16 Reserved_3;
uint32 Serial_Number;
uint8 Week_of_Manufacture;
uint8 Year_of_Manufacture;
uint16 parameter_CRC;
/* 16-bit CRC of all the bytes in the packet including Packet Length. */
} mddi_client_capability_type;
typedef struct GCC_PACKED {
uint16 packet_length;
/* total # of bytes in the packet not including the packet_length field. */
uint16 packet_type;
/* A Packet Type of 16 identifies the packet as a Video Stream Packet. */
uint16 bClient_ID;
/* This field is reserved for future use and shall be set to zero. */
uint16 video_data_format_descriptor;
/* format of each pixel in the Pixel Data in the present stream in the
* present packet.
* If bits [15:13] = 000 monochrome
* If bits [15:13] = 001 color pixels (palette).
* If bits [15:13] = 010 color pixels in raw RGB
* If bits [15:13] = 011 data in 4:2:2 Y Cb Cr format
* If bits [15:13] = 100 Bayer pixels
*/
uint16 pixel_data_attributes;
/* interpreted as follows:
* Bits [1:0] = 11 pixel data is displayed to both eyes
* Bits [1:0] = 10 pixel data is routed to the left eye only.
* Bits [1:0] = 01 pixel data is routed to the right eye only.
* Bits [1:0] = 00 pixel data is routed to the alternate display.
* Bit 2 is 0 Pixel Data is in the standard progressive format.
* Bit 2 is 1 Pixel Data is in interlace format.
* Bit 3 is 0 Pixel Data is in the standard progressive format.
* Bit 3 is 1 Pixel Data is in alternate pixel format.
* Bit 4 is 0 Pixel Data is to or from the display frame buffer.
* Bit 4 is 1 Pixel Data is to or from the camera.
* Bit 5 is 0 pixel data contains the next consecutive row of pixels.
* Bit 5 is 1 X Left Edge, Y Top Edge, X Right Edge, Y Bottom Edge,
* X Start, and Y Start parameters are not defined and
* shall be ignored by the client.
* Bits [7:6] = 01 Pixel data is written to the offline image buffer.
* Bits [7:6] = 00 Pixel data is written to the buffer to refresh display.
* Bits [7:6] = 11 Pixel data is written to all image buffers.
* Bits [7:6] = 10 Invalid. Reserved for future use.
* Bits 8 through 11 alternate display number.
* Bits 12 through 14 are reserved for future use and shall be set to zero.
* Bit 15 is 1 the row of pixels is the last row of pixels in a frame.
*/
uint16 x_left_edge;
uint16 y_top_edge;
/* X,Y coordinate of the top left edge of the screen window */
uint16 x_right_edge;
uint16 y_bottom_edge;
/* X,Y coordinate of the bottom right edge of the window being updated. */
uint16 x_start;
uint16 y_start;
/* (X Start, Y Start) is the first pixel in the Pixel Data field below. */
uint16 pixel_count;
/* number of pixels in the Pixel Data field below. */
uint16 parameter_CRC;
/* 16-bit CRC of all bytes from the Packet Length to the Pixel Count. */
uint16 reserved;
/* 16-bit variable to make structure align on 4 byte boundary */
} mddi_video_stream_packet_type;
typedef struct GCC_PACKED {
uint16 packet_length;
/* total # of bytes in the packet not including the packet_length field. */
uint16 packet_type;
/* A Packet Type of 146 identifies the packet as a Register Access Packet. */
uint16 bClient_ID;
/* This field is reserved for future use and shall be set to zero. */
uint16 read_write_info;
/* Bits 13:0 a 14-bit unsigned integer that specifies the number of
* 32-bit Register Data List items to be transferred in the
* Register Data List field.
* Bits[15:14] = 00 Write to register(s);
* Bits[15:14] = 10 Read from register(s);
* Bits[15:14] = 11 Response to a Read.
* Bits[15:14] = 01 this value is reserved for future use. */
uint32 register_address;
/* the register address that is to be written to or read from. */
uint16 parameter_CRC;
/* 16-bit CRC of all bytes from the Packet Length to the Register Address. */
uint32 register_data_list;
/* list of 4-byte register data values for/from client registers */
} mddi_register_access_packet_type;
typedef union GCC_PACKED {
mddi_video_stream_packet_type video_pkt;
mddi_register_access_packet_type register_pkt;
/* add 48 byte pad to ensure 64 byte llist struct, that can be
* manipulated easily with cache */
uint32 alignment_pad[12]; /* 48 bytes */
} mddi_packet_header_type;
typedef struct GCC_PACKED mddi_host_llist_struct {
uint16 link_controller_flags;
uint16 packet_header_count;
uint16 packet_data_count;
void *packet_data_pointer;
struct mddi_host_llist_struct *next_packet_pointer;
uint16 reserved;
mddi_packet_header_type packet_header;
} mddi_linked_list_type;
typedef struct {
struct completion done_comp;
mddi_llist_done_cb_type done_cb;
uint16 next_idx;
boolean waiting;
boolean in_use;
} mddi_linked_list_notify_type;
#define MDDI_LLIST_POOL_SIZE 0x1000
#define MDDI_MAX_NUM_LLIST_ITEMS (MDDI_LLIST_POOL_SIZE / \
sizeof(mddi_linked_list_type))
#define UNASSIGNED_INDEX MDDI_MAX_NUM_LLIST_ITEMS
#define MDDI_FIRST_DYNAMIC_LLIST_IDX 0
/* Static llist items can be used for applications that frequently send
* the same set of packets using the linked list interface. */
/* Here we configure for 6 static linked list items:
* The 1st is used for a the adaptive backlight setting.
* and the remaining 5 are used for sending window adjustments for
* MDDI clients that need windowing info sent separate from video
* packets. */
#define MDDI_NUM_STATIC_ABL_ITEMS 1
#define MDDI_NUM_STATIC_WINDOW_ITEMS 5
#define MDDI_NUM_STATIC_LLIST_ITEMS (MDDI_NUM_STATIC_ABL_ITEMS + \
MDDI_NUM_STATIC_WINDOW_ITEMS)
#define MDDI_NUM_DYNAMIC_LLIST_ITEMS (MDDI_MAX_NUM_LLIST_ITEMS - \
MDDI_NUM_STATIC_LLIST_ITEMS)
#define MDDI_FIRST_STATIC_LLIST_IDX MDDI_NUM_DYNAMIC_LLIST_ITEMS
#define MDDI_FIRST_STATIC_ABL_IDX MDDI_FIRST_STATIC_LLIST_IDX
#define MDDI_FIRST_STATIC_WINDOW_IDX (MDDI_FIRST_STATIC_LLIST_IDX + \
MDDI_NUM_STATIC_ABL_ITEMS)
/* GPIO registers */
#define VSYNC_WAKEUP_REG 0x80
#define GPIO_REG 0x81
#define GPIO_OUTPUT_REG 0x82
#define GPIO_INTERRUPT_REG 0x83
#define GPIO_INTERRUPT_ENABLE_REG 0x84
#define GPIO_POLARITY_REG 0x85
/* Interrupt Bits */
#define MDDI_INT_PRI_PTR_READ 0x0001
#define MDDI_INT_SEC_PTR_READ 0x0002
#define MDDI_INT_REV_DATA_AVAIL 0x0004
#define MDDI_INT_DISP_REQ 0x0008
#define MDDI_INT_PRI_UNDERFLOW 0x0010
#define MDDI_INT_SEC_UNDERFLOW 0x0020
#define MDDI_INT_REV_OVERFLOW 0x0040
#define MDDI_INT_CRC_ERROR 0x0080
#define MDDI_INT_MDDI_IN 0x0100
#define MDDI_INT_PRI_OVERWRITE 0x0200
#define MDDI_INT_SEC_OVERWRITE 0x0400
#define MDDI_INT_REV_OVERWRITE 0x0800
#define MDDI_INT_DMA_FAILURE 0x1000
#define MDDI_INT_LINK_ACTIVE 0x2000
#define MDDI_INT_IN_HIBERNATION 0x4000
#define MDDI_INT_PRI_LINK_LIST_DONE 0x8000
#define MDDI_INT_SEC_LINK_LIST_DONE 0x10000
#define MDDI_INT_NO_CMD_PKTS_PEND 0x20000
#define MDDI_INT_RTD_FAILURE 0x40000
#define MDDI_INT_ERROR_CONDITIONS ( \
MDDI_INT_PRI_UNDERFLOW | MDDI_INT_SEC_UNDERFLOW | \
MDDI_INT_REV_OVERFLOW | MDDI_INT_CRC_ERROR | \
MDDI_INT_PRI_OVERWRITE | MDDI_INT_SEC_OVERWRITE | \
MDDI_INT_RTD_FAILURE | \
MDDI_INT_REV_OVERWRITE | MDDI_INT_DMA_FAILURE)
#define MDDI_INT_LINK_STATE_CHANGES ( \
MDDI_INT_LINK_ACTIVE | MDDI_INT_IN_HIBERNATION)
/* Status Bits */
#define MDDI_STAT_LINK_ACTIVE 0x0001
#define MDDI_STAT_NEW_REV_PTR 0x0002
#define MDDI_STAT_NEW_PRI_PTR 0x0004
#define MDDI_STAT_NEW_SEC_PTR 0x0008
#define MDDI_STAT_IN_HIBERNATION 0x0010
#define MDDI_STAT_PRI_LINK_LIST_DONE 0x0020
#define MDDI_STAT_SEC_LINK_LIST_DONE 0x0040
#define MDDI_STAT_PENDING_TIMING_PKT 0x0080
#define MDDI_STAT_PENDING_REV_ENCAP 0x0100
#define MDDI_STAT_PENDING_POWERDOWN 0x0200
#define MDDI_STAT_RTD_MEAS_FAIL 0x0800
#define MDDI_STAT_CLIENT_WAKEUP_REQ 0x1000
/* Command Bits */
#define MDDI_CMD_POWERDOWN 0x0100
#define MDDI_CMD_POWERUP 0x0200
#define MDDI_CMD_HIBERNATE 0x0300
#define MDDI_CMD_RESET 0x0400
#define MDDI_CMD_DISP_IGNORE 0x0501
#define MDDI_CMD_DISP_LISTEN 0x0500
#define MDDI_CMD_SEND_REV_ENCAP 0x0600
#define MDDI_CMD_GET_CLIENT_CAP 0x0601
#define MDDI_CMD_GET_CLIENT_STATUS 0x0602
#define MDDI_CMD_SEND_RTD 0x0700
#define MDDI_CMD_LINK_ACTIVE 0x0900
#define MDDI_CMD_PERIODIC_REV_ENCAP 0x0A00
extern void mddi_host_init(mddi_host_type host);
extern void mddi_host_powerdown(mddi_host_type host);
extern uint16 mddi_get_next_free_llist_item(mddi_host_type host, boolean wait);
extern uint16 mddi_get_reg_read_llist_item(mddi_host_type host, boolean wait);
extern void mddi_queue_forward_packets(uint16 first_llist_idx,
uint16 last_llist_idx,
boolean wait,
mddi_llist_done_cb_type llist_done_cb,
mddi_host_type host);
extern void mddi_host_write_pix_attr_reg(uint32 value);
extern void mddi_client_lcd_gpio_poll(uint32 poll_reg_val);
extern void mddi_client_lcd_vsync_detected(boolean detected);
extern void mddi_host_disable_hibernation(boolean disable);
extern mddi_linked_list_type *llist_extern[];
extern mddi_linked_list_type *llist_dma_extern[];
extern mddi_linked_list_notify_type *llist_extern_notify[];
extern struct timer_list mddi_host_timer;
typedef struct {
uint16 transmitting_start_idx;
uint16 transmitting_end_idx;
uint16 waiting_start_idx;
uint16 waiting_end_idx;
uint16 reg_read_idx;
uint16 next_free_idx;
boolean reg_read_waiting;
} mddi_llist_info_type;
extern mddi_llist_info_type mddi_llist;
#define MDDI_GPIO_DEFAULT_POLLING_INTERVAL 200
typedef struct {
uint32 polling_reg;
uint32 polling_val;
uint32 polling_interval;
boolean polling_enabled;
} mddi_gpio_info_type;
uint32 mddi_get_client_id(void);
void mddi_mhctl_remove(mddi_host_type host_idx);
void mddi_host_timer_service(unsigned long data);
#endif /* MDDIHOSTI_H */

File diff suppressed because it is too large Load diff

View file

@ -1,679 +0,0 @@
/* Copyright (c) 2008-2010, 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.
*/
#ifndef MDP_H
#define MDP_H
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/fb.h>
#include <linux/hrtimer.h>
#include "msm_mdp.h"
#include <mach/hardware.h>
#include <linux/io.h>
#include <asm/system.h>
#include <asm/mach-types.h>
#include "msm_fb_panel.h"
#ifdef CONFIG_MDP_PPP_ASYNC_OP
#include "mdp_ppp_dq.h"
#endif
#ifdef BIT
#undef BIT
#endif
#define BIT(x) (1<<(x))
#define MDPOP_NOP 0
#define MDPOP_LR BIT(0) /* left to right flip */
#define MDPOP_UD BIT(1) /* up and down flip */
#define MDPOP_ROT90 BIT(2) /* rotate image to 90 degree */
#define MDPOP_ROT180 (MDPOP_UD|MDPOP_LR)
#define MDPOP_ROT270 (MDPOP_ROT90|MDPOP_UD|MDPOP_LR)
#define MDPOP_ASCALE BIT(7)
#define MDPOP_ALPHAB BIT(8) /* enable alpha blending */
#define MDPOP_TRANSP BIT(9) /* enable transparency */
#define MDPOP_DITHER BIT(10) /* enable dither */
#define MDPOP_SHARPENING BIT(11) /* enable sharpening */
#define MDPOP_BLUR BIT(12) /* enable blur */
#define MDPOP_FG_PM_ALPHA BIT(13)
struct mdp_table_entry {
uint32_t reg;
uint32_t val;
};
extern struct mdp_ccs mdp_ccs_yuv2rgb ;
extern struct mdp_ccs mdp_ccs_rgb2yuv ;
/*
* MDP Image Structure
*/
typedef struct mdpImg_ {
uint32 imgType; /* Image type */
uint32 *bmy_addr; /* bitmap or y addr */
uint32 *cbcr_addr; /* cbcr addr */
uint32 width; /* image width */
uint32 mdpOp; /* image opertion (rotation,flip up/down, alpha/tp) */
uint32 tpVal; /* transparency color */
uint32 alpha; /* alpha percentage 0%(0x0) ~ 100%(0x100) */
int sp_value; /* sharpening strength */
} MDPIMG;
#ifdef CONFIG_MDP_PPP_ASYNC_OP
#define MDP_OUTP(addr, data) mdp_ppp_outdw((uint32_t)(addr), \
(uint32_t)(data))
#else
#define MDP_OUTP(addr, data) outpdw((addr), (data))
#endif
#define MDP_KTIME2USEC(kt) (kt.tv.sec*1000000 + kt.tv.nsec/1000)
#define MDP_BASE msm_mdp_base
typedef enum {
MDP_BC_SCALE_POINT2_POINT4,
MDP_BC_SCALE_POINT4_POINT6,
MDP_BC_SCALE_POINT6_POINT8,
MDP_BC_SCALE_POINT8_1,
MDP_BC_SCALE_UP,
MDP_PR_SCALE_POINT2_POINT4,
MDP_PR_SCALE_POINT4_POINT6,
MDP_PR_SCALE_POINT6_POINT8,
MDP_PR_SCALE_POINT8_1,
MDP_PR_SCALE_UP,
MDP_SCALE_BLUR,
MDP_INIT_SCALE
} MDP_SCALE_MODE;
typedef enum {
MDP_BLOCK_POWER_OFF,
MDP_BLOCK_POWER_ON
} MDP_BLOCK_POWER_STATE;
typedef enum {
MDP_MASTER_BLOCK,
MDP_CMD_BLOCK,
MDP_PPP_BLOCK,
MDP_DMA2_BLOCK,
MDP_DMA3_BLOCK,
MDP_DMA_S_BLOCK,
MDP_DMA_E_BLOCK,
MDP_OVERLAY0_BLOCK,
MDP_OVERLAY1_BLOCK,
MDP_MAX_BLOCK
} MDP_BLOCK_TYPE;
/* Let's keep Q Factor power of 2 for optimization */
#define MDP_SCALE_Q_FACTOR 512
#ifdef CONFIG_FB_MSM_MDP31
#define MDP_MAX_X_SCALE_FACTOR (MDP_SCALE_Q_FACTOR*8)
#define MDP_MIN_X_SCALE_FACTOR (MDP_SCALE_Q_FACTOR/8)
#define MDP_MAX_Y_SCALE_FACTOR (MDP_SCALE_Q_FACTOR*8)
#define MDP_MIN_Y_SCALE_FACTOR (MDP_SCALE_Q_FACTOR/8)
#else
#define MDP_MAX_X_SCALE_FACTOR (MDP_SCALE_Q_FACTOR*4)
#define MDP_MIN_X_SCALE_FACTOR (MDP_SCALE_Q_FACTOR/4)
#define MDP_MAX_Y_SCALE_FACTOR (MDP_SCALE_Q_FACTOR*4)
#define MDP_MIN_Y_SCALE_FACTOR (MDP_SCALE_Q_FACTOR/4)
#endif
/* SHIM Q Factor */
#define PHI_Q_FACTOR 29
#define PQF_PLUS_5 (PHI_Q_FACTOR + 5) /* due to 32 phases */
#define PQF_PLUS_4 (PHI_Q_FACTOR + 4)
#define PQF_PLUS_2 (PHI_Q_FACTOR + 2) /* to get 4.0 */
#define PQF_MINUS_2 (PHI_Q_FACTOR - 2) /* to get 0.25 */
#define PQF_PLUS_5_PLUS_2 (PQF_PLUS_5 + 2)
#define PQF_PLUS_5_MINUS_2 (PQF_PLUS_5 - 2)
#define MDP_CONVTP(tpVal) (((tpVal&0xF800)<<8)|((tpVal&0x7E0)<<5)|((tpVal&0x1F)<<3))
#define MDPOP_ROTATION (MDPOP_ROT90|MDPOP_LR|MDPOP_UD)
#define MDP_CHKBIT(val, bit) ((bit) == ((val) & (bit)))
/* overlay interface API defines */
typedef enum {
MORE_IBUF,
FINAL_IBUF,
COMPLETE_IBUF
} MDP_IBUF_STATE;
struct mdp_dirty_region {
__u32 xoffset; /* source origin in the x-axis */
__u32 yoffset; /* source origin in the y-axis */
__u32 width; /* number of pixels in the x-axis */
__u32 height; /* number of pixels in the y-axis */
};
/*
* MDP extended data types
*/
typedef struct mdp_roi_s {
uint32 x;
uint32 y;
uint32 width;
uint32 height;
int32 lcd_x;
int32 lcd_y;
uint32 dst_width;
uint32 dst_height;
} MDP_ROI;
typedef struct mdp_ibuf_s {
uint8 *buf;
uint32 bpp;
uint32 ibuf_type;
uint32 ibuf_width;
uint32 ibuf_height;
MDP_ROI roi;
MDPIMG mdpImg;
int32 dma_x;
int32 dma_y;
uint32 dma_w;
uint32 dma_h;
uint32 vsync_enable;
uint32 visible_swapped;
} MDPIBUF;
struct mdp_dma_data {
boolean busy;
boolean waiting;
struct mutex ov_mutex;
struct semaphore mutex;
struct completion comp;
};
#define MDP_CMD_DEBUG_ACCESS_BASE (MDP_BASE+0x10000)
#define MDP_DMA2_TERM 0x1
#define MDP_DMA3_TERM 0x2
#define MDP_PPP_TERM 0x4
#define MDP_DMA_S_TERM 0x8
#ifdef CONFIG_FB_MSM_MDP40
#define MDP_DMA_E_TERM 0x10
#define MDP_OVERLAY0_TERM 0x20
#define MDP_OVERLAY1_TERM 0x40
#endif
#define ACTIVE_START_X_EN BIT(31)
#define ACTIVE_START_Y_EN BIT(31)
#define ACTIVE_HIGH 0
#define ACTIVE_LOW 1
#define MDP_DMA_S_DONE BIT(2)
#define LCDC_FRAME_START BIT(15)
#define LCDC_UNDERFLOW BIT(16)
#ifdef CONFIG_FB_MSM_MDP22
#define MDP_DMA_P_DONE BIT(2)
#else
#define MDP_DMA_P_DONE BIT(14)
#endif
#define MDP_PPP_DONE BIT(0)
#define TV_OUT_DMA3_DONE BIT(6)
#define TV_ENC_UNDERRUN BIT(7)
#define TV_OUT_DMA3_START BIT(13)
#define MDP_HIST_DONE BIT(20)
#ifdef CONFIG_FB_MSM_MDP22
#define MDP_ANY_INTR_MASK (MDP_PPP_DONE| \
MDP_DMA_P_DONE| \
TV_ENC_UNDERRUN)
#else
#define MDP_ANY_INTR_MASK (MDP_PPP_DONE| \
MDP_DMA_P_DONE| \
MDP_DMA_S_DONE| \
LCDC_UNDERFLOW| \
MDP_HIST_DONE| \
TV_ENC_UNDERRUN)
#endif
#define MDP_TOP_LUMA 16
#define MDP_TOP_CHROMA 0
#define MDP_BOTTOM_LUMA 19
#define MDP_BOTTOM_CHROMA 3
#define MDP_LEFT_LUMA 22
#define MDP_LEFT_CHROMA 6
#define MDP_RIGHT_LUMA 25
#define MDP_RIGHT_CHROMA 9
#define CLR_G 0x0
#define CLR_B 0x1
#define CLR_R 0x2
#define CLR_ALPHA 0x3
#define CLR_Y CLR_G
#define CLR_CB CLR_B
#define CLR_CR CLR_R
/* from lsb to msb */
#define MDP_GET_PACK_PATTERN(a,x,y,z,bit) (((a)<<(bit*3))|((x)<<(bit*2))|((y)<<bit)|(z))
/*
* 0x0000 0x0004 0x0008 MDP sync config
*/
#ifdef CONFIG_FB_MSM_MDP22
#define MDP_SYNCFG_HGT_LOC 22
#define MDP_SYNCFG_VSYNC_EXT_EN BIT(21)
#define MDP_SYNCFG_VSYNC_INT_EN BIT(20)
#else
#define MDP_SYNCFG_HGT_LOC 21
#define MDP_SYNCFG_VSYNC_EXT_EN BIT(20)
#define MDP_SYNCFG_VSYNC_INT_EN BIT(19)
#define MDP_HW_VSYNC
#endif
/*
* 0x0018 MDP VSYNC THREASH
*/
#define MDP_PRIM_BELOW_LOC 0
#define MDP_PRIM_ABOVE_LOC 8
/*
* MDP_PRIMARY_VSYNC_OUT_CTRL
* 0x0080,84,88 internal vsync pulse config
*/
#define VSYNC_PULSE_EN BIT(31)
#define VSYNC_PULSE_INV BIT(30)
/*
* 0x008c MDP VSYNC CONTROL
*/
#define DISP0_VSYNC_MAP_VSYNC0 0
#define DISP0_VSYNC_MAP_VSYNC1 BIT(0)
#define DISP0_VSYNC_MAP_VSYNC2 BIT(0)|BIT(1)
#define DISP1_VSYNC_MAP_VSYNC0 0
#define DISP1_VSYNC_MAP_VSYNC1 BIT(2)
#define DISP1_VSYNC_MAP_VSYNC2 BIT(2)|BIT(3)
#define PRIMARY_LCD_SYNC_EN BIT(4)
#define PRIMARY_LCD_SYNC_DISABLE 0
#define SECONDARY_LCD_SYNC_EN BIT(5)
#define SECONDARY_LCD_SYNC_DISABLE 0
#define EXTERNAL_LCD_SYNC_EN BIT(6)
#define EXTERNAL_LCD_SYNC_DISABLE 0
/*
* 0x101f0 MDP VSYNC Threshold
*/
#define VSYNC_THRESHOLD_ABOVE_LOC 0
#define VSYNC_THRESHOLD_BELOW_LOC 16
#define VSYNC_ANTI_TEAR_EN BIT(31)
/*
* 0x10004 command config
*/
#define MDP_CMD_DBGBUS_EN BIT(0)
/*
* 0x10124 or 0x101d4PPP source config
*/
#define PPP_SRC_C0G_8BITS (BIT(1)|BIT(0))
#define PPP_SRC_C1B_8BITS (BIT(3)|BIT(2))
#define PPP_SRC_C2R_8BITS (BIT(5)|BIT(4))
#define PPP_SRC_C3A_8BITS (BIT(7)|BIT(6))
#define PPP_SRC_C0G_6BITS BIT(1)
#define PPP_SRC_C1B_6BITS BIT(3)
#define PPP_SRC_C2R_6BITS BIT(5)
#define PPP_SRC_C0G_5BITS BIT(0)
#define PPP_SRC_C1B_5BITS BIT(2)
#define PPP_SRC_C2R_5BITS BIT(4)
#define PPP_SRC_C3_ALPHA_EN BIT(8)
#define PPP_SRC_BPP_INTERLVD_1BYTES 0
#define PPP_SRC_BPP_INTERLVD_2BYTES BIT(9)
#define PPP_SRC_BPP_INTERLVD_3BYTES BIT(10)
#define PPP_SRC_BPP_INTERLVD_4BYTES (BIT(10)|BIT(9))
#define PPP_SRC_BPP_ROI_ODD_X BIT(11)
#define PPP_SRC_BPP_ROI_ODD_Y BIT(12)
#define PPP_SRC_INTERLVD_2COMPONENTS BIT(13)
#define PPP_SRC_INTERLVD_3COMPONENTS BIT(14)
#define PPP_SRC_INTERLVD_4COMPONENTS (BIT(14)|BIT(13))
/*
* RGB666 unpack format
* TIGHT means R6+G6+B6 together
* LOOSE means R6+2 +G6+2+ B6+2 (with MSB)
* or 2+R6 +2+G6 +2+B6 (with LSB)
*/
#define PPP_SRC_UNPACK_TIGHT BIT(17)
#define PPP_SRC_UNPACK_LOOSE 0
#define PPP_SRC_UNPACK_ALIGN_LSB 0
#define PPP_SRC_UNPACK_ALIGN_MSB BIT(18)
#define PPP_SRC_FETCH_PLANES_INTERLVD 0
#define PPP_SRC_FETCH_PLANES_PSEUDOPLNR BIT(20)
#define PPP_SRC_WMV9_MODE BIT(21) /* window media version 9 */
/*
* 0x10138 PPP operation config
*/
#define PPP_OP_SCALE_X_ON BIT(0)
#define PPP_OP_SCALE_Y_ON BIT(1)
#define PPP_OP_CONVERT_RGB2YCBCR 0
#define PPP_OP_CONVERT_YCBCR2RGB BIT(2)
#define PPP_OP_CONVERT_ON BIT(3)
#define PPP_OP_CONVERT_MATRIX_PRIMARY 0
#define PPP_OP_CONVERT_MATRIX_SECONDARY BIT(4)
#define PPP_OP_LUT_C0_ON BIT(5)
#define PPP_OP_LUT_C1_ON BIT(6)
#define PPP_OP_LUT_C2_ON BIT(7)
/* rotate or blend enable */
#define PPP_OP_ROT_ON BIT(8)
#define PPP_OP_ROT_90 BIT(9)
#define PPP_OP_FLIP_LR BIT(10)
#define PPP_OP_FLIP_UD BIT(11)
#define PPP_OP_BLEND_ON BIT(12)
#define PPP_OP_BLEND_SRCPIXEL_ALPHA 0
#define PPP_OP_BLEND_DSTPIXEL_ALPHA BIT(13)
#define PPP_OP_BLEND_CONSTANT_ALPHA BIT(14)
#define PPP_OP_BLEND_SRCPIXEL_TRANSP (BIT(13)|BIT(14))
#define PPP_OP_BLEND_ALPHA_BLEND_NORMAL 0
#define PPP_OP_BLEND_ALPHA_BLEND_REVERSE BIT(15)
#define PPP_OP_DITHER_EN BIT(16)
#define PPP_OP_COLOR_SPACE_RGB 0
#define PPP_OP_COLOR_SPACE_YCBCR BIT(17)
#define PPP_OP_SRC_CHROMA_RGB 0
#define PPP_OP_SRC_CHROMA_H2V1 BIT(18)
#define PPP_OP_SRC_CHROMA_H1V2 BIT(19)
#define PPP_OP_SRC_CHROMA_420 (BIT(18)|BIT(19))
#define PPP_OP_SRC_CHROMA_COSITE 0
#define PPP_OP_SRC_CHROMA_OFFSITE BIT(20)
#define PPP_OP_DST_CHROMA_RGB 0
#define PPP_OP_DST_CHROMA_H2V1 BIT(21)
#define PPP_OP_DST_CHROMA_H1V2 BIT(22)
#define PPP_OP_DST_CHROMA_420 (BIT(21)|BIT(22))
#define PPP_OP_DST_CHROMA_COSITE 0
#define PPP_OP_DST_CHROMA_OFFSITE BIT(23)
#define PPP_BLEND_CALPHA_TRNASP BIT(24)
#define PPP_OP_BG_CHROMA_RGB 0
#define PPP_OP_BG_CHROMA_H2V1 BIT(25)
#define PPP_OP_BG_CHROMA_H1V2 BIT(26)
#define PPP_OP_BG_CHROMA_420 BIT(25)|BIT(26)
#define PPP_OP_BG_CHROMA_SITE_COSITE 0
#define PPP_OP_BG_CHROMA_SITE_OFFSITE BIT(27)
#define PPP_OP_DEINT_EN BIT(29)
#define PPP_BLEND_BG_USE_ALPHA_SEL (1 << 0)
#define PPP_BLEND_BG_ALPHA_REVERSE (1 << 3)
#define PPP_BLEND_BG_SRCPIXEL_ALPHA (0 << 1)
#define PPP_BLEND_BG_DSTPIXEL_ALPHA (1 << 1)
#define PPP_BLEND_BG_CONSTANT_ALPHA (2 << 1)
#define PPP_BLEND_BG_CONST_ALPHA_VAL(x) ((x) << 24)
#define PPP_OP_DST_RGB 0
#define PPP_OP_DST_YCBCR BIT(30)
/*
* 0x10150 PPP destination config
*/
#define PPP_DST_C0G_8BIT (BIT(0)|BIT(1))
#define PPP_DST_C1B_8BIT (BIT(3)|BIT(2))
#define PPP_DST_C2R_8BIT (BIT(5)|BIT(4))
#define PPP_DST_C3A_8BIT (BIT(7)|BIT(6))
#define PPP_DST_C0G_6BIT BIT(1)
#define PPP_DST_C1B_6BIT BIT(3)
#define PPP_DST_C2R_6BIT BIT(5)
#define PPP_DST_C0G_5BIT BIT(0)
#define PPP_DST_C1B_5BIT BIT(2)
#define PPP_DST_C2R_5BIT BIT(4)
#define PPP_DST_C3A_8BIT (BIT(7)|BIT(6))
#define PPP_DST_C3ALPHA_EN BIT(8)
#define PPP_DST_PACKET_CNT_INTERLVD_2ELEM BIT(9)
#define PPP_DST_PACKET_CNT_INTERLVD_3ELEM BIT(10)
#define PPP_DST_PACKET_CNT_INTERLVD_4ELEM (BIT(10)|BIT(9))
#define PPP_DST_PACKET_CNT_INTERLVD_6ELEM (BIT(11)|BIT(9))
#define PPP_DST_PACK_LOOSE 0
#define PPP_DST_PACK_TIGHT BIT(13)
#define PPP_DST_PACK_ALIGN_LSB 0
#define PPP_DST_PACK_ALIGN_MSB BIT(14)
#define PPP_DST_OUT_SEL_AXI 0
#define PPP_DST_OUT_SEL_MDDI BIT(15)
#define PPP_DST_BPP_2BYTES BIT(16)
#define PPP_DST_BPP_3BYTES BIT(17)
#define PPP_DST_BPP_4BYTES (BIT(17)|BIT(16))
#define PPP_DST_PLANE_INTERLVD 0
#define PPP_DST_PLANE_PLANAR BIT(18)
#define PPP_DST_PLANE_PSEUDOPLN BIT(19)
#define PPP_DST_TO_TV BIT(20)
#define PPP_DST_MDDI_PRIMARY 0
#define PPP_DST_MDDI_SECONDARY BIT(21)
#define PPP_DST_MDDI_EXTERNAL BIT(22)
/*
* 0x10180 DMA config
*/
#define DMA_DSTC0G_8BITS (BIT(1)|BIT(0))
#define DMA_DSTC1B_8BITS (BIT(3)|BIT(2))
#define DMA_DSTC2R_8BITS (BIT(5)|BIT(4))
#define DMA_DSTC0G_6BITS BIT(1)
#define DMA_DSTC1B_6BITS BIT(3)
#define DMA_DSTC2R_6BITS BIT(5)
#define DMA_DSTC0G_5BITS BIT(0)
#define DMA_DSTC1B_5BITS BIT(2)
#define DMA_DSTC2R_5BITS BIT(4)
#define DMA_PACK_TIGHT BIT(6)
#define DMA_PACK_LOOSE 0
#define DMA_PACK_ALIGN_LSB 0
/*
* use DMA_PACK_ALIGN_MSB if the upper 6 bits from 8 bits output
* from LCDC block maps into 6 pins out to the panel
*/
#define DMA_PACK_ALIGN_MSB BIT(7)
#define DMA_PACK_PATTERN_RGB \
(MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 2)<<8)
#define DMA_PACK_PATTERN_BGR \
(MDP_GET_PACK_PATTERN(0, CLR_B, CLR_G, CLR_R, 2)<<8)
#define DMA_OUT_SEL_AHB 0
#define DMA_OUT_SEL_LCDC BIT(20)
#define DMA_IBUF_FORMAT_RGB888 0
#define DMA_IBUF_FORMAT_xRGB8888_OR_ARGB8888 BIT(26)
#ifdef CONFIG_FB_MSM_MDP22
#define DMA_OUT_SEL_MDDI BIT(14)
#define DMA_AHBM_LCD_SEL_PRIMARY 0
#define DMA_AHBM_LCD_SEL_SECONDARY BIT(15)
#define DMA_IBUF_C3ALPHA_EN BIT(16)
#define DMA_DITHER_EN BIT(17)
#define DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY 0
#define DMA_MDDI_DMAOUT_LCD_SEL_SECONDARY BIT(18)
#define DMA_MDDI_DMAOUT_LCD_SEL_EXTERNAL BIT(19)
#define DMA_IBUF_FORMAT_RGB565 BIT(20)
#define DMA_IBUF_FORMAT_RGB888_OR_ARGB8888 0
#define DMA_IBUF_NONCONTIGUOUS BIT(21)
#else
#define DMA_OUT_SEL_MDDI BIT(19)
#define DMA_AHBM_LCD_SEL_PRIMARY 0
#define DMA_AHBM_LCD_SEL_SECONDARY 0
#define DMA_IBUF_C3ALPHA_EN 0
#define DMA_DITHER_EN BIT(24)
#define DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY 0
#define DMA_MDDI_DMAOUT_LCD_SEL_SECONDARY 0
#define DMA_MDDI_DMAOUT_LCD_SEL_EXTERNAL 0
#define DMA_IBUF_FORMAT_RGB565 BIT(25)
#define DMA_IBUF_NONCONTIGUOUS 0
#endif
/*
* MDDI Register
*/
#define MDDI_VDO_PACKET_DESC 0x5666
#ifdef CONFIG_FB_MSM_MDP40
#define MDP_INTR_ENABLE (msm_mdp_base + 0x0050)
#define MDP_INTR_STATUS (msm_mdp_base + 0x0054)
#define MDP_INTR_CLEAR (msm_mdp_base + 0x0058)
#define MDP_EBI2_LCD0 (msm_mdp_base + 0x0060)
#define MDP_EBI2_LCD1 (msm_mdp_base + 0x0064)
#define MDP_EBI2_PORTMAP_MODE (msm_mdp_base + 0x0070)
#define MDP_DMA_P_HIST_INTR_STATUS (msm_mdp_base + 0x95014)
#define MDP_DMA_P_HIST_INTR_CLEAR (msm_mdp_base + 0x95018)
#define MDP_DMA_P_HIST_INTR_ENABLE (msm_mdp_base + 0x9501C)
#else
#define MDP_INTR_ENABLE (msm_mdp_base + 0x0020)
#define MDP_INTR_STATUS (msm_mdp_base + 0x0024)
#define MDP_INTR_CLEAR (msm_mdp_base + 0x0028)
#define MDP_EBI2_LCD0 (msm_mdp_base + 0x003c)
#define MDP_EBI2_LCD1 (msm_mdp_base + 0x0040)
#define MDP_EBI2_PORTMAP_MODE (msm_mdp_base + 0x005c)
#endif
#define MDP_FULL_BYPASS_WORD43 (msm_mdp_base + 0x101ac)
#define MDP_CSC_PFMVn(n) (msm_mdp_base + 0x40400 + 4 * (n))
#define MDP_CSC_PRMVn(n) (msm_mdp_base + 0x40440 + 4 * (n))
#define MDP_CSC_PRE_BV1n(n) (msm_mdp_base + 0x40500 + 4 * (n))
#define MDP_CSC_PRE_BV2n(n) (msm_mdp_base + 0x40540 + 4 * (n))
#define MDP_CSC_POST_BV1n(n) (msm_mdp_base + 0x40580 + 4 * (n))
#define MDP_CSC_POST_BV2n(n) (msm_mdp_base + 0x405c0 + 4 * (n))
#ifdef CONFIG_FB_MSM_MDP31
#define MDP_CSC_PRE_LV1n(n) (msm_mdp_base + 0x40600 + 4 * (n))
#define MDP_CSC_PRE_LV2n(n) (msm_mdp_base + 0x40640 + 4 * (n))
#define MDP_CSC_POST_LV1n(n) (msm_mdp_base + 0x40680 + 4 * (n))
#define MDP_CSC_POST_LV2n(n) (msm_mdp_base + 0x406c0 + 4 * (n))
#define MDP_PPP_SCALE_COEFF_LSBn(n) (msm_mdp_base + 0x50400 + 8 * (n))
#define MDP_PPP_SCALE_COEFF_MSBn(n) (msm_mdp_base + 0x50404 + 8 * (n))
#define SCALE_D0_SET 0
#define SCALE_D1_SET BIT(0)
#define SCALE_D2_SET BIT(1)
#define SCALE_U1_SET (BIT(0)|BIT(1))
#else
#define MDP_CSC_PRE_LV1n(n) (msm_mdp_base + 0x40580 + 4 * (n))
#endif
#define MDP_CURSOR_WIDTH 64
#define MDP_CURSOR_HEIGHT 64
#define MDP_CURSOR_SIZE (MDP_CURSOR_WIDTH*MDP_CURSOR_WIDTH*4)
#define MDP_DMA_P_LUT_C0_EN BIT(0)
#define MDP_DMA_P_LUT_C1_EN BIT(1)
#define MDP_DMA_P_LUT_C2_EN BIT(2)
#define MDP_DMA_P_LUT_POST BIT(4)
void mdp_hw_init(void);
int mdp_ppp_pipe_wait(void);
void mdp_pipe_kickoff(uint32 term, struct msm_fb_data_type *mfd);
void mdp_pipe_ctrl(MDP_BLOCK_TYPE block, MDP_BLOCK_POWER_STATE state,
boolean isr);
void mdp_set_dma_pan_info(struct fb_info *info, struct mdp_dirty_region *dirty,
boolean sync);
void mdp_dma_pan_update(struct fb_info *info);
void mdp_refresh_screen(unsigned long data);
int mdp_ppp_blit(struct fb_info *info, struct mdp_blit_req *req,
struct file **pp_src, struct file **pp_dest);
void mdp_lcd_update_workqueue_handler(struct work_struct *work);
void mdp_vsync_resync_workqueue_handler(struct work_struct *work);
void mdp_dma2_update(struct msm_fb_data_type *mfd);
void mdp_config_vsync(struct msm_fb_data_type *);
uint32 mdp_get_lcd_line_counter(struct msm_fb_data_type *mfd);
enum hrtimer_restart mdp_dma2_vsync_hrtimer_handler(struct hrtimer *ht);
void mdp_set_scale(MDPIBUF *iBuf,
uint32 dst_roi_width,
uint32 dst_roi_height,
boolean inputRGB, boolean outputRGB, uint32 *pppop_reg_ptr);
void mdp_init_scale_table(void);
void mdp_adjust_start_addr(uint8 **src0,
uint8 **src1,
int v_slice,
int h_slice,
int x,
int y,
uint32 width,
uint32 height, int bpp, MDPIBUF *iBuf, int layer);
void mdp_set_blend_attr(MDPIBUF *iBuf,
uint32 *alpha,
uint32 *tpVal,
uint32 perPixelAlpha, uint32 *pppop_reg_ptr);
int mdp_dma3_on(struct platform_device *pdev);
int mdp_dma3_off(struct platform_device *pdev);
void mdp_dma3_update(struct msm_fb_data_type *mfd);
int mdp_lcdc_on(struct platform_device *pdev);
int mdp_lcdc_off(struct platform_device *pdev);
void mdp_lcdc_update(struct msm_fb_data_type *mfd);
int mdp_hw_cursor_update(struct fb_info *info, struct fb_cursor *cursor);
void mdp_enable_irq(uint32 term);
void mdp_disable_irq(uint32 term);
void mdp_disable_irq_nolock(uint32 term);
uint32_t mdp_get_bytes_per_pixel(uint32_t format);
#ifdef MDP_HW_VSYNC
void mdp_hw_vsync_clk_enable(struct msm_fb_data_type *mfd);
void mdp_hw_vsync_clk_disable(struct msm_fb_data_type *mfd);
#endif
void mdp_dma_s_update(struct msm_fb_data_type *mfd);
/* Added to support flipping */
void mdp_set_offset_info(struct fb_info *info, uint32 address, uint32 interval);
int get_gem_img(struct mdp_img *img, unsigned long *start,
unsigned long *len);
int get_img(struct mdp_img *img, struct fb_info *info,
unsigned long *start, unsigned long *len,
struct file **pp_file);
/*int get_img(struct msmfb_data *img, struct fb_info *info,
unsigned long *start, unsigned long *len, struct file **pp_file);*/
#endif /* MDP_H */

View file

@ -1,336 +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.
*/
#ifndef MDP4_H
#define MDP4_H
extern struct mdp_dma_data dma2_data;
extern struct mdp_dma_data dma_s_data;
extern struct mdp_dma_data dma_e_data;
extern struct mdp_histogram mdp_hist;
extern struct completion mdp_hist_comp;
extern boolean mdp_is_in_isr;
extern uint32 mdp_intr_mask;
extern spinlock_t mdp_spin_lock;
#define MDP4_NONBLOCKING /* enable non blocking ioctl */
#define MDP4_OVERLAYPROC0_BASE 0x10000
#define MDP4_OVERLAYPROC1_BASE 0x18000
#define MDP4_VIDEO_BASE 0x20000
#define MDP4_VIDEO_OFF 0x10000
#define MDP4_RGB_BASE 0x40000
#define MDP4_RGB_OFF 0x10000
enum { /* display */
PRIMARY_INTF_SEL,
SECONDARY_INTF_SEL,
EXTERNAL_INTF_SEL
};
enum {
LCDC_RGB_INTF,
DTV_INTF = LCDC_RGB_INTF,
MDDI_LCDC_INTF,
MDDI_INTF,
EBI2_INTF
};
enum {
MDDI_PRIMARY_SET,
MDDI_SECONDARY_SET,
MDDI_EXTERNAL_SET
};
enum {
EBI2_LCD0,
EBI2_LCD1
};
enum {
OVERLAY_MODE_NONE,
OVERLAY_MODE_BLT
};
enum {
OVERLAY_REFRESH_ON_DEMAND,
OVERLAY_REFRESH_VSYNC,
OVERLAY_REFRESH_VSYNC_HALF,
OVERLAY_REFRESH_VSYNC_QUARTER
};
enum {
OVERLAY_FRAMEBUF,
OVERLAY_DIRECTOUT
};
/* system interrupts */
#define INTR_OVERLAY0_DONE BIT(0)
#define INTR_OVERLAY1_DONE BIT(1)
#define INTR_DMA_S_DONE BIT(2)
#define INTR_DMA_E_DONE BIT(3)
#define INTR_DMA_P_DONE BIT(4)
#define INTR_VG1_HISTOGRAM BIT(5)
#define INTR_VG2_HISTOGRAM BIT(6)
#define INTR_PRIMARY_VSYNC BIT(7)
#define INTR_PRIMARY_INTF_UDERRUN BIT(8)
#define INTR_EXTERNAL_VSYNC BIT(9)
#define INTR_EXTERNAL_INTF_UDERRUN BIT(10)
#define INTR_DMA_P_HISTOGRAM BIT(17)
/* histogram interrupts */
#define INTR_HIST_DONE BIT(0)
#define INTR_HIST_RESET_SEQ_DONE BIT(1)
#ifdef CONFIG_FB_MSM_OVERLAY
#define MDP4_ANY_INTR_MASK (INTR_OVERLAY0_DONE)
#else
#define MDP4_ANY_INTR_MASK (INTR_DMA_P_DONE)
#endif
enum {
OVERLAY_PIPE_RGB1,
OVERLAY_PIPE_RGB2,
};
enum {
OVERLAY_PIPE_VG1, /* video/graphic */
OVERLAY_PIPE_VG2
};
enum {
OVERLAY_TYPE_RGB,
OVERLAY_TYPE_VG /* video/graphic */
};
enum {
MDP4_MIXER0,
MDP4_MIXER1
};
#define MDP4_MAX_MIXER 2
enum {
OVERLAY_PLANE_INTERLEAVED,
OVERLAY_PLANE_PLANAR,
OVERLAY_PLANE_PSEUDO_PLANAR
};
enum {
MDP4_MIXER_STAGE_UNUNSED, /* pipe not used */
MDP4_MIXER_STAGE_BASE,
MDP4_MIXER_STAGE0, /* zorder 0 */
MDP4_MIXER_STAGE1, /* zorder 1 */
MDP4_MIXER_STAGE2 /* zorder 2 */
};
#define MDP4_MAX_STAGE 4
enum {
MDP4_FRAME_FORMAT_LINEAR,
MDP4_FRAME_FORMAT_ARGB_TILE,
MDP4_FRAME_FORMAT_VIDEO_SUPERTILE
};
enum {
MDP4_CHROMA_RGB,
MDP4_CHROMA_H2V1,
MDP4_CHROMA_H1V2,
MDP4_CHROMA_420
};
#define MDP4_BLEND_BG_TRANSP_EN BIT(9)
#define MDP4_BLEND_FG_TRANSP_EN BIT(8)
#define MDP4_BLEND_BG_MOD_ALPHA BIT(7)
#define MDP4_BLEND_BG_INV_ALPHA BIT(6)
#define MDP4_BLEND_BG_ALPHA_FG_CONST (0 << 4)
#define MDP4_BLEND_BG_ALPHA_BG_CONST (1 << 4)
#define MDP4_BLEND_BG_ALPHA_FG_PIXEL (2 << 4)
#define MDP4_BLEND_BG_ALPHA_BG_PIXEL (3 << 4)
#define MDP4_BLEND_FG_MOD_ALPHA BIT(3)
#define MDP4_BLEND_FG_INV_ALPHA BIT(2)
#define MDP4_BLEND_FG_ALPHA_FG_CONST (0 << 0)
#define MDP4_BLEND_FG_ALPHA_BG_CONST (1 << 0)
#define MDP4_BLEND_FG_ALPHA_FG_PIXEL (2 << 0)
#define MDP4_BLEND_FG_ALPHA_BG_PIXEL (3 << 0)
#define MDP4_FORMAT_SOLID_FILL BIT(22)
#define MDP4_FORMAT_UNPACK_ALIGN_MSB BIT(18)
#define MDP4_FORMAT_UNPACK_TIGHT BIT(17)
#define MDP4_FORMAT_90_ROTATED BIT(12)
#define MDP4_FORMAT_ALPHA_ENABLE BIT(8)
#define MDP4_OP_DEINT_ODD_REF BIT(19)
#define MDP4_OP_IGC_LUT_EN BIT(16)
#define MDP4_OP_DITHER_EN BIT(15)
#define MDP4_OP_FLIP_UD BIT(14)
#define MDP4_OP_FLIP_LR BIT(13)
#define MDP4_OP_CSC_EN BIT(11)
#define MDP4_OP_SRC_DATA_YCBCR BIT(9)
#define MDP4_OP_SCALEY_FIR (0 << 4)
#define MDP4_OP_SCALEY_MN_PHASE (1 << 4)
#define MDP4_OP_SCALEY_PIXEL_RPT (2 << 4)
#define MDP4_OP_SCALEX_FIR (0 << 2)
#define MDP4_OP_SCALEX_MN_PHASE (1 << 2)
#define MDP4_OP_SCALEX_PIXEL_RPT (2 << 2)
#define MDP4_OP_SCALEY_EN BIT(1)
#define MDP4_OP_SCALEX_EN BIT(0)
#define MDP4_PIPE_PER_MIXER 2
#define MDP4_MAX_PLANE 4
#define MDP4_MAX_VIDEO_PIPE 2
#define MDP4_MAX_RGB_PIPE 2
#define MDP4_MAX_OVERLAY_PIPE 16
struct mdp4_overlay_pipe {
uint32 pipe_type; /* rgb, video/graphic */
uint32 pipe_num;
uint32 pipe_ndx;
uint32 mixer_num; /* which mixer used */
uint32 mixer_stage; /* which stage of mixer used */
uint32 src_format;
uint32 src_width; /* source img width */
uint32 src_height; /* source img height */
uint32 src_w; /* roi */
uint32 src_h; /* roi */
uint32 src_x; /* roi */
uint32 src_y; /* roi */
uint32 dst_w; /* roi */
uint32 dst_h; /* roi */
uint32 dst_x; /* roi */
uint32 dst_y; /* roi */
uint32 op_mode;
uint32 transp;
uint32 blend_op;
uint32 phasex_step;
uint32 phasey_step;
uint32 alpha;
uint32 is_fg; /* control alpha & color key */
uint32 srcp0_addr; /* interleave, luma */
uint32 srcp0_ystride;
uint32 srcp1_addr; /* pseudoplanar, chroma plane */
uint32 srcp1_ystride;
uint32 srcp2_addr; /* planar color 2*/
uint32 srcp2_ystride;
uint32 srcp3_addr; /* alpha/color 3 */
uint32 srcp3_ystride;
uint32 fetch_plane;
uint32 frame_format; /* video */
uint32 chroma_site; /* video */
uint32 chroma_sample; /* video */
uint32 solid_fill;
uint32 vc1_reduce; /* video */
uint32 fatch_planes; /* video */
uint32 unpack_align_msb;/* 0 to LSB, 1 to MSB */
uint32 unpack_tight;/* 0 for loose, 1 for tight */
uint32 unpack_count;/* 0 = 1 component, 1 = 2 component ... */
uint32 rotated_90; /* has been rotated 90 degree */
uint32 bpp; /* byte per pixel */
uint32 alpha_enable;/* source has alpha */
/*
* number of bits for source component,
* 0 = 1 bit, 1 = 2 bits, 2 = 6 bits, 3 = 8 bits
*/
uint32 a_bit; /* component 3, alpha */
uint32 r_bit; /* component 2, R_Cr */
uint32 b_bit; /* component 1, B_Cb */
uint32 g_bit; /* component 0, G_lumz */
/*
* unpack pattern
* A = C3, R = C2, B = C1, G = C0
*/
uint32 element3; /* 0 = C0, 1 = C1, 2 = C2, 3 = C3 */
uint32 element2; /* 0 = C0, 1 = C1, 2 = C2, 3 = C3 */
uint32 element1; /* 0 = C0, 1 = C1, 2 = C2, 3 = C3 */
uint32 element0; /* 0 = C0, 1 = C1, 2 = C2, 3 = C3 */
struct completion comp;
struct mdp_overlay req_data;
};
void mdp4_sw_reset(unsigned long bits);
void mdp4_display_intf_sel(int output, unsigned long intf);
void mdp4_overlay_cfg(int layer, int blt_mode, int refresh, int direct_out);
void mdp4_ebi2_lcd_setup(int lcd, unsigned long base, int ystride);
void mdp4_mddi_setup(int which, unsigned long id);
unsigned long mdp4_display_status(void);
void mdp4_enable_clk_irq(void);
void mdp4_disable_clk_irq(void);
void mdp4_dma_p_update(struct msm_fb_data_type *mfd);
void mdp4_dma_s_update(struct msm_fb_data_type *mfd);
void mdp_pipe_ctrl(MDP_BLOCK_TYPE block, MDP_BLOCK_POWER_STATE state,
boolean isr);
void mdp4_pipe_kickoff(uint32 pipe, struct msm_fb_data_type *mfd);
int mdp4_lcdc_on(struct platform_device *pdev);
int mdp4_lcdc_off(struct platform_device *pdev);
void mdp4_lcdc_update(struct msm_fb_data_type *mfd);
void mdp4_intr_clear_set(ulong clear, ulong set);
void mdp4_dma_p_cfg(void);
void mdp4_hw_init(void);
void mdp4_isr_read(int);
void mdp4_clear_lcdc(void);
void mdp4_mixer_blend_init(int mixer_num);
void mdp4_vg_qseed_init(int vg_num);
void mdp4_vg_csc_mv_setup(int vp_num);
void mdp4_vg_csc_pre_bv_setup(int vp_num);
void mdp4_vg_csc_post_bv_setup(int vp_num);
void mdp4_vg_csc_pre_lv_setup(int vp_num);
void mdp4_vg_csc_post_lv_setup(int vp_num);
irqreturn_t mdp4_isr(int irq, void *ptr);
void mdp4_overlay_format_to_pipe(uint32 format, struct mdp4_overlay_pipe *pipe);
uint32 mdp4_overlay_format(struct mdp4_overlay_pipe *pipe);
uint32 mdp4_overlay_unpack_pattern(struct mdp4_overlay_pipe *pipe);
uint32 mdp4_overlay_op_mode(struct mdp4_overlay_pipe *pipe);
void mdp4_lcdc_overlay(struct msm_fb_data_type *mfd);
void mdp4_overlay_rgb_setup(struct mdp4_overlay_pipe *pipe);
void mdp4_overlay_reg_flush(struct mdp4_overlay_pipe *pipe, int all);
void mdp4_mixer_blend_setup(struct mdp4_overlay_pipe *pipe);
void mdp4_mixer_stage_up(struct mdp4_overlay_pipe *pipe);
void mdp4_mixer_stage_down(struct mdp4_overlay_pipe *pipe);
int mdp4_mixer_stage_can_run(struct mdp4_overlay_pipe *pipe);
void mdp4_overlayproc_cfg(struct mdp4_overlay_pipe *pipe);
void mdp4_mddi_overlay(struct msm_fb_data_type *mfd);
int mdp4_overlay_format2type(uint32 format);
int mdp4_overlay_format2pipe(struct mdp4_overlay_pipe *pipe);
int mdp4_overlay_get(struct fb_info *info, struct mdp_overlay *req);
int mdp4_overlay_set(struct fb_info *info, struct mdp_overlay *req);
int mdp4_overlay_unset(struct fb_info *info, int ndx);
int mdp4_overlay_play(struct fb_info *info, struct msmfb_overlay_data *req,
struct file **pp_src_file);
struct mdp4_overlay_pipe *mdp4_overlay_pipe_alloc(void);
void mdp4_overlay_pipe_free(struct mdp4_overlay_pipe *pipe);
void mdp4_overlay_dmap_cfg(struct msm_fb_data_type *mfd, int lcdc);
void mdp4_overlay_dmap_xy(struct mdp4_overlay_pipe *pipe);
int mdp4_overlay_active(int mixer);
void mdp4_overlay0_done_lcdc(void);
void mdp4_overlay0_done_mddi(void);
void mdp4_mddi_overlay_restore(void);
void mdp4_mddi_overlay_kickoff(struct msm_fb_data_type *mfd,
struct mdp4_overlay_pipe *pipe);
void mdp4_rgb_igc_lut_setup(int num);
void mdp4_vg_igc_lut_setup(int num);
void mdp4_mixer_gc_lut_setup(int mixer_num);
#ifdef CONFIG_DEBUG_FS
int mdp4_debugfs_init(void);
#endif
int mdp_ppp_blit(struct fb_info *info, struct mdp_blit_req *req,
struct file **pp_src_file, struct file **pp_dst_file);
#endif /* MDP_H */

View file

@ -1,175 +0,0 @@
/* Copyright (c) 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 <asm/system.h>
#include <asm/mach-types.h>
#include <linux/semaphore.h>
#include <linux/uaccess.h>
#include "mdp.h"
#include "msm_fb.h"
#include "mdp4.h"
#define MDP4_DEBUG_BUF 128
static char mdp4_debug_buf[MDP4_DEBUG_BUF];
static ulong mdp4_debug_offset;
static ulong mdp4_base_addr;
static int mdp4_offset_set(void *data, u64 val)
{
mdp4_debug_offset = (int)val;
return 0;
}
static int mdp4_offset_get(void *data, u64 *val)
{
*val = (u64)mdp4_debug_offset;
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(
mdp4_offset_fops,
mdp4_offset_get,
mdp4_offset_set,
"%llx\n");
static int mdp4_debugfs_release(struct inode *inode, struct file *file)
{
return 0;
}
static ssize_t mdp4_debugfs_write(
struct file *file,
const char __user *buff,
size_t count,
loff_t *ppos)
{
int cnt;
unsigned int data;
printk(KERN_INFO "%s: offset=%d count=%d *ppos=%d\n",
__func__, (int)mdp4_debug_offset, (int)count, (int)*ppos);
if (count > sizeof(mdp4_debug_buf))
return -EFAULT;
if (copy_from_user(mdp4_debug_buf, buff, count))
return -EFAULT;
mdp4_debug_buf[count] = 0; /* end of string */
cnt = sscanf(mdp4_debug_buf, "%x", &data);
if (cnt < 1) {
printk(KERN_ERR "%s: sscanf failed cnt=%d" , __func__, cnt);
return -EINVAL;
}
writel(&data, mdp4_base_addr + mdp4_debug_offset);
return 0;
}
static ssize_t mdp4_debugfs_read(
struct file *file,
char __user *buff,
size_t count,
loff_t *ppos)
{
int len = 0;
unsigned int data;
printk(KERN_INFO "%s: offset=%d count=%d *ppos=%d\n",
__func__, (int)mdp4_debug_offset, (int)count, (int)*ppos);
if (*ppos)
return 0; /* the end */
data = readl(mdp4_base_addr + mdp4_debug_offset);
len = snprintf(mdp4_debug_buf, 4, "%x\n", data);
if (len > 0) {
if (len > count)
len = count;
if (copy_to_user(buff, mdp4_debug_buf, len))
return -EFAULT;
}
printk(KERN_INFO "%s: len=%d\n", __func__, len);
if (len < 0)
return 0;
*ppos += len; /* increase offset */
return len;
}
static const struct file_operations mdp4_debugfs_fops = {
.open = nonseekable_open,
.release = mdp4_debugfs_release,
.read = mdp4_debugfs_read,
.write = mdp4_debugfs_write,
.llseek = no_llseek,
};
int mdp4_debugfs_init(void)
{
struct dentry *dent = debugfs_create_dir("mdp4", NULL);
if (IS_ERR(dent)) {
printk(KERN_ERR "%s(%d): debugfs_create_dir fail, error %ld\n",
__FILE__, __LINE__, PTR_ERR(dent));
return -1;
}
if (debugfs_create_file("offset", 0644, dent, 0, &mdp4_offset_fops)
== NULL) {
printk(KERN_ERR "%s(%d): debugfs_create_file: offset fail\n",
__FILE__, __LINE__);
return -1;
}
if (debugfs_create_file("regs", 0644, dent, 0, &mdp4_debugfs_fops)
== NULL) {
printk(KERN_ERR "%s(%d): debugfs_create_file: regs fail\n",
__FILE__, __LINE__);
return -1;
}
mdp4_debug_offset = 0;
mdp4_base_addr = (ulong) msm_mdp_base; /* defined at msm_fb_def.h */
return 0;
}

File diff suppressed because it is too large Load diff

View file

@ -1,313 +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/hrtimer.h>
#include <linux/delay.h>
#include <mach/hardware.h>
#include <linux/io.h>
#include <asm/system.h>
#include <asm/mach-types.h>
#include <linux/semaphore.h>
#include <linux/spinlock.h>
#include <linux/fb.h>
#include "mdp.h"
#include "msm_fb.h"
#include "mdp4.h"
#ifdef CONFIG_FB_MSM_MDP40
#define LCDC_BASE 0xC0000
#else
#define LCDC_BASE 0xE0000
#endif
int first_pixel_start_x;
int first_pixel_start_y;
static struct mdp4_overlay_pipe *lcdc_pipe;
int mdp_lcdc_on(struct platform_device *pdev)
{
int lcdc_width;
int lcdc_height;
int lcdc_bpp;
int lcdc_border_clr;
int lcdc_underflow_clr;
int lcdc_hsync_skew;
int hsync_period;
int hsync_ctrl;
int vsync_period;
int display_hctl;
int display_v_start;
int display_v_end;
int active_hctl;
int active_h_start;
int active_h_end;
int active_v_start;
int active_v_end;
int ctrl_polarity;
int h_back_porch;
int h_front_porch;
int v_back_porch;
int v_front_porch;
int hsync_pulse_width;
int vsync_pulse_width;
int hsync_polarity;
int vsync_polarity;
int data_en_polarity;
int hsync_start_x;
int hsync_end_x;
uint8 *buf;
int bpp, ptype;
uint32 format;
struct fb_info *fbi;
struct fb_var_screeninfo *var;
struct msm_fb_data_type *mfd;
struct mdp4_overlay_pipe *pipe;
int ret;
mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
if (!mfd)
return -ENODEV;
if (mfd->key != MFD_KEY)
return -EINVAL;
fbi = mfd->fbi;
var = &fbi->var;
/* MDP cmd block enable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
bpp = fbi->var.bits_per_pixel / 8;
buf = (uint8 *) fbi->fix.smem_start;
buf += fbi->var.xoffset * bpp +
fbi->var.yoffset * fbi->fix.line_length;
if (bpp == 2)
format = MDP_RGB_565;
else if (bpp == 3)
format = MDP_RGB_888;
else
format = MDP_ARGB_8888;
if (lcdc_pipe == NULL) {
ptype = mdp4_overlay_format2type(format);
pipe = mdp4_overlay_pipe_alloc();
pipe->pipe_type = ptype;
/* use RGB1 pipe */
pipe->pipe_num = OVERLAY_PIPE_RGB1;
pipe->mixer_stage = MDP4_MIXER_STAGE_BASE;
pipe->mixer_num = MDP4_MIXER0;
pipe->src_format = format;
mdp4_overlay_format2pipe(pipe);
lcdc_pipe = pipe; /* keep it */
} else {
pipe = lcdc_pipe;
}
pipe->src_height = fbi->var.yres;
pipe->src_width = fbi->var.xres;
pipe->src_h = fbi->var.yres;
pipe->src_w = fbi->var.xres;
pipe->src_y = 0;
pipe->src_x = 0;
pipe->srcp0_addr = (uint32) buf;
pipe->srcp0_ystride = fbi->fix.line_length;
mdp4_overlay_dmap_xy(pipe);
mdp4_overlay_dmap_cfg(mfd, 1);
mdp4_overlay_rgb_setup(pipe);
mdp4_mixer_stage_up(pipe);
mdp4_overlayproc_cfg(pipe);
/*
* LCDC timing setting
*/
h_back_porch = var->left_margin;
h_front_porch = var->right_margin;
v_back_porch = var->upper_margin;
v_front_porch = var->lower_margin;
hsync_pulse_width = var->hsync_len;
vsync_pulse_width = var->vsync_len;
lcdc_border_clr = mfd->panel_info.lcdc.border_clr;
lcdc_underflow_clr = mfd->panel_info.lcdc.underflow_clr;
lcdc_hsync_skew = mfd->panel_info.lcdc.hsync_skew;
lcdc_width = mfd->panel_info.xres;
lcdc_height = mfd->panel_info.yres;
lcdc_bpp = mfd->panel_info.bpp;
hsync_period =
hsync_pulse_width + h_back_porch + lcdc_width + h_front_porch;
hsync_ctrl = (hsync_period << 16) | hsync_pulse_width;
hsync_start_x = hsync_pulse_width + h_back_porch;
hsync_end_x = hsync_period - h_front_porch - 1;
display_hctl = (hsync_end_x << 16) | hsync_start_x;
vsync_period =
(vsync_pulse_width + v_back_porch + lcdc_height +
v_front_porch) * hsync_period;
display_v_start =
(vsync_pulse_width + v_back_porch) * hsync_period + lcdc_hsync_skew;
display_v_end =
vsync_period - (v_front_porch * hsync_period) + lcdc_hsync_skew - 1;
if (lcdc_width != var->xres) {
active_h_start = hsync_start_x + first_pixel_start_x;
active_h_end = active_h_start + var->xres - 1;
active_hctl =
ACTIVE_START_X_EN | (active_h_end << 16) | active_h_start;
} else {
active_hctl = 0;
}
if (lcdc_height != var->yres) {
active_v_start =
display_v_start + first_pixel_start_y * hsync_period;
active_v_end = active_v_start + (var->yres) * hsync_period - 1;
active_v_start |= ACTIVE_START_Y_EN;
} else {
active_v_start = 0;
active_v_end = 0;
}
#ifdef CONFIG_FB_MSM_MDP40
hsync_polarity = 1;
vsync_polarity = 1;
lcdc_underflow_clr |= 0x80000000; /* enable recovery */
#else
hsync_polarity = 0;
vsync_polarity = 0;
#endif
data_en_polarity = 0;
ctrl_polarity =
(data_en_polarity << 2) | (vsync_polarity << 1) | (hsync_polarity);
MDP_OUTP(MDP_BASE + LCDC_BASE + 0x4, hsync_ctrl);
MDP_OUTP(MDP_BASE + LCDC_BASE + 0x8, vsync_period);
MDP_OUTP(MDP_BASE + LCDC_BASE + 0xc, vsync_pulse_width * hsync_period);
MDP_OUTP(MDP_BASE + LCDC_BASE + 0x10, display_hctl);
MDP_OUTP(MDP_BASE + LCDC_BASE + 0x14, display_v_start);
MDP_OUTP(MDP_BASE + LCDC_BASE + 0x18, display_v_end);
MDP_OUTP(MDP_BASE + LCDC_BASE + 0x28, lcdc_border_clr);
MDP_OUTP(MDP_BASE + LCDC_BASE + 0x2c, lcdc_underflow_clr);
MDP_OUTP(MDP_BASE + LCDC_BASE + 0x30, lcdc_hsync_skew);
MDP_OUTP(MDP_BASE + LCDC_BASE + 0x38, ctrl_polarity);
MDP_OUTP(MDP_BASE + LCDC_BASE + 0x1c, active_hctl);
MDP_OUTP(MDP_BASE + LCDC_BASE + 0x20, active_v_start);
MDP_OUTP(MDP_BASE + LCDC_BASE + 0x24, active_v_end);
ret = panel_next_on(pdev);
if (ret == 0) {
/* enable LCDC block */
MDP_OUTP(MDP_BASE + LCDC_BASE, 1);
mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
}
/* MDP cmd block disable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
return ret;
}
int mdp_lcdc_off(struct platform_device *pdev)
{
int ret = 0;
struct mdp4_overlay_pipe *pipe;
/* MDP cmd block enable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
MDP_OUTP(MDP_BASE + LCDC_BASE, 0);
/* MDP cmd block disable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
ret = panel_next_off(pdev);
/* delay to make sure the last frame finishes */
mdelay(100);
/* dis-engage rgb0 from mixer */
pipe = lcdc_pipe;
mdp4_mixer_stage_down(pipe);
return ret;
}
/*
* mdp4_overlay0_done_lcdc: called from isr
*/
void mdp4_overlay0_done_lcdc()
{
complete(&lcdc_pipe->comp);
}
void mdp4_lcdc_overlay(struct msm_fb_data_type *mfd)
{
struct fb_info *fbi = mfd->fbi;
uint8 *buf;
int bpp;
unsigned long flag;
struct mdp4_overlay_pipe *pipe;
if (!mfd->panel_power_on)
return;
/* no need to power on cmd block since it's lcdc mode */
bpp = fbi->var.bits_per_pixel / 8;
buf = (uint8 *) fbi->fix.smem_start;
buf += fbi->var.xoffset * bpp +
fbi->var.yoffset * fbi->fix.line_length;
mutex_lock(&mfd->dma->ov_mutex);
pipe = lcdc_pipe;
pipe->srcp0_addr = (uint32) buf;
mdp4_overlay_rgb_setup(pipe);
mdp4_overlay_reg_flush(pipe, 1); /* rgb1 and mixer0 */
/* enable irq */
spin_lock_irqsave(&mdp_spin_lock, flag);
mdp_enable_irq(MDP_OVERLAY0_TERM);
INIT_COMPLETION(lcdc_pipe->comp);
mfd->dma->waiting = TRUE;
outp32(MDP_INTR_CLEAR, INTR_OVERLAY0_DONE);
mdp_intr_mask |= INTR_OVERLAY0_DONE;
outp32(MDP_INTR_ENABLE, mdp_intr_mask);
spin_unlock_irqrestore(&mdp_spin_lock, flag);
wait_for_completion_killable(&lcdc_pipe->comp);
mdp_disable_irq(MDP_OVERLAY0_TERM);
mutex_unlock(&mfd->dma->ov_mutex);
}

View file

@ -1,254 +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/hrtimer.h>
#include <linux/delay.h>
#include <mach/hardware.h>
#include <linux/io.h>
#include <asm/system.h>
#include <asm/mach-types.h>
#include <linux/semaphore.h>
#include <linux/spinlock.h>
#include <linux/fb.h>
#include "mdp.h"
#include "msm_fb.h"
#include "mdp4.h"
static struct mdp4_overlay_pipe *mddi_pipe;
static struct mdp4_overlay_pipe *pending_pipe;
static struct msm_fb_data_type *mddi_mfd;
#define WHOLESCREEN
void mdp4_overlay_update_lcd(struct msm_fb_data_type *mfd)
{
MDPIBUF *iBuf = &mfd->ibuf;
uint8 *src;
int bpp, ptype;
uint32 format;
uint32 mddi_ld_param;
uint16 mddi_vdo_packet_reg;
struct mdp4_overlay_pipe *pipe;
if (mfd->key != MFD_KEY)
return;
mddi_mfd = mfd; /* keep it */
bpp = iBuf->bpp;
if (bpp == 2)
format = MDP_RGB_565;
else if (bpp == 3)
format = MDP_RGB_888;
else
format = MDP_ARGB_8888;
/* MDP cmd block enable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
if (mddi_pipe == NULL) {
ptype = mdp4_overlay_format2type(format);
pipe = mdp4_overlay_pipe_alloc();
pipe->pipe_type = ptype;
/* use RGB1 pipe */
pipe->pipe_num = OVERLAY_PIPE_RGB1;
pipe->mixer_num = MDP4_MIXER0;
pipe->src_format = format;
mdp4_overlay_format2pipe(pipe);
mddi_pipe = pipe; /* keep it */
mddi_ld_param = 0;
mddi_vdo_packet_reg = mfd->panel_info.mddi.vdopkt;
if (mfd->panel_info.type == MDDI_PANEL) {
if (mfd->panel_info.pdest == DISPLAY_1)
mddi_ld_param = 0;
else
mddi_ld_param = 1;
} else {
mddi_ld_param = 2;
}
MDP_OUTP(MDP_BASE + 0x00090, mddi_ld_param);
MDP_OUTP(MDP_BASE + 0x00094,
(MDDI_VDO_PACKET_DESC << 16) | mddi_vdo_packet_reg);
} else {
pipe = mddi_pipe;
}
src = (uint8 *) iBuf->buf;
#ifdef WHOLESCREEN
{
struct fb_info *fbi;
fbi = mfd->fbi;
pipe->src_height = fbi->var.yres;
pipe->src_width = fbi->var.xres;
pipe->src_h = fbi->var.yres;
pipe->src_w = fbi->var.xres;
pipe->src_y = 0;
pipe->src_x = 0;
pipe->dst_h = fbi->var.yres;
pipe->dst_w = fbi->var.xres;
pipe->dst_y = 0;
pipe->dst_x = 0;
pipe->srcp0_addr = (uint32)src;
pipe->srcp0_ystride = fbi->var.xres_virtual * bpp;
}
#else
if (mdp4_overlay_active(MDP4_MIXER0)) {
struct fb_info *fbi;
fbi = mfd->fbi;
pipe->src_height = fbi->var.yres;
pipe->src_width = fbi->var.xres;
pipe->src_h = fbi->var.yres;
pipe->src_w = fbi->var.xres;
pipe->src_y = 0;
pipe->src_x = 0;
pipe->dst_h = fbi->var.yres;
pipe->dst_w = fbi->var.xres;
pipe->dst_y = 0;
pipe->dst_x = 0;
pipe->srcp0_addr = (uint32) src;
pipe->srcp0_ystride = fbi->var.xres_virtual * bpp;
} else {
/* starting input address */
src += (iBuf->dma_x + iBuf->dma_y * iBuf->ibuf_width) * bpp;
pipe->src_height = iBuf->dma_h;
pipe->src_width = iBuf->dma_w;
pipe->src_h = iBuf->dma_h;
pipe->src_w = iBuf->dma_w;
pipe->src_y = 0;
pipe->src_x = 0;
pipe->dst_h = iBuf->dma_h;
pipe->dst_w = iBuf->dma_w;
pipe->dst_y = iBuf->dma_y;
pipe->dst_x = iBuf->dma_x;
pipe->srcp0_addr = (uint32) src;
pipe->srcp0_ystride = iBuf->ibuf_width * bpp;
}
#endif
pipe->mixer_stage = MDP4_MIXER_STAGE_BASE;
mdp4_overlay_rgb_setup(pipe);
mdp4_mixer_stage_up(pipe);
mdp4_overlayproc_cfg(pipe);
mdp4_overlay_dmap_xy(pipe);
mdp4_overlay_dmap_cfg(mfd, 0);
/* MDP cmd block disable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
}
/*
* mdp4_overlay0_done_mddi: called from isr
*/
void mdp4_overlay0_done_mddi()
{
if (pending_pipe)
complete(&pending_pipe->comp);
}
void mdp4_mddi_overlay_restore(void)
{
/* mutex holded by caller */
mdp4_overlay_update_lcd(mddi_mfd);
mdp4_mddi_overlay_kickoff(mddi_mfd, mddi_pipe);
}
void mdp4_mddi_overlay_kickoff(struct msm_fb_data_type *mfd,
struct mdp4_overlay_pipe *pipe)
{
#ifdef MDP4_NONBLOCKING
unsigned long flag;
spin_lock_irqsave(&mdp_spin_lock, flag);
if (mfd->dma->busy == TRUE) {
INIT_COMPLETION(pipe->comp);
pending_pipe = pipe;
}
spin_unlock_irqrestore(&mdp_spin_lock, flag);
if (pending_pipe != NULL) {
/* wait until DMA finishes the current job */
wait_for_completion_killable(&pipe->comp);
pending_pipe = NULL;
}
down(&mfd->sem);
mdp_enable_irq(MDP_OVERLAY0_TERM);
mfd->dma->busy = TRUE;
/* start OVERLAY pipe */
mdp_pipe_kickoff(MDP_OVERLAY0_TERM, mfd);
up(&mfd->sem);
#else
down(&mfd->sem);
mdp_enable_irq(MDP_OVERLAY0_TERM);
mfd->dma->busy = TRUE;
INIT_COMPLETION(pipe->comp);
pending_pipe = pipe;
/* start OVERLAY pipe */
mdp_pipe_kickoff(MDP_OVERLAY0_TERM, mfd);
up(&mfd->sem);
/* wait until DMA finishes the current job */
wait_for_completion_killable(&pipe->comp);
mdp_disable_irq(MDP_OVERLAY0_TERM);
#endif
}
void mdp4_mddi_overlay(struct msm_fb_data_type *mfd)
{
mutex_lock(&mfd->dma->ov_mutex);
if ((mfd) && (!mfd->dma->busy) && (mfd->panel_power_on)) {
mdp4_overlay_update_lcd(mfd);
mdp4_mddi_overlay_kickoff(mfd, mddi_pipe);
/* signal if pan function is waiting for the update completion */
if (mfd->pan_waiting) {
mfd->pan_waiting = FALSE;
complete(&mfd->pan_comp);
}
}
mutex_unlock(&mfd->dma->ov_mutex);
}

File diff suppressed because it is too large Load diff

View file

@ -1,104 +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/hrtimer.h>
#include <mach/hardware.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/mach-types.h>
#include <linux/semaphore.h>
#include <linux/spinlock.h>
#include <linux/fb.h>
#include "mdp.h"
#include "msm_fb.h"
static int cursor_enabled;
int mdp_hw_cursor_update(struct fb_info *info, struct fb_cursor *cursor)
{
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
struct fb_image *img = &cursor->image;
int calpha_en, transp_en;
int alpha;
int ret = 0;
if ((img->width > MDP_CURSOR_WIDTH) ||
(img->height > MDP_CURSOR_HEIGHT) ||
(img->depth != 32))
return -EINVAL;
if (cursor->set & FB_CUR_SETPOS)
MDP_OUTP(MDP_BASE + 0x9004c, (img->dy << 16) | img->dx);
if (cursor->set & FB_CUR_SETIMAGE) {
ret = copy_from_user(mfd->cursor_buf, img->data,
img->width*img->height*4);
if (ret)
return ret;
if (img->bg_color == 0xffffffff)
transp_en = 0;
else
transp_en = 1;
alpha = (img->fg_color & 0xff000000) >> 24;
if (alpha)
calpha_en = 0x2; /* xrgb */
else
calpha_en = 0x1; /* argb */
MDP_OUTP(MDP_BASE + 0x90044, (img->height << 16) | img->width);
MDP_OUTP(MDP_BASE + 0x90048, mfd->cursor_buf_phys);
/* order the writes the cursor_buf before updating the
* hardware */
// dma_coherent_pre_ops();
MDP_OUTP(MDP_BASE + 0x90060,
(transp_en << 3) | (calpha_en << 1) |
(inp32(MDP_BASE + 0x90060) & 0x1));
#ifdef CONFIG_FB_MSM_MDP40
MDP_OUTP(MDP_BASE + 0x90064, (alpha << 24));
MDP_OUTP(MDP_BASE + 0x90068, (0xffffff & img->bg_color));
MDP_OUTP(MDP_BASE + 0x9006C, (0xffffff & img->bg_color));
#else
MDP_OUTP(MDP_BASE + 0x90064,
(alpha << 24) | (0xffffff & img->bg_color));
MDP_OUTP(MDP_BASE + 0x90068, 0);
#endif
}
if ((cursor->enable) && (!cursor_enabled)) {
cursor_enabled = 1;
MDP_OUTP(MDP_BASE + 0x90060, inp32(MDP_BASE + 0x90060) | 0x1);
} else if ((!cursor->enable) && (cursor_enabled)) {
cursor_enabled = 0;
MDP_OUTP(MDP_BASE + 0x90060,
inp32(MDP_BASE + 0x90060) & (~0x1));
}
return 0;
}

View file

@ -1,561 +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/hrtimer.h>
#include <mach/hardware.h>
#include <linux/io.h>
#include <asm/system.h>
#include <asm/mach-types.h>
#include <linux/semaphore.h>
#include <linux/spinlock.h>
#include <linux/fb.h>
#include "mdp.h"
#include "msm_fb.h"
#include "mddihost.h"
static uint32 mdp_last_dma2_update_width;
static uint32 mdp_last_dma2_update_height;
static uint32 mdp_curr_dma2_update_width;
static uint32 mdp_curr_dma2_update_height;
ktime_t mdp_dma2_last_update_time = { 0 };
int mdp_lcd_rd_cnt_offset_slow = 20;
int mdp_lcd_rd_cnt_offset_fast = 20;
int mdp_vsync_usec_wait_line_too_short = 5;
uint32 mdp_dma2_update_time_in_usec;
uint32 mdp_total_vdopkts;
extern u32 msm_fb_debug_enabled;
extern struct workqueue_struct *mdp_dma_wq;
int vsync_start_y_adjust = 4;
static void mdp_dma2_update_lcd(struct msm_fb_data_type *mfd)
{
MDPIBUF *iBuf = &mfd->ibuf;
int mddi_dest = FALSE;
uint32 outBpp = iBuf->bpp;
uint32 dma2_cfg_reg;
uint8 *src;
uint32 mddi_ld_param;
uint16 mddi_vdo_packet_reg;
struct msm_fb_panel_data *pdata =
(struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
uint32 ystride = mfd->fbi->fix.line_length;
dma2_cfg_reg = DMA_PACK_TIGHT | DMA_PACK_ALIGN_LSB |
DMA_OUT_SEL_AHB | DMA_IBUF_NONCONTIGUOUS;
#ifdef CONFIG_FB_MSM_MDP30
/*
* Software workaround: On 7x25/7x27, the MDP will not
* respond if dma_w is 1 pixel. Set the update width to
* 2 pixels and adjust the x offset if needed.
*/
if (iBuf->dma_w == 1) {
iBuf->dma_w = 2;
if (iBuf->dma_x == (iBuf->ibuf_width - 2))
iBuf->dma_x--;
}
#endif
if (mfd->fb_imgType == MDP_BGR_565)
dma2_cfg_reg |= DMA_PACK_PATTERN_BGR;
else
dma2_cfg_reg |= DMA_PACK_PATTERN_RGB;
if (outBpp == 4)
dma2_cfg_reg |= DMA_IBUF_C3ALPHA_EN;
if (outBpp == 2)
dma2_cfg_reg |= DMA_IBUF_FORMAT_RGB565;
mddi_ld_param = 0;
mddi_vdo_packet_reg = mfd->panel_info.mddi.vdopkt;
if ((mfd->panel_info.type == MDDI_PANEL) ||
(mfd->panel_info.type == EXT_MDDI_PANEL)) {
dma2_cfg_reg |= DMA_OUT_SEL_MDDI;
mddi_dest = TRUE;
if (mfd->panel_info.type == MDDI_PANEL) {
mdp_total_vdopkts++;
if (mfd->panel_info.pdest == DISPLAY_1) {
dma2_cfg_reg |= DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY;
mddi_ld_param = 0;
#ifdef MDDI_HOST_WINDOW_WORKAROUND
mddi_window_adjust(mfd, iBuf->dma_x,
iBuf->dma_w - 1, iBuf->dma_y,
iBuf->dma_h - 1);
#endif
} else {
dma2_cfg_reg |=
DMA_MDDI_DMAOUT_LCD_SEL_SECONDARY;
mddi_ld_param = 1;
#ifdef MDDI_HOST_WINDOW_WORKAROUND
mddi_window_adjust(mfd, iBuf->dma_x,
iBuf->dma_w - 1, iBuf->dma_y,
iBuf->dma_h - 1);
#endif
}
} else {
dma2_cfg_reg |= DMA_MDDI_DMAOUT_LCD_SEL_EXTERNAL;
mddi_ld_param = 2;
}
} else {
if (mfd->panel_info.pdest == DISPLAY_1) {
dma2_cfg_reg |= DMA_AHBM_LCD_SEL_PRIMARY;
outp32(MDP_EBI2_LCD0, mfd->data_port_phys);
} else {
dma2_cfg_reg |= DMA_AHBM_LCD_SEL_SECONDARY;
outp32(MDP_EBI2_LCD1, mfd->data_port_phys);
}
}
dma2_cfg_reg |= DMA_DITHER_EN;
src = (uint8 *) iBuf->buf;
/* starting input address */
src += iBuf->dma_x * outBpp + iBuf->dma_y * ystride;
mdp_curr_dma2_update_width = iBuf->dma_w;
mdp_curr_dma2_update_height = iBuf->dma_h;
/* MDP cmd block enable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
#ifdef CONFIG_FB_MSM_MDP22
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0184,
(iBuf->dma_h << 16 | iBuf->dma_w));
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0188, src);
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x018C, ystride);
#else
MDP_OUTP(MDP_BASE + 0x90004, (iBuf->dma_h << 16 | iBuf->dma_w));
MDP_OUTP(MDP_BASE + 0x90008, src);
MDP_OUTP(MDP_BASE + 0x9000c, ystride);
#endif
if (mfd->panel_info.bpp == 18) {
dma2_cfg_reg |= DMA_DSTC0G_6BITS | /* 666 18BPP */
DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
} else {
dma2_cfg_reg |= DMA_DSTC0G_6BITS | /* 565 16BPP */
DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
}
if (mddi_dest) {
#ifdef CONFIG_FB_MSM_MDP22
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0194,
(iBuf->dma_y << 16) | iBuf->dma_x);
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01a0, mddi_ld_param);
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01a4,
(MDDI_VDO_PACKET_DESC << 16) | mddi_vdo_packet_reg);
#else
MDP_OUTP(MDP_BASE + 0x90010, (iBuf->dma_y << 16) | iBuf->dma_x);
MDP_OUTP(MDP_BASE + 0x00090, mddi_ld_param);
MDP_OUTP(MDP_BASE + 0x00094,
(MDDI_VDO_PACKET_DESC << 16) | mddi_vdo_packet_reg);
#endif
} else {
/* setting EBI2 LCDC write window */
pdata->set_rect(iBuf->dma_x, iBuf->dma_y, iBuf->dma_w,
iBuf->dma_h);
}
/* dma2 config register */
#ifdef MDP_HW_VSYNC
MDP_OUTP(MDP_BASE + 0x90000, dma2_cfg_reg);
if ((mfd->use_mdp_vsync) &&
(mfd->ibuf.vsync_enable) && (mfd->panel_info.lcd.vsync_enable)) {
uint32 start_y;
if (vsync_start_y_adjust <= iBuf->dma_y)
start_y = iBuf->dma_y - vsync_start_y_adjust;
else
start_y =
(mfd->total_lcd_lines - 1) - (vsync_start_y_adjust -
iBuf->dma_y);
/*
* MDP VSYNC clock must be On by now so, we don't have to
* re-enable it
*/
MDP_OUTP(MDP_BASE + 0x210, start_y);
MDP_OUTP(MDP_BASE + 0x20c, 1); /* enable prim vsync */
} else {
MDP_OUTP(MDP_BASE + 0x20c, 0); /* disable prim vsync */
}
#else
#ifdef CONFIG_FB_MSM_MDP22
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0180, dma2_cfg_reg);
#else
MDP_OUTP(MDP_BASE + 0x90000, dma2_cfg_reg);
#endif
#endif /* MDP_HW_VSYNC */
/* MDP cmd block disable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
}
static ktime_t vt = { 0 };
int mdp_usec_diff_threshold = 100;
int mdp_expected_usec_wait;
enum hrtimer_restart mdp_dma2_vsync_hrtimer_handler(struct hrtimer *ht)
{
struct msm_fb_data_type *mfd = NULL;
mfd = container_of(ht, struct msm_fb_data_type, dma_hrtimer);
mdp_pipe_kickoff(MDP_DMA2_TERM, mfd);
if (msm_fb_debug_enabled) {
ktime_t t;
int usec_diff;
int actual_wait;
t = ktime_get_real();
actual_wait =
(t.tv.sec - vt.tv.sec) * 1000000 + (t.tv.nsec -
vt.tv.nsec) / 1000;
usec_diff = actual_wait - mdp_expected_usec_wait;
if ((mdp_usec_diff_threshold < usec_diff) || (usec_diff < 0))
MSM_FB_DEBUG
("HRT Diff = %d usec Exp=%d usec Act=%d usec\n",
usec_diff, mdp_expected_usec_wait, actual_wait);
}
return HRTIMER_NORESTART;
}
static void mdp_dma_schedule(struct msm_fb_data_type *mfd, uint32 term)
{
/*
* dma2 configure VSYNC block
* vsync supported on Primary LCD only for now
*/
int32 mdp_lcd_rd_cnt;
uint32 usec_wait_time;
uint32 start_y;
/*
* ToDo: if we can move HRT timer callback to workqueue, we can
* move DMA2 power on under mdp_pipe_kickoff().
* This will save a power for hrt time wait.
* However if the latency for context switch (hrt irq -> workqueue)
* is too big, we will miss the vsync timing.
*/
if (term == MDP_DMA2_TERM)
mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
mdp_dma2_update_time_in_usec =
MDP_KTIME2USEC(mdp_dma2_last_update_time);
if ((!mfd->ibuf.vsync_enable) || (!mfd->panel_info.lcd.vsync_enable)
|| (mfd->use_mdp_vsync)) {
mdp_pipe_kickoff(term, mfd);
return;
}
/* SW vsync logic starts here */
/* get current rd counter */
mdp_lcd_rd_cnt = mdp_get_lcd_line_counter(mfd);
if (mdp_dma2_update_time_in_usec != 0) {
uint32 num, den;
/*
* roi width boundary calculation to know the size of pixel
* width that MDP can send faster or slower than LCD read
* pointer
*/
num = mdp_last_dma2_update_width * mdp_last_dma2_update_height;
den =
(((mfd->panel_info.lcd.refx100 * mfd->total_lcd_lines) /
1000) * (mdp_dma2_update_time_in_usec / 100)) / 1000;
if (den == 0)
mfd->vsync_width_boundary[mdp_last_dma2_update_width] =
mfd->panel_info.xres + 1;
else
mfd->vsync_width_boundary[mdp_last_dma2_update_width] =
(int)(num / den);
}
if (mfd->vsync_width_boundary[mdp_last_dma2_update_width] >
mdp_curr_dma2_update_width) {
/* MDP wrp is faster than LCD rdp */
mdp_lcd_rd_cnt += mdp_lcd_rd_cnt_offset_fast;
} else {
/* MDP wrp is slower than LCD rdp */
mdp_lcd_rd_cnt -= mdp_lcd_rd_cnt_offset_slow;
}
if (mdp_lcd_rd_cnt < 0)
mdp_lcd_rd_cnt = mfd->total_lcd_lines + mdp_lcd_rd_cnt;
else if (mdp_lcd_rd_cnt > mfd->total_lcd_lines)
mdp_lcd_rd_cnt = mdp_lcd_rd_cnt - mfd->total_lcd_lines - 1;
/* get wrt pointer position */
start_y = mfd->ibuf.dma_y;
/* measure line difference between start_y and rd counter */
if (start_y > mdp_lcd_rd_cnt) {
/*
* *100 for lcd_ref_hzx100 was already multiplied by 100
* *1000000 is for usec conversion
*/
if ((start_y - mdp_lcd_rd_cnt) <=
mdp_vsync_usec_wait_line_too_short)
usec_wait_time = 0;
else
usec_wait_time =
((start_y -
mdp_lcd_rd_cnt) * 1000000) /
((mfd->total_lcd_lines *
mfd->panel_info.lcd.refx100) / 100);
} else {
if ((start_y + (mfd->total_lcd_lines - mdp_lcd_rd_cnt)) <=
mdp_vsync_usec_wait_line_too_short)
usec_wait_time = 0;
else
usec_wait_time =
((start_y +
(mfd->total_lcd_lines -
mdp_lcd_rd_cnt)) * 1000000) /
((mfd->total_lcd_lines *
mfd->panel_info.lcd.refx100) / 100);
}
mdp_last_dma2_update_width = mdp_curr_dma2_update_width;
mdp_last_dma2_update_height = mdp_curr_dma2_update_height;
if (usec_wait_time == 0) {
mdp_pipe_kickoff(term, mfd);
} else {
ktime_t wait_time;
wait_time.tv.sec = 0;
wait_time.tv.nsec = usec_wait_time * 1000;
if (msm_fb_debug_enabled) {
vt = ktime_get_real();
mdp_expected_usec_wait = usec_wait_time;
}
hrtimer_start(&mfd->dma_hrtimer, wait_time, HRTIMER_MODE_REL);
}
}
#ifdef MDDI_HOST_WINDOW_WORKAROUND
void mdp_dma2_update(struct msm_fb_data_type *mfd)
{
MDPIBUF *iBuf;
uint32 upper_height;
if (mfd->panel.type == EXT_MDDI_PANEL) {
mdp_dma2_update_sub(mfd);
return;
}
iBuf = &mfd->ibuf;
upper_height =
(uint32) mddi_assign_pkt_height((uint16) iBuf->dma_w,
(uint16) iBuf->dma_h, 18);
if (upper_height >= iBuf->dma_h) {
mdp_dma2_update_sub(mfd);
} else {
MDPIBUF lower_height;
/* sending the upper region first */
lower_height = iBuf->dma_h - upper_height;
iBuf->dma_h = upper_height;
mdp_dma2_update_sub(mfd);
/* sending the lower region second */
iBuf->dma_h = lower_height;
iBuf->dma_y += lower_height;
iBuf->vsync_enable = FALSE;
mdp_dma2_update_sub(mfd);
}
}
void mdp_dma2_update_sub(struct msm_fb_data_type *mfd)
#else
void mdp_dma2_update(struct msm_fb_data_type *mfd)
#endif
{
down(&mfd->dma->mutex);
if ((mfd) && (!mfd->dma->busy) && (mfd->panel_power_on)) {
down(&mfd->sem);
mfd->ibuf_flushed = TRUE;
mdp_dma2_update_lcd(mfd);
mdp_enable_irq(MDP_DMA2_TERM);
mfd->dma->busy = TRUE;
INIT_COMPLETION(mfd->dma->comp);
/* schedule DMA to start */
mdp_dma_schedule(mfd, MDP_DMA2_TERM);
up(&mfd->sem);
/* wait until DMA finishes the current job */
wait_for_completion_killable(&mfd->dma->comp);
mdp_disable_irq(MDP_DMA2_TERM);
/* signal if pan function is waiting for the update completion */
if (mfd->pan_waiting) {
mfd->pan_waiting = FALSE;
complete(&mfd->pan_comp);
}
}
up(&mfd->dma->mutex);
}
void mdp_lcd_update_workqueue_handler(struct work_struct *work)
{
struct msm_fb_data_type *mfd = NULL;
mfd = container_of(work, struct msm_fb_data_type, dma_update_worker);
if (mfd)
mfd->dma_fnc(mfd);
}
void mdp_set_dma_pan_info(struct fb_info *info, struct mdp_dirty_region *dirty,
boolean sync)
{
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
MDPIBUF *iBuf;
int bpp = info->var.bits_per_pixel / 8;
down(&mfd->sem);
iBuf = &mfd->ibuf;
iBuf->buf = (uint8 *) info->fix.smem_start;
iBuf->buf += info->var.xoffset * bpp +
info->var.yoffset * info->fix.line_length;
iBuf->ibuf_width = info->var.xres_virtual;
iBuf->bpp = bpp;
iBuf->vsync_enable = sync;
if (dirty) {
/*
* ToDo: dirty region check inside var.xoffset+xres
* <-> var.yoffset+yres
*/
iBuf->dma_x = dirty->xoffset % info->var.xres;
iBuf->dma_y = dirty->yoffset % info->var.yres;
iBuf->dma_w = dirty->width;
iBuf->dma_h = dirty->height;
} else {
iBuf->dma_x = 0;
iBuf->dma_y = 0;
iBuf->dma_w = info->var.xres;
iBuf->dma_h = info->var.yres;
}
mfd->ibuf_flushed = FALSE;
up(&mfd->sem);
}
void mdp_set_offset_info(struct fb_info *info, uint32 addr, uint32 sync)
{
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
MDPIBUF *iBuf;
int bpp = info->var.bits_per_pixel / 8;
down(&mfd->sem);
iBuf = &mfd->ibuf;
iBuf->ibuf_width = info->var.xres_virtual;
iBuf->bpp = bpp;
iBuf->vsync_enable = sync;
iBuf->dma_x = 0;
iBuf->dma_y = 0;
iBuf->dma_w = info->var.xres;
iBuf->dma_h = info->var.yres;
iBuf->buf = (uint8 *) addr;
mfd->ibuf_flushed = FALSE;
up(&mfd->sem);
}
void mdp_dma_pan_update(struct fb_info *info)
{
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
MDPIBUF *iBuf;
iBuf = &mfd->ibuf;
if (mfd->sw_currently_refreshing) {
/* we need to wait for the pending update */
mfd->pan_waiting = TRUE;
if (!mfd->ibuf_flushed) {
wait_for_completion_killable(&mfd->pan_comp);
}
/* waiting for this update to complete */
mfd->pan_waiting = TRUE;
wait_for_completion_killable(&mfd->pan_comp);
} else
mfd->dma_fnc(mfd);
}
void mdp_refresh_screen(unsigned long data)
{
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)data;
if ((mfd->sw_currently_refreshing) && (mfd->sw_refreshing_enable)) {
init_timer(&mfd->refresh_timer);
mfd->refresh_timer.function = mdp_refresh_screen;
mfd->refresh_timer.data = data;
if (mfd->dma->busy)
/* come back in 1 msec */
mfd->refresh_timer.expires = jiffies + (HZ / 1000);
else
mfd->refresh_timer.expires =
jiffies + mfd->refresh_timer_duration;
add_timer(&mfd->refresh_timer);
if (!mfd->dma->busy) {
if (!queue_work(mdp_dma_wq, &mfd->dma_update_worker)) {
MSM_FB_DEBUG("mdp_dma: can't queue_work! -> \
MDP/MDDI/LCD clock speed needs to be increased\n");
}
}
} else {
if (!mfd->hw_refresh)
complete(&mfd->refresher_comp);
}
}

View file

@ -1,379 +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/hrtimer.h>
#include <linux/delay.h>
#include <mach/hardware.h>
#include <linux/io.h>
#include <asm/system.h>
#include <asm/mach-types.h>
#include <linux/semaphore.h>
#include <linux/spinlock.h>
#include <linux/fb.h>
#include "mdp.h"
#include "msm_fb.h"
#include "mdp4.h"
#ifdef CONFIG_FB_MSM_MDP40
#define LCDC_BASE 0xC0000
#define DTV_BASE 0xD0000
#define DMA_E_BASE 0xB0000
#else
#define LCDC_BASE 0xE0000
#endif
#define DMA_P_BASE 0x90000
extern spinlock_t mdp_spin_lock;
#ifndef CONFIG_FB_MSM_MDP40
extern uint32 mdp_intr_mask;
#endif
int first_pixel_start_x;
int first_pixel_start_y;
int mdp_lcdc_on(struct platform_device *pdev)
{
int lcdc_width;
int lcdc_height;
int lcdc_bpp;
int lcdc_border_clr;
int lcdc_underflow_clr;
int lcdc_hsync_skew;
int hsync_period;
int hsync_ctrl;
int vsync_period;
int display_hctl;
int display_v_start;
int display_v_end;
int active_hctl;
int active_h_start;
int active_h_end;
int active_v_start;
int active_v_end;
int ctrl_polarity;
int h_back_porch;
int h_front_porch;
int v_back_porch;
int v_front_porch;
int hsync_pulse_width;
int vsync_pulse_width;
int hsync_polarity;
int vsync_polarity;
int data_en_polarity;
int hsync_start_x;
int hsync_end_x;
uint8 *buf;
int bpp;
uint32 dma2_cfg_reg;
struct fb_info *fbi;
struct fb_var_screeninfo *var;
struct msm_fb_data_type *mfd;
uint32 dma_base;
uint32 timer_base = LCDC_BASE;
uint32 block = MDP_DMA2_BLOCK;
int ret;
mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
if (!mfd)
return -ENODEV;
if (mfd->key != MFD_KEY)
return -EINVAL;
fbi = mfd->fbi;
var = &fbi->var;
/* MDP cmd block enable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
bpp = fbi->var.bits_per_pixel / 8;
buf = (uint8 *) fbi->fix.smem_start;
buf += fbi->var.xoffset * bpp + fbi->var.yoffset * fbi->fix.line_length;
dma2_cfg_reg = DMA_PACK_ALIGN_LSB | DMA_DITHER_EN | DMA_OUT_SEL_LCDC;
if (mfd->fb_imgType == MDP_BGR_565)
dma2_cfg_reg |= DMA_PACK_PATTERN_BGR;
else
dma2_cfg_reg |= DMA_PACK_PATTERN_RGB;
if (bpp == 2)
dma2_cfg_reg |= DMA_IBUF_FORMAT_RGB565;
else if (bpp == 3)
dma2_cfg_reg |= DMA_IBUF_FORMAT_RGB888;
else
dma2_cfg_reg |= DMA_IBUF_FORMAT_xRGB8888_OR_ARGB8888;
switch (mfd->panel_info.bpp) {
case 24:
dma2_cfg_reg |= DMA_DSTC0G_8BITS |
DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS;
break;
case 18:
dma2_cfg_reg |= DMA_DSTC0G_6BITS |
DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
break;
case 16:
dma2_cfg_reg |= DMA_DSTC0G_6BITS |
DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
break;
default:
printk(KERN_ERR "mdp lcdc can't support format %d bpp!\n",
mfd->panel_info.bpp);
return -ENODEV;
}
/* DMA register config */
dma_base = DMA_P_BASE;
#ifdef CONFIG_FB_MSM_MDP40
if (mfd->panel.type == HDMI_PANEL)
dma_base = DMA_E_BASE;
#endif
/* starting address */
MDP_OUTP(MDP_BASE + dma_base + 0x8, (uint32) buf);
/* active window width and height */
MDP_OUTP(MDP_BASE + dma_base + 0x4, ((fbi->var.yres) << 16) |
(fbi->var.xres));
/* buffer ystride */
MDP_OUTP(MDP_BASE + dma_base + 0xc, fbi->fix.line_length);
/* x/y coordinate = always 0 for lcdc */
MDP_OUTP(MDP_BASE + dma_base + 0x10, 0);
/* dma config */
MDP_OUTP(MDP_BASE + dma_base, dma2_cfg_reg);
/*
* LCDC timing setting
*/
h_back_porch = var->left_margin;
h_front_porch = var->right_margin;
v_back_porch = var->upper_margin;
v_front_porch = var->lower_margin;
hsync_pulse_width = var->hsync_len;
vsync_pulse_width = var->vsync_len;
lcdc_border_clr = mfd->panel_info.lcdc.border_clr;
lcdc_underflow_clr = mfd->panel_info.lcdc.underflow_clr;
lcdc_hsync_skew = mfd->panel_info.lcdc.hsync_skew;
lcdc_width = mfd->panel_info.xres;
lcdc_height = mfd->panel_info.yres;
lcdc_bpp = mfd->panel_info.bpp;
hsync_period =
hsync_pulse_width + h_back_porch + lcdc_width + h_front_porch;
hsync_ctrl = (hsync_period << 16) | hsync_pulse_width;
hsync_start_x = hsync_pulse_width + h_back_porch;
hsync_end_x = hsync_period - h_front_porch - 1;
display_hctl = (hsync_end_x << 16) | hsync_start_x;
vsync_period =
(vsync_pulse_width + v_back_porch + lcdc_height +
v_front_porch) * hsync_period;
display_v_start =
(vsync_pulse_width + v_back_porch) * hsync_period + lcdc_hsync_skew;
display_v_end =
vsync_period - (v_front_porch * hsync_period) + lcdc_hsync_skew - 1;
if (lcdc_width != var->xres) {
active_h_start = hsync_start_x + first_pixel_start_x;
active_h_end = active_h_start + var->xres - 1;
active_hctl =
ACTIVE_START_X_EN | (active_h_end << 16) | active_h_start;
} else {
active_hctl = 0;
}
if (lcdc_height != var->yres) {
active_v_start =
display_v_start + first_pixel_start_y * hsync_period;
active_v_end = active_v_start + (var->yres) * hsync_period - 1;
active_v_start |= ACTIVE_START_Y_EN;
} else {
active_v_start = 0;
active_v_end = 0;
}
#ifdef CONFIG_FB_MSM_MDP40
if (mfd->panel.type == HDMI_PANEL) {
block = MDP_DMA_E_BLOCK;
timer_base = DTV_BASE;
hsync_polarity = 0;
vsync_polarity = 0;
} else {
hsync_polarity = 1;
vsync_polarity = 1;
}
lcdc_underflow_clr |= 0x80000000; /* enable recovery */
#else
hsync_polarity = 0;
vsync_polarity = 0;
#endif
data_en_polarity = 0;
ctrl_polarity =
(data_en_polarity << 2) | (vsync_polarity << 1) | (hsync_polarity);
MDP_OUTP(MDP_BASE + timer_base + 0x4, hsync_ctrl);
MDP_OUTP(MDP_BASE + timer_base + 0x8, vsync_period);
MDP_OUTP(MDP_BASE + timer_base + 0xc, vsync_pulse_width * hsync_period);
if (timer_base == LCDC_BASE) {
MDP_OUTP(MDP_BASE + timer_base + 0x10, display_hctl);
MDP_OUTP(MDP_BASE + timer_base + 0x14, display_v_start);
MDP_OUTP(MDP_BASE + timer_base + 0x18, display_v_end);
MDP_OUTP(MDP_BASE + timer_base + 0x28, lcdc_border_clr);
MDP_OUTP(MDP_BASE + timer_base + 0x2c, lcdc_underflow_clr);
MDP_OUTP(MDP_BASE + timer_base + 0x30, lcdc_hsync_skew);
MDP_OUTP(MDP_BASE + timer_base + 0x38, ctrl_polarity);
MDP_OUTP(MDP_BASE + timer_base + 0x1c, active_hctl);
MDP_OUTP(MDP_BASE + timer_base + 0x20, active_v_start);
MDP_OUTP(MDP_BASE + timer_base + 0x24, active_v_end);
} else {
MDP_OUTP(MDP_BASE + timer_base + 0x18, display_hctl);
MDP_OUTP(MDP_BASE + timer_base + 0x1c, display_v_start);
MDP_OUTP(MDP_BASE + timer_base + 0x20, display_v_end);
MDP_OUTP(MDP_BASE + timer_base + 0x40, lcdc_border_clr);
MDP_OUTP(MDP_BASE + timer_base + 0x44, lcdc_underflow_clr);
MDP_OUTP(MDP_BASE + timer_base + 0x48, lcdc_hsync_skew);
MDP_OUTP(MDP_BASE + timer_base + 0x50, ctrl_polarity);
MDP_OUTP(MDP_BASE + timer_base + 0x2c, active_hctl);
MDP_OUTP(MDP_BASE + timer_base + 0x30, active_v_start);
MDP_OUTP(MDP_BASE + timer_base + 0x38, active_v_end);
}
ret = panel_next_on(pdev);
if (ret == 0) {
/* enable LCDC block */
MDP_OUTP(MDP_BASE + timer_base, 1);
mdp_pipe_ctrl(block, MDP_BLOCK_POWER_ON, FALSE);
}
/* MDP cmd block disable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
return ret;
}
int mdp_lcdc_off(struct platform_device *pdev)
{
int ret = 0;
struct msm_fb_data_type *mfd;
uint32 timer_base = LCDC_BASE;
uint32 block = MDP_DMA2_BLOCK;
mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
#ifdef CONFIG_FB_MSM_MDP40
if (mfd->panel.type == HDMI_PANEL) {
block = MDP_DMA_E_BLOCK;
timer_base = DTV_BASE;
}
#endif
/* MDP cmd block enable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
MDP_OUTP(MDP_BASE + timer_base, 0);
/* MDP cmd block disable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
mdp_pipe_ctrl(block, MDP_BLOCK_POWER_OFF, FALSE);
ret = panel_next_off(pdev);
/* delay to make sure the last frame finishes */
mdelay(100);
return ret;
}
void mdp_lcdc_update(struct msm_fb_data_type *mfd)
{
struct fb_info *fbi = mfd->fbi;
uint8 *buf;
int bpp;
unsigned long flag;
uint32 dma_base;
int irq_block = MDP_DMA2_TERM;
#ifdef CONFIG_FB_MSM_MDP40
int intr = INTR_DMA_P_DONE;
#endif
if (!mfd->panel_power_on)
return;
/* no need to power on cmd block since it's lcdc mode */
if (!mfd->ibuf.visible_swapped) {
bpp = fbi->var.bits_per_pixel / 8;
buf = (uint8 *) fbi->fix.smem_start;
buf += fbi->var.xoffset * bpp +
fbi->var.yoffset * fbi->fix.line_length;
} else {
/* we've done something to update the pointer. */
bpp = mfd->ibuf.bpp;
buf = mfd->ibuf.buf;
}
dma_base = DMA_P_BASE;
#ifdef CONFIG_FB_MSM_MDP40
if (mfd->panel.type == HDMI_PANEL) {
intr = INTR_DMA_E_DONE;
irq_block = MDP_DMA_E_TERM;
dma_base = DMA_E_BASE;
}
#endif
/* starting address */
MDP_OUTP(MDP_BASE + dma_base + 0x8, (uint32) buf);
/* enable LCDC irq */
spin_lock_irqsave(&mdp_spin_lock, flag);
mdp_enable_irq(irq_block);
INIT_COMPLETION(mfd->dma->comp);
mfd->dma->waiting = TRUE;
#ifdef CONFIG_FB_MSM_MDP40
outp32(MDP_INTR_CLEAR, intr);
mdp_intr_mask |= intr;
outp32(MDP_INTR_ENABLE, mdp_intr_mask);
#else
outp32(MDP_INTR_CLEAR, LCDC_FRAME_START);
mdp_intr_mask |= LCDC_FRAME_START;
outp32(MDP_INTR_ENABLE, mdp_intr_mask);
#endif
spin_unlock_irqrestore(&mdp_spin_lock, flag);
if (mfd->ibuf.vsync_enable)
wait_for_completion_killable(&mfd->dma->comp);
mdp_disable_irq(irq_block);
}

View file

@ -1,139 +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/hrtimer.h>
#include <mach/hardware.h>
#include <linux/io.h>
#include <asm/system.h>
#include <asm/mach-types.h>
#include <linux/semaphore.h>
#include <linux/spinlock.h>
#include <linux/fb.h>
#include "mdp.h"
#include "msm_fb.h"
static void mdp_dma_s_update_lcd(struct msm_fb_data_type *mfd)
{
MDPIBUF *iBuf = &mfd->ibuf;
int mddi_dest = FALSE;
uint32 outBpp = iBuf->bpp;
uint32 dma_s_cfg_reg;
uint8 *src;
struct msm_fb_panel_data *pdata =
(struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
dma_s_cfg_reg = DMA_PACK_TIGHT | DMA_PACK_ALIGN_LSB |
DMA_OUT_SEL_AHB | DMA_IBUF_NONCONTIGUOUS;
if (mfd->fb_imgType == MDP_BGR_565)
dma_s_cfg_reg |= DMA_PACK_PATTERN_BGR;
else
dma_s_cfg_reg |= DMA_PACK_PATTERN_RGB;
if (outBpp == 4)
dma_s_cfg_reg |= DMA_IBUF_C3ALPHA_EN;
if (outBpp == 2)
dma_s_cfg_reg |= DMA_IBUF_FORMAT_RGB565;
if (mfd->panel_info.pdest != DISPLAY_2) {
printk(KERN_ERR "error: non-secondary type through dma_s!\n");
return;
}
if (mfd->panel_info.type == MDDI_PANEL) {
dma_s_cfg_reg |= DMA_OUT_SEL_MDDI;
mddi_dest = TRUE;
} else {
dma_s_cfg_reg |= DMA_AHBM_LCD_SEL_SECONDARY;
outp32(MDP_EBI2_LCD1, mfd->data_port_phys);
}
dma_s_cfg_reg |= DMA_DITHER_EN;
src = (uint8 *) iBuf->buf;
/* starting input address */
src += (iBuf->dma_x + iBuf->dma_y * iBuf->ibuf_width) * outBpp;
/* MDP cmd block enable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
/* PIXELSIZE */
MDP_OUTP(MDP_BASE + 0xa0004, (iBuf->dma_h << 16 | iBuf->dma_w));
MDP_OUTP(MDP_BASE + 0xa0008, src); /* ibuf address */
MDP_OUTP(MDP_BASE + 0xa000c, iBuf->ibuf_width * outBpp);/* ystride */
if (mfd->panel_info.bpp == 18) {
dma_s_cfg_reg |= DMA_DSTC0G_6BITS | /* 666 18BPP */
DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
} else {
dma_s_cfg_reg |= DMA_DSTC0G_6BITS | /* 565 16BPP */
DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
}
if (mddi_dest) {
MDP_OUTP(MDP_BASE + 0xa0010, (iBuf->dma_y << 16) | iBuf->dma_x);
MDP_OUTP(MDP_BASE + 0x00090, 1);
MDP_OUTP(MDP_BASE + 0x00094,
(MDDI_VDO_PACKET_DESC << 16) |
mfd->panel_info.mddi.vdopkt);
} else {
/* setting LCDC write window */
pdata->set_rect(iBuf->dma_x, iBuf->dma_y, iBuf->dma_w,
iBuf->dma_h);
}
MDP_OUTP(MDP_BASE + 0xa0000, dma_s_cfg_reg);
/* MDP cmd block disable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
mdp_pipe_kickoff(MDP_DMA_S_TERM, mfd);
}
void mdp_dma_s_update(struct msm_fb_data_type *mfd)
{
down(&mfd->dma->mutex);
if ((mfd) && (!mfd->dma->busy) && (mfd->panel_power_on)) {
down(&mfd->sem);
mdp_enable_irq(MDP_DMA_S_TERM);
mfd->dma->busy = TRUE;
INIT_COMPLETION(mfd->dma->comp);
mfd->ibuf_flushed = TRUE;
mdp_dma_s_update_lcd(mfd);
up(&mfd->sem);
/* wait until DMA finishes the current job */
wait_for_completion_killable(&mfd->dma->comp);
mdp_disable_irq(MDP_DMA_S_TERM);
/* signal if pan function is waiting for the update completion */
if (mfd->pan_waiting) {
mfd->pan_waiting = FALSE;
complete(&mfd->pan_comp);
}
}
up(&mfd->dma->mutex);
}

View file

@ -1,142 +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/hrtimer.h>
#include <linux/delay.h>
#include <mach/hardware.h>
#include <linux/io.h>
#include <asm/system.h>
#include <asm/mach-types.h>
#include <linux/semaphore.h>
#include <linux/spinlock.h>
#include <linux/fb.h>
#include "mdp.h"
#include "msm_fb.h"
extern spinlock_t mdp_spin_lock;
extern uint32 mdp_intr_mask;
int mdp_dma3_on(struct platform_device *pdev)
{
struct msm_fb_data_type *mfd;
struct fb_info *fbi;
uint8 *buf;
int bpp;
int ret = 0;
mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
if (!mfd)
return -ENODEV;
if (mfd->key != MFD_KEY)
return -EINVAL;
fbi = mfd->fbi;
/* MDP cmd block enable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
bpp = fbi->var.bits_per_pixel / 8;
buf = (uint8 *) fbi->fix.smem_start;
buf += fbi->var.xoffset * bpp +
fbi->var.yoffset * fbi->fix.line_length;
/* starting address[31..8] of Video frame buffer is CS0 */
MDP_OUTP(MDP_BASE + 0xC0008, (uint32) buf >> 3);
mdp_pipe_ctrl(MDP_DMA3_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
MDP_OUTP(MDP_BASE + 0xC0004, 0x4c60674); /* flicker filter enabled */
MDP_OUTP(MDP_BASE + 0xC0010, 0x20); /* sobel treshold */
MDP_OUTP(MDP_BASE + 0xC0018, 0xeb0010); /* Y Max, Y min */
MDP_OUTP(MDP_BASE + 0xC001C, 0xf00010); /* Cb Max, Cb min */
MDP_OUTP(MDP_BASE + 0xC0020, 0xf00010); /* Cb Max, Cb min */
MDP_OUTP(MDP_BASE + 0xC000C, 0x67686970); /* add a few chars for CC */
MDP_OUTP(MDP_BASE + 0xC0000, 0x1); /* MDP tv out enable */
/* MDP cmd block disable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
ret = panel_next_on(pdev);
return ret;
}
int mdp_dma3_off(struct platform_device *pdev)
{
int ret = 0;
ret = panel_next_off(pdev);
if (ret)
return ret;
/* MDP cmd block enable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
MDP_OUTP(MDP_BASE + 0xC0000, 0x0);
/* MDP cmd block disable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
mdp_pipe_ctrl(MDP_DMA3_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
/* delay to make sure the last frame finishes */
mdelay(100);
return ret;
}
void mdp_dma3_update(struct msm_fb_data_type *mfd)
{
struct fb_info *fbi = mfd->fbi;
uint8 *buf;
int bpp;
unsigned long flag;
if (!mfd->panel_power_on)
return;
/* no need to power on cmd block since dma3 is running */
bpp = fbi->var.bits_per_pixel / 8;
buf = (uint8 *) fbi->fix.smem_start;
buf += fbi->var.xoffset * bpp +
fbi->var.yoffset * fbi->fix.line_length;
MDP_OUTP(MDP_BASE + 0xC0008, (uint32) buf >> 3);
spin_lock_irqsave(&mdp_spin_lock, flag);
mdp_enable_irq(MDP_DMA3_TERM);
INIT_COMPLETION(mfd->dma->comp);
mfd->dma->waiting = TRUE;
outp32(MDP_INTR_CLEAR, TV_OUT_DMA3_START);
mdp_intr_mask |= TV_OUT_DMA3_START;
outp32(MDP_INTR_ENABLE, mdp_intr_mask);
spin_unlock_irqrestore(&mdp_spin_lock, flag);
wait_for_completion_killable(&mfd->dma->comp);
mdp_disable_irq(MDP_DMA3_TERM);
}

View file

@ -1,720 +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 "mdp.h"
/* mdp primary csc limit vector */
uint32 mdp_plv[] = { 0x10, 0xeb, 0x10, 0xf0 };
/* Color Coefficient matrix for YUV -> RGB */
struct mdp_ccs mdp_ccs_yuv2rgb = {
MDP_CCS_YUV2RGB,
{
0x254,
0x000,
0x331,
0x254,
0xff38,
0xfe61,
0x254,
0x409,
0x000,
},
{
#ifdef CONFIG_FB_MSM_MDP31
0x1f0,
0x180,
0x180
#else
0x10,
0x80,
0x80
#endif
}
};
/* Color Coefficient matrix for RGB -> YUV */
struct mdp_ccs mdp_ccs_rgb2yuv = {
MDP_CCS_RGB2YUV,
{
0x83,
0x102,
0x32,
0xffb5,
0xff6c,
0xe1,
0xe1,
0xff45,
0xffdc,
},
#ifdef CONFIG_FB_MSM_MDP31
{
0x10,
0x80,
0x80
}
#endif
};
static void mdp_load_lut_param(void)
{
outpdw(MDP_BASE + 0x40800, 0x0);
outpdw(MDP_BASE + 0x40804, 0x151515);
outpdw(MDP_BASE + 0x40808, 0x1d1d1d);
outpdw(MDP_BASE + 0x4080c, 0x232323);
outpdw(MDP_BASE + 0x40810, 0x272727);
outpdw(MDP_BASE + 0x40814, 0x2b2b2b);
outpdw(MDP_BASE + 0x40818, 0x2f2f2f);
outpdw(MDP_BASE + 0x4081c, 0x333333);
outpdw(MDP_BASE + 0x40820, 0x363636);
outpdw(MDP_BASE + 0x40824, 0x393939);
outpdw(MDP_BASE + 0x40828, 0x3b3b3b);
outpdw(MDP_BASE + 0x4082c, 0x3e3e3e);
outpdw(MDP_BASE + 0x40830, 0x404040);
outpdw(MDP_BASE + 0x40834, 0x434343);
outpdw(MDP_BASE + 0x40838, 0x454545);
outpdw(MDP_BASE + 0x4083c, 0x474747);
outpdw(MDP_BASE + 0x40840, 0x494949);
outpdw(MDP_BASE + 0x40844, 0x4b4b4b);
outpdw(MDP_BASE + 0x40848, 0x4d4d4d);
outpdw(MDP_BASE + 0x4084c, 0x4f4f4f);
outpdw(MDP_BASE + 0x40850, 0x515151);
outpdw(MDP_BASE + 0x40854, 0x535353);
outpdw(MDP_BASE + 0x40858, 0x555555);
outpdw(MDP_BASE + 0x4085c, 0x565656);
outpdw(MDP_BASE + 0x40860, 0x585858);
outpdw(MDP_BASE + 0x40864, 0x5a5a5a);
outpdw(MDP_BASE + 0x40868, 0x5b5b5b);
outpdw(MDP_BASE + 0x4086c, 0x5d5d5d);
outpdw(MDP_BASE + 0x40870, 0x5e5e5e);
outpdw(MDP_BASE + 0x40874, 0x606060);
outpdw(MDP_BASE + 0x40878, 0x616161);
outpdw(MDP_BASE + 0x4087c, 0x636363);
outpdw(MDP_BASE + 0x40880, 0x646464);
outpdw(MDP_BASE + 0x40884, 0x666666);
outpdw(MDP_BASE + 0x40888, 0x676767);
outpdw(MDP_BASE + 0x4088c, 0x686868);
outpdw(MDP_BASE + 0x40890, 0x6a6a6a);
outpdw(MDP_BASE + 0x40894, 0x6b6b6b);
outpdw(MDP_BASE + 0x40898, 0x6c6c6c);
outpdw(MDP_BASE + 0x4089c, 0x6e6e6e);
outpdw(MDP_BASE + 0x408a0, 0x6f6f6f);
outpdw(MDP_BASE + 0x408a4, 0x707070);
outpdw(MDP_BASE + 0x408a8, 0x717171);
outpdw(MDP_BASE + 0x408ac, 0x727272);
outpdw(MDP_BASE + 0x408b0, 0x747474);
outpdw(MDP_BASE + 0x408b4, 0x757575);
outpdw(MDP_BASE + 0x408b8, 0x767676);
outpdw(MDP_BASE + 0x408bc, 0x777777);
outpdw(MDP_BASE + 0x408c0, 0x787878);
outpdw(MDP_BASE + 0x408c4, 0x797979);
outpdw(MDP_BASE + 0x408c8, 0x7a7a7a);
outpdw(MDP_BASE + 0x408cc, 0x7c7c7c);
outpdw(MDP_BASE + 0x408d0, 0x7d7d7d);
outpdw(MDP_BASE + 0x408d4, 0x7e7e7e);
outpdw(MDP_BASE + 0x408d8, 0x7f7f7f);
outpdw(MDP_BASE + 0x408dc, 0x808080);
outpdw(MDP_BASE + 0x408e0, 0x818181);
outpdw(MDP_BASE + 0x408e4, 0x828282);
outpdw(MDP_BASE + 0x408e8, 0x838383);
outpdw(MDP_BASE + 0x408ec, 0x848484);
outpdw(MDP_BASE + 0x408f0, 0x858585);
outpdw(MDP_BASE + 0x408f4, 0x868686);
outpdw(MDP_BASE + 0x408f8, 0x878787);
outpdw(MDP_BASE + 0x408fc, 0x888888);
outpdw(MDP_BASE + 0x40900, 0x898989);
outpdw(MDP_BASE + 0x40904, 0x8a8a8a);
outpdw(MDP_BASE + 0x40908, 0x8b8b8b);
outpdw(MDP_BASE + 0x4090c, 0x8c8c8c);
outpdw(MDP_BASE + 0x40910, 0x8d8d8d);
outpdw(MDP_BASE + 0x40914, 0x8e8e8e);
outpdw(MDP_BASE + 0x40918, 0x8f8f8f);
outpdw(MDP_BASE + 0x4091c, 0x8f8f8f);
outpdw(MDP_BASE + 0x40920, 0x909090);
outpdw(MDP_BASE + 0x40924, 0x919191);
outpdw(MDP_BASE + 0x40928, 0x929292);
outpdw(MDP_BASE + 0x4092c, 0x939393);
outpdw(MDP_BASE + 0x40930, 0x949494);
outpdw(MDP_BASE + 0x40934, 0x959595);
outpdw(MDP_BASE + 0x40938, 0x969696);
outpdw(MDP_BASE + 0x4093c, 0x969696);
outpdw(MDP_BASE + 0x40940, 0x979797);
outpdw(MDP_BASE + 0x40944, 0x989898);
outpdw(MDP_BASE + 0x40948, 0x999999);
outpdw(MDP_BASE + 0x4094c, 0x9a9a9a);
outpdw(MDP_BASE + 0x40950, 0x9b9b9b);
outpdw(MDP_BASE + 0x40954, 0x9c9c9c);
outpdw(MDP_BASE + 0x40958, 0x9c9c9c);
outpdw(MDP_BASE + 0x4095c, 0x9d9d9d);
outpdw(MDP_BASE + 0x40960, 0x9e9e9e);
outpdw(MDP_BASE + 0x40964, 0x9f9f9f);
outpdw(MDP_BASE + 0x40968, 0xa0a0a0);
outpdw(MDP_BASE + 0x4096c, 0xa0a0a0);
outpdw(MDP_BASE + 0x40970, 0xa1a1a1);
outpdw(MDP_BASE + 0x40974, 0xa2a2a2);
outpdw(MDP_BASE + 0x40978, 0xa3a3a3);
outpdw(MDP_BASE + 0x4097c, 0xa4a4a4);
outpdw(MDP_BASE + 0x40980, 0xa4a4a4);
outpdw(MDP_BASE + 0x40984, 0xa5a5a5);
outpdw(MDP_BASE + 0x40988, 0xa6a6a6);
outpdw(MDP_BASE + 0x4098c, 0xa7a7a7);
outpdw(MDP_BASE + 0x40990, 0xa7a7a7);
outpdw(MDP_BASE + 0x40994, 0xa8a8a8);
outpdw(MDP_BASE + 0x40998, 0xa9a9a9);
outpdw(MDP_BASE + 0x4099c, 0xaaaaaa);
outpdw(MDP_BASE + 0x409a0, 0xaaaaaa);
outpdw(MDP_BASE + 0x409a4, 0xababab);
outpdw(MDP_BASE + 0x409a8, 0xacacac);
outpdw(MDP_BASE + 0x409ac, 0xadadad);
outpdw(MDP_BASE + 0x409b0, 0xadadad);
outpdw(MDP_BASE + 0x409b4, 0xaeaeae);
outpdw(MDP_BASE + 0x409b8, 0xafafaf);
outpdw(MDP_BASE + 0x409bc, 0xafafaf);
outpdw(MDP_BASE + 0x409c0, 0xb0b0b0);
outpdw(MDP_BASE + 0x409c4, 0xb1b1b1);
outpdw(MDP_BASE + 0x409c8, 0xb2b2b2);
outpdw(MDP_BASE + 0x409cc, 0xb2b2b2);
outpdw(MDP_BASE + 0x409d0, 0xb3b3b3);
outpdw(MDP_BASE + 0x409d4, 0xb4b4b4);
outpdw(MDP_BASE + 0x409d8, 0xb4b4b4);
outpdw(MDP_BASE + 0x409dc, 0xb5b5b5);
outpdw(MDP_BASE + 0x409e0, 0xb6b6b6);
outpdw(MDP_BASE + 0x409e4, 0xb6b6b6);
outpdw(MDP_BASE + 0x409e8, 0xb7b7b7);
outpdw(MDP_BASE + 0x409ec, 0xb8b8b8);
outpdw(MDP_BASE + 0x409f0, 0xb8b8b8);
outpdw(MDP_BASE + 0x409f4, 0xb9b9b9);
outpdw(MDP_BASE + 0x409f8, 0xbababa);
outpdw(MDP_BASE + 0x409fc, 0xbababa);
outpdw(MDP_BASE + 0x40a00, 0xbbbbbb);
outpdw(MDP_BASE + 0x40a04, 0xbcbcbc);
outpdw(MDP_BASE + 0x40a08, 0xbcbcbc);
outpdw(MDP_BASE + 0x40a0c, 0xbdbdbd);
outpdw(MDP_BASE + 0x40a10, 0xbebebe);
outpdw(MDP_BASE + 0x40a14, 0xbebebe);
outpdw(MDP_BASE + 0x40a18, 0xbfbfbf);
outpdw(MDP_BASE + 0x40a1c, 0xc0c0c0);
outpdw(MDP_BASE + 0x40a20, 0xc0c0c0);
outpdw(MDP_BASE + 0x40a24, 0xc1c1c1);
outpdw(MDP_BASE + 0x40a28, 0xc1c1c1);
outpdw(MDP_BASE + 0x40a2c, 0xc2c2c2);
outpdw(MDP_BASE + 0x40a30, 0xc3c3c3);
outpdw(MDP_BASE + 0x40a34, 0xc3c3c3);
outpdw(MDP_BASE + 0x40a38, 0xc4c4c4);
outpdw(MDP_BASE + 0x40a3c, 0xc5c5c5);
outpdw(MDP_BASE + 0x40a40, 0xc5c5c5);
outpdw(MDP_BASE + 0x40a44, 0xc6c6c6);
outpdw(MDP_BASE + 0x40a48, 0xc6c6c6);
outpdw(MDP_BASE + 0x40a4c, 0xc7c7c7);
outpdw(MDP_BASE + 0x40a50, 0xc8c8c8);
outpdw(MDP_BASE + 0x40a54, 0xc8c8c8);
outpdw(MDP_BASE + 0x40a58, 0xc9c9c9);
outpdw(MDP_BASE + 0x40a5c, 0xc9c9c9);
outpdw(MDP_BASE + 0x40a60, 0xcacaca);
outpdw(MDP_BASE + 0x40a64, 0xcbcbcb);
outpdw(MDP_BASE + 0x40a68, 0xcbcbcb);
outpdw(MDP_BASE + 0x40a6c, 0xcccccc);
outpdw(MDP_BASE + 0x40a70, 0xcccccc);
outpdw(MDP_BASE + 0x40a74, 0xcdcdcd);
outpdw(MDP_BASE + 0x40a78, 0xcecece);
outpdw(MDP_BASE + 0x40a7c, 0xcecece);
outpdw(MDP_BASE + 0x40a80, 0xcfcfcf);
outpdw(MDP_BASE + 0x40a84, 0xcfcfcf);
outpdw(MDP_BASE + 0x40a88, 0xd0d0d0);
outpdw(MDP_BASE + 0x40a8c, 0xd0d0d0);
outpdw(MDP_BASE + 0x40a90, 0xd1d1d1);
outpdw(MDP_BASE + 0x40a94, 0xd2d2d2);
outpdw(MDP_BASE + 0x40a98, 0xd2d2d2);
outpdw(MDP_BASE + 0x40a9c, 0xd3d3d3);
outpdw(MDP_BASE + 0x40aa0, 0xd3d3d3);
outpdw(MDP_BASE + 0x40aa4, 0xd4d4d4);
outpdw(MDP_BASE + 0x40aa8, 0xd4d4d4);
outpdw(MDP_BASE + 0x40aac, 0xd5d5d5);
outpdw(MDP_BASE + 0x40ab0, 0xd6d6d6);
outpdw(MDP_BASE + 0x40ab4, 0xd6d6d6);
outpdw(MDP_BASE + 0x40ab8, 0xd7d7d7);
outpdw(MDP_BASE + 0x40abc, 0xd7d7d7);
outpdw(MDP_BASE + 0x40ac0, 0xd8d8d8);
outpdw(MDP_BASE + 0x40ac4, 0xd8d8d8);
outpdw(MDP_BASE + 0x40ac8, 0xd9d9d9);
outpdw(MDP_BASE + 0x40acc, 0xd9d9d9);
outpdw(MDP_BASE + 0x40ad0, 0xdadada);
outpdw(MDP_BASE + 0x40ad4, 0xdbdbdb);
outpdw(MDP_BASE + 0x40ad8, 0xdbdbdb);
outpdw(MDP_BASE + 0x40adc, 0xdcdcdc);
outpdw(MDP_BASE + 0x40ae0, 0xdcdcdc);
outpdw(MDP_BASE + 0x40ae4, 0xdddddd);
outpdw(MDP_BASE + 0x40ae8, 0xdddddd);
outpdw(MDP_BASE + 0x40aec, 0xdedede);
outpdw(MDP_BASE + 0x40af0, 0xdedede);
outpdw(MDP_BASE + 0x40af4, 0xdfdfdf);
outpdw(MDP_BASE + 0x40af8, 0xdfdfdf);
outpdw(MDP_BASE + 0x40afc, 0xe0e0e0);
outpdw(MDP_BASE + 0x40b00, 0xe0e0e0);
outpdw(MDP_BASE + 0x40b04, 0xe1e1e1);
outpdw(MDP_BASE + 0x40b08, 0xe1e1e1);
outpdw(MDP_BASE + 0x40b0c, 0xe2e2e2);
outpdw(MDP_BASE + 0x40b10, 0xe3e3e3);
outpdw(MDP_BASE + 0x40b14, 0xe3e3e3);
outpdw(MDP_BASE + 0x40b18, 0xe4e4e4);
outpdw(MDP_BASE + 0x40b1c, 0xe4e4e4);
outpdw(MDP_BASE + 0x40b20, 0xe5e5e5);
outpdw(MDP_BASE + 0x40b24, 0xe5e5e5);
outpdw(MDP_BASE + 0x40b28, 0xe6e6e6);
outpdw(MDP_BASE + 0x40b2c, 0xe6e6e6);
outpdw(MDP_BASE + 0x40b30, 0xe7e7e7);
outpdw(MDP_BASE + 0x40b34, 0xe7e7e7);
outpdw(MDP_BASE + 0x40b38, 0xe8e8e8);
outpdw(MDP_BASE + 0x40b3c, 0xe8e8e8);
outpdw(MDP_BASE + 0x40b40, 0xe9e9e9);
outpdw(MDP_BASE + 0x40b44, 0xe9e9e9);
outpdw(MDP_BASE + 0x40b48, 0xeaeaea);
outpdw(MDP_BASE + 0x40b4c, 0xeaeaea);
outpdw(MDP_BASE + 0x40b50, 0xebebeb);
outpdw(MDP_BASE + 0x40b54, 0xebebeb);
outpdw(MDP_BASE + 0x40b58, 0xececec);
outpdw(MDP_BASE + 0x40b5c, 0xececec);
outpdw(MDP_BASE + 0x40b60, 0xededed);
outpdw(MDP_BASE + 0x40b64, 0xededed);
outpdw(MDP_BASE + 0x40b68, 0xeeeeee);
outpdw(MDP_BASE + 0x40b6c, 0xeeeeee);
outpdw(MDP_BASE + 0x40b70, 0xefefef);
outpdw(MDP_BASE + 0x40b74, 0xefefef);
outpdw(MDP_BASE + 0x40b78, 0xf0f0f0);
outpdw(MDP_BASE + 0x40b7c, 0xf0f0f0);
outpdw(MDP_BASE + 0x40b80, 0xf1f1f1);
outpdw(MDP_BASE + 0x40b84, 0xf1f1f1);
outpdw(MDP_BASE + 0x40b88, 0xf2f2f2);
outpdw(MDP_BASE + 0x40b8c, 0xf2f2f2);
outpdw(MDP_BASE + 0x40b90, 0xf2f2f2);
outpdw(MDP_BASE + 0x40b94, 0xf3f3f3);
outpdw(MDP_BASE + 0x40b98, 0xf3f3f3);
outpdw(MDP_BASE + 0x40b9c, 0xf4f4f4);
outpdw(MDP_BASE + 0x40ba0, 0xf4f4f4);
outpdw(MDP_BASE + 0x40ba4, 0xf5f5f5);
outpdw(MDP_BASE + 0x40ba8, 0xf5f5f5);
outpdw(MDP_BASE + 0x40bac, 0xf6f6f6);
outpdw(MDP_BASE + 0x40bb0, 0xf6f6f6);
outpdw(MDP_BASE + 0x40bb4, 0xf7f7f7);
outpdw(MDP_BASE + 0x40bb8, 0xf7f7f7);
outpdw(MDP_BASE + 0x40bbc, 0xf8f8f8);
outpdw(MDP_BASE + 0x40bc0, 0xf8f8f8);
outpdw(MDP_BASE + 0x40bc4, 0xf9f9f9);
outpdw(MDP_BASE + 0x40bc8, 0xf9f9f9);
outpdw(MDP_BASE + 0x40bcc, 0xfafafa);
outpdw(MDP_BASE + 0x40bd0, 0xfafafa);
outpdw(MDP_BASE + 0x40bd4, 0xfafafa);
outpdw(MDP_BASE + 0x40bd8, 0xfbfbfb);
outpdw(MDP_BASE + 0x40bdc, 0xfbfbfb);
outpdw(MDP_BASE + 0x40be0, 0xfcfcfc);
outpdw(MDP_BASE + 0x40be4, 0xfcfcfc);
outpdw(MDP_BASE + 0x40be8, 0xfdfdfd);
outpdw(MDP_BASE + 0x40bec, 0xfdfdfd);
outpdw(MDP_BASE + 0x40bf0, 0xfefefe);
outpdw(MDP_BASE + 0x40bf4, 0xfefefe);
outpdw(MDP_BASE + 0x40bf8, 0xffffff);
outpdw(MDP_BASE + 0x40bfc, 0xffffff);
outpdw(MDP_BASE + 0x40c00, 0x0);
outpdw(MDP_BASE + 0x40c04, 0x0);
outpdw(MDP_BASE + 0x40c08, 0x0);
outpdw(MDP_BASE + 0x40c0c, 0x0);
outpdw(MDP_BASE + 0x40c10, 0x0);
outpdw(MDP_BASE + 0x40c14, 0x0);
outpdw(MDP_BASE + 0x40c18, 0x0);
outpdw(MDP_BASE + 0x40c1c, 0x0);
outpdw(MDP_BASE + 0x40c20, 0x0);
outpdw(MDP_BASE + 0x40c24, 0x0);
outpdw(MDP_BASE + 0x40c28, 0x0);
outpdw(MDP_BASE + 0x40c2c, 0x0);
outpdw(MDP_BASE + 0x40c30, 0x0);
outpdw(MDP_BASE + 0x40c34, 0x0);
outpdw(MDP_BASE + 0x40c38, 0x0);
outpdw(MDP_BASE + 0x40c3c, 0x0);
outpdw(MDP_BASE + 0x40c40, 0x10101);
outpdw(MDP_BASE + 0x40c44, 0x10101);
outpdw(MDP_BASE + 0x40c48, 0x10101);
outpdw(MDP_BASE + 0x40c4c, 0x10101);
outpdw(MDP_BASE + 0x40c50, 0x10101);
outpdw(MDP_BASE + 0x40c54, 0x10101);
outpdw(MDP_BASE + 0x40c58, 0x10101);
outpdw(MDP_BASE + 0x40c5c, 0x10101);
outpdw(MDP_BASE + 0x40c60, 0x10101);
outpdw(MDP_BASE + 0x40c64, 0x10101);
outpdw(MDP_BASE + 0x40c68, 0x20202);
outpdw(MDP_BASE + 0x40c6c, 0x20202);
outpdw(MDP_BASE + 0x40c70, 0x20202);
outpdw(MDP_BASE + 0x40c74, 0x20202);
outpdw(MDP_BASE + 0x40c78, 0x20202);
outpdw(MDP_BASE + 0x40c7c, 0x20202);
outpdw(MDP_BASE + 0x40c80, 0x30303);
outpdw(MDP_BASE + 0x40c84, 0x30303);
outpdw(MDP_BASE + 0x40c88, 0x30303);
outpdw(MDP_BASE + 0x40c8c, 0x30303);
outpdw(MDP_BASE + 0x40c90, 0x30303);
outpdw(MDP_BASE + 0x40c94, 0x40404);
outpdw(MDP_BASE + 0x40c98, 0x40404);
outpdw(MDP_BASE + 0x40c9c, 0x40404);
outpdw(MDP_BASE + 0x40ca0, 0x40404);
outpdw(MDP_BASE + 0x40ca4, 0x40404);
outpdw(MDP_BASE + 0x40ca8, 0x50505);
outpdw(MDP_BASE + 0x40cac, 0x50505);
outpdw(MDP_BASE + 0x40cb0, 0x50505);
outpdw(MDP_BASE + 0x40cb4, 0x50505);
outpdw(MDP_BASE + 0x40cb8, 0x60606);
outpdw(MDP_BASE + 0x40cbc, 0x60606);
outpdw(MDP_BASE + 0x40cc0, 0x60606);
outpdw(MDP_BASE + 0x40cc4, 0x70707);
outpdw(MDP_BASE + 0x40cc8, 0x70707);
outpdw(MDP_BASE + 0x40ccc, 0x70707);
outpdw(MDP_BASE + 0x40cd0, 0x70707);
outpdw(MDP_BASE + 0x40cd4, 0x80808);
outpdw(MDP_BASE + 0x40cd8, 0x80808);
outpdw(MDP_BASE + 0x40cdc, 0x80808);
outpdw(MDP_BASE + 0x40ce0, 0x90909);
outpdw(MDP_BASE + 0x40ce4, 0x90909);
outpdw(MDP_BASE + 0x40ce8, 0xa0a0a);
outpdw(MDP_BASE + 0x40cec, 0xa0a0a);
outpdw(MDP_BASE + 0x40cf0, 0xa0a0a);
outpdw(MDP_BASE + 0x40cf4, 0xb0b0b);
outpdw(MDP_BASE + 0x40cf8, 0xb0b0b);
outpdw(MDP_BASE + 0x40cfc, 0xb0b0b);
outpdw(MDP_BASE + 0x40d00, 0xc0c0c);
outpdw(MDP_BASE + 0x40d04, 0xc0c0c);
outpdw(MDP_BASE + 0x40d08, 0xd0d0d);
outpdw(MDP_BASE + 0x40d0c, 0xd0d0d);
outpdw(MDP_BASE + 0x40d10, 0xe0e0e);
outpdw(MDP_BASE + 0x40d14, 0xe0e0e);
outpdw(MDP_BASE + 0x40d18, 0xe0e0e);
outpdw(MDP_BASE + 0x40d1c, 0xf0f0f);
outpdw(MDP_BASE + 0x40d20, 0xf0f0f);
outpdw(MDP_BASE + 0x40d24, 0x101010);
outpdw(MDP_BASE + 0x40d28, 0x101010);
outpdw(MDP_BASE + 0x40d2c, 0x111111);
outpdw(MDP_BASE + 0x40d30, 0x111111);
outpdw(MDP_BASE + 0x40d34, 0x121212);
outpdw(MDP_BASE + 0x40d38, 0x121212);
outpdw(MDP_BASE + 0x40d3c, 0x131313);
outpdw(MDP_BASE + 0x40d40, 0x131313);
outpdw(MDP_BASE + 0x40d44, 0x141414);
outpdw(MDP_BASE + 0x40d48, 0x151515);
outpdw(MDP_BASE + 0x40d4c, 0x151515);
outpdw(MDP_BASE + 0x40d50, 0x161616);
outpdw(MDP_BASE + 0x40d54, 0x161616);
outpdw(MDP_BASE + 0x40d58, 0x171717);
outpdw(MDP_BASE + 0x40d5c, 0x171717);
outpdw(MDP_BASE + 0x40d60, 0x181818);
outpdw(MDP_BASE + 0x40d64, 0x191919);
outpdw(MDP_BASE + 0x40d68, 0x191919);
outpdw(MDP_BASE + 0x40d6c, 0x1a1a1a);
outpdw(MDP_BASE + 0x40d70, 0x1b1b1b);
outpdw(MDP_BASE + 0x40d74, 0x1b1b1b);
outpdw(MDP_BASE + 0x40d78, 0x1c1c1c);
outpdw(MDP_BASE + 0x40d7c, 0x1c1c1c);
outpdw(MDP_BASE + 0x40d80, 0x1d1d1d);
outpdw(MDP_BASE + 0x40d84, 0x1e1e1e);
outpdw(MDP_BASE + 0x40d88, 0x1f1f1f);
outpdw(MDP_BASE + 0x40d8c, 0x1f1f1f);
outpdw(MDP_BASE + 0x40d90, 0x202020);
outpdw(MDP_BASE + 0x40d94, 0x212121);
outpdw(MDP_BASE + 0x40d98, 0x212121);
outpdw(MDP_BASE + 0x40d9c, 0x222222);
outpdw(MDP_BASE + 0x40da0, 0x232323);
outpdw(MDP_BASE + 0x40da4, 0x242424);
outpdw(MDP_BASE + 0x40da8, 0x242424);
outpdw(MDP_BASE + 0x40dac, 0x252525);
outpdw(MDP_BASE + 0x40db0, 0x262626);
outpdw(MDP_BASE + 0x40db4, 0x272727);
outpdw(MDP_BASE + 0x40db8, 0x272727);
outpdw(MDP_BASE + 0x40dbc, 0x282828);
outpdw(MDP_BASE + 0x40dc0, 0x292929);
outpdw(MDP_BASE + 0x40dc4, 0x2a2a2a);
outpdw(MDP_BASE + 0x40dc8, 0x2b2b2b);
outpdw(MDP_BASE + 0x40dcc, 0x2c2c2c);
outpdw(MDP_BASE + 0x40dd0, 0x2c2c2c);
outpdw(MDP_BASE + 0x40dd4, 0x2d2d2d);
outpdw(MDP_BASE + 0x40dd8, 0x2e2e2e);
outpdw(MDP_BASE + 0x40ddc, 0x2f2f2f);
outpdw(MDP_BASE + 0x40de0, 0x303030);
outpdw(MDP_BASE + 0x40de4, 0x313131);
outpdw(MDP_BASE + 0x40de8, 0x323232);
outpdw(MDP_BASE + 0x40dec, 0x333333);
outpdw(MDP_BASE + 0x40df0, 0x333333);
outpdw(MDP_BASE + 0x40df4, 0x343434);
outpdw(MDP_BASE + 0x40df8, 0x353535);
outpdw(MDP_BASE + 0x40dfc, 0x363636);
outpdw(MDP_BASE + 0x40e00, 0x373737);
outpdw(MDP_BASE + 0x40e04, 0x383838);
outpdw(MDP_BASE + 0x40e08, 0x393939);
outpdw(MDP_BASE + 0x40e0c, 0x3a3a3a);
outpdw(MDP_BASE + 0x40e10, 0x3b3b3b);
outpdw(MDP_BASE + 0x40e14, 0x3c3c3c);
outpdw(MDP_BASE + 0x40e18, 0x3d3d3d);
outpdw(MDP_BASE + 0x40e1c, 0x3e3e3e);
outpdw(MDP_BASE + 0x40e20, 0x3f3f3f);
outpdw(MDP_BASE + 0x40e24, 0x404040);
outpdw(MDP_BASE + 0x40e28, 0x414141);
outpdw(MDP_BASE + 0x40e2c, 0x424242);
outpdw(MDP_BASE + 0x40e30, 0x434343);
outpdw(MDP_BASE + 0x40e34, 0x444444);
outpdw(MDP_BASE + 0x40e38, 0x464646);
outpdw(MDP_BASE + 0x40e3c, 0x474747);
outpdw(MDP_BASE + 0x40e40, 0x484848);
outpdw(MDP_BASE + 0x40e44, 0x494949);
outpdw(MDP_BASE + 0x40e48, 0x4a4a4a);
outpdw(MDP_BASE + 0x40e4c, 0x4b4b4b);
outpdw(MDP_BASE + 0x40e50, 0x4c4c4c);
outpdw(MDP_BASE + 0x40e54, 0x4d4d4d);
outpdw(MDP_BASE + 0x40e58, 0x4f4f4f);
outpdw(MDP_BASE + 0x40e5c, 0x505050);
outpdw(MDP_BASE + 0x40e60, 0x515151);
outpdw(MDP_BASE + 0x40e64, 0x525252);
outpdw(MDP_BASE + 0x40e68, 0x535353);
outpdw(MDP_BASE + 0x40e6c, 0x545454);
outpdw(MDP_BASE + 0x40e70, 0x565656);
outpdw(MDP_BASE + 0x40e74, 0x575757);
outpdw(MDP_BASE + 0x40e78, 0x585858);
outpdw(MDP_BASE + 0x40e7c, 0x595959);
outpdw(MDP_BASE + 0x40e80, 0x5b5b5b);
outpdw(MDP_BASE + 0x40e84, 0x5c5c5c);
outpdw(MDP_BASE + 0x40e88, 0x5d5d5d);
outpdw(MDP_BASE + 0x40e8c, 0x5e5e5e);
outpdw(MDP_BASE + 0x40e90, 0x606060);
outpdw(MDP_BASE + 0x40e94, 0x616161);
outpdw(MDP_BASE + 0x40e98, 0x626262);
outpdw(MDP_BASE + 0x40e9c, 0x646464);
outpdw(MDP_BASE + 0x40ea0, 0x656565);
outpdw(MDP_BASE + 0x40ea4, 0x666666);
outpdw(MDP_BASE + 0x40ea8, 0x686868);
outpdw(MDP_BASE + 0x40eac, 0x696969);
outpdw(MDP_BASE + 0x40eb0, 0x6a6a6a);
outpdw(MDP_BASE + 0x40eb4, 0x6c6c6c);
outpdw(MDP_BASE + 0x40eb8, 0x6d6d6d);
outpdw(MDP_BASE + 0x40ebc, 0x6f6f6f);
outpdw(MDP_BASE + 0x40ec0, 0x707070);
outpdw(MDP_BASE + 0x40ec4, 0x717171);
outpdw(MDP_BASE + 0x40ec8, 0x737373);
outpdw(MDP_BASE + 0x40ecc, 0x747474);
outpdw(MDP_BASE + 0x40ed0, 0x767676);
outpdw(MDP_BASE + 0x40ed4, 0x777777);
outpdw(MDP_BASE + 0x40ed8, 0x797979);
outpdw(MDP_BASE + 0x40edc, 0x7a7a7a);
outpdw(MDP_BASE + 0x40ee0, 0x7c7c7c);
outpdw(MDP_BASE + 0x40ee4, 0x7d7d7d);
outpdw(MDP_BASE + 0x40ee8, 0x7f7f7f);
outpdw(MDP_BASE + 0x40eec, 0x808080);
outpdw(MDP_BASE + 0x40ef0, 0x828282);
outpdw(MDP_BASE + 0x40ef4, 0x838383);
outpdw(MDP_BASE + 0x40ef8, 0x858585);
outpdw(MDP_BASE + 0x40efc, 0x868686);
outpdw(MDP_BASE + 0x40f00, 0x888888);
outpdw(MDP_BASE + 0x40f04, 0x898989);
outpdw(MDP_BASE + 0x40f08, 0x8b8b8b);
outpdw(MDP_BASE + 0x40f0c, 0x8d8d8d);
outpdw(MDP_BASE + 0x40f10, 0x8e8e8e);
outpdw(MDP_BASE + 0x40f14, 0x909090);
outpdw(MDP_BASE + 0x40f18, 0x919191);
outpdw(MDP_BASE + 0x40f1c, 0x939393);
outpdw(MDP_BASE + 0x40f20, 0x959595);
outpdw(MDP_BASE + 0x40f24, 0x969696);
outpdw(MDP_BASE + 0x40f28, 0x989898);
outpdw(MDP_BASE + 0x40f2c, 0x9a9a9a);
outpdw(MDP_BASE + 0x40f30, 0x9b9b9b);
outpdw(MDP_BASE + 0x40f34, 0x9d9d9d);
outpdw(MDP_BASE + 0x40f38, 0x9f9f9f);
outpdw(MDP_BASE + 0x40f3c, 0xa1a1a1);
outpdw(MDP_BASE + 0x40f40, 0xa2a2a2);
outpdw(MDP_BASE + 0x40f44, 0xa4a4a4);
outpdw(MDP_BASE + 0x40f48, 0xa6a6a6);
outpdw(MDP_BASE + 0x40f4c, 0xa7a7a7);
outpdw(MDP_BASE + 0x40f50, 0xa9a9a9);
outpdw(MDP_BASE + 0x40f54, 0xababab);
outpdw(MDP_BASE + 0x40f58, 0xadadad);
outpdw(MDP_BASE + 0x40f5c, 0xafafaf);
outpdw(MDP_BASE + 0x40f60, 0xb0b0b0);
outpdw(MDP_BASE + 0x40f64, 0xb2b2b2);
outpdw(MDP_BASE + 0x40f68, 0xb4b4b4);
outpdw(MDP_BASE + 0x40f6c, 0xb6b6b6);
outpdw(MDP_BASE + 0x40f70, 0xb8b8b8);
outpdw(MDP_BASE + 0x40f74, 0xbababa);
outpdw(MDP_BASE + 0x40f78, 0xbbbbbb);
outpdw(MDP_BASE + 0x40f7c, 0xbdbdbd);
outpdw(MDP_BASE + 0x40f80, 0xbfbfbf);
outpdw(MDP_BASE + 0x40f84, 0xc1c1c1);
outpdw(MDP_BASE + 0x40f88, 0xc3c3c3);
outpdw(MDP_BASE + 0x40f8c, 0xc5c5c5);
outpdw(MDP_BASE + 0x40f90, 0xc7c7c7);
outpdw(MDP_BASE + 0x40f94, 0xc9c9c9);
outpdw(MDP_BASE + 0x40f98, 0xcbcbcb);
outpdw(MDP_BASE + 0x40f9c, 0xcdcdcd);
outpdw(MDP_BASE + 0x40fa0, 0xcfcfcf);
outpdw(MDP_BASE + 0x40fa4, 0xd1d1d1);
outpdw(MDP_BASE + 0x40fa8, 0xd3d3d3);
outpdw(MDP_BASE + 0x40fac, 0xd5d5d5);
outpdw(MDP_BASE + 0x40fb0, 0xd7d7d7);
outpdw(MDP_BASE + 0x40fb4, 0xd9d9d9);
outpdw(MDP_BASE + 0x40fb8, 0xdbdbdb);
outpdw(MDP_BASE + 0x40fbc, 0xdddddd);
outpdw(MDP_BASE + 0x40fc0, 0xdfdfdf);
outpdw(MDP_BASE + 0x40fc4, 0xe1e1e1);
outpdw(MDP_BASE + 0x40fc8, 0xe3e3e3);
outpdw(MDP_BASE + 0x40fcc, 0xe5e5e5);
outpdw(MDP_BASE + 0x40fd0, 0xe7e7e7);
outpdw(MDP_BASE + 0x40fd4, 0xe9e9e9);
outpdw(MDP_BASE + 0x40fd8, 0xebebeb);
outpdw(MDP_BASE + 0x40fdc, 0xeeeeee);
outpdw(MDP_BASE + 0x40fe0, 0xf0f0f0);
outpdw(MDP_BASE + 0x40fe4, 0xf2f2f2);
outpdw(MDP_BASE + 0x40fe8, 0xf4f4f4);
outpdw(MDP_BASE + 0x40fec, 0xf6f6f6);
outpdw(MDP_BASE + 0x40ff0, 0xf8f8f8);
outpdw(MDP_BASE + 0x40ff4, 0xfbfbfb);
outpdw(MDP_BASE + 0x40ff8, 0xfdfdfd);
outpdw(MDP_BASE + 0x40ffc, 0xffffff);
}
#define IRQ_EN_1__MDP_IRQ___M 0x00000800
void mdp_hw_init(void)
{
int i;
/* MDP cmd block enable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
/* debug interface write access */
outpdw(MDP_BASE + 0x60, 1);
outp32(MDP_INTR_ENABLE, MDP_ANY_INTR_MASK);
outp32(MDP_EBI2_PORTMAP_MODE, 0x3);
outpdw(MDP_CMD_DEBUG_ACCESS_BASE + 0x01f8, 0x0);
outpdw(MDP_CMD_DEBUG_ACCESS_BASE + 0x01fc, 0x0);
outpdw(MDP_BASE + 0x60, 0x1);
mdp_load_lut_param();
/*
* clear up unused fg/main registers
*/
/* comp.plane 2&3 ystride */
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0120, 0x0);
/* unpacked pattern */
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x012c, 0x0);
/* unpacked pattern */
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0130, 0x0);
/* unpacked pattern */
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0134, 0x0);
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0158, 0x0);
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x15c, 0x0);
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0160, 0x0);
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0170, 0x0);
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0174, 0x0);
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x017c, 0x0);
/* comp.plane 2 */
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0114, 0x0);
/* comp.plane 3 */
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0118, 0x0);
/* clear up unused bg registers */
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01c8, 0);
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01d0, 0);
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01dc, 0);
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01e0, 0);
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01e4, 0);
#ifndef CONFIG_FB_MSM_MDP22
MDP_OUTP(MDP_BASE + 0xE0000, 0);
MDP_OUTP(MDP_BASE + 0x100, 0xffffffff);
MDP_OUTP(MDP_BASE + 0x90070, 0);
MDP_OUTP(MDP_BASE + 0x94010, 1);
MDP_OUTP(MDP_BASE + 0x9401c, 2);
#endif
/*
* limit vector
* pre gets applied before color matrix conversion
* post is after ccs
*/
writel(mdp_plv[0], MDP_CSC_PRE_LV1n(0));
writel(mdp_plv[1], MDP_CSC_PRE_LV1n(1));
writel(mdp_plv[2], MDP_CSC_PRE_LV1n(2));
writel(mdp_plv[3], MDP_CSC_PRE_LV1n(3));
#ifdef CONFIG_FB_MSM_MDP31
writel(mdp_plv[2], MDP_CSC_PRE_LV1n(4));
writel(mdp_plv[3], MDP_CSC_PRE_LV1n(5));
writel(0, MDP_CSC_POST_LV1n(0));
writel(0xff, MDP_CSC_POST_LV1n(1));
writel(0, MDP_CSC_POST_LV1n(2));
writel(0xff, MDP_CSC_POST_LV1n(3));
writel(0, MDP_CSC_POST_LV1n(4));
writel(0xff, MDP_CSC_POST_LV1n(5));
writel(0, MDP_CSC_PRE_LV2n(0));
writel(0xff, MDP_CSC_PRE_LV2n(1));
writel(0, MDP_CSC_PRE_LV2n(2));
writel(0xff, MDP_CSC_PRE_LV2n(3));
writel(0, MDP_CSC_PRE_LV2n(4));
writel(0xff, MDP_CSC_PRE_LV2n(5));
writel(mdp_plv[0], MDP_CSC_POST_LV2n(0));
writel(mdp_plv[1], MDP_CSC_POST_LV2n(1));
writel(mdp_plv[2], MDP_CSC_POST_LV2n(2));
writel(mdp_plv[3], MDP_CSC_POST_LV2n(3));
writel(mdp_plv[2], MDP_CSC_POST_LV2n(4));
writel(mdp_plv[3], MDP_CSC_POST_LV2n(5));
#endif
/* primary forward matrix */
for (i = 0; i < MDP_CCS_SIZE; i++)
writel(mdp_ccs_rgb2yuv.ccs[i], MDP_CSC_PFMVn(i));
#ifdef CONFIG_FB_MSM_MDP31
for (i = 0; i < MDP_BV_SIZE; i++)
writel(mdp_ccs_rgb2yuv.bv[i], MDP_CSC_POST_BV2n(i));
writel(0, MDP_CSC_PRE_BV2n(0));
writel(0, MDP_CSC_PRE_BV2n(1));
writel(0, MDP_CSC_PRE_BV2n(2));
#endif
/* primary reverse matrix */
for (i = 0; i < MDP_CCS_SIZE; i++)
writel(mdp_ccs_yuv2rgb.ccs[i], MDP_CSC_PRMVn(i));
for (i = 0; i < MDP_BV_SIZE; i++)
writel(mdp_ccs_yuv2rgb.bv[i], MDP_CSC_PRE_BV1n(i));
#ifdef CONFIG_FB_MSM_MDP31
writel(0, MDP_CSC_POST_BV1n(0));
writel(0, MDP_CSC_POST_BV1n(1));
writel(0, MDP_CSC_POST_BV1n(2));
outpdw(MDP_BASE + 0x30010, 0x03e0);
outpdw(MDP_BASE + 0x30014, 0x0360);
outpdw(MDP_BASE + 0x30018, 0x0120);
outpdw(MDP_BASE + 0x3001c, 0x0140);
#endif
mdp_init_scale_table();
#ifndef CONFIG_FB_MSM_MDP31
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0104,
((16 << 6) << 16) | (16) << 6);
#endif
/* MDP cmd block disable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
}

File diff suppressed because it is too large Load diff

View file

@ -1,347 +0,0 @@
/* Copyright (c) 2009-2010, 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 "mdp.h"
static boolean mdp_ppp_intr_flag = FALSE;
static boolean mdp_ppp_busy_flag = FALSE;
/* Queue to keep track of the completed jobs for cleaning */
static LIST_HEAD(mdp_ppp_djob_clnrq);
static DEFINE_SPINLOCK(mdp_ppp_djob_clnrq_lock);
/* Worker to cleanup Display Jobs */
static struct workqueue_struct *mdp_ppp_djob_clnr;
/* Display Queue (DQ) for MDP PPP Block */
static LIST_HEAD(mdp_ppp_dq);
static DEFINE_SPINLOCK(mdp_ppp_dq_lock);
/* Current Display Job for MDP PPP */
static struct mdp_ppp_djob *curr_djob;
/* Track ret code for the last opeartion */
static int mdp_ppp_ret_code;
inline int mdp_ppp_get_ret_code(void)
{
return mdp_ppp_ret_code;
}
/* Push <Reg, Val> pair into DQ (if available) to later
* program the MDP PPP Block */
inline void mdp_ppp_outdw(uint32_t addr, uint32_t data)
{
if (curr_djob) {
/* get the last node of the list. */
struct mdp_ppp_roi_cmd_set *node =
list_entry(curr_djob->roi_cmd_list.prev,
struct mdp_ppp_roi_cmd_set, node);
/* If a node is already full, create a new one and add it to
* the list (roi_cmd_list).
*/
if (node->ncmds == MDP_PPP_ROI_NODE_SIZE) {
node = kmalloc(sizeof(struct mdp_ppp_roi_cmd_set),
GFP_KERNEL);
if (!node) {
printk(KERN_ERR
"MDP_PPP: not enough memory.\n");
mdp_ppp_ret_code = -EINVAL;
return;
}
/* no ROI commands initially */
node->ncmds = 0;
/* add one node to roi_cmd_list. */
list_add_tail(&node->node, &curr_djob->roi_cmd_list);
}
/* register ROI commands */
node->cmd[node->ncmds].reg = addr;
node->cmd[node->ncmds].val = data;
node->ncmds++;
} else
/* program MDP PPP block now */
outpdw((addr), (data));
}
/* Initialize DQ */
inline void mdp_ppp_dq_init(void)
{
mdp_ppp_djob_clnr = create_singlethread_workqueue("MDPDJobClnrThrd");
}
/* Release resources of a job (DJob). */
static void mdp_ppp_del_djob(struct mdp_ppp_djob *job)
{
struct mdp_ppp_roi_cmd_set *node, *tmp;
/* release mem */
mdp_ppp_put_img(job->p_src_file, job->p_dst_file);
/* release roi_cmd_list */
list_for_each_entry_safe(node, tmp, &job->roi_cmd_list, node) {
list_del(&node->node);
kfree(node);
}
/* release job struct */
kfree(job);
}
/* Worker thread to reclaim resources once a display job is done */
static void mdp_ppp_djob_cleaner(struct work_struct *work)
{
struct mdp_ppp_djob *job;
MDP_PPP_DEBUG_MSG("mdp ppp display job cleaner started \n");
/* cleanup display job */
job = container_of(work, struct mdp_ppp_djob, cleaner.work);
if (likely(work && job))
mdp_ppp_del_djob(job);
}
/* Create a new Display Job (DJob) */
inline struct mdp_ppp_djob *mdp_ppp_new_djob(void)
{
struct mdp_ppp_djob *job;
struct mdp_ppp_roi_cmd_set *node;
/* create a new djob */
job = kmalloc(sizeof(struct mdp_ppp_djob), GFP_KERNEL);
if (!job)
return NULL;
/* add the first node to curr_djob->roi_cmd_list */
node = kmalloc(sizeof(struct mdp_ppp_roi_cmd_set), GFP_KERNEL);
if (!node) {
kfree(job);
return NULL;
}
/* make this current djob container to keep track of the curr djob not
* used in the async path i.e. no sync needed
*
* Should not contain any references from the past djob
*/
BUG_ON(curr_djob);
curr_djob = job;
INIT_LIST_HEAD(&curr_djob->roi_cmd_list);
/* no ROI commands initially */
node->ncmds = 0;
INIT_LIST_HEAD(&node->node);
list_add_tail(&node->node, &curr_djob->roi_cmd_list);
/* register this djob with the djob cleaner
* initializes 'work' data struct
*/
INIT_DELAYED_WORK(&curr_djob->cleaner, mdp_ppp_djob_cleaner);
INIT_LIST_HEAD(&curr_djob->entry);
curr_djob->p_src_file = 0;
curr_djob->p_dst_file = 0;
return job;
}
/* Undo the effect of mdp_ppp_new_djob() */
inline void mdp_ppp_clear_curr_djob(void)
{
if (likely(curr_djob)) {
mdp_ppp_del_djob(curr_djob);
curr_djob = NULL;
}
}
/* Cleanup dirty djobs */
static void mdp_ppp_flush_dirty_djobs(void *cond)
{
unsigned long flags;
struct mdp_ppp_djob *job;
/* Flush the jobs from the djob clnr queue */
while (cond && test_bit(0, (unsigned long *)cond)) {
/* Until we are done with the cleanup queue */
spin_lock_irqsave(&mdp_ppp_djob_clnrq_lock, flags);
if (list_empty(&mdp_ppp_djob_clnrq)) {
spin_unlock_irqrestore(&mdp_ppp_djob_clnrq_lock, flags);
break;
}
MDP_PPP_DEBUG_MSG("flushing djobs ... loop \n");
/* Retrieve the job that needs to be cleaned */
job = list_entry(mdp_ppp_djob_clnrq.next,
struct mdp_ppp_djob, entry);
list_del_init(&job->entry);
spin_unlock_irqrestore(&mdp_ppp_djob_clnrq_lock, flags);
/* Keep mem state coherent */
msm_fb_ensure_mem_coherency_after_dma(job->info, &job->req, 1);
/* Schedule jobs for cleanup
* A separate worker thread does this */
queue_delayed_work(mdp_ppp_djob_clnr, &job->cleaner,
mdp_timer_duration);
}
}
/* If MDP PPP engine is busy, wait until it is available again */
void mdp_ppp_wait(void)
{
unsigned long flags;
int cond = 1;
/* keep flushing dirty djobs as long as MDP PPP engine is busy */
mdp_ppp_flush_dirty_djobs(&mdp_ppp_busy_flag);
/* block if MDP PPP engine is still busy */
spin_lock_irqsave(&mdp_ppp_dq_lock, flags);
if (test_bit(0, (unsigned long *)&mdp_ppp_busy_flag)) {
/* prepare for the wakeup event */
test_and_set_bit(0, (unsigned long *)&mdp_ppp_waiting);
INIT_COMPLETION(mdp_ppp_comp);
spin_unlock_irqrestore(&mdp_ppp_dq_lock, flags);
/* block uninterruptibly until available */
MDP_PPP_DEBUG_MSG("waiting for mdp... \n");
wait_for_completion_killable(&mdp_ppp_comp);
/* if MDP PPP engine is still free,
* disable INT_MDP if enabled
*/
spin_lock_irqsave(&mdp_ppp_dq_lock, flags);
if (!test_bit(0, (unsigned long *)&mdp_ppp_busy_flag) &&
test_and_clear_bit(0, (unsigned long *)&mdp_ppp_intr_flag))
mdp_disable_irq(MDP_PPP_TERM);
}
spin_unlock_irqrestore(&mdp_ppp_dq_lock, flags);
/* flush remaining dirty djobs, if any */
mdp_ppp_flush_dirty_djobs(&cond);
}
/* Program MDP PPP block to process this ROI */
static void mdp_ppp_process_roi(struct list_head *roi_cmd_list)
{
/* program PPP engine with registered ROI commands */
struct mdp_ppp_roi_cmd_set *node;
list_for_each_entry(node, roi_cmd_list, node) {
int i = 0;
for (; i < node->ncmds; i++) {
MDP_PPP_DEBUG_MSG("%d: reg: 0x%x val: 0x%x \n",
i, node->cmd[i].reg, node->cmd[i].val);
outpdw(node->cmd[i].reg, node->cmd[i].val);
}
}
/* kickoff MDP PPP engine */
MDP_PPP_DEBUG_MSG("kicking off mdp \n");
outpdw(MDP_BASE + 0x30, 0x1000);
}
/* Submit this display job to MDP PPP engine */
static void mdp_ppp_dispatch_djob(struct mdp_ppp_djob *job)
{
/* enable INT_MDP if disabled */
if (!test_and_set_bit(0, (unsigned long *)&mdp_ppp_intr_flag))
mdp_enable_irq(MDP_PPP_TERM);
/* turn on PPP and CMD blocks */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
mdp_pipe_ctrl(MDP_PPP_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
/* process this ROI */
mdp_ppp_process_roi(&job->roi_cmd_list);
}
/* Enqueue this display job to be cleaned up later in "mdp_ppp_djob_done" */
static inline void mdp_ppp_enqueue_djob(struct mdp_ppp_djob *job)
{
unsigned long flags;
spin_lock_irqsave(&mdp_ppp_dq_lock, flags);
list_add_tail(&job->entry, &mdp_ppp_dq);
spin_unlock_irqrestore(&mdp_ppp_dq_lock, flags);
}
/* First enqueue display job for cleanup and dispatch immediately
* if MDP PPP engine is free */
void mdp_ppp_process_curr_djob(void)
{
/* enqueue djob */
mdp_ppp_enqueue_djob(curr_djob);
/* dispatch now if MDP PPP engine is free */
if (!test_and_set_bit(0, (unsigned long *)&mdp_ppp_busy_flag))
mdp_ppp_dispatch_djob(curr_djob);
/* done with the current djob */
curr_djob = NULL;
}
/* Called from mdp_isr - cleanup finished job and start with next
* if available else set MDP PPP engine free */
void mdp_ppp_djob_done(void)
{
struct mdp_ppp_djob *curr, *next;
unsigned long flags;
/* dequeue current */
spin_lock_irqsave(&mdp_ppp_dq_lock, flags);
curr = list_entry(mdp_ppp_dq.next, struct mdp_ppp_djob, entry);
list_del_init(&curr->entry);
spin_unlock_irqrestore(&mdp_ppp_dq_lock, flags);
/* cleanup current - enqueue in the djob clnr queue */
spin_lock_irqsave(&mdp_ppp_djob_clnrq_lock, flags);
list_add_tail(&curr->entry, &mdp_ppp_djob_clnrq);
spin_unlock_irqrestore(&mdp_ppp_djob_clnrq_lock, flags);
/* grab next pending */
spin_lock_irqsave(&mdp_ppp_dq_lock, flags);
if (!list_empty(&mdp_ppp_dq)) {
next = list_entry(mdp_ppp_dq.next, struct mdp_ppp_djob,
entry);
spin_unlock_irqrestore(&mdp_ppp_dq_lock, flags);
/* process next in the queue */
mdp_ppp_process_roi(&next->roi_cmd_list);
} else {
/* no pending display job */
spin_unlock_irqrestore(&mdp_ppp_dq_lock, flags);
/* turn off PPP and CMD blocks - "in_isr" is TRUE */
mdp_pipe_ctrl(MDP_PPP_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
/* notify if waiting */
if (test_and_clear_bit(0, (unsigned long *)&mdp_ppp_waiting))
complete(&mdp_ppp_comp);
/* set free */
test_and_clear_bit(0, (unsigned long *)&mdp_ppp_busy_flag);
}
}

View file

@ -1,69 +0,0 @@
/* Copyright (c) 2009-2010, 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.
*/
#ifndef MDP_PPP_DQ_H
#define MDP_PPP_DQ_H
#include "msm_fb_def.h"
#define MDP_PPP_DEBUG_MSG MSM_FB_DEBUG
/* The maximum number of <Reg,Val> pairs in an mdp_ppp_roi_cmd_set structure (a
* node)
*/
#define MDP_PPP_ROI_NODE_SIZE 32
/* ROI config command (<Reg,Val> pair) for MDP PPP block */
struct mdp_ppp_roi_cmd {
uint32_t reg;
uint32_t val;
};
/* ROI config commands for MDP PPP block are stored in a list of
* mdp_ppp_roi_cmd_set structures (nodes).
*/
struct mdp_ppp_roi_cmd_set {
struct list_head node;
uint32_t ncmds; /* number of commands in this set (node). */
struct mdp_ppp_roi_cmd cmd[MDP_PPP_ROI_NODE_SIZE];
};
/* MDP PPP Display Job (DJob) */
struct mdp_ppp_djob {
struct list_head entry;
/* One ROI per MDP PPP DJob */
struct list_head roi_cmd_list;
struct mdp_blit_req req;
struct fb_info *info;
struct delayed_work cleaner;
struct file *p_src_file, *p_dst_file;
};
extern struct completion mdp_ppp_comp;
extern boolean mdp_ppp_waiting;
extern unsigned long mdp_timer_duration;
unsigned int mdp_ppp_async_op_get(void);
void mdp_ppp_async_op_set(unsigned int flag);
void msm_fb_ensure_mem_coherency_after_dma(struct fb_info *info,
struct mdp_blit_req *req_list, int req_list_count);
void mdp_ppp_put_img(struct file *p_src_file, struct file *p_dst_file);
void mdp_ppp_dq_init(void);
void mdp_ppp_outdw(uint32_t addr, uint32_t data);
struct mdp_ppp_djob *mdp_ppp_new_djob(void);
void mdp_ppp_clear_curr_djob(void);
void mdp_ppp_process_curr_djob(void);
int mdp_ppp_get_ret_code(void);
void mdp_ppp_djob_done(void);
void mdp_ppp_wait(void);
#endif /* MDP_PPP_DQ_H */

File diff suppressed because it is too large Load diff

View file

@ -1,828 +0,0 @@
/* Copyright (c) 2008-2010, 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/fb.h>
#include <linux/proc_fs.h>
#include <mach/hardware.h>
#include <linux/io.h>
#include <asm/system.h>
#include <asm/mach-types.h>
#include <linux/semaphore.h>
#include <asm/div64.h>
#include "mdp.h"
#include "msm_fb.h"
#define MDP_SCALE_COEFF_NUM 32
#define MDP_SCALE_0P2_TO_0P4_INDEX 0
#define MDP_SCALE_0P4_TO_0P6_INDEX 32
#define MDP_SCALE_0P6_TO_0P8_INDEX 64
#define MDP_SCALE_0P8_TO_8P0_INDEX 96
#define MDP_SCALE_COEFF_MASK 0x3ff
#define MDP_SCALE_PR 0
#define MDP_SCALE_FIR 1
static uint32 mdp_scale_0p8_to_8p0_mode;
static uint32 mdp_scale_0p6_to_0p8_mode;
static uint32 mdp_scale_0p4_to_0p6_mode;
static uint32 mdp_scale_0p2_to_0p4_mode;
/* -------- All scaling range, "pixel repeat" -------- */
static int16 mdp_scale_pixel_repeat_C0[MDP_SCALE_COEFF_NUM] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
static int16 mdp_scale_pixel_repeat_C1[MDP_SCALE_COEFF_NUM] = {
511, 511, 511, 511, 511, 511, 511, 511,
511, 511, 511, 511, 511, 511, 511, 511,
511, 511, 511, 511, 511, 511, 511, 511,
511, 511, 511, 511, 511, 511, 511, 511
};
static int16 mdp_scale_pixel_repeat_C2[MDP_SCALE_COEFF_NUM] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
static int16 mdp_scale_pixel_repeat_C3[MDP_SCALE_COEFF_NUM] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
/* --------------------------- FIR ------------------------------------- */
/* -------- Downscale, ranging from 0.8x to 8.0x of original size -------- */
static int16 mdp_scale_0p8_to_8p0_C0[MDP_SCALE_COEFF_NUM] = {
0, -7, -13, -19, -24, -28, -32, -34, -37, -39,
-40, -41, -41, -41, -40, -40, -38, -37, -35, -33,
-31, -29, -26, -24, -21, -18, -15, -13, -10, -7,
-5, -2
};
static int16 mdp_scale_0p8_to_8p0_C1[MDP_SCALE_COEFF_NUM] = {
511, 507, 501, 494, 485, 475, 463, 450, 436, 422,
405, 388, 370, 352, 333, 314, 293, 274, 253, 233,
213, 193, 172, 152, 133, 113, 95, 77, 60, 43,
28, 13
};
static int16 mdp_scale_0p8_to_8p0_C2[MDP_SCALE_COEFF_NUM] = {
0, 13, 28, 43, 60, 77, 95, 113, 133, 152,
172, 193, 213, 233, 253, 274, 294, 314, 333, 352,
370, 388, 405, 422, 436, 450, 463, 475, 485, 494,
501, 507,
};
static int16 mdp_scale_0p8_to_8p0_C3[MDP_SCALE_COEFF_NUM] = {
0, -2, -5, -7, -10, -13, -15, -18, -21, -24,
-26, -29, -31, -33, -35, -37, -38, -40, -40, -41,
-41, -41, -40, -39, -37, -34, -32, -28, -24, -19,
-13, -7
};
/* -------- Downscale, ranging from 0.6x to 0.8x of original size -------- */
static int16 mdp_scale_0p6_to_0p8_C0[MDP_SCALE_COEFF_NUM] = {
104, 96, 89, 82, 75, 68, 61, 55, 49, 43,
38, 33, 28, 24, 20, 16, 12, 9, 6, 4,
2, 0, -2, -4, -5, -6, -7, -7, -8, -8,
-8, -8
};
static int16 mdp_scale_0p6_to_0p8_C1[MDP_SCALE_COEFF_NUM] = {
303, 303, 302, 300, 298, 296, 293, 289, 286, 281,
276, 270, 265, 258, 252, 245, 238, 230, 223, 214,
206, 197, 189, 180, 172, 163, 154, 145, 137, 128,
120, 112
};
static int16 mdp_scale_0p6_to_0p8_C2[MDP_SCALE_COEFF_NUM] = {
112, 120, 128, 137, 145, 154, 163, 172, 180, 189,
197, 206, 214, 223, 230, 238, 245, 252, 258, 265,
270, 276, 281, 286, 289, 293, 296, 298, 300, 302,
303, 303
};
static int16 mdp_scale_0p6_to_0p8_C3[MDP_SCALE_COEFF_NUM] = {
-8, -8, -8, -8, -7, -7, -6, -5, -4, -2,
0, 2, 4, 6, 9, 12, 16, 20, 24, 28,
33, 38, 43, 49, 55, 61, 68, 75, 82, 89,
96, 104
};
/* -------- Downscale, ranging from 0.4x to 0.6x of original size -------- */
static int16 mdp_scale_0p4_to_0p6_C0[MDP_SCALE_COEFF_NUM] = {
136, 132, 128, 123, 119, 115, 111, 107, 103, 98,
95, 91, 87, 84, 80, 76, 73, 69, 66, 62,
59, 57, 54, 50, 47, 44, 41, 39, 36, 33,
32, 29
};
static int16 mdp_scale_0p4_to_0p6_C1[MDP_SCALE_COEFF_NUM] = {
206, 205, 204, 204, 201, 200, 199, 197, 196, 194,
191, 191, 189, 185, 184, 182, 180, 178, 176, 173,
170, 168, 165, 162, 160, 157, 155, 152, 148, 146,
142, 140
};
static int16 mdp_scale_0p4_to_0p6_C2[MDP_SCALE_COEFF_NUM] = {
140, 142, 146, 148, 152, 155, 157, 160, 162, 165,
168, 170, 173, 176, 178, 180, 182, 184, 185, 189,
191, 191, 194, 196, 197, 199, 200, 201, 204, 204,
205, 206
};
static int16 mdp_scale_0p4_to_0p6_C3[MDP_SCALE_COEFF_NUM] = {
29, 32, 33, 36, 39, 41, 44, 47, 50, 54,
57, 59, 62, 66, 69, 73, 76, 80, 84, 87,
91, 95, 98, 103, 107, 111, 115, 119, 123, 128,
132, 136
};
/* -------- Downscale, ranging from 0.2x to 0.4x of original size -------- */
static int16 mdp_scale_0p2_to_0p4_C0[MDP_SCALE_COEFF_NUM] = {
131, 131, 130, 129, 128, 127, 127, 126, 125, 125,
124, 123, 123, 121, 120, 119, 119, 118, 117, 117,
116, 115, 115, 114, 113, 112, 111, 110, 109, 109,
108, 107
};
static int16 mdp_scale_0p2_to_0p4_C1[MDP_SCALE_COEFF_NUM] = {
141, 140, 140, 140, 140, 139, 138, 138, 138, 137,
137, 137, 136, 137, 137, 137, 136, 136, 136, 135,
135, 135, 134, 134, 134, 134, 134, 133, 133, 132,
132, 132
};
static int16 mdp_scale_0p2_to_0p4_C2[MDP_SCALE_COEFF_NUM] = {
132, 132, 132, 133, 133, 134, 134, 134, 134, 134,
135, 135, 135, 136, 136, 136, 137, 137, 137, 136,
137, 137, 137, 138, 138, 138, 139, 140, 140, 140,
140, 141
};
static int16 mdp_scale_0p2_to_0p4_C3[MDP_SCALE_COEFF_NUM] = {
107, 108, 109, 109, 110, 111, 112, 113, 114, 115,
115, 116, 117, 117, 118, 119, 119, 120, 121, 123,
123, 124, 125, 125, 126, 127, 127, 128, 129, 130,
131, 131
};
static void mdp_update_scale_table(int index, int16 *c0, int16 *c1,
int16 *c2, int16 *c3)
{
int i, val;
for (i = 0; i < MDP_SCALE_COEFF_NUM; i++) {
val =
((MDP_SCALE_COEFF_MASK & c1[i]) << 16) |
(MDP_SCALE_COEFF_MASK & c0[i]);
MDP_OUTP(MDP_PPP_SCALE_COEFF_LSBn(index), val);
val =
((MDP_SCALE_COEFF_MASK & c3[i]) << 16) |
(MDP_SCALE_COEFF_MASK & c2[i]);
MDP_OUTP(MDP_PPP_SCALE_COEFF_MSBn(index), val);
index++;
}
}
void mdp_init_scale_table(void)
{
mdp_scale_0p2_to_0p4_mode = MDP_SCALE_FIR;
mdp_update_scale_table(MDP_SCALE_0P2_TO_0P4_INDEX,
mdp_scale_0p2_to_0p4_C0,
mdp_scale_0p2_to_0p4_C1,
mdp_scale_0p2_to_0p4_C2,
mdp_scale_0p2_to_0p4_C3);
mdp_scale_0p4_to_0p6_mode = MDP_SCALE_FIR;
mdp_update_scale_table(MDP_SCALE_0P4_TO_0P6_INDEX,
mdp_scale_0p4_to_0p6_C0,
mdp_scale_0p4_to_0p6_C1,
mdp_scale_0p4_to_0p6_C2,
mdp_scale_0p4_to_0p6_C3);
mdp_scale_0p6_to_0p8_mode = MDP_SCALE_FIR;
mdp_update_scale_table(MDP_SCALE_0P6_TO_0P8_INDEX,
mdp_scale_0p6_to_0p8_C0,
mdp_scale_0p6_to_0p8_C1,
mdp_scale_0p6_to_0p8_C2,
mdp_scale_0p6_to_0p8_C3);
mdp_scale_0p8_to_8p0_mode = MDP_SCALE_FIR;
mdp_update_scale_table(MDP_SCALE_0P8_TO_8P0_INDEX,
mdp_scale_0p8_to_8p0_C0,
mdp_scale_0p8_to_8p0_C1,
mdp_scale_0p8_to_8p0_C2,
mdp_scale_0p8_to_8p0_C3);
}
static long long mdp_do_div(long long num, long long den)
{
do_div(num, den);
return num;
}
#define SCALER_PHASE_BITS 29
#define HAL_MDP_PHASE_STEP_2P50 0x50000000
#define HAL_MDP_PHASE_STEP_1P66 0x35555555
#define HAL_MDP_PHASE_STEP_1P25 0x28000000
struct phase_val {
int phase_init_x;
int phase_init_y;
int phase_step_x;
int phase_step_y;
};
static void mdp_calc_scaleInitPhase_3p1(uint32 in_w,
uint32 in_h,
uint32 out_w,
uint32 out_h,
boolean is_rotate,
boolean is_pp_x,
boolean is_pp_y, struct phase_val *pval)
{
uint64 dst_ROI_width;
uint64 dst_ROI_height;
uint64 src_ROI_width;
uint64 src_ROI_height;
/*
* phase_step_x, phase_step_y, phase_init_x and phase_init_y
* are represented in fixed-point, unsigned 3.29 format
*/
uint32 phase_step_x = 0;
uint32 phase_step_y = 0;
uint32 phase_init_x = 0;
uint32 phase_init_y = 0;
uint32 yscale_filter_sel, xscale_filter_sel;
uint32 scale_unit_sel_x, scale_unit_sel_y;
uint64 numerator, denominator;
uint64 temp_dim;
src_ROI_width = in_w;
src_ROI_height = in_h;
dst_ROI_width = out_w;
dst_ROI_height = out_h;
/* if there is a 90 degree rotation */
if (is_rotate) {
/* decide whether to use FIR or M/N for scaling */
/* if down-scaling by a factor smaller than 1/4 */
if (src_ROI_width > (4 * dst_ROI_height))
scale_unit_sel_x = 1; /* use M/N scalar */
else
scale_unit_sel_x = 0; /* use FIR scalar */
/* if down-scaling by a factor smaller than 1/4 */
if (src_ROI_height > (4 * dst_ROI_width))
scale_unit_sel_y = 1; /* use M/N scalar */
else
scale_unit_sel_y = 0; /* use FIR scalar */
} else {
/* decide whether to use FIR or M/N for scaling */
if (src_ROI_width > (4 * dst_ROI_width))
scale_unit_sel_x = 1; /* use M/N scalar */
else
scale_unit_sel_x = 0; /* use FIR scalar */
if (src_ROI_height > (4 * dst_ROI_height))
scale_unit_sel_y = 1; /* use M/N scalar */
else
scale_unit_sel_y = 0; /* use FIR scalar */
}
/* if there is a 90 degree rotation */
if (is_rotate) {
/* swap the width and height of dst ROI */
temp_dim = dst_ROI_width;
dst_ROI_width = dst_ROI_height;
dst_ROI_height = temp_dim;
}
/* calculate phase step for the x direction */
/* if destination is only 1 pixel wide, the value of phase_step_x
is unimportant. Assigning phase_step_x to src ROI width
as an arbitrary value. */
if (dst_ROI_width == 1)
phase_step_x = (uint32) ((src_ROI_width) << SCALER_PHASE_BITS);
/* if using FIR scalar */
else if (scale_unit_sel_x == 0) {
/* Calculate the quotient ( src_ROI_width - 1 ) / ( dst_ROI_width - 1)
with u3.29 precision. Quotient is rounded up to the larger
29th decimal point. */
numerator = (src_ROI_width - 1) << SCALER_PHASE_BITS;
denominator = (dst_ROI_width - 1); /* never equals to 0 because of the "( dst_ROI_width == 1 ) case" */
phase_step_x = (uint32) mdp_do_div((numerator + denominator - 1), denominator); /* divide and round up to the larger 29th decimal point. */
}
/* if M/N scalar */
else if (scale_unit_sel_x == 1) {
/* Calculate the quotient ( src_ROI_width ) / ( dst_ROI_width)
with u3.29 precision. Quotient is rounded down to the
smaller 29th decimal point. */
numerator = (src_ROI_width) << SCALER_PHASE_BITS;
denominator = (dst_ROI_width);
phase_step_x = (uint32) mdp_do_div(numerator, denominator);
}
/* calculate phase step for the y direction */
/* if destination is only 1 pixel wide, the value of
phase_step_x is unimportant. Assigning phase_step_x
to src ROI width as an arbitrary value. */
if (dst_ROI_height == 1)
phase_step_y = (uint32) ((src_ROI_height) << SCALER_PHASE_BITS);
/* if FIR scalar */
else if (scale_unit_sel_y == 0) {
/* Calculate the quotient ( src_ROI_height - 1 ) / ( dst_ROI_height - 1)
with u3.29 precision. Quotient is rounded up to the larger
29th decimal point. */
numerator = (src_ROI_height - 1) << SCALER_PHASE_BITS;
denominator = (dst_ROI_height - 1); /* never equals to 0 because of the "( dst_ROI_height == 1 )" case */
phase_step_y = (uint32) mdp_do_div((numerator + denominator - 1), denominator); /* Quotient is rounded up to the larger 29th decimal point. */
}
/* if M/N scalar */
else if (scale_unit_sel_y == 1) {
/* Calculate the quotient ( src_ROI_height ) / ( dst_ROI_height)
with u3.29 precision. Quotient is rounded down to the smaller
29th decimal point. */
numerator = (src_ROI_height) << SCALER_PHASE_BITS;
denominator = (dst_ROI_height);
phase_step_y = (uint32) mdp_do_div(numerator, denominator);
}
/* decide which set of FIR coefficients to use */
if (phase_step_x > HAL_MDP_PHASE_STEP_2P50)
xscale_filter_sel = 0;
else if (phase_step_x > HAL_MDP_PHASE_STEP_1P66)
xscale_filter_sel = 1;
else if (phase_step_x > HAL_MDP_PHASE_STEP_1P25)
xscale_filter_sel = 2;
else
xscale_filter_sel = 3;
if (phase_step_y > HAL_MDP_PHASE_STEP_2P50)
yscale_filter_sel = 0;
else if (phase_step_y > HAL_MDP_PHASE_STEP_1P66)
yscale_filter_sel = 1;
else if (phase_step_y > HAL_MDP_PHASE_STEP_1P25)
yscale_filter_sel = 2;
else
yscale_filter_sel = 3;
/* calculate phase init for the x direction */
/* if using FIR scalar */
if (scale_unit_sel_x == 0) {
if (dst_ROI_width == 1)
phase_init_x =
(uint32) ((src_ROI_width - 1) << SCALER_PHASE_BITS);
else
phase_init_x = 0;
}
/* M over N scalar */
else if (scale_unit_sel_x == 1)
phase_init_x = 0;
/* calculate phase init for the y direction
if using FIR scalar */
if (scale_unit_sel_y == 0) {
if (dst_ROI_height == 1)
phase_init_y =
(uint32) ((src_ROI_height -
1) << SCALER_PHASE_BITS);
else
phase_init_y = 0;
}
/* M over N scalar */
else if (scale_unit_sel_y == 1)
phase_init_y = 0;
/* write registers */
pval->phase_step_x = (uint32) phase_step_x;
pval->phase_step_y = (uint32) phase_step_y;
pval->phase_init_x = (uint32) phase_init_x;
pval->phase_init_y = (uint32) phase_init_y;
return;
}
void mdp_set_scale(MDPIBUF *iBuf,
uint32 dst_roi_width,
uint32 dst_roi_height,
boolean inputRGB, boolean outputRGB, uint32 *pppop_reg_ptr)
{
uint32 dst_roi_width_scale;
uint32 dst_roi_height_scale;
struct phase_val pval;
boolean use_pr;
uint32 ppp_scale_config = 0;
if (!inputRGB)
ppp_scale_config |= BIT(6);
if (iBuf->mdpImg.mdpOp & MDPOP_ASCALE) {
if (iBuf->mdpImg.mdpOp & MDPOP_ROT90) {
dst_roi_width_scale = dst_roi_height;
dst_roi_height_scale = dst_roi_width;
} else {
dst_roi_width_scale = dst_roi_width;
dst_roi_height_scale = dst_roi_height;
}
if ((dst_roi_width_scale != iBuf->roi.width) ||
(dst_roi_height_scale != iBuf->roi.height) ||
(iBuf->mdpImg.mdpOp & MDPOP_SHARPENING)) {
*pppop_reg_ptr |=
(PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON);
mdp_calc_scaleInitPhase_3p1(iBuf->roi.width,
iBuf->roi.height,
dst_roi_width,
dst_roi_height,
iBuf->mdpImg.
mdpOp & MDPOP_ROT90, 1, 1,
&pval);
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x013c,
pval.phase_init_x);
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0140,
pval.phase_init_y);
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0144,
pval.phase_step_x);
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0148,
pval.phase_step_y);
use_pr = (inputRGB) && (outputRGB);
/* x-direction */
if ((dst_roi_width_scale == iBuf->roi.width) &&
!(iBuf->mdpImg.mdpOp & MDPOP_SHARPENING)) {
*pppop_reg_ptr &= ~PPP_OP_SCALE_X_ON;
} else
if (((dst_roi_width_scale * 10) / iBuf->roi.width) >
8) {
if ((use_pr)
&& (mdp_scale_0p8_to_8p0_mode !=
MDP_SCALE_PR)) {
mdp_scale_0p8_to_8p0_mode =
MDP_SCALE_PR;
mdp_update_scale_table
(MDP_SCALE_0P8_TO_8P0_INDEX,
mdp_scale_pixel_repeat_C0,
mdp_scale_pixel_repeat_C1,
mdp_scale_pixel_repeat_C2,
mdp_scale_pixel_repeat_C3);
} else if ((!use_pr)
&& (mdp_scale_0p8_to_8p0_mode !=
MDP_SCALE_FIR)) {
mdp_scale_0p8_to_8p0_mode =
MDP_SCALE_FIR;
mdp_update_scale_table
(MDP_SCALE_0P8_TO_8P0_INDEX,
mdp_scale_0p8_to_8p0_C0,
mdp_scale_0p8_to_8p0_C1,
mdp_scale_0p8_to_8p0_C2,
mdp_scale_0p8_to_8p0_C3);
}
ppp_scale_config |= (SCALE_U1_SET << 2);
} else
if (((dst_roi_width_scale * 10) / iBuf->roi.width) >
6) {
if ((use_pr)
&& (mdp_scale_0p6_to_0p8_mode !=
MDP_SCALE_PR)) {
mdp_scale_0p6_to_0p8_mode =
MDP_SCALE_PR;
mdp_update_scale_table
(MDP_SCALE_0P6_TO_0P8_INDEX,
mdp_scale_pixel_repeat_C0,
mdp_scale_pixel_repeat_C1,
mdp_scale_pixel_repeat_C2,
mdp_scale_pixel_repeat_C3);
} else if ((!use_pr)
&& (mdp_scale_0p6_to_0p8_mode !=
MDP_SCALE_FIR)) {
mdp_scale_0p6_to_0p8_mode =
MDP_SCALE_FIR;
mdp_update_scale_table
(MDP_SCALE_0P6_TO_0P8_INDEX,
mdp_scale_0p6_to_0p8_C0,
mdp_scale_0p6_to_0p8_C1,
mdp_scale_0p6_to_0p8_C2,
mdp_scale_0p6_to_0p8_C3);
}
ppp_scale_config |= (SCALE_D2_SET << 2);
} else
if (((dst_roi_width_scale * 10) / iBuf->roi.width) >
4) {
if ((use_pr)
&& (mdp_scale_0p4_to_0p6_mode !=
MDP_SCALE_PR)) {
mdp_scale_0p4_to_0p6_mode =
MDP_SCALE_PR;
mdp_update_scale_table
(MDP_SCALE_0P4_TO_0P6_INDEX,
mdp_scale_pixel_repeat_C0,
mdp_scale_pixel_repeat_C1,
mdp_scale_pixel_repeat_C2,
mdp_scale_pixel_repeat_C3);
} else if ((!use_pr)
&& (mdp_scale_0p4_to_0p6_mode !=
MDP_SCALE_FIR)) {
mdp_scale_0p4_to_0p6_mode =
MDP_SCALE_FIR;
mdp_update_scale_table
(MDP_SCALE_0P4_TO_0P6_INDEX,
mdp_scale_0p4_to_0p6_C0,
mdp_scale_0p4_to_0p6_C1,
mdp_scale_0p4_to_0p6_C2,
mdp_scale_0p4_to_0p6_C3);
}
ppp_scale_config |= (SCALE_D1_SET << 2);
} else
if (((dst_roi_width_scale * 4) / iBuf->roi.width) >=
1) {
if ((use_pr)
&& (mdp_scale_0p2_to_0p4_mode !=
MDP_SCALE_PR)) {
mdp_scale_0p2_to_0p4_mode =
MDP_SCALE_PR;
mdp_update_scale_table
(MDP_SCALE_0P2_TO_0P4_INDEX,
mdp_scale_pixel_repeat_C0,
mdp_scale_pixel_repeat_C1,
mdp_scale_pixel_repeat_C2,
mdp_scale_pixel_repeat_C3);
} else if ((!use_pr)
&& (mdp_scale_0p2_to_0p4_mode !=
MDP_SCALE_FIR)) {
mdp_scale_0p2_to_0p4_mode =
MDP_SCALE_FIR;
mdp_update_scale_table
(MDP_SCALE_0P2_TO_0P4_INDEX,
mdp_scale_0p2_to_0p4_C0,
mdp_scale_0p2_to_0p4_C1,
mdp_scale_0p2_to_0p4_C2,
mdp_scale_0p2_to_0p4_C3);
}
ppp_scale_config |= (SCALE_D0_SET << 2);
} else
ppp_scale_config |= BIT(0);
/* y-direction */
if ((dst_roi_height_scale == iBuf->roi.height) &&
!(iBuf->mdpImg.mdpOp & MDPOP_SHARPENING)) {
*pppop_reg_ptr &= ~PPP_OP_SCALE_Y_ON;
} else if (((dst_roi_height_scale * 10) /
iBuf->roi.height) > 8) {
if ((use_pr)
&& (mdp_scale_0p8_to_8p0_mode !=
MDP_SCALE_PR)) {
mdp_scale_0p8_to_8p0_mode =
MDP_SCALE_PR;
mdp_update_scale_table
(MDP_SCALE_0P8_TO_8P0_INDEX,
mdp_scale_pixel_repeat_C0,
mdp_scale_pixel_repeat_C1,
mdp_scale_pixel_repeat_C2,
mdp_scale_pixel_repeat_C3);
} else if ((!use_pr)
&& (mdp_scale_0p8_to_8p0_mode !=
MDP_SCALE_FIR)) {
mdp_scale_0p8_to_8p0_mode =
MDP_SCALE_FIR;
mdp_update_scale_table
(MDP_SCALE_0P8_TO_8P0_INDEX,
mdp_scale_0p8_to_8p0_C0,
mdp_scale_0p8_to_8p0_C1,
mdp_scale_0p8_to_8p0_C2,
mdp_scale_0p8_to_8p0_C3);
}
ppp_scale_config |= (SCALE_U1_SET << 4);
} else
if (((dst_roi_height_scale * 10) /
iBuf->roi.height) > 6) {
if ((use_pr)
&& (mdp_scale_0p6_to_0p8_mode !=
MDP_SCALE_PR)) {
mdp_scale_0p6_to_0p8_mode =
MDP_SCALE_PR;
mdp_update_scale_table
(MDP_SCALE_0P6_TO_0P8_INDEX,
mdp_scale_pixel_repeat_C0,
mdp_scale_pixel_repeat_C1,
mdp_scale_pixel_repeat_C2,
mdp_scale_pixel_repeat_C3);
} else if ((!use_pr)
&& (mdp_scale_0p6_to_0p8_mode !=
MDP_SCALE_FIR)) {
mdp_scale_0p6_to_0p8_mode =
MDP_SCALE_FIR;
mdp_update_scale_table
(MDP_SCALE_0P6_TO_0P8_INDEX,
mdp_scale_0p6_to_0p8_C0,
mdp_scale_0p6_to_0p8_C1,
mdp_scale_0p6_to_0p8_C2,
mdp_scale_0p6_to_0p8_C3);
}
ppp_scale_config |= (SCALE_D2_SET << 4);
} else
if (((dst_roi_height_scale * 10) /
iBuf->roi.height) > 4) {
if ((use_pr)
&& (mdp_scale_0p4_to_0p6_mode !=
MDP_SCALE_PR)) {
mdp_scale_0p4_to_0p6_mode =
MDP_SCALE_PR;
mdp_update_scale_table
(MDP_SCALE_0P4_TO_0P6_INDEX,
mdp_scale_pixel_repeat_C0,
mdp_scale_pixel_repeat_C1,
mdp_scale_pixel_repeat_C2,
mdp_scale_pixel_repeat_C3);
} else if ((!use_pr)
&& (mdp_scale_0p4_to_0p6_mode !=
MDP_SCALE_FIR)) {
mdp_scale_0p4_to_0p6_mode =
MDP_SCALE_FIR;
mdp_update_scale_table
(MDP_SCALE_0P4_TO_0P6_INDEX,
mdp_scale_0p4_to_0p6_C0,
mdp_scale_0p4_to_0p6_C1,
mdp_scale_0p4_to_0p6_C2,
mdp_scale_0p4_to_0p6_C3);
}
ppp_scale_config |= (SCALE_D1_SET << 4);
} else
if (((dst_roi_height_scale * 4) /
iBuf->roi.height) >= 1) {
if ((use_pr)
&& (mdp_scale_0p2_to_0p4_mode !=
MDP_SCALE_PR)) {
mdp_scale_0p2_to_0p4_mode =
MDP_SCALE_PR;
mdp_update_scale_table
(MDP_SCALE_0P2_TO_0P4_INDEX,
mdp_scale_pixel_repeat_C0,
mdp_scale_pixel_repeat_C1,
mdp_scale_pixel_repeat_C2,
mdp_scale_pixel_repeat_C3);
} else if ((!use_pr)
&& (mdp_scale_0p2_to_0p4_mode !=
MDP_SCALE_FIR)) {
mdp_scale_0p2_to_0p4_mode =
MDP_SCALE_FIR;
mdp_update_scale_table
(MDP_SCALE_0P2_TO_0P4_INDEX,
mdp_scale_0p2_to_0p4_C0,
mdp_scale_0p2_to_0p4_C1,
mdp_scale_0p2_to_0p4_C2,
mdp_scale_0p2_to_0p4_C3);
}
ppp_scale_config |= (SCALE_D0_SET << 4);
} else
ppp_scale_config |= BIT(1);
if (iBuf->mdpImg.mdpOp & MDPOP_SHARPENING) {
ppp_scale_config |= BIT(7);
MDP_OUTP(MDP_BASE + 0x50020,
iBuf->mdpImg.sp_value);
}
MDP_OUTP(MDP_BASE + 0x10230, ppp_scale_config);
} else {
iBuf->mdpImg.mdpOp &= ~(MDPOP_ASCALE);
}
}
}
void mdp_adjust_start_addr(uint8 **src0,
uint8 **src1,
int v_slice,
int h_slice,
int x,
int y,
uint32 width,
uint32 height, int bpp, MDPIBUF *iBuf, int layer)
{
switch (layer) {
case 0:
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0200, (y << 16) | (x));
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0208,
(height << 16) | (width));
break;
case 1:
/* MDP 3.1 HW bug workaround */
if (iBuf->ibuf_type == MDP_YCRYCB_H2V1) {
*src0 += (x + y * width) * bpp;
x = y = 0;
width = iBuf->roi.dst_width;
height = iBuf->roi.dst_height;
}
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0204, (y << 16) | (x));
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x020c,
(height << 16) | (width));
break;
case 2:
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x019c, (y << 16) | (x));
break;
}
}
void mdp_set_blend_attr(MDPIBUF *iBuf,
uint32 *alpha,
uint32 *tpVal,
uint32 perPixelAlpha, uint32 *pppop_reg_ptr)
{
int bg_alpha;
*alpha = iBuf->mdpImg.alpha;
*tpVal = iBuf->mdpImg.tpVal;
if (iBuf->mdpImg.mdpOp & MDPOP_FG_PM_ALPHA) {
*pppop_reg_ptr |= PPP_OP_ROT_ON |
PPP_OP_BLEND_ON | PPP_OP_BLEND_CONSTANT_ALPHA;
bg_alpha = PPP_BLEND_BG_USE_ALPHA_SEL |
PPP_BLEND_BG_ALPHA_REVERSE;
if (perPixelAlpha)
bg_alpha |= PPP_BLEND_BG_SRCPIXEL_ALPHA;
else
bg_alpha |= PPP_BLEND_BG_CONSTANT_ALPHA;
outpdw(MDP_BASE + 0x70010, bg_alpha);
if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)
*pppop_reg_ptr |= PPP_BLEND_CALPHA_TRNASP;
} else if (perPixelAlpha) {
*pppop_reg_ptr |= PPP_OP_ROT_ON |
PPP_OP_BLEND_ON | PPP_OP_BLEND_SRCPIXEL_ALPHA;
} else {
if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
&& (iBuf->mdpImg.alpha == 0xff)) {
iBuf->mdpImg.mdpOp &= ~(MDPOP_ALPHAB);
}
if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
|| (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)) {
*pppop_reg_ptr |=
PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
PPP_OP_BLEND_CONSTANT_ALPHA |
PPP_OP_BLEND_ALPHA_BLEND_NORMAL;
}
if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)
*pppop_reg_ptr |= PPP_BLEND_CALPHA_TRNASP;
}
}

View file

@ -1,389 +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/vmalloc.h>
#include <linux/clk.h>
#include <mach/hardware.h>
#include <linux/io.h>
#include <asm/system.h>
#include <asm/mach-types.h>
#include <linux/semaphore.h>
#include <linux/uaccess.h>
#include <mach/gpio.h>
#include "mdp.h"
#include "msm_fb.h"
#include "mddihost.h"
#ifdef CONFIG_FB_MSM_MDP40
#define MDP_SYNC_CFG_0 0x100
#define MDP_SYNC_STATUS_0 0x10c
#define MDP_PRIM_VSYNC_OUT_CTRL 0x118
#define MDP_PRIM_VSYNC_INIT_VAL 0x128
#else
#define MDP_SYNC_CFG_0 0x300
#define MDP_SYNC_STATUS_0 0x30c
#define MDP_PRIM_VSYNC_OUT_CTRL 0x318
#define MDP_PRIM_VSYNC_INIT_VAL 0x328
#endif
extern mddi_lcd_type mddi_lcd_idx;
extern spinlock_t mdp_spin_lock;
extern struct workqueue_struct *mdp_vsync_wq;
extern int lcdc_mode;
extern int vsync_mode;
#ifdef MDP_HW_VSYNC
int vsync_above_th = 4;
int vsync_start_th = 1;
int vsync_load_cnt;
struct clk *mdp_vsync_clk;
void mdp_hw_vsync_clk_enable(struct msm_fb_data_type *mfd)
{
if (mfd->use_mdp_vsync)
clk_enable(mdp_vsync_clk);
}
void mdp_hw_vsync_clk_disable(struct msm_fb_data_type *mfd)
{
if (mfd->use_mdp_vsync)
clk_disable(mdp_vsync_clk);
}
#endif
static void mdp_set_vsync(unsigned long data)
{
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)data;
struct msm_fb_panel_data *pdata = NULL;
pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
if ((pdata) && (pdata->set_vsync_notifier == NULL))
return;
init_timer(&mfd->vsync_resync_timer);
mfd->vsync_resync_timer.function = mdp_set_vsync;
mfd->vsync_resync_timer.data = data;
mfd->vsync_resync_timer.expires =
jiffies + mfd->panel_info.lcd.vsync_notifier_period;
add_timer(&mfd->vsync_resync_timer);
if ((mfd->panel_info.lcd.vsync_enable) && (mfd->panel_power_on)
&& (!mfd->vsync_handler_pending)) {
mfd->vsync_handler_pending = TRUE;
if (!queue_work(mdp_vsync_wq, &mfd->vsync_resync_worker)) {
MSM_FB_INFO
("mdp_set_vsync: can't queue_work! -> needs to increase vsync_resync_timer_duration\n");
}
} else {
MSM_FB_DEBUG
("mdp_set_vsync failed! EN:%d PWR:%d PENDING:%d\n",
mfd->panel_info.lcd.vsync_enable, mfd->panel_power_on,
mfd->vsync_handler_pending);
}
}
static void mdp_vsync_handler(void *data)
{
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)data;
if (mfd->use_mdp_vsync) {
#ifdef MDP_HW_VSYNC
if (mfd->panel_power_on)
MDP_OUTP(MDP_BASE + MDP_SYNC_STATUS_0, vsync_load_cnt);
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
#endif
} else {
mfd->last_vsync_timetick = ktime_get_real();
}
mfd->vsync_handler_pending = FALSE;
}
irqreturn_t mdp_hw_vsync_handler_proxy(int irq, void *data)
{
/*
* ToDo: tried enabling/disabling GPIO MDP HW VSYNC interrupt
* but getting inaccurate timing in mdp_vsync_handler()
* disable_irq(MDP_HW_VSYNC_IRQ);
*/
mdp_vsync_handler(data);
return IRQ_HANDLED;
}
#ifdef MDP_HW_VSYNC
static void mdp_set_sync_cfg_0(struct msm_fb_data_type *mfd, int vsync_cnt)
{
unsigned long cfg;
cfg = mfd->total_lcd_lines - 1;
cfg <<= MDP_SYNCFG_HGT_LOC;
if (mfd->panel_info.lcd.hw_vsync_mode)
cfg |= MDP_SYNCFG_VSYNC_EXT_EN;
cfg |= (MDP_SYNCFG_VSYNC_INT_EN | vsync_cnt);
MDP_OUTP(MDP_BASE + MDP_SYNC_CFG_0, cfg);
}
#endif
void mdp_config_vsync(struct msm_fb_data_type *mfd)
{
/* vsync on primary lcd only for now */
if ((mfd->dest != DISPLAY_LCD) || (mfd->panel_info.pdest != DISPLAY_1)
|| (!vsync_mode)) {
goto err_handle;
}
if (mfd->panel_info.lcd.vsync_enable) {
mfd->total_porch_lines = mfd->panel_info.lcd.v_back_porch +
mfd->panel_info.lcd.v_front_porch +
mfd->panel_info.lcd.v_pulse_width;
mfd->total_lcd_lines =
mfd->panel_info.yres + mfd->total_porch_lines;
mfd->lcd_ref_usec_time =
100000000 / mfd->panel_info.lcd.refx100;
mfd->vsync_handler_pending = FALSE;
mfd->last_vsync_timetick.tv.sec = 0;
mfd->last_vsync_timetick.tv.nsec = 0;
#ifdef MDP_HW_VSYNC
if (mdp_vsync_clk == NULL)
mdp_vsync_clk = clk_get(NULL, "mdp_vsync_clk");
if (IS_ERR(mdp_vsync_clk)) {
printk(KERN_ERR "error: can't get mdp_vsync_clk!\n");
mfd->use_mdp_vsync = 0;
} else
mfd->use_mdp_vsync = 1;
if (mfd->use_mdp_vsync) {
uint32 vsync_cnt_cfg, vsync_cnt_cfg_dem;
uint32 mdp_vsync_clk_speed_hz;
mdp_vsync_clk_speed_hz = clk_get_rate(mdp_vsync_clk);
if (mdp_vsync_clk_speed_hz == 0) {
mfd->use_mdp_vsync = 0;
} else {
/*
* Do this calculation in 2 steps for
* rounding uint32 properly.
*/
vsync_cnt_cfg_dem =
(mfd->panel_info.lcd.refx100 *
mfd->total_lcd_lines) / 100;
vsync_cnt_cfg =
(mdp_vsync_clk_speed_hz) /
vsync_cnt_cfg_dem;
/* MDP cmd block enable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON,
FALSE);
mdp_hw_vsync_clk_enable(mfd);
mdp_set_sync_cfg_0(mfd, vsync_cnt_cfg);
/*
* load the last line + 1 to be in the
* safety zone
*/
vsync_load_cnt = mfd->panel_info.yres;
/* line counter init value at the next pulse */
MDP_OUTP(MDP_BASE + MDP_PRIM_VSYNC_INIT_VAL,
vsync_load_cnt);
/*
* external vsync source pulse width and
* polarity flip
*/
MDP_OUTP(MDP_BASE + MDP_PRIM_VSYNC_OUT_CTRL,
BIT(30) | BIT(0));
/* threshold */
MDP_OUTP(MDP_BASE + 0x200,
(vsync_above_th << 16) |
(vsync_start_th));
mdp_hw_vsync_clk_disable(mfd);
/* MDP cmd block disable */
mdp_pipe_ctrl(MDP_CMD_BLOCK,
MDP_BLOCK_POWER_OFF, FALSE);
}
}
#else
mfd->use_mdp_vsync = 0;
hrtimer_init(&mfd->dma_hrtimer, CLOCK_MONOTONIC,
HRTIMER_MODE_REL);
mfd->dma_hrtimer.function = mdp_dma2_vsync_hrtimer_handler;
mfd->vsync_width_boundary = vmalloc(mfd->panel_info.xres * 4);
#endif
mfd->channel_irq = 0;
if (mfd->panel_info.lcd.hw_vsync_mode) {
u32 vsync_gpio = mfd->vsync_gpio;
u32 ret;
if (vsync_gpio == -1) {
MSM_FB_INFO("vsync_gpio not defined!\n");
goto err_handle;
}
ret = gpio_tlmm_config(GPIO_CFG
(vsync_gpio,
(mfd->use_mdp_vsync) ? 1 : 0,
GPIO_INPUT,
GPIO_PULL_DOWN,
GPIO_2MA),
GPIO_ENABLE);
if (ret)
goto err_handle;
if (!mfd->use_mdp_vsync) {
mfd->channel_irq = MSM_GPIO_TO_INT(vsync_gpio);
if (request_irq
(mfd->channel_irq,
&mdp_hw_vsync_handler_proxy,
IRQF_TRIGGER_FALLING, "VSYNC_GPIO",
(void *)mfd)) {
MSM_FB_INFO
("irq=%d failed! vsync_gpio=%d\n",
mfd->channel_irq,
vsync_gpio);
goto err_handle;
}
}
}
mdp_set_vsync((unsigned long)mfd);
}
return;
err_handle:
if (mfd->vsync_width_boundary)
vfree(mfd->vsync_width_boundary);
mfd->panel_info.lcd.vsync_enable = FALSE;
printk(KERN_ERR "%s: failed!\n", __func__);
}
void mdp_vsync_resync_workqueue_handler(struct work_struct *work)
{
struct msm_fb_data_type *mfd = NULL;
int vsync_fnc_enabled = FALSE;
struct msm_fb_panel_data *pdata = NULL;
mfd = container_of(work, struct msm_fb_data_type, vsync_resync_worker);
if (mfd) {
if (mfd->panel_power_on) {
pdata =
(struct msm_fb_panel_data *)mfd->pdev->dev.
platform_data;
/*
* we need to turn on MDP power if it uses MDP vsync
* HW block in SW mode
*/
if ((!mfd->panel_info.lcd.hw_vsync_mode) &&
(mfd->use_mdp_vsync) &&
(pdata) && (pdata->set_vsync_notifier != NULL)) {
/*
* enable pwr here since we can't enable it in
* vsync callback in isr mode
*/
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON,
FALSE);
}
if (pdata->set_vsync_notifier != NULL) {
vsync_fnc_enabled = TRUE;
pdata->set_vsync_notifier(mdp_vsync_handler,
(void *)mfd);
}
}
}
if ((mfd) && (!vsync_fnc_enabled))
mfd->vsync_handler_pending = FALSE;
}
boolean mdp_hw_vsync_set_handler(msm_fb_vsync_handler_type handler, void *data)
{
/*
* ToDo: tried enabling/disabling GPIO MDP HW VSYNC interrupt
* but getting inaccurate timing in mdp_vsync_handler()
* enable_irq(MDP_HW_VSYNC_IRQ);
*/
return TRUE;
}
uint32 mdp_get_lcd_line_counter(struct msm_fb_data_type *mfd)
{
uint32 elapsed_usec_time;
uint32 lcd_line;
ktime_t last_vsync_timetick_local;
ktime_t curr_time;
unsigned long flag;
if ((!mfd->panel_info.lcd.vsync_enable) || (!vsync_mode))
return 0;
spin_lock_irqsave(&mdp_spin_lock, flag);
last_vsync_timetick_local = mfd->last_vsync_timetick;
spin_unlock_irqrestore(&mdp_spin_lock, flag);
curr_time = ktime_get_real();
elapsed_usec_time =
((curr_time.tv.sec - last_vsync_timetick_local.tv.sec) * 1000000) +
((curr_time.tv.nsec - last_vsync_timetick_local.tv.nsec) / 1000);
elapsed_usec_time = elapsed_usec_time % mfd->lcd_ref_usec_time;
/* lcd line calculation referencing to line counter = 0 */
lcd_line =
(elapsed_usec_time * mfd->total_lcd_lines) / mfd->lcd_ref_usec_time;
/* lcd line adjusment referencing to the actual line counter at vsync */
lcd_line =
(mfd->total_lcd_lines - mfd->panel_info.lcd.v_back_porch +
lcd_line) % (mfd->total_lcd_lines + 1);
if (lcd_line > mfd->total_lcd_lines) {
MSM_FB_INFO
("mdp_get_lcd_line_counter: mdp_lcd_rd_cnt >= mfd->total_lcd_lines error!\n");
}
return lcd_line;
}

View file

@ -1,214 +0,0 @@
/* arch/arm/mach-msm/memory.c
*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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.
*
*/
#include <linux/mm.h>
#include <linux/mm_types.h>
#include <linux/bootmem.h>
#include <linux/module.h>
#include <asm/pgtable.h>
#include <asm/io.h>
#include <asm/mach/map.h>
#include "memory_ll.h"
#include <asm/cacheflush.h>
#if defined(CONFIG_MSM_NPA_REMOTE)
#include "npa_remote.h"
#include <linux/completion.h>
#include <linux/err.h>
#endif
int arch_io_remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
unsigned long pfn, unsigned long size, pgprot_t prot)
{
unsigned long pfn_addr = pfn << PAGE_SHIFT;
/*
if ((pfn_addr >= 0x88000000) && (pfn_addr < 0xD0000000)) {
prot = pgprot_device(prot);
printk("remapping device %lx\n", prot);
}
*/
panic("Memory remap PFN stuff not done\n");
return remap_pfn_range(vma, addr, pfn, size, prot);
}
void *zero_page_strongly_ordered;
static void map_zero_page_strongly_ordered(void)
{
if (zero_page_strongly_ordered)
return;
/*
zero_page_strongly_ordered =
ioremap_strongly_ordered(page_to_pfn(empty_zero_page)
<< PAGE_SHIFT, PAGE_SIZE);
*/
panic("Strongly ordered memory functions not implemented\n");
}
void write_to_strongly_ordered_memory(void)
{
map_zero_page_strongly_ordered();
*(int *)zero_page_strongly_ordered = 0;
}
EXPORT_SYMBOL(write_to_strongly_ordered_memory);
void flush_axi_bus_buffer(void)
{
__asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
: : "r" (0) : "memory");
write_to_strongly_ordered_memory();
}
#define CACHE_LINE_SIZE 32
/* These cache related routines make the assumption that the associated
* physical memory is contiguous. They will operate on all (L1
* and L2 if present) caches.
*/
void clean_and_invalidate_caches(unsigned long vstart,
unsigned long length, unsigned long pstart)
{
unsigned long vaddr;
for (vaddr = vstart; vaddr < vstart + length; vaddr += CACHE_LINE_SIZE)
asm ("mcr p15, 0, %0, c7, c14, 1" : : "r" (vaddr));
#ifdef CONFIG_OUTER_CACHE
outer_flush_range(pstart, pstart + length);
#endif
asm ("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
asm ("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
flush_axi_bus_buffer();
}
void clean_caches(unsigned long vstart,
unsigned long length, unsigned long pstart)
{
unsigned long vaddr;
for (vaddr = vstart; vaddr < vstart + length; vaddr += CACHE_LINE_SIZE)
asm ("mcr p15, 0, %0, c7, c10, 1" : : "r" (vaddr));
#ifdef CONFIG_OUTER_CACHE
outer_clean_range(pstart, pstart + length);
#endif
asm ("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
asm ("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
flush_axi_bus_buffer();
}
void invalidate_caches(unsigned long vstart,
unsigned long length, unsigned long pstart)
{
unsigned long vaddr;
for (vaddr = vstart; vaddr < vstart + length; vaddr += CACHE_LINE_SIZE)
asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (vaddr));
#ifdef CONFIG_OUTER_CACHE
outer_inv_range(pstart, pstart + length);
#endif
asm ("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
asm ("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
flush_axi_bus_buffer();
}
void *alloc_bootmem_aligned(unsigned long size, unsigned long alignment)
{
void *unused_addr = NULL;
unsigned long addr, tmp_size, unused_size;
/* Allocate maximum size needed, see where it ends up.
* Then free it -- in this path there are no other allocators
* so we can depend on getting the same address back
* when we allocate a smaller piece that is aligned
* at the end (if necessary) and the piece we really want,
* then free the unused first piece.
*/
tmp_size = size + alignment - PAGE_SIZE;
addr = (unsigned long)alloc_bootmem(tmp_size);
free_bootmem(__pa(addr), tmp_size);
unused_size = alignment - (addr % alignment);
if (unused_size)
unused_addr = alloc_bootmem(unused_size);
addr = (unsigned long)alloc_bootmem(size);
if (unused_size)
free_bootmem(__pa(unused_addr), unused_size);
return (void *)addr;
}
#if defined(CONFIG_MSM_NPA_REMOTE)
struct npa_client *npa_memory_client;
#endif
static int change_memory_power_state(unsigned long start_pfn,
unsigned long nr_pages, int state)
{
#if defined(CONFIG_MSM_NPA_REMOTE)
static atomic_t node_created_flag = ATOMIC_INIT(1);
#else
unsigned long start;
unsigned long size;
unsigned long virtual;
#endif
int rc = 0;
#if defined(CONFIG_MSM_NPA_REMOTE)
if (atomic_dec_and_test(&node_created_flag)) {
/* Create NPA 'required' client. */
npa_memory_client = npa_create_sync_client(NPA_MEMORY_NODE_NAME,
"memory node", NPA_CLIENT_REQUIRED);
if (IS_ERR(npa_memory_client)) {
rc = PTR_ERR(npa_memory_client);
return rc;
}
}
rc = npa_issue_required_request(npa_memory_client, state);
#else
if (state == MEMORY_DEEP_POWERDOWN) {
/* simulate turning off memory by writing bit pattern into it */
start = start_pfn << PAGE_SHIFT;
size = nr_pages << PAGE_SHIFT;
virtual = __phys_to_virt(start);
memset((void *)virtual, 0x27, size);
}
#endif
return rc;
}
int platform_physical_remove_pages(unsigned long start_pfn,
unsigned long nr_pages)
{
return change_memory_power_state(start_pfn, nr_pages,
MEMORY_DEEP_POWERDOWN);
}
int platform_physical_add_pages(unsigned long start_pfn,
unsigned long nr_pages)
{
return change_memory_power_state(start_pfn, nr_pages, MEMORY_ACTIVE);
}
int platform_physical_low_power_pages(unsigned long start_pfn,
unsigned long nr_pages)
{
return change_memory_power_state(start_pfn, nr_pages,
MEMORY_SELF_REFRESH);
}

View file

@ -1,61 +0,0 @@
/*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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.
*
*/
#ifndef __ASM_ARCH_MEMORY_LL_H
#define __ASM_ARCH_MEMORY_LL_H
#define MAX_PHYSMEM_BITS 32
#define SECTION_SIZE_BITS 25
#define HAS_ARCH_IO_REMAP_PFN_RANGE
#ifndef __ASSEMBLY__
void *alloc_bootmem_aligned(unsigned long size, unsigned long alignment);
void clean_and_invalidate_caches(unsigned long, unsigned long, unsigned long);
void clean_caches(unsigned long, unsigned long, unsigned long);
void invalidate_caches(unsigned long, unsigned long, unsigned long);
int platform_physical_remove_pages(unsigned long, unsigned long);
int platform_physical_add_pages(unsigned long, unsigned long);
int platform_physical_low_power_pages(unsigned long, unsigned long);
#ifdef CONFIG_ARCH_MSM_ARM11
void write_to_strongly_ordered_memory(void);
#include <asm/mach-types.h>
#define arch_barrier_extra() do \
{ if (machine_is_msm7x27_surf() || machine_is_msm7x27_ffa()) \
write_to_strongly_ordered_memory(); \
} while (0)
#endif
#ifdef CONFIG_CACHE_L2X0
extern void l2x0_cache_sync(void);
#define finish_arch_switch(prev) do { l2x0_cache_sync(); } while (0)
#endif
#endif
#ifdef CONFIG_ARCH_MSM_SCORPION
#define arch_has_speculative_dfetch() 1
#endif
#endif
/* these correspond to values known by the modem */
#define MEMORY_DEEP_POWERDOWN 0
#define MEMORY_SELF_REFRESH 1
#define MEMORY_ACTIVE 2
#define NPA_MEMORY_NODE_NAME "/mem/ebi1/cs1"

File diff suppressed because it is too large Load diff

View file

@ -1,158 +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.
*/
#ifndef MSM_FB_H
#define MSM_FB_H
#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/proc_fs.h>
#include <mach/hardware.h>
#include <linux/io.h>
#include <mach/board.h>
#include <asm/system.h>
#include <asm/mach-types.h>
#include <mach/memory.h>
#include <linux/semaphore.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <linux/hrtimer.h>
#include <linux/fb.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include "msm_fb_panel.h"
#include "mdp.h"
#define MSM_FB_DEFAULT_PAGE_SIZE 2
#define MFD_KEY 0x11161126
#define MSM_FB_MAX_DEV_LIST 32
struct disp_info_type_suspend {
boolean op_enable;
boolean sw_refreshing_enable;
boolean panel_power_on;
};
struct msm_fb_data_type {
__u32 key;
__u32 index;
__u32 ref_cnt;
__u32 fb_page;
panel_id_type panel;
struct msm_panel_info panel_info;
DISP_TARGET dest;
struct fb_info *fbi;
boolean op_enable;
uint32 fb_imgType;
boolean sw_currently_refreshing;
boolean sw_refreshing_enable;
boolean hw_refresh;
MDPIBUF ibuf;
boolean ibuf_flushed;
struct timer_list refresh_timer;
struct completion refresher_comp;
boolean pan_waiting;
struct completion pan_comp;
/* vsync */
boolean use_mdp_vsync;
__u32 vsync_gpio;
__u32 total_lcd_lines;
__u32 total_porch_lines;
__u32 lcd_ref_usec_time;
__u32 refresh_timer_duration;
struct hrtimer dma_hrtimer;
boolean panel_power_on;
struct work_struct dma_update_worker;
struct semaphore sem;
struct timer_list vsync_resync_timer;
boolean vsync_handler_pending;
struct work_struct vsync_resync_worker;
ktime_t last_vsync_timetick;
__u32 *vsync_width_boundary;
unsigned int pmem_id;
struct disp_info_type_suspend suspend;
__u32 channel_irq;
struct mdp_dma_data *dma;
void (*dma_fnc) (struct msm_fb_data_type *mfd);
int (*cursor_update) (struct fb_info *info,
struct fb_cursor *cursor);
int (*lut_update) (struct fb_info *info,
struct fb_cmap *cmap);
int (*do_histogram) (struct fb_info *info,
struct mdp_histogram *hist);
void *cursor_buf;
void *cursor_buf_phys;
void *cmd_port;
void *data_port;
void *data_port_phys;
__u32 bl_level;
struct platform_device *pdev;
__u32 var_xres;
__u32 var_yres;
__u32 var_pixclock;
#ifdef MSM_FB_ENABLE_DBGFS
struct dentry *sub_dir;
#endif
#ifdef CONFIG_HAS_EARLYSUSPEND
struct early_suspend early_suspend;
struct early_suspend mddi_early_suspend;
struct early_suspend mddi_ext_early_suspend;
#endif
u32 mdp_fb_page_protection;
int allow_set_offset;
};
struct dentry *msm_fb_get_debugfs_root(void);
void msm_fb_debugfs_file_create(struct dentry *root, const char *name,
u32 *var);
void msm_fb_set_backlight(struct msm_fb_data_type *mfd, __u32 bkl_lvl,
u32 save);
void msm_fb_add_device(struct platform_device *pdev);
int msm_fb_detect_client(const char *name);
#ifdef CONFIG_FB_BACKLIGHT
void msm_fb_config_backlight(struct msm_fb_data_type *mfd);
#endif
#endif /* MSM_FB_H */

View file

@ -1,78 +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/moduleparam.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/fb.h>
#include <linux/string.h>
#include <linux/backlight.h>
#include "msm_fb.h"
static int msm_fb_bl_get_brightness(struct backlight_device *pbd)
{
return pbd->props.brightness;
}
static int msm_fb_bl_update_status(struct backlight_device *pbd)
{
struct msm_fb_data_type *mfd = bl_get_data(pbd);
__u32 bl_lvl;
bl_lvl = pbd->props.brightness;
bl_lvl = mfd->fbi->bl_curve[bl_lvl];
msm_fb_set_backlight(mfd, bl_lvl, 1);
return 0;
}
static const struct backlight_ops msm_fb_bl_ops = {
.get_brightness = msm_fb_bl_get_brightness,
.update_status = msm_fb_bl_update_status,
};
void msm_fb_config_backlight(struct msm_fb_data_type *mfd)
{
struct msm_fb_panel_data *pdata;
struct backlight_device *pbd;
struct fb_info *fbi;
char name[16];
fbi = mfd->fbi;
pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
if ((pdata) && (pdata->set_backlight)) {
snprintf(name, sizeof(name), "msmfb_bl%d", mfd->index);
pbd =
backlight_device_register(name, fbi->dev, mfd,
&msm_fb_bl_ops);
if (!IS_ERR(pbd)) {
fbi->bl_dev = pbd;
fb_bl_default_curve(fbi,
0,
mfd->panel_info.bl_min,
mfd->panel_info.bl_max);
pbd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
pbd->props.brightness = FB_BACKLIGHT_LEVELS - 1;
backlight_update_status(pbd);
} else {
fbi->bl_dev = NULL;
printk(KERN_ERR "msm_fb: backlight_device_register failed!\n");
}
}
}

View file

@ -1,180 +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.
*/
#ifndef MSM_FB_DEF_H
#define MSM_FB_DEF_H
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/fb.h>
#include "msm_mdp.h"
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/uaccess.h>
#include <linux/workqueue.h>
#include <linux/string.h>
#include <linux/proc_fs.h>
#include <linux/vmalloc.h>
#include <linux/debugfs.h>
#include <linux/console.h>
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/interrupt.h>
#include <mach/hardware.h>
#include <linux/io.h>
#include <asm/system.h>
#include <asm/mach-types.h>
#include <linux/platform_device.h>
typedef s64 int64;
typedef s32 int32;
typedef s16 int16;
typedef s8 int8;
typedef u64 uint64;
typedef u32 uint32;
typedef u16 uint16;
typedef u8 uint8;
typedef s32 int4;
typedef s16 int2;
typedef s8 int1;
typedef u32 uint4;
typedef u16 uint2;
typedef u8 uint1;
typedef u32 dword;
typedef u16 word;
typedef u8 byte;
typedef unsigned int boolean;
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#define MSM_FB_ENABLE_DBGFS
#define FEATURE_MDDI
#define outp32(addr, val) writel(val, addr)
#define outp16(addr, val) writew(val, addr)
#define outp8(addr, val) writeb(val, addr)
#define outp(addr, val) outp32(addr, val)
#ifndef MAX
#define MAX( x, y ) (((x) > (y)) ? (x) : (y))
#endif
#ifndef MIN
#define MIN( x, y ) (((x) < (y)) ? (x) : (y))
#endif
/*--------------------------------------------------------------------------*/
#define inp32(addr) readl(addr)
#define inp16(addr) readw(addr)
#define inp8(addr) readb(addr)
#define inp(addr) inp32(addr)
#define inpw(port) readw(port)
#define outpw(port, val) writew(val, port)
#define inpdw(port) readl(port)
#define outpdw(port, val) writel(val, port)
#define clk_busy_wait(x) msleep_interruptible((x)/1000)
#define memory_barrier()
#define assert(expr) \
if(!(expr)) { \
printk(KERN_ERR "msm_fb: assertion failed! %s,%s,%s,line=%d\n",\
#expr, __FILE__, __func__, __LINE__); \
}
#define ASSERT(x) assert(x)
#define DISP_EBI2_LOCAL_DEFINE
#ifdef DISP_EBI2_LOCAL_DEFINE
#define LCD_PRIM_BASE_PHYS 0x98000000
#define LCD_SECD_BASE_PHYS 0x9c000000
#define EBI2_PRIM_LCD_RS_PIN 0x20000
#define EBI2_SECD_LCD_RS_PIN 0x20000
#define EBI2_PRIM_LCD_CLR 0xC0
#define EBI2_PRIM_LCD_SEL 0x40
#define EBI2_SECD_LCD_CLR 0x300
#define EBI2_SECD_LCD_SEL 0x100
#endif
extern u32 msm_fb_msg_level;
/*
* Message printing priorities:
* LEVEL 0 KERN_EMERG (highest priority)
* LEVEL 1 KERN_ALERT
* LEVEL 2 KERN_CRIT
* LEVEL 3 KERN_ERR
* LEVEL 4 KERN_WARNING
* LEVEL 5 KERN_NOTICE
* LEVEL 6 KERN_INFO
* LEVEL 7 KERN_DEBUG (Lowest priority)
*/
#define MSM_FB_EMERG(msg, ...) \
if (msm_fb_msg_level > 0) \
printk(KERN_EMERG msg, ## __VA_ARGS__);
#define MSM_FB_ALERT(msg, ...) \
if (msm_fb_msg_level > 1) \
printk(KERN_ALERT msg, ## __VA_ARGS__);
#define MSM_FB_CRIT(msg, ...) \
if (msm_fb_msg_level > 2) \
printk(KERN_CRIT msg, ## __VA_ARGS__);
#define MSM_FB_ERR(msg, ...) \
if (msm_fb_msg_level > 3) \
printk(KERN_ERR msg, ## __VA_ARGS__);
#define MSM_FB_WARNING(msg, ...) \
if (msm_fb_msg_level > 4) \
printk(KERN_WARNING msg, ## __VA_ARGS__);
#define MSM_FB_NOTICE(msg, ...) \
if (msm_fb_msg_level > 5) \
printk(KERN_NOTICE msg, ## __VA_ARGS__);
#define MSM_FB_INFO(msg, ...) \
if (msm_fb_msg_level > 6) \
printk(KERN_INFO msg, ## __VA_ARGS__);
#define MSM_FB_DEBUG(msg, ...) \
if (msm_fb_msg_level > 7) \
printk(KERN_DEBUG msg, ## __VA_ARGS__);
#ifdef MSM_FB_C
unsigned char *msm_mdp_base;
unsigned char *msm_pmdh_base;
unsigned char *msm_emdh_base;
#else
extern unsigned char *msm_mdp_base;
extern unsigned char *msm_pmdh_base;
extern unsigned char *msm_emdh_base;
#endif
#endif /* MSM_FB_DEF_H */

View file

@ -1,135 +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/moduleparam.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/uaccess.h>
#include <linux/workqueue.h>
#include <linux/string.h>
#include <linux/proc_fs.h>
#include <linux/vmalloc.h>
#include <linux/debugfs.h>
#include "msm_fb_panel.h"
int panel_next_on(struct platform_device *pdev)
{
int ret = 0;
struct msm_fb_panel_data *pdata;
struct msm_fb_panel_data *next_pdata;
struct platform_device *next_pdev;
pdata = (struct msm_fb_panel_data *)pdev->dev.platform_data;
if (pdata) {
next_pdev = pdata->next;
if (next_pdev) {
next_pdata =
(struct msm_fb_panel_data *)next_pdev->dev.
platform_data;
if ((next_pdata) && (next_pdata->on))
ret = next_pdata->on(next_pdev);
}
}
return ret;
}
int panel_next_off(struct platform_device *pdev)
{
int ret = 0;
struct msm_fb_panel_data *pdata;
struct msm_fb_panel_data *next_pdata;
struct platform_device *next_pdev;
pdata = (struct msm_fb_panel_data *)pdev->dev.platform_data;
if (pdata) {
next_pdev = pdata->next;
if (next_pdev) {
next_pdata =
(struct msm_fb_panel_data *)next_pdev->dev.
platform_data;
if ((next_pdata) && (next_pdata->on))
ret = next_pdata->off(next_pdev);
}
}
return ret;
}
struct platform_device *msm_fb_device_alloc(struct msm_fb_panel_data *pdata,
u32 type, u32 id)
{
struct platform_device *this_dev = NULL;
char dev_name[16];
switch (type) {
case EBI2_PANEL:
snprintf(dev_name, sizeof(dev_name), "ebi2_lcd");
break;
case MDDI_PANEL:
snprintf(dev_name, sizeof(dev_name), "mddi");
break;
case EXT_MDDI_PANEL:
snprintf(dev_name, sizeof(dev_name), "mddi_ext");
break;
case TV_PANEL:
snprintf(dev_name, sizeof(dev_name), "tvenc");
break;
case HDMI_PANEL:
case LCDC_PANEL:
snprintf(dev_name, sizeof(dev_name), "lcdc");
break;
default:
return NULL;
}
if (pdata != NULL)
pdata->next = NULL;
else
return NULL;
this_dev =
platform_device_alloc(dev_name, ((u32) type << 16) | (u32) id);
if (this_dev) {
if (platform_device_add_data
(this_dev, pdata, sizeof(struct msm_fb_panel_data))) {
printk
("msm_fb_device_alloc: platform_device_add_data failed!\n");
platform_device_put(this_dev);
return NULL;
}
}
return this_dev;
}

View file

@ -1,129 +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.
*/
#ifndef MSM_FB_PANEL_H
#define MSM_FB_PANEL_H
#include "msm_fb_def.h"
struct msm_fb_data_type;
typedef void (*msm_fb_vsync_handler_type) (void *arg);
/* panel id type */
typedef struct panel_id_s {
uint16 id;
uint16 type;
} panel_id_type;
/* panel type list */
#define NO_PANEL 0xffff /* No Panel */
#define MDDI_PANEL 1 /* MDDI */
#define EBI2_PANEL 2 /* EBI2 */
#define LCDC_PANEL 3 /* internal LCDC type */
#define EXT_MDDI_PANEL 4 /* Ext.MDDI */
#define TV_PANEL 5 /* TV */
#define HDMI_PANEL 6 /* HDMI TV */
/* panel class */
typedef enum {
DISPLAY_LCD = 0, /* lcd = ebi2/mddi */
DISPLAY_LCDC, /* lcdc */
DISPLAY_TV, /* TV Out */
DISPLAY_EXT_MDDI, /* External MDDI */
} DISP_TARGET;
/* panel device locaiton */
typedef enum {
DISPLAY_1 = 0, /* attached as first device */
DISPLAY_2, /* attached on second device */
MAX_PHYS_TARGET_NUM,
} DISP_TARGET_PHYS;
/* panel info type */
struct lcd_panel_info {
__u32 vsync_enable;
__u32 refx100;
__u32 v_back_porch;
__u32 v_front_porch;
__u32 v_pulse_width;
__u32 hw_vsync_mode;
__u32 vsync_notifier_period;
};
struct lcdc_panel_info {
__u32 h_back_porch;
__u32 h_front_porch;
__u32 h_pulse_width;
__u32 v_back_porch;
__u32 v_front_porch;
__u32 v_pulse_width;
__u32 border_clr;
__u32 underflow_clr;
__u32 hsync_skew;
};
struct mddi_panel_info {
__u32 vdopkt;
};
struct msm_panel_info {
__u32 xres;
__u32 yres;
__u32 bpp;
__u32 type;
__u32 wait_cycle;
DISP_TARGET_PHYS pdest;
__u32 bl_max;
__u32 bl_min;
__u32 fb_num;
__u32 clk_rate;
__u32 clk_min;
__u32 clk_max;
__u32 frame_count;
union {
struct mddi_panel_info mddi;
};
union {
struct lcd_panel_info lcd;
struct lcdc_panel_info lcdc;
};
};
struct msm_fb_panel_data {
struct msm_panel_info panel_info;
void (*set_rect) (int x, int y, int xres, int yres);
void (*set_vsync_notifier) (msm_fb_vsync_handler_type, void *arg);
void (*set_backlight) (struct msm_fb_data_type *);
/* function entry chain */
int (*on) (struct platform_device *pdev);
int (*off) (struct platform_device *pdev);
struct platform_device *next;
};
/*===========================================================================
FUNCTIONS PROTOTYPES
============================================================================*/
struct platform_device *msm_fb_device_alloc(struct msm_fb_panel_data *pdata,
u32 type, u32 id);
int panel_next_on(struct platform_device *pdev);
int panel_next_off(struct platform_device *pdev);
int lcdc_device_register(struct msm_panel_info *pinfo);
int mddi_toshiba_device_register(struct msm_panel_info *pinfo,
u32 channel, u32 panel);
#endif /* MSM_FB_PANEL_H */

View file

@ -1,245 +0,0 @@
/* include/linux/msm_mdp.h
*
* Copyright (C) 2007 Google Incorporated
* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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.
*/
#ifndef _MSM_MDP_H_
#define _MSM_MDP_H_
#include <linux/types.h>
#include <linux/fb.h>
#define MSMFB_IOCTL_MAGIC 'm'
#define MSMFB_GRP_DISP _IOW(MSMFB_IOCTL_MAGIC, 1, unsigned int)
#define MSMFB_BLIT _IOW(MSMFB_IOCTL_MAGIC, 2, unsigned int)
#define MSMFB_SUSPEND_SW_REFRESHER _IOW(MSMFB_IOCTL_MAGIC, 128, unsigned int)
#define MSMFB_RESUME_SW_REFRESHER _IOW(MSMFB_IOCTL_MAGIC, 129, unsigned int)
#define MSMFB_CURSOR _IOW(MSMFB_IOCTL_MAGIC, 130, struct fb_cursor)
#define MSMFB_SET_LUT _IOW(MSMFB_IOCTL_MAGIC, 131, struct fb_cmap)
#define MSMFB_HISTOGRAM _IOWR(MSMFB_IOCTL_MAGIC, 132, struct mdp_histogram)
/* new ioctls's for set/get ccs matrix */
#define MSMFB_GET_CCS_MATRIX _IOWR(MSMFB_IOCTL_MAGIC, 133, struct mdp_ccs)
#define MSMFB_SET_CCS_MATRIX _IOW(MSMFB_IOCTL_MAGIC, 134, struct mdp_ccs)
#define MSMFB_OVERLAY_SET _IOWR(MSMFB_IOCTL_MAGIC, 135, \
struct mdp_overlay)
#define MSMFB_OVERLAY_UNSET _IOW(MSMFB_IOCTL_MAGIC, 136, unsigned int)
#define MSMFB_OVERLAY_PLAY _IOW(MSMFB_IOCTL_MAGIC, 137, \
struct msmfb_overlay_data)
#define MSMFB_GET_PAGE_PROTECTION _IOR(MSMFB_IOCTL_MAGIC, 138, \
struct mdp_page_protection)
#define MSMFB_SET_PAGE_PROTECTION _IOW(MSMFB_IOCTL_MAGIC, 139, \
struct mdp_page_protection)
#define MSMFB_OVERLAY_GET _IOR(MSMFB_IOCTL_MAGIC, 140, \
struct mdp_overlay)
/* new ioctls for async MDP ops */
#define MSMFB_ASYNC_BLIT _IOW(MSMFB_IOCTL_MAGIC, 141, unsigned int)
#define MSMFB_BLIT_FLUSH _IOR(MSMFB_IOCTL_MAGIC, 142, unsigned int)
#define MDP_IMGTYPE2_START 0x10000
enum {
MDP_RGB_565, /* RGB 565 planer */
MDP_XRGB_8888, /* RGB 888 padded */
MDP_Y_CBCR_H2V2, /* Y and CbCr, pseudo planer w/ Cb is in MSB */
MDP_ARGB_8888, /* ARGB 888 */
MDP_RGB_888, /* RGB 888 planer */
MDP_Y_CRCB_H2V2, /* Y and CrCb, pseudo planer w/ Cr is in MSB */
MDP_YCRYCB_H2V1, /* YCrYCb interleave */
MDP_Y_CRCB_H2V1, /* Y and CrCb, pseduo planer w/ Cr is in MSB */
MDP_Y_CBCR_H2V1, /* Y and CrCb, pseduo planer w/ Cr is in MSB */
MDP_RGBA_8888, /* ARGB 888 */
MDP_BGRA_8888, /* ABGR 888 */
MDP_Y_CRCB_H2V2_TILE, /* Y and CrCb, pseudo planer tile */
MDP_Y_CBCR_H2V2_TILE, /* Y and CbCr, pseudo planer tile */
MDP_IMGTYPE_LIMIT,
MDP_BGR_565 = MDP_IMGTYPE2_START, /* BGR 565 planer */
MDP_FB_FORMAT, /* framebuffer format */
MDP_IMGTYPE_LIMIT2 /* Non valid image type after this enum */
};
enum {
PMEM_IMG,
FB_IMG,
};
/* mdp_blit_req flag values */
#define MDP_ROT_NOP 0
#define MDP_FLIP_LR 0x1
#define MDP_FLIP_UD 0x2
#define MDP_ROT_90 0x4
#define MDP_ROT_180 (MDP_FLIP_UD|MDP_FLIP_LR)
#define MDP_ROT_270 (MDP_ROT_90|MDP_FLIP_UD|MDP_FLIP_LR)
#define MDP_DITHER 0x8
#define MDP_BLUR 0x10
#define MDP_BLEND_FG_PREMULT 0x20000
#define MDP_DEINTERLACE 0x80000000
#define MDP_SHARPENING 0x40000000
#define MDP_NO_DMA_BARRIER_START 0x20000000
#define MDP_NO_DMA_BARRIER_END 0x10000000
#define MDP_NO_BLIT 0x08000000
#define MDP_BLIT_WITH_DMA_BARRIERS 0x000
#define MDP_BLIT_WITH_NO_DMA_BARRIERS \
(MDP_NO_DMA_BARRIER_START | MDP_NO_DMA_BARRIER_END)
#define MDP_TRANSP_NOP 0xffffffff
#define MDP_ALPHA_NOP 0xff
#define MDP_BLIT_SRC_GEM 0x02000000 /* set for GEM, clear for PMEM */
#define MDP_BLIT_DST_GEM 0x01000000 /* set for GEM, clear for PMEM */
#define MDP_FB_PAGE_PROTECTION_NONCACHED (0)
#define MDP_FB_PAGE_PROTECTION_WRITECOMBINE (1)
#define MDP_FB_PAGE_PROTECTION_WRITETHROUGHCACHE (2)
#define MDP_FB_PAGE_PROTECTION_WRITEBACKCACHE (3)
#define MDP_FB_PAGE_PROTECTION_WRITEBACKWACACHE (4)
/* Sentinel: Don't use! */
#define MDP_FB_PAGE_PROTECTION_INVALID (5)
/* Count of the number of MDP_FB_PAGE_PROTECTION_... values. */
#define MDP_NUM_FB_PAGE_PROTECTION_VALUES (5)
struct mdp_rect {
uint32_t x;
uint32_t y;
uint32_t w;
uint32_t h;
};
struct mdp_img {
uint32_t width;
uint32_t height;
uint32_t format;
uint32_t offset;
int memory_id; /* the file descriptor */
uint32_t priv;
};
/*
* {3x3} + {3} ccs matrix
*/
#define MDP_CCS_RGB2YUV 0
#define MDP_CCS_YUV2RGB 1
#define MDP_CCS_SIZE 9
#define MDP_BV_SIZE 3
struct mdp_ccs {
int direction; /* MDP_CCS_RGB2YUV or YUV2RGB */
uint16_t ccs[MDP_CCS_SIZE]; /* 3x3 color coefficients */
uint16_t bv[MDP_BV_SIZE]; /* 1x3 bias vector */
};
/* The version of the mdp_blit_req structure so that
* user applications can selectively decide which functionality
* to include
*/
#define MDP_BLIT_REQ_VERSION 2
struct mdp_blit_req {
struct mdp_img src;
struct mdp_img dst;
struct mdp_rect src_rect;
struct mdp_rect dst_rect;
uint32_t alpha;
uint32_t transp_mask;
uint32_t flags;
int sharpening_strength; /* -127 <--> 127, default 64 */
};
struct mdp_blit_req_list {
uint32_t count;
struct mdp_blit_req req[];
};
struct msmfb_data {
uint32_t offset;
int memory_id;
int id;
};
#define MSMFB_NEW_REQUEST -1
struct msmfb_overlay_data {
uint32_t id;
struct msmfb_data data;
};
struct msmfb_img {
uint32_t width;
uint32_t height;
uint32_t format;
};
struct mdp_overlay {
struct msmfb_img src;
struct mdp_rect src_rect;
struct mdp_rect dst_rect;
uint32_t z_order; /* stage number */
uint32_t is_fg; /* control alpha & transp */
uint32_t alpha;
uint32_t transp_mask;
uint32_t flags;
uint32_t id;
uint32_t user_data[8];
};
struct mdp_histogram {
uint32_t frame_cnt;
uint32_t bin_cnt;
uint32_t *r;
uint32_t *g;
uint32_t *b;
};
struct mdp_page_protection {
uint32_t page_protection;
};
struct msm_panel_common_pdata {
int gpio;
int (*backlight_level)(int level, int max, int min);
int (*pmic_backlight)(int level);
int (*panel_num)(void);
void (*panel_config_gpio)(int);
int *gpio_num;
};
struct lcdc_platform_data {
int (*lcdc_gpio_config)(int on);
void (*lcdc_power_save)(int);
};
struct tvenc_platform_data {
int (*pm_vid_en)(int on);
};
struct mddi_platform_data {
void (*mddi_power_save)(int on);
int (*mddi_sel_clk)(u32 *clk_rate);
};
struct msm_fb_platform_data {
int (*detect_client)(const char *name);
int mddi_prescan;
int (*allow_set_offset)(void);
};
struct msm_hdmi_platform_data {
int irq;
int (*cable_detect)(int insert);
};
#endif /*_MSM_MDP_H_*/

View file

@ -1,312 +0,0 @@
#include <linux/kernel.h>
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/bootmem.h>
#include <linux/delay.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/io.h>
#include <asm/setup.h>
#include <mach/board.h>
#include <mach/irqs.h>
#include <mach/sirc.h>
#include <mach/gpio.h>
#include "msm_mdp.h"
#include "memory_ll.h"
//#include "android_pmem.h"
#ifdef CONFIG_MSM_SOC_REV_A
#define MSM_SMI_BASE 0xE0000000
#else
#define MSM_SMI_BASE 0x00000000
#endif
#define TOUCHPAD_SUSPEND 34
#define TOUCHPAD_IRQ 38
#define MSM_PMEM_MDP_SIZE 0x1591000
#ifdef CONFIG_MSM_SOC_REV_A
#define SMEM_SPINLOCK_I2C "D:I2C02000021"
#else
#define SMEM_SPINLOCK_I2C "S:6"
#endif
#define MSM_PMEM_ADSP_SIZE 0x1C00000
#define MSM_FB_SIZE 0x500000
#define MSM_FB_SIZE_ST15 0x800000
#define MSM_AUDIO_SIZE 0x80000
#define MSM_GPU_PHYS_SIZE SZ_2M
#ifdef CONFIG_MSM_SOC_REV_A
#define MSM_SMI_BASE 0xE0000000
#else
#define MSM_SMI_BASE 0x00000000
#endif
#define MSM_SHARED_RAM_PHYS (MSM_SMI_BASE + 0x00100000)
#define MSM_PMEM_SMI_BASE (MSM_SMI_BASE + 0x02B00000)
#define MSM_PMEM_SMI_SIZE 0x01500000
#define MSM_FB_BASE MSM_PMEM_SMI_BASE
#define MSM_GPU_PHYS_BASE (MSM_FB_BASE + MSM_FB_SIZE)
#define MSM_PMEM_SMIPOOL_BASE (MSM_GPU_PHYS_BASE + MSM_GPU_PHYS_SIZE)
#define MSM_PMEM_SMIPOOL_SIZE (MSM_PMEM_SMI_SIZE - MSM_FB_SIZE \
- MSM_GPU_PHYS_SIZE)
#if defined(CONFIG_FB_MSM_MDP40)
#define MDP_BASE 0xA3F00000
#define PMDH_BASE 0xAD600000
#define EMDH_BASE 0xAD700000
#define TVENC_BASE 0xAD400000
#else
#define MDP_BASE 0xAA200000
#define PMDH_BASE 0xAA600000
#define EMDH_BASE 0xAA700000
#define TVENC_BASE 0xAA400000
#endif
#define PMEM_KERNEL_EBI1_SIZE (CONFIG_PMEM_KERNEL_SIZE * 1024 * 1024)
static struct resource msm_fb_resources[] = {
{
.flags = IORESOURCE_DMA,
}
};
static struct resource msm_mdp_resources[] = {
{
.name = "mdp",
.start = MDP_BASE,
.end = MDP_BASE + 0x000F0000 - 1,
.flags = IORESOURCE_MEM,
}
};
static struct platform_device msm_mdp_device = {
.name = "mdp",
.id = 0,
.num_resources = ARRAY_SIZE(msm_mdp_resources),
.resource = msm_mdp_resources,
};
static struct platform_device msm_lcdc_device = {
.name = "lcdc",
.id = 0,
};
static int msm_fb_detect_panel(const char *name)
{
int ret = -EPERM;
if (machine_is_qsd8x50_ffa() || machine_is_qsd8x50a_ffa()) {
if (!strncmp(name, "mddi_toshiba_wvga_pt", 20))
ret = 0;
else
ret = -ENODEV;
} else if ((machine_is_qsd8x50_surf() || machine_is_qsd8x50a_surf())
&& !strcmp(name, "lcdc_external"))
ret = 0;
else if (machine_is_qsd8x50a_st1_5()) {
if (!strcmp(name, "lcdc_st15") ||
!strcmp(name, "hdmi_sii9022"))
ret = 0;
else
ret = -ENODEV;
}
return ret;
}
/* Only allow a small subset of machines to set the offset via
FB PAN_DISPLAY */
static int msm_fb_allow_set_offset(void)
{
return (machine_is_qsd8x50_st1() ||
machine_is_qsd8x50a_st1_5()) ? 1 : 0;
}
static struct msm_fb_platform_data msm_fb_pdata = {
.detect_client = msm_fb_detect_panel,
.allow_set_offset = msm_fb_allow_set_offset,
};
static struct platform_device msm_fb_device = {
.name = "msm_fb",
.id = 0,
.num_resources = ARRAY_SIZE(msm_fb_resources),
.resource = msm_fb_resources,
.dev = {
.platform_data = &msm_fb_pdata,
}
};
static void __init qsd8x50_allocate_memory_regions(void)
{
void *addr;
unsigned long size;
if (machine_is_qsd8x50a_st1_5())
size = MSM_FB_SIZE_ST15;
else
size = MSM_FB_SIZE;
addr = alloc_bootmem(size); // (void *)MSM_FB_BASE;
if (!addr)
printk("Failed to allocate bootmem for framebuffer\n");
msm_fb_resources[0].start = __pa(addr);
msm_fb_resources[0].end = msm_fb_resources[0].start + size - 1;
pr_info("using %lu bytes of SMI at %lx physical for fb\n",
size, (unsigned long)addr);
}
static int msm_fb_lcdc_gpio_config(int on)
{
// return 0;
if (machine_is_qsd8x50_st1()) {
if (on) {
gpio_set_value(32, 1);
mdelay(100);
gpio_set_value(20, 1);
gpio_set_value(17, 1);
gpio_set_value(19, 1);
} else {
gpio_set_value(17, 0);
gpio_set_value(19, 0);
gpio_set_value(20, 0);
mdelay(100);
gpio_set_value(32, 0);
}
} else if (machine_is_qsd8x50a_st1_5()) {
if (on) {
gpio_set_value(17, 1);
gpio_set_value(19, 1);
gpio_set_value(20, 1);
gpio_set_value(22, 0);
gpio_set_value(32, 1);
gpio_set_value(155, 1);
//st15_hdmi_power(1);
gpio_set_value(22, 1);
} else {
gpio_set_value(17, 0);
gpio_set_value(19, 0);
gpio_set_value(22, 0);
gpio_set_value(32, 0);
gpio_set_value(155, 0);
// st15_hdmi_power(0);
}
}
return 0;
}
static struct lcdc_platform_data lcdc_pdata = {
.lcdc_gpio_config = msm_fb_lcdc_gpio_config,
};
static struct msm_gpio msm_fb_st15_gpio_config_data[] = {
{ GPIO_CFG(17, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_en0" },
{ GPIO_CFG(19, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "dat_pwr_sv" },
{ GPIO_CFG(20, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lvds_pwr_dn" },
{ GPIO_CFG(22, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_en1" },
{ GPIO_CFG(32, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_en2" },
{ GPIO_CFG(103, 0, GPIO_INPUT, GPIO_NO_PULL, GPIO_2MA), "hdmi_irq" },
{ GPIO_CFG(155, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "hdmi_3v3" },
};
static struct msm_panel_common_pdata mdp_pdata = {
.gpio = 98,
};
static struct platform_device *devices[] __initdata = {
&msm_fb_device,
};
static void __init msm_register_device(struct platform_device *pdev, void *data)
{
int ret;
pdev->dev.platform_data = data;
ret = platform_device_register(pdev);
if (ret)
dev_err(&pdev->dev,
"%s: platform_device_register() failed = %d\n",
__func__, ret);
}
void __init msm_fb_register_device(char *name, void *data)
{
if (!strncmp(name, "mdp", 3))
msm_register_device(&msm_mdp_device, data);
/*
else if (!strncmp(name, "pmdh", 4))
msm_register_device(&msm_mddi_device, data);
else if (!strncmp(name, "emdh", 4))
msm_register_device(&msm_mddi_ext_device, data);
else if (!strncmp(name, "ebi2", 4))
msm_register_device(&msm_ebi2_lcd_device, data);
else if (!strncmp(name, "tvenc", 5))
msm_register_device(&msm_tvenc_device, data);
else */
if (!strncmp(name, "lcdc", 4))
msm_register_device(&msm_lcdc_device, data);
/*else
printk(KERN_ERR "%s: unknown device! %s\n", __func__, name);
*/
}
static void __init msm_fb_add_devices(void)
{
int rc;
msm_fb_register_device("mdp", &mdp_pdata);
// msm_fb_register_device("pmdh", &mddi_pdata);
// msm_fb_register_device("emdh", &mddi_pdata);
// msm_fb_register_device("tvenc", 0);
if (machine_is_qsd8x50a_st1_5()) {
/* rc = st15_hdmi_vreg_init();
if (rc)
return;
*/
rc = msm_gpios_request_enable(
msm_fb_st15_gpio_config_data,
ARRAY_SIZE(msm_fb_st15_gpio_config_data));
if (rc) {
printk(KERN_ERR "%s: unable to init lcdc gpios\n",
__func__);
return;
}
msm_fb_register_device("lcdc", &lcdc_pdata);
} else
msm_fb_register_device("lcdc", 0);
}
int __init staging_init_pmem(void)
{
qsd8x50_allocate_memory_regions();
return 0;
}
int __init staging_init_devices(void)
{
platform_add_devices(devices, ARRAY_SIZE(devices));
msm_fb_add_devices();
return 0;
}
arch_initcall(staging_init_pmem);
arch_initcall(staging_init_devices);

View file

@ -1,163 +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/delay.h>
#include <mach/hardware.h>
#include <linux/io.h>
#include <asm/system.h>
#include <asm/mach-types.h>
#include <linux/semaphore.h>
#include <linux/uaccess.h>
#include <linux/clk.h>
#include "msm_fb.h"
#include "tvenc.h"
#define NTSC_TV_DIMENSION_WIDTH 720
#define NTSC_TV_DIMENSION_HEIGHT 480
static int ntsc_off(struct platform_device *pdev);
static int ntsc_on(struct platform_device *pdev);
static int ntsc_on(struct platform_device *pdev)
{
uint32 reg = 0;
int ret = 0;
struct msm_fb_data_type *mfd;
mfd = platform_get_drvdata(pdev);
if (!mfd)
return -ENODEV;
if (mfd->key != MFD_KEY)
return -EINVAL;
TV_OUT(TV_ENC_CTL, 0); /* disable TV encoder */
if (mfd->panel.id == NTSC_M) {
/* Cr gain 11, Cb gain C6, y_gain 97 */
TV_OUT(TV_GAIN, 0x0081B697);
} else {
/* Cr gain 11, Cb gain C6, y_gain 97 */
TV_OUT(TV_GAIN, 0x008bc4a3);
reg |= TVENC_CTL_NTSCJ_MODE;
}
TV_OUT(TV_CGMS, 0x0);
/* NTSC Timing */
TV_OUT(TV_SYNC_1, 0x0020009e);
TV_OUT(TV_SYNC_2, 0x011306B4);
TV_OUT(TV_SYNC_3, 0x0006000C);
TV_OUT(TV_SYNC_4, 0x0028020D);
TV_OUT(TV_SYNC_5, 0x005E02FB);
TV_OUT(TV_SYNC_6, 0x0006000C);
TV_OUT(TV_SYNC_7, 0x00000012);
TV_OUT(TV_BURST_V1, 0x0013020D);
TV_OUT(TV_BURST_V2, 0x0014020C);
TV_OUT(TV_BURST_V3, 0x0013020D);
TV_OUT(TV_BURST_V4, 0x0014020C);
TV_OUT(TV_BURST_H, 0x00AE00F2);
TV_OUT(TV_SOL_REQ_ODD, 0x00280208);
TV_OUT(TV_SOL_REQ_EVEN, 0x00290209);
reg |= TVENC_CTL_TV_MODE_NTSC_M_PAL60;
reg |= TVENC_CTL_Y_FILTER_EN |
TVENC_CTL_CR_FILTER_EN |
TVENC_CTL_CB_FILTER_EN | TVENC_CTL_SINX_FILTER_EN;
#ifdef CONFIG_FB_MSM_TVOUT_SVIDEO
reg |= TVENC_CTL_S_VIDEO_EN;
#endif
TV_OUT(TV_LEVEL, 0x00000000); /* DC offset to 0. */
TV_OUT(TV_OFFSET, 0x008080f0);
#ifdef CONFIG_FB_MSM_MDP31
TV_OUT(TV_DAC_INTF, 0x29);
#endif
TV_OUT(TV_ENC_CTL, reg);
reg |= TVENC_CTL_ENC_EN;
TV_OUT(TV_ENC_CTL, reg);
return ret;
}
static int ntsc_off(struct platform_device *pdev)
{
TV_OUT(TV_ENC_CTL, 0); /* disable TV encoder */
return 0;
}
static int __init ntsc_probe(struct platform_device *pdev)
{
msm_fb_add_device(pdev);
return 0;
}
static struct platform_driver this_driver = {
.probe = ntsc_probe,
.driver = {
.name = "tv_ntsc",
},
};
static struct msm_fb_panel_data ntsc_panel_data = {
.panel_info.xres = NTSC_TV_DIMENSION_WIDTH,
.panel_info.yres = NTSC_TV_DIMENSION_HEIGHT,
.panel_info.type = TV_PANEL,
.panel_info.pdest = DISPLAY_1,
.panel_info.wait_cycle = 0,
.panel_info.bpp = 16,
.panel_info.fb_num = 2,
.on = ntsc_on,
.off = ntsc_off,
};
static struct platform_device this_device = {
.name = "tv_ntsc",
.id = 0,
.dev = {
.platform_data = &ntsc_panel_data,
}
};
static int __init ntsc_init(void)
{
int ret;
ret = platform_driver_register(&this_driver);
if (!ret) {
ret = platform_device_register(&this_device);
if (ret)
platform_driver_unregister(&this_driver);
}
return ret;
}
module_init(ntsc_init);

View file

@ -1,213 +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/delay.h>
#include <mach/hardware.h>
#include <linux/io.h>
#include <asm/system.h>
#include <asm/mach-types.h>
#include <linux/semaphore.h>
#include <linux/uaccess.h>
#include <linux/clk.h>
#include "msm_fb.h"
#include "tvenc.h"
#ifdef CONFIG_FB_MSM_TVOUT_PAL_M
#define PAL_TV_DIMENSION_WIDTH 720
#define PAL_TV_DIMENSION_HEIGHT 480
#else
#define PAL_TV_DIMENSION_WIDTH 720
#define PAL_TV_DIMENSION_HEIGHT 576
#endif
static int pal_on(struct platform_device *pdev)
{
uint32 reg = 0;
int ret = 0;
struct msm_fb_data_type *mfd;
mfd = platform_get_drvdata(pdev);
if (!mfd)
return -ENODEV;
if (mfd->key != MFD_KEY)
return -EINVAL;
TV_OUT(TV_ENC_CTL, 0); /* disable TV encoder */
switch (mfd->panel.id) {
case PAL_BDGHIN:
/* Cr gain 11, Cb gain C6, y_gain 97 */
TV_OUT(TV_GAIN, 0x0088c1a0);
TV_OUT(TV_CGMS, 0x00012345);
TV_OUT(TV_TEST_MUX, 0x0);
/* PAL Timing */
TV_OUT(TV_SYNC_1, 0x00180097);
TV_OUT(TV_SYNC_2, 0x011f06c0);
TV_OUT(TV_SYNC_3, 0x0005000a);
TV_OUT(TV_SYNC_4, 0x00320271);
TV_OUT(TV_SYNC_5, 0x005602f9);
TV_OUT(TV_SYNC_6, 0x0005000a);
TV_OUT(TV_SYNC_7, 0x0000000f);
TV_OUT(TV_BURST_V1, 0x0012026e);
TV_OUT(TV_BURST_V2, 0x0011026d);
TV_OUT(TV_BURST_V3, 0x00100270);
TV_OUT(TV_BURST_V4, 0x0013026f);
TV_OUT(TV_BURST_H, 0x00af00ea);
TV_OUT(TV_SOL_REQ_ODD, 0x0030026e);
TV_OUT(TV_SOL_REQ_EVEN, 0x0031026f);
reg |= TVENC_CTL_TV_MODE_PAL_BDGHIN;
break;
case PAL_M:
/* Cr gain 11, Cb gain C6, y_gain 97 */
TV_OUT(TV_GAIN, 0x0081b697);
TV_OUT(TV_CGMS, 0x000af317);
TV_OUT(TV_TEST_MUX, 0x000001c3);
TV_OUT(TV_TEST_MODE, 0x00000002);
/* PAL Timing */
TV_OUT(TV_SYNC_1, 0x0020009e);
TV_OUT(TV_SYNC_2, 0x011306b4);
TV_OUT(TV_SYNC_3, 0x0006000c);
TV_OUT(TV_SYNC_4, 0x0028020D);
TV_OUT(TV_SYNC_5, 0x005e02fb);
TV_OUT(TV_SYNC_6, 0x0006000c);
TV_OUT(TV_SYNC_7, 0x00000012);
TV_OUT(TV_BURST_V1, 0x0012020b);
TV_OUT(TV_BURST_V2, 0x0016020c);
TV_OUT(TV_BURST_V3, 0x00150209);
TV_OUT(TV_BURST_V4, 0x0013020c);
TV_OUT(TV_BURST_H, 0x00bf010b);
TV_OUT(TV_SOL_REQ_ODD, 0x00280208);
TV_OUT(TV_SOL_REQ_EVEN, 0x00290209);
reg |= TVENC_CTL_TV_MODE_PAL_M;
break;
case PAL_N:
/* Cr gain 11, Cb gain C6, y_gain 97 */
TV_OUT(TV_GAIN, 0x0081b697);
TV_OUT(TV_CGMS, 0x000af317);
TV_OUT(TV_TEST_MUX, 0x000001c3);
TV_OUT(TV_TEST_MODE, 0x00000002);
/* PAL Timing */
TV_OUT(TV_SYNC_1, 0x00180097);
TV_OUT(TV_SYNC_2, 0x12006c0);
TV_OUT(TV_SYNC_3, 0x0005000a);
TV_OUT(TV_SYNC_4, 0x00320271);
TV_OUT(TV_SYNC_5, 0x005602f9);
TV_OUT(TV_SYNC_6, 0x0005000a);
TV_OUT(TV_SYNC_7, 0x0000000f);
TV_OUT(TV_BURST_V1, 0x0012026e);
TV_OUT(TV_BURST_V2, 0x0011026d);
TV_OUT(TV_BURST_V3, 0x00100270);
TV_OUT(TV_BURST_V4, 0x0013026f);
TV_OUT(TV_BURST_H, 0x00af00fa);
TV_OUT(TV_SOL_REQ_ODD, 0x0030026e);
TV_OUT(TV_SOL_REQ_EVEN, 0x0031026f);
reg |= TVENC_CTL_TV_MODE_PAL_N;
break;
default:
return -ENODEV;
}
reg |= TVENC_CTL_Y_FILTER_EN |
TVENC_CTL_CR_FILTER_EN |
TVENC_CTL_CB_FILTER_EN | TVENC_CTL_SINX_FILTER_EN;
#ifdef CONFIG_FB_MSM_TVOUT_SVIDEO
reg |= TVENC_CTL_S_VIDEO_EN;
#endif
TV_OUT(TV_LEVEL, 0x00000000); /* DC offset to 0. */
TV_OUT(TV_OFFSET, 0x008080f0);
#ifdef CONFIG_FB_MSM_MDP31
TV_OUT(TV_DAC_INTF, 0x29);
#endif
TV_OUT(TV_ENC_CTL, reg);
reg |= TVENC_CTL_ENC_EN;
TV_OUT(TV_ENC_CTL, reg);
return ret;
}
static int pal_off(struct platform_device *pdev)
{
TV_OUT(TV_ENC_CTL, 0); /* disable TV encoder */
return 0;
}
static int __init pal_probe(struct platform_device *pdev)
{
msm_fb_add_device(pdev);
return 0;
}
static struct platform_driver this_driver = {
.probe = pal_probe,
.driver = {
.name = "tv_pal",
},
};
static struct msm_fb_panel_data pal_panel_data = {
.panel_info.xres = PAL_TV_DIMENSION_WIDTH,
.panel_info.yres = PAL_TV_DIMENSION_HEIGHT,
.panel_info.type = TV_PANEL,
.panel_info.pdest = DISPLAY_1,
.panel_info.wait_cycle = 0,
.panel_info.bpp = 16,
.panel_info.fb_num = 2,
.on = pal_on,
.off = pal_off,
};
static struct platform_device this_device = {
.name = "tv_pal",
.id = 0,
.dev = {
.platform_data = &pal_panel_data,
}
};
static int __init pal_init(void)
{
int ret;
ret = platform_driver_register(&this_driver);
if (!ret) {
ret = platform_device_register(&this_device);
if (ret)
platform_driver_unregister(&this_driver);
}
return ret;
}
module_init(pal_init);

View file

@ -1,296 +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/delay.h>
#include <mach/hardware.h>
#include <linux/io.h>
#include <asm/system.h>
#include <asm/mach-types.h>
#include <linux/semaphore.h>
#include <linux/uaccess.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/pm_qos_params.h>
#define TVENC_C
#include "tvenc.h"
#include "msm_fb.h"
static int tvenc_probe(struct platform_device *pdev);
static int tvenc_remove(struct platform_device *pdev);
static int tvenc_off(struct platform_device *pdev);
static int tvenc_on(struct platform_device *pdev);
static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
static int pdev_list_cnt;
static struct clk *tvenc_clk;
static struct clk *tvdac_clk;
static struct platform_driver tvenc_driver = {
.probe = tvenc_probe,
.remove = tvenc_remove,
.suspend = NULL,
// .suspend_late = NULL,
// .resume_early = NULL,
.resume = NULL,
.shutdown = NULL,
.driver = {
.name = "tvenc",
},
};
static struct tvenc_platform_data *tvenc_pdata;
static int tvenc_off(struct platform_device *pdev)
{
int ret = 0;
ret = panel_next_off(pdev);
clk_disable(tvenc_clk);
clk_disable(tvdac_clk);
if (tvenc_pdata && tvenc_pdata->pm_vid_en)
ret = tvenc_pdata->pm_vid_en(0);
//pm_qos_update_requirement(PM_QOS_SYSTEM_BUS_FREQ , "tvenc",
// PM_QOS_DEFAULT_VALUE);
if (ret)
printk(KERN_ERR "%s: pm_vid_en(off) failed! %d\n",
__func__, ret);
return ret;
}
static int tvenc_on(struct platform_device *pdev)
{
int ret = 0;
// pm_qos_update_requirement(PM_QOS_SYSTEM_BUS_FREQ , "tvenc",
// 128000);
if (tvenc_pdata && tvenc_pdata->pm_vid_en)
ret = tvenc_pdata->pm_vid_en(1);
if (ret) {
printk(KERN_ERR "%s: pm_vid_en(on) failed! %d\n",
__func__, ret);
return ret;
}
clk_enable(tvenc_clk);
clk_enable(tvdac_clk);
ret = panel_next_on(pdev);
return ret;
}
void tvenc_gen_test_pattern(struct msm_fb_data_type *mfd)
{
uint32 reg = 0, i;
reg = readl(MSM_TV_ENC_CTL);
reg |= TVENC_CTL_TEST_PATT_EN;
for (i = 0; i < 3; i++) {
TV_OUT(TV_ENC_CTL, 0); /* disable TV encoder */
switch (i) {
/*
* TV Encoder - Color Bar Test Pattern
*/
case 0:
reg |= TVENC_CTL_TPG_CLRBAR;
break;
/*
* TV Encoder - Red Frame Test Pattern
*/
case 1:
reg |= TVENC_CTL_TPG_REDCLR;
break;
/*
* TV Encoder - Modulated Ramp Test Pattern
*/
default:
reg |= TVENC_CTL_TPG_MODRAMP;
break;
}
TV_OUT(TV_ENC_CTL, reg);
mdelay(5000);
switch (i) {
/*
* TV Encoder - Color Bar Test Pattern
*/
case 0:
reg &= ~TVENC_CTL_TPG_CLRBAR;
break;
/*
* TV Encoder - Red Frame Test Pattern
*/
case 1:
reg &= ~TVENC_CTL_TPG_REDCLR;
break;
/*
* TV Encoder - Modulated Ramp Test Pattern
*/
default:
reg &= ~TVENC_CTL_TPG_MODRAMP;
break;
}
}
}
static int tvenc_resource_initialized;
static int tvenc_probe(struct platform_device *pdev)
{
struct msm_fb_data_type *mfd;
struct platform_device *mdp_dev = NULL;
struct msm_fb_panel_data *pdata = NULL;
int rc;
if (pdev->id == 0) {
tvenc_base = ioremap(pdev->resource[0].start,
pdev->resource[0].end -
pdev->resource[0].start + 1);
if (!tvenc_base) {
printk(KERN_ERR
"tvenc_base ioremap failed!\n");
return -ENOMEM;
}
tvenc_pdata = pdev->dev.platform_data;
tvenc_resource_initialized = 1;
return 0;
}
if (!tvenc_resource_initialized)
return -EPERM;
mfd = platform_get_drvdata(pdev);
if (!mfd)
return -ENODEV;
if (mfd->key != MFD_KEY)
return -EINVAL;
if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
return -ENOMEM;
if (tvenc_base == NULL)
return -ENOMEM;
mdp_dev = platform_device_alloc("mdp", pdev->id);
if (!mdp_dev)
return -ENOMEM;
/*
* link to the latest pdev
*/
mfd->pdev = mdp_dev;
mfd->dest = DISPLAY_TV;
/*
* alloc panel device data
*/
if (platform_device_add_data
(mdp_dev, pdev->dev.platform_data,
sizeof(struct msm_fb_panel_data))) {
printk(KERN_ERR "tvenc_probe: platform_device_add_data failed!\n");
platform_device_put(mdp_dev);
return -ENOMEM;
}
/*
* data chain
*/
pdata = mdp_dev->dev.platform_data;
pdata->on = tvenc_on;
pdata->off = tvenc_off;
pdata->next = pdev;
/*
* get/set panel specific fb info
*/
mfd->panel_info = pdata->panel_info;
mfd->fb_imgType = MDP_YCRYCB_H2V1;
/*
* set driver data
*/
platform_set_drvdata(mdp_dev, mfd);
/*
* register in mdp driver
*/
rc = platform_device_add(mdp_dev);
if (rc)
goto tvenc_probe_err;
pdev_list[pdev_list_cnt++] = pdev;
return 0;
tvenc_probe_err:
platform_device_put(mdp_dev);
return rc;
}
static int tvenc_remove(struct platform_device *pdev)
{
// pm_qos_remove_requirement(PM_QOS_SYSTEM_BUS_FREQ , "tvenc");
return 0;
}
static int tvenc_register_driver(void)
{
return platform_driver_register(&tvenc_driver);
}
static int __init tvenc_driver_init(void)
{
tvenc_clk = clk_get(NULL, "tv_enc_clk");
tvdac_clk = clk_get(NULL, "tv_dac_clk");
if (IS_ERR(tvenc_clk)) {
printk(KERN_ERR "error: can't get tvenc_clk!\n");
return PTR_ERR(tvenc_clk);
}
if (IS_ERR(tvdac_clk)) {
printk(KERN_ERR "error: can't get tvdac_clk!\n");
clk_put(tvenc_clk);
return PTR_ERR(tvdac_clk);
}
// pm_qos_add_requirement(PM_QOS_SYSTEM_BUS_FREQ , "tvenc",
// PM_QOS_DEFAULT_VALUE);
return tvenc_register_driver();
}
module_init(tvenc_driver_init);

View file

@ -1,101 +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.
*/
#ifndef TVENC_H
#define TVENC_H
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/fb.h>
#include <mach/hardware.h>
#include <linux/io.h>
#include <asm/system.h>
#include <asm/mach-types.h>
#include "msm_fb_panel.h"
#define NTSC_M 0 /* North America, Korea */
#define NTSC_J 1 /* Japan */
#define PAL_BDGHIN 2 /* Non-argentina PAL-N */
#define PAL_M 3 /* PAL-M */
#define PAL_N 4 /* Argentina PAL-N */
/* 3.57954545 Mhz */
#define TVENC_CTL_TV_MODE_NTSC_M_PAL60 0
/* 3.57961149 Mhz */
#define TVENC_CTL_TV_MODE_PAL_M BIT(0)
/*non-Argintina = 4.3361875 Mhz */
#define TVENC_CTL_TV_MODE_PAL_BDGHIN BIT(1)
/*Argentina = 3.582055625 Mhz */
#define TVENC_CTL_TV_MODE_PAL_N (BIT(1)|BIT(0))
#define TVENC_CTL_ENC_EN BIT(2)
#define TVENC_CTL_CC_EN BIT(3)
#define TVENC_CTL_CGMS_EN BIT(4)
#define TVENC_CTL_MACRO_EN BIT(5)
#define TVENC_CTL_Y_FILTER_W_NOTCH BIT(6)
#define TVENC_CTL_Y_FILTER_WO_NOTCH 0
#define TVENC_CTL_Y_FILTER_EN BIT(7)
#define TVENC_CTL_CR_FILTER_EN BIT(8)
#define TVENC_CTL_CB_FILTER_EN BIT(9)
#define TVENC_CTL_SINX_FILTER_EN BIT(10)
#define TVENC_CTL_TEST_PATT_EN BIT(11)
#define TVENC_CTL_OUTPUT_INV BIT(12)
#define TVENC_CTL_PAL60_MODE BIT(13)
#define TVENC_CTL_NTSCJ_MODE BIT(14)
#define TVENC_CTL_TPG_CLRBAR 0
#define TVENC_CTL_TPG_MODRAMP BIT(15)
#define TVENC_CTL_TPG_REDCLR BIT(16)
#define TVENC_CTL_S_VIDEO_EN BIT(19)
#ifdef TVENC_C
void *tvenc_base;
#else
extern void *tvenc_base;
#endif
#define TV_OUT(reg, v) writel(v, tvenc_base + MSM_##reg)
#define MSM_TV_ENC_CTL 0x00
#define MSM_TV_LEVEL 0x04
#define MSM_TV_GAIN 0x08
#define MSM_TV_OFFSET 0x0c
#define MSM_TV_CGMS 0x10
#define MSM_TV_SYNC_1 0x14
#define MSM_TV_SYNC_2 0x18
#define MSM_TV_SYNC_3 0x1c
#define MSM_TV_SYNC_4 0x20
#define MSM_TV_SYNC_5 0x24
#define MSM_TV_SYNC_6 0x28
#define MSM_TV_SYNC_7 0x2c
#define MSM_TV_BURST_V1 0x30
#define MSM_TV_BURST_V2 0x34
#define MSM_TV_BURST_V3 0x38
#define MSM_TV_BURST_V4 0x3c
#define MSM_TV_BURST_H 0x40
#define MSM_TV_SOL_REQ_ODD 0x44
#define MSM_TV_SOL_REQ_EVEN 0x48
#define MSM_TV_DAC_CTL 0x4c
#define MSM_TV_TEST_MUX 0x50
#define MSM_TV_TEST_MODE 0x54
#define MSM_TV_TEST_MISR_RESET 0x58
#define MSM_TV_TEST_EXPORT_MISR 0x5c
#define MSM_TV_TEST_MISR_CURR_VAL 0x60
#define MSM_TV_TEST_SOF_CFG 0x64
#define MSM_TV_DAC_INTF 0x100
#endif /* TVENC_H */