From 935a9ce79780605671c8a80e65a9a0dd3746081a Mon Sep 17 00:00:00 2001 From: Jon Benson Date: Wed, 29 Sep 2010 15:12:34 +1000 Subject: [PATCH] Added video driver cleanup and tweaks by gauner1986. Thanks to huanyu for isolating them. --- drivers/video/msm/Kconfig | 50 +- drivers/video/msm/Makefile | 20 +- drivers/video/msm/gpu/kgsl/kgsl.c | 62 +- drivers/video/msm/gpu/kgsl/kgsl.h | 4 +- drivers/video/msm/gpu/kgsl/kgsl_mmu.c | 3 - drivers/video/msm/gpu/kgsl/kgsl_ringbuffer.c | 46 +- drivers/video/msm/hdmi/Makefile | 9 - drivers/video/msm/hdmi/edid.c | 695 ----------- drivers/video/msm/hdmi/fb-hdmi.c | 716 ------------ drivers/video/msm/hdmi/hdmi_lcdc.c | 633 ---------- drivers/video/msm/hdmi/include/edid.h | 82 -- drivers/video/msm/hdmi/include/fb-hdmi.h | 27 - drivers/video/msm/hdmi/include/sil902x.h | 399 ------- drivers/video/msm/hdmi/include/tpi.h | 411 ------- drivers/video/msm/hdmi/silicon-image/Makefile | 7 - .../video/msm/hdmi/silicon-image/av_config.c | 365 ------ .../msm/hdmi/silicon-image/debug-sil902x.c | 109 -- drivers/video/msm/hdmi/silicon-image/hdcp.c | 354 ------ drivers/video/msm/hdmi/silicon-image/tpi.c | 960 ---------------- drivers/video/msm/hdmi/transmitter.c | 1019 ----------------- drivers/video/msm/mddi.c | 233 +--- drivers/video/msm/mddi_client_epson.c | 267 ----- drivers/video/msm/mddi_client_novb9f6_5582.c | 269 ----- drivers/video/msm/mddi_hw.h | 24 +- drivers/video/msm/mdp.c | 329 ++---- drivers/video/msm/mdp_hw.h | 140 +-- drivers/video/msm/mdp_lcdc.c | 199 +--- drivers/video/msm/mdp_ppp.c | 274 +---- drivers/video/msm/mdp_ppp.h | 13 +- drivers/video/msm/mdp_ppp31.c | 229 ++++ drivers/video/msm/msm_fb.c | 318 +---- 31 files changed, 508 insertions(+), 7758 deletions(-) delete mode 100644 drivers/video/msm/hdmi/Makefile delete mode 100644 drivers/video/msm/hdmi/edid.c delete mode 100644 drivers/video/msm/hdmi/fb-hdmi.c delete mode 100644 drivers/video/msm/hdmi/hdmi_lcdc.c delete mode 100644 drivers/video/msm/hdmi/include/edid.h delete mode 100644 drivers/video/msm/hdmi/include/fb-hdmi.h delete mode 100644 drivers/video/msm/hdmi/include/sil902x.h delete mode 100644 drivers/video/msm/hdmi/include/tpi.h delete mode 100644 drivers/video/msm/hdmi/silicon-image/Makefile delete mode 100644 drivers/video/msm/hdmi/silicon-image/av_config.c delete mode 100644 drivers/video/msm/hdmi/silicon-image/debug-sil902x.c delete mode 100644 drivers/video/msm/hdmi/silicon-image/hdcp.c delete mode 100644 drivers/video/msm/hdmi/silicon-image/tpi.c delete mode 100644 drivers/video/msm/hdmi/transmitter.c delete mode 100644 drivers/video/msm/mddi_client_epson.c delete mode 100644 drivers/video/msm/mddi_client_novb9f6_5582.c diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig index 1ca3622c..831fdd7e 100644 --- a/drivers/video/msm/Kconfig +++ b/drivers/video/msm/Kconfig @@ -7,29 +7,14 @@ config FB_MSM default y config FB_MSM_LCDC - bool "Support for integrated LCD controller in qsd8x50 and MSM7x27" - depends on FB_MSM && (MSM_MDP31 || MSM_MDP302) - default y - -config FB_MSM_TVOUT - bool "Support for TV-Out in qsd8x50" + bool "Support for integrated LCD controller in qsd8x50" depends on FB_MSM && MSM_MDP31 - default n - -config FB_MSM_OVERLAY - bool "Support for overlay in MSM7X30" - depends on FB_MSM && MSM_MDP40 default y -config FB_MSM_DTV - depends on FB_MSM_OVERLAY - bool - default n - config GPU_MSM_KGSL tristate "MSM 3D Graphics driver for QSD8x50 and MSM7x27" default n - depends on FB_MSM && (ARCH_QSD8X50 || ARCH_MSM7227 || ARCH_MSM7X30) + depends on FB_MSM && ARCH_QSD8X50 select GENERIC_ALLOCATOR select CONFIG_FW_LOADER help @@ -37,24 +22,6 @@ config GPU_MSM_KGSL use hardware accelerated OpenGL ES 2.0 and 1.1 on these chips. -config MSM_ROTATOR - tristate "MSM Offline Image Rotator Driver" - depends on ARCH_MSM7X30 && ANDROID_PMEM - default y - help - This driver provides support for the image rotator HW block in the - MSM 7x30 SoC. - -config MSM_ROTATOR_USE_IMEM - bool "Enable rotator driver to use iMem" - depends on MSM_ROTATOR - default y - help - This option enables the msm_rotator driver to use the move efficient - iMem. Some MSM platforms may not have iMem available for the rotator - block. Or some systems may want the iMem to be dedicated to a - different function. - config MSM_KGSL_MMU bool "Turn on MMU for graphics driver " depends on GPU_MSM_KGSL && MMU @@ -63,19 +30,6 @@ config MSM_KGSL_MMU If enabled, the GPU driver will allocate memory from vmalloc and enable the use of GPU MMU, instead of using pmem. -config MSM_KGSL_PER_FD_PAGETABLE - bool "Turn on per-fd pagetable for MMU of graphics driver " - depends on MSM_KGSL_MMU && MMU - default n - help - If enabled, the MMU unit of GPU driver will use seperate - pagetables for each file descriptor - -config MSM_HDMI - bool "Support for HDMI in QCT platform" - depends on MSM_MDP31 - default n - config FB_MSM_LOGO bool "Use boot splashscreen" depends on FB_MSM diff --git a/drivers/video/msm/Makefile b/drivers/video/msm/Makefile index bb2447d1..40bc6c9b 100644 --- a/drivers/video/msm/Makefile +++ b/drivers/video/msm/Makefile @@ -1,7 +1,7 @@ # core framebuffer # -obj-y := msm_fb.o logo.o +obj-y := msm_fb.o ifeq ($(CONFIG_FB_MSM_LOGO),y) obj-y += logo.o endif @@ -9,14 +9,9 @@ endif # MDP DMA/PPP engine # obj-y += mdp.o mdp_ppp.o -obj-$(CONFIG_FB_MSM_OVERLAY) += mdp4_util.o -obj-$(CONFIG_FB_MSM_OVERLAY) += mdp4_overlay.o -obj-$(CONFIG_FB_MSM_OVERLAY) += mdp4_overlay_mddi.o -obj-$(CONFIG_MSM_MDP40) += msm_rotator.o + obj-$(CONFIG_MSM_MDP22) += mdp_ppp22.o -obj-$(CONFIG_MSM_MDP30) += mdp_ppp22.o -obj-$(CONFIG_MSM_MDP302)+= mdp_ppp22.o obj-$(CONFIG_MSM_MDP31) += mdp_ppp31.o # MDDI interface @@ -26,18 +21,11 @@ obj-y += mddi.o # MDDI client/panel drivers # obj-y += mddi_client_dummy.o -obj-y += mddi_client_epson.o -obj-y += mddi_client_novb9f6_5582.o +obj-y += mddi_client_toshiba.o +obj-y += mddi_client_nt35399.o # MDP LCD controller driver obj-$(CONFIG_FB_MSM_LCDC) += mdp_lcdc.o -obj-$(CONFIG_FB_MSM_TVOUT) += tvenc.o tvfb.o # Yamato GL driver -ifeq ($(CONFIG_ARCH_MSM7X30),y) -obj-$(CONFIG_GPU_MSM_KGSL) += gpu/kgsl_adreno205/ -else obj-$(CONFIG_GPU_MSM_KGSL) += gpu/kgsl/ -endif - -obj-$(CONFIG_MSM_HDMI) += hdmi/ diff --git a/drivers/video/msm/gpu/kgsl/kgsl.c b/drivers/video/msm/gpu/kgsl/kgsl.c index 423cdd11..ed590b3f 100644 --- a/drivers/video/msm/gpu/kgsl/kgsl.c +++ b/drivers/video/msm/gpu/kgsl/kgsl.c @@ -119,16 +119,10 @@ static void kgsl_clk_enable(void) clk_set_rate(kgsl_driver.ebi1_clk, 128000000); clk_enable(kgsl_driver.imem_clk); clk_enable(kgsl_driver.grp_clk); -#ifdef CONFIG_ARCH_MSM7227 - clk_enable(kgsl_driver.grp_pclk); -#endif } static void kgsl_clk_disable(void) { -#ifdef CONFIG_ARCH_MSM7227 - clk_disable(kgsl_driver.grp_pclk); -#endif clk_disable(kgsl_driver.grp_clk); clk_disable(kgsl_driver.imem_clk); clk_set_rate(kgsl_driver.ebi1_clk, 0); @@ -169,7 +163,7 @@ static void kgsl_hw_put_locked(bool start_timer) { if ((--kgsl_driver.active_cnt == 0) && start_timer) { mod_timer(&kgsl_driver.standby_timer, - jiffies + msecs_to_jiffies(512)); + jiffies + msecs_to_jiffies(20)); } } @@ -1037,52 +1031,10 @@ static long kgsl_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) return result; } -static int kgsl_mmap(struct file *file, struct vm_area_struct *vma) -{ - int result; - struct kgsl_memdesc *memdesc = NULL; - unsigned long vma_size = vma->vm_end - vma->vm_start; - unsigned long vma_offset = vma->vm_pgoff << PAGE_SHIFT; - struct kgsl_device *device = NULL; - - mutex_lock(&kgsl_driver.mutex); - - device = &kgsl_driver.yamato_device; - - /*allow yamato memstore to be mapped read only */ - if (vma_offset == device->memstore.physaddr) { - if (vma->vm_flags & VM_WRITE) { - result = -EPERM; - goto done; - } - memdesc = &device->memstore; - } - - if (memdesc->size != vma_size) { - KGSL_MEM_ERR("file %p bad size %ld, should be %d\n", - file, vma_size, memdesc->size); - result = -EINVAL; - goto done; - } - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - - result = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, - vma_size, vma->vm_page_prot); - if (result != 0) { - KGSL_MEM_ERR("remap_pfn_range returned %d\n", - result); - goto done; - } -done: - mutex_unlock(&kgsl_driver.mutex); - return result; -} - static struct file_operations kgsl_fops = { .owner = THIS_MODULE, .release = kgsl_release, .open = kgsl_open, - .mmap = kgsl_mmap, .unlocked_ioctl = kgsl_ioctl, }; @@ -1144,9 +1096,6 @@ static int __devinit kgsl_platform_probe(struct platform_device *pdev) BUG_ON(kgsl_driver.grp_clk != NULL); BUG_ON(kgsl_driver.imem_clk != NULL); BUG_ON(kgsl_driver.ebi1_clk != NULL); -#ifdef CONFIG_ARCH_MSM7227 - BUG_ON(kgsl_driver.grp_pclk != NULL); -#endif kgsl_driver.pdev = pdev; @@ -1177,15 +1126,6 @@ static int __devinit kgsl_platform_probe(struct platform_device *pdev) } kgsl_driver.ebi1_clk = clk; -#ifdef CONFIG_ARCH_MSM7227 - clk = clk_get(&pdev->dev, "grp_pclk"); - if (IS_ERR(clk)) { - result = PTR_ERR(clk); - KGSL_DRV_ERR("clk_get(grp_pclk) returned %d\n", result); - goto done; - } - kgsl_driver.grp_pclk = clk; -#endif /*acquire interrupt */ kgsl_driver.interrupt_num = platform_get_irq(pdev, 0); if (kgsl_driver.interrupt_num <= 0) { diff --git a/drivers/video/msm/gpu/kgsl/kgsl.h b/drivers/video/msm/gpu/kgsl/kgsl.h index f4ec3c96..c445f75d 100644 --- a/drivers/video/msm/gpu/kgsl/kgsl.h +++ b/drivers/video/msm/gpu/kgsl/kgsl.h @@ -47,9 +47,7 @@ struct kgsl_driver { struct clk *grp_clk; struct clk *imem_clk; struct clk *ebi1_clk; -#ifdef CONFIG_ARCH_MSM7227 - struct clk *grp_pclk; -#endif + struct kgsl_devconfig yamato_config; uint32_t flags_debug; diff --git a/drivers/video/msm/gpu/kgsl/kgsl_mmu.c b/drivers/video/msm/gpu/kgsl/kgsl_mmu.c index 7ffc8b50..d4862201 100644 --- a/drivers/video/msm/gpu/kgsl/kgsl_mmu.c +++ b/drivers/video/msm/gpu/kgsl/kgsl_mmu.c @@ -464,9 +464,6 @@ int kgsl_mmu_map(struct kgsl_pagetable *pagetable, KGSL_MEM_VDBG("enter (pt=%p, physaddr=%08x, range=%08d, gpuaddr=%p)\n", pagetable, address, range, gpuaddr); -#ifdef CONFIG_CACHE_L2X0 - l2x0_cache_flush_all(); -#endif mmu = pagetable->mmu; BUG_ON(mmu == NULL); diff --git a/drivers/video/msm/gpu/kgsl/kgsl_ringbuffer.c b/drivers/video/msm/gpu/kgsl/kgsl_ringbuffer.c index 89dd24e5..8a1f2859 100644 --- a/drivers/video/msm/gpu/kgsl/kgsl_ringbuffer.c +++ b/drivers/video/msm/gpu/kgsl/kgsl_ringbuffer.c @@ -63,7 +63,7 @@ inline unsigned int kgsl_ringbuffer_sizelog2quadwords(unsigned int sizedwords) return sizelog2quadwords; } -#if defined(CONFIG_MACH_HTCLEO) + // +Cotulla hack #ifndef ARRAYSIZE #define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0])) @@ -727,7 +727,6 @@ unsigned char fw_yamato_pm4[9220] = 0x00, 0x00, 0x00, 0x00 }; // -Cotulla hack -#endif /* functions */ void kgsl_cp_intrcallback(struct kgsl_device *device) @@ -938,12 +937,13 @@ static int kgsl_ringbuffer_load_pm4_ucode(struct kgsl_device *device) { int status = 0; int i; +// const struct firmware *fw = NULL; unsigned int *fw_ptr = NULL; size_t fw_word_size = 0; - -#if !defined(CONFIG_MACH_HTCLEO) - const struct firmware *fw = NULL; + struct firmware foo_fw; + struct firmware *fw = &foo_fw; +/* status = request_firmware(&fw, YAMATO_PM4_FW, kgsl_driver.misc.this_device); if (status != 0) { @@ -951,13 +951,10 @@ static int kgsl_ringbuffer_load_pm4_ucode(struct kgsl_device *device) YAMATO_PM4_FW, status); goto done; } -#else - struct firmware foo_fw; - struct firmware *fw = &foo_fw; - +*/ fw->data = fw_yamato_pm4; fw->size = ARRAYSIZE(fw_yamato_pm4); -#endif + /*this firmware must come in 3 word chunks. plus 1 word of version*/ if ((fw->size % (sizeof(uint32_t)*3)) != 4) { KGSL_DRV_ERR("bad firmware size %d.\n", fw->size); @@ -974,38 +971,32 @@ static int kgsl_ringbuffer_load_pm4_ucode(struct kgsl_device *device) kgsl_yamato_regwrite(device, REG_CP_ME_RAM_DATA, fw_ptr[i]); done: -#if !defined(CONFIG_MACH_HTCLEO) - release_firmware(fw); - return status; -#else +// release_firmware(fw); +// return status; return 0; -#endif - } static int kgsl_ringbuffer_load_pfp_ucode(struct kgsl_device *device) { int status = 0; int i; + //const struct firmware *fw = NULL; unsigned int *fw_ptr = NULL; size_t fw_word_size = 0; -#if !defined(CONFIG_MACH_HTCLEO) - const struct firmware *fw = NULL; + struct firmware foo_fw; + struct firmware *fw = &foo_fw; - status = request_firmware(&fw, YAMATO_PFP_FW, +/* status = request_firmware(&fw, YAMATO_PFP_FW, kgsl_driver.misc.this_device); if (status != 0) { KGSL_DRV_ERR("request_firmware for %s failed with error %d\n", YAMATO_PFP_FW, status); return status; } -#else - struct firmware foo_fw; - struct firmware *fw = &foo_fw; - +*/ fw->data = fw_yamato_pfp; fw->size = ARRAYSIZE(fw_yamato_pfp); -#endif + /*this firmware must come in 1 word chunks. */ if ((fw->size % sizeof(uint32_t)) != 0) { @@ -1022,12 +1013,9 @@ static int kgsl_ringbuffer_load_pfp_ucode(struct kgsl_device *device) for (i = 1; i < fw_word_size; i++) kgsl_yamato_regwrite(device, REG_CP_PFP_UCODE_DATA, fw_ptr[i]); -#if !defined(CONFIG_MACH_HTCLEO) - release_firmware(fw); - return status; -#else +// release_firmware(fw); +// return status; return 0; -#endif } static int kgsl_ringbuffer_start(struct kgsl_ringbuffer *rb) diff --git a/drivers/video/msm/hdmi/Makefile b/drivers/video/msm/hdmi/Makefile deleted file mode 100644 index a6734d5d..00000000 --- a/drivers/video/msm/hdmi/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -msm_hdmi-objs = \ - transmitter.o \ - hdmi_lcdc.o \ - fb-hdmi.o \ - edid.o - -obj-$(CONFIG_MSM_HDMI) += msm_hdmi.o - -obj-$(CONFIG_MSM_HDMI) += silicon-image/ diff --git a/drivers/video/msm/hdmi/edid.c b/drivers/video/msm/hdmi/edid.c deleted file mode 100644 index 101afa1d..00000000 --- a/drivers/video/msm/hdmi/edid.c +++ /dev/null @@ -1,695 +0,0 @@ -/* - * Copyright (C) 2009 HTC - * - * 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. - - * Common function for accessing/debugging EDID data. - * Reference: - http://en.wikipedia.org/wiki/Extended_display_identification_data -*/ - -#include -#include -#include - -#include "include/fb-hdmi.h" -#include "include/sil902x.h" - -#if 1 -#define EDID_DBG(s...) printk("[hdmi/edid]" s) -#else -#define EDID_DBG(s...) do {} while (0) -#endif - -static struct video_mode established_timing_db[] = { - {800, 600, 60, ASPECT(4, 3), PROGRESSIVE, false, "800x600 @ 60 Hz"}, - {800, 600, 56, ASPECT(4, 3), PROGRESSIVE, false, "800x600 @ 56 Hz"}, - {640, 480, 75, ASPECT(4, 3), PROGRESSIVE, false, "800x600 @ 75 Hz"}, - {640, 480, 72, ASPECT(4, 3), PROGRESSIVE, false, "640x480 @ 72 Hz"}, - {640, 480, 67, ASPECT(4, 3), PROGRESSIVE, false, "640x480 @ 67 Hz"}, - {640, 480, 60, ASPECT(4, 3), PROGRESSIVE, false, "640x480 @ 60 Hz"}, - {720, 400, 88, ASPECT(4, 3), PROGRESSIVE, false, "720x400 @ 88 Hz"}, - {720, 400, 70, ASPECT(4, 3), PROGRESSIVE, false, "720x400 @ 70 Hz"}, - - {1280, 1024, 75, ASPECT(4, 3), PROGRESSIVE, false, "1280x1024@75 Hz"}, - {1024, 768, 75, ASPECT(4, 3), PROGRESSIVE, false, "1024x768@75 Hz"}, - {1024, 768, 70, ASPECT(4, 3), PROGRESSIVE, false, "1024x768@70 Hz"}, - {1024, 768, 60, ASPECT(4, 3), PROGRESSIVE, false, "1024x768@60 Hz"}, - {1024, 768, 87, ASPECT(4, 3), INTERLACE, false, - "1024x768@87 Hz (Interlaced)"}, - {832, 624, 75, ASPECT(4, 3), PROGRESSIVE, false, "832x624@75 Hz"}, - {800, 600, 75, ASPECT(4, 3), PROGRESSIVE, false, "800x600@75 Hz"}, - {800, 600, 72, ASPECT(4, 3), PROGRESSIVE, false, "800x600@72 Hz"}, - - {1152, 870, 75, ASPECT(4, 3), PROGRESSIVE, false, "1152x870 @ 75 Hz"}, -}; - -static struct video_mode standard_timing_db[8]; - -static struct video_mode additional_timing_db[] = { - {640, 480, 60, ASPECT(4, 3), PROGRESSIVE, false, - " 1 DMT0659 4:3 640x480p @ 59.94/60Hz"}, - {720, 480, 60, ASPECT(4, 3), PROGRESSIVE, false, - " 2 480p 4:3 720x480p @ 59.94/60Hz"}, - {720, 480, 60, ASPECT(16, 9), PROGRESSIVE, false, - " 3 480pH 16:9 720x480p @ 59.94/60Hz"}, - {1280, 720, 60, ASPECT(16, 9), PROGRESSIVE, false, - " 4 720p 16:9 1280x720p @ 59.94/60Hz"}, - {1920, 1080, 60, ASPECT(4, 3), INTERLACE, false, - " 5 1080i 16:9 1920x1080i @ 59.94/60Hz"}, - {720, 480, 60, ASPECT(4, 3), INTERLACE, false, - " 6 480i 4:3 720(1440)x480i @ 59.94/60Hz"}, - {720, 480, 60, ASPECT(16, 9), INTERLACE, false, - " 7 480iH 16:9 720(1440)x480i @ 59.94/60Hz"}, - {720, 240, 60, ASPECT(4, 3), PROGRESSIVE, false, - " 8 240p 4:3 720(1440)x240p @ 59.94/60Hz"}, - {720, 480, 60, ASPECT(16, 9), PROGRESSIVE, false, - " 9 240pH 16:9 720(1440)x240p @ 59.94/60Hz"}, - {2880, 480, 60, ASPECT(4, 3), INTERLACE, false, - "10 480i4x 4:3 (2880)x480i @ 59.94/60Hz"}, - {2880, 480, 60, ASPECT(16, 9), INTERLACE, false, - "11 480i4xH 16:9 (2880)x480i @ 59.94/60Hz"}, - {2880, 240, 60, ASPECT(4, 3), PROGRESSIVE, false, - "12 240p4x 4:3 (2880)x240p @ 59.94/60Hz"}, - {2880, 240, 60, ASPECT(16, 9), PROGRESSIVE, false, - "13 240p4xH 16:9 (2880)x240p @ 59.94/60Hz"}, - {1440, 480, 60, ASPECT(4, 3), PROGRESSIVE, false, - "14 480p2x 4:3 1440x480p @ 59.94/60Hz"}, - {1440, 480, 60, ASPECT(16, 9), PROGRESSIVE, false, - "15 480p2xH 16:9 1440x480p @ 59.94/60Hz"}, - {1920, 1080, 60, ASPECT(16, 9), PROGRESSIVE, false, - "16 1080p 16:9 1920x1080p @ 59.94/60Hz"}, - {720, 576, 50, ASPECT(4, 3), PROGRESSIVE, false, - "17 576p 4:3 720x576p @ 50Hz"}, - {720, 576, 50, ASPECT(16, 9), PROGRESSIVE, false, - "18 576pH 16:9 720x576p @ 50Hz"}, - {1280, 720, 50, ASPECT(16, 9), PROGRESSIVE, false, - "19 720p50 16:9 1280x720p @ 50Hz"}, - {1920, 1080, 50, ASPECT(16, 9), INTERLACE, false, - "20 1080i25 16:9 1920x1080i @ 50Hz*"}, - {1440, 576, 50, ASPECT(4, 3), INTERLACE, false, - "21 576i 4:3 720(1440)x576i @ 50Hz"}, - {1440, 576, 50, ASPECT(4, 3), PROGRESSIVE, false, - "22 576iH 16:9 720(1440)x576i @ 50Hz"}, - {720, 288, 50, ASPECT(4, 3), PROGRESSIVE, false, - "23 288p 4:3 720(1440)x288p @ 50Hz"}, - {720, 288, 50, ASPECT(16, 9), PROGRESSIVE, false, - "24 288pH 16:9 720(1440)x288p @ 50Hz"}, - {2880, 576, 50, ASPECT(4, 3), INTERLACE, false, - "25 576i4x 4:3 (2880)x576i @ 50Hz"}, - {2880, 576, 50, ASPECT(16, 9), INTERLACE, false, - "26 576i4xH 16:9 (2880)x576i @ 50Hz"}, - {2880, 288, 50, ASPECT(4, 3), PROGRESSIVE, false, - "27 288p4x 4:3 (2880)x288p @ 50Hz"}, - {2880, 288, 50, ASPECT(16, 9), PROGRESSIVE, false, - "28 288p4xH 16:9 (2880)x288p @ 50Hz"}, - {1440, 576, 50, ASPECT(4, 3), PROGRESSIVE, false, - "29 576p2x 4:3 1440x576p @ 50Hz"}, - {1440, 576, 50, ASPECT(16, 9), PROGRESSIVE, false, - "30 576p2xH 16:9 1440x576p @ 50Hz"}, - {1920, 1080, 50, ASPECT(16, 9), PROGRESSIVE, false, - "31 1080p50 16:9 1920x1080p @ 50Hz"}, - {1920, 1080, 24, ASPECT(16, 9), PROGRESSIVE, false, - "32 1080p24 16:9 1920x1080p @ 23.98/24Hz"}, - {1920, 1080, 25, ASPECT(16, 9), PROGRESSIVE, false, - "33 1080p25 16:9 1920x1080p @ 25Hz"}, - {1920, 1080, 30, ASPECT(16, 9), PROGRESSIVE, false, - "34 1080p30 16:9 1920x1080p @ 29.97/30Hz"}, - {2880, 480, 60, ASPECT(4, 3), PROGRESSIVE, false, - "35 480p4x 4:3 (2880)x480p @ 59.94/60Hz"}, - {2880, 480, 60, ASPECT(16, 9), PROGRESSIVE, false, - "36 480p4xH 16:9 (2880)x480p @ 59.94/60Hz"}, - {2880, 576, 50, ASPECT(4, 3), PROGRESSIVE, false, - "37 576p4x 4:3 (2880)x576p @ 50Hz"}, - {2880, 576, 50, ASPECT(16, 9), PROGRESSIVE, false, - "38 576p4xH 16:9 (2880)x576p @ 50Hz"}, - {1920, 1080, 50, ASPECT(16, 9), INTERLACE, false, - "39 108Oi25 16:9 1920x1080i(1250 Total) @ 50Hz*"}, - {1920, 1080, 100, ASPECT(16, 9), INTERLACE, false, - "40 1080i50 16:9 1920x1080i @ 100Hz"}, - {1280, 720, 100, ASPECT(16, 9), PROGRESSIVE, false, - "41 720p100 16:9 1280x720p @ 100Hz"}, - {720, 576, 100, ASPECT(4, 3), PROGRESSIVE, false, - "42 576p100 4:3 720x576p @ 100Hz"}, - {720, 576, 100, ASPECT(16, 9), PROGRESSIVE, false, - "43 576p100H 16:9 720x576p @ 100Hz"}, - {720, 576, 100, ASPECT(4, 3), INTERLACE, false, - "44 576i50 4:3 720(1440)x576i @ 100Hz"}, - {720, 576, 100, ASPECT(16, 9), INTERLACE, false, - "45 576i50H 16:9 720(1440)x576i @ 100Hz"}, - {1920, 1080, 120, ASPECT(16, 9), INTERLACE, false, - "46 1080i60 16:9 1920x1080i @ 119.88/120Hz"}, - {1280, 720, 120, ASPECT(16, 9), PROGRESSIVE, false, - "47 720p120 16:9 1280x720p @ 119.88/120Hz"}, - {720, 480, 120, ASPECT(4, 3), PROGRESSIVE, false, - "48 480p119 4:3 720x480p @ 119.88/120Hz"}, - {720, 480, 120, ASPECT(16, 9), PROGRESSIVE, false, - "49 480p119H 16:9 720x480p @ 119.88/120Hz"}, - {720, 480, 120, ASPECT(4, 3), INTERLACE, false, - "50 480i59 4:3 720(1440)x480i @ 119.88/120Hz"}, - {720, 480, 120, ASPECT(16, 9), INTERLACE, false, - "51 480i59H 16:9 720(1440)x480i @ 119.88/120Hz"}, - {720, 576, 200, ASPECT(4, 3), PROGRESSIVE, false, - "52 576p200 4:3 720x576p @ 200Hz"}, - {720, 576, 200, ASPECT(16, 9), PROGRESSIVE, false, - "53 576p200H 16:9 720x576p @ 200Hz"}, - {720, 576, 200, ASPECT(4, 3), INTERLACE, false, - "54 576i100 4:3 720(1440)x576i @ 200Hz"}, - {720, 576, 200, ASPECT(16, 9), INTERLACE, false, - "55 576i100H 16:9 720(1440)x576i @ 200Hz"}, - {720, 480, 240, ASPECT(4, 3), PROGRESSIVE, false, - "56 480p239 4:3 720x480p @ 239.76/240Hz"}, - {720, 480, 240, ASPECT(16, 9), PROGRESSIVE, false, - "57 480p239H 16:9 720x480p @ 239.76/240Hz"}, - {720, 480, 240, ASPECT(4, 3), INTERLACE, false, - "58 480i119 4:3 720(1440)x480i @ 239.76/240Hz"}, - {720, 480, 240, ASPECT(16, 9), INTERLACE, false, - "59 480i119H 16:9 720(1440)x480i @ 239.76/240Hz"}, - {1280, 720, 24, ASPECT(16, 9), PROGRESSIVE, false, - "60 720p24 16:9 1280x720p @ 23.98/24Hz"}, - {1280, 720, 25, ASPECT(16, 9), PROGRESSIVE, false, - "61 720p25 16:9 1280x720p @ 25Hz"}, - {1280, 720, 30, ASPECT(16, 9), PROGRESSIVE, false, - "62 720p30 16:9 1280x720p @ 29.97/30Hz"}, - {1920, 1080, 120, ASPECT(16, 9), PROGRESSIVE, false, - "63 1080p120 16:9 1920x1080 @ 119.88/120Hz"}, -}; - -/* device supported modes in CEA */ -enum { - CEA_MODE_640X480P_60HZ_4_3 = 0, - CEA_MODE_720X480P_60HZ_4_3 = 1, - CEA_MODE_720X480P_60HZ_16_9 = 2, - CEA_MODE_1280X720P_60HZ_16_9 = 3, - CEA_MODE_720X576P_50HZ_4_3 = 16, - CEA_MODE_720X576P_50HZ_16_9 = 17, -}; - -/* device supported modes in established timing */ -enum { - ESTABLISHED_MODE_800X600_60HZ = 0, - ESTABLISHED_MODE_640X480_60HZ = 5, -}; - -int init_edid_info(struct edid_info_struct *edid_info) -{ - edid_info->is_valid = false; - mutex_init(&edid_info->access_lock); - - return 0; -} - -/* Byte 35-37 of block-0 */ -static char *established_timing_str[] = { - "800x600 @ 60 Hz", - "800x600 @ 56 Hz", - "640x480 @ 75 Hz", - "640x480 @ 72 Hz", - "640x480 @ 67 Hz", - "640x480 @ 60 Hz", - "720x400 @ 88 Hz", - "720x400 @ 70 Hz", - - "1280x1024@75 Hz", - "1024x768@75 Hz", - "1024x768@70 Hz", - "1024x768@60 Hz", - "1024x768@87 Hz (Interlaced)", - "832x624@75 Hz", - "800x600@75 Hz", - "800x600@72 Hz", - - "", - "", - "", - "", - "", - "", - "", - "1152x870 @ 75 Hz", -}; - -/* E-EDID Video data block: */ -static char *vdb_modes_str[] = { - " 1 DMT0659 4:3 640x480p @ 59.94/60Hz", - " 2 480p 4:3 720x480p @ 59.94/60Hz", - " 3 480pH 16:9 720x480p @ 59.94/60Hz", - " 4 720p 16:9 1280x720p @ 59.94/60Hz", - " 5 1080i 16:9 1920x1080i @ 59.94/60Hz", - " 6 480i 4:3 720(1440)x480i @ 59.94/60Hz", - " 7 480iH 16:9 720(1440)x480i @ 59.94/60Hz", - " 8 240p 4:3 720(1440)x240p @ 59.94/60Hz", - " 9 240pH 16:9 720(1440)x240p @ 59.94/60Hz", - "10 480i4x 4:3 (2880)x480i @ 59.94/60Hz", - "11 480i4xH 16:9 (2880)x480i @ 59.94/60Hz", - "12 240p4x 4:3 (2880)x240p @ 59.94/60Hz", - "13 240p4xH 16:9 (2880)x240p @ 59.94/60Hz", - "14 480p2x 4:3 1440x480p @ 59.94/60Hz", - "15 480p2xH 16:9 1440x480p @ 59.94/60Hz", - "16 1080p 16:9 1920x1080p @ 59.94/60Hz", - "17 576p 4:3 720x576p @ 50Hz", - "18 576pH 16:9 720x576p @ 50Hz", - "19 720p50 16:9 1280x720p @ 50Hz", - "20 1080i25 16:9 1920x1080i @ 50Hz*", - "21 576i 4:3 720(1440)x576i @ 50Hz", - "22 576iH 16:9 720(1440)x576i @ 50Hz", - "23 288p 4:3 720(1440)x288p @ 50Hz", - "24 288pH 16:9 720(1440)x288p @ 50Hz", - "25 576i4x 4:3 (2880)x576i @ 50Hz", - "26 576i4xH 16:9 (2880)x576i @ 50Hz", - "27 288p4x 4:3 (2880)x288p @ 50Hz", - "28 288p4xH 16:9 (2880)x288p @ 50Hz", - "29 576p2x 4:3 1440x576p @ 50Hz", - "30 576p2xH 16:9 1440x576p @ 50Hz", - "31 1080p50 16:9 1920x1080p @ 50Hz", - "32 1080p24 16:9 1920x1080p @ 23.98/24Hz", - "33 1080p25 16:9 1920x1080p @ 25Hz", - "34 1080p30 16:9 1920x1080p @ 29.97/30Hz", - "35 480p4x 4:3 (2880)x480p @ 59.94/60Hz", - "36 480p4xH 16:9 (2880)x480p @ 59.94/60Hz", - "37 576p4x 4:3 (2880)x576p @ 50Hz", - "38 576p4xH 16:9 (2880)x576p @ 50Hz", - "39 108Oi25 16:9 1920x1080i(1250 Total) @ 50Hz*", - "40 1080i50 16:9 1920x1080i @ 100Hz", - "41 720p100 16:9 1280x720p @ 100Hz", - "42 576p100 4:3 720x576p @ 100Hz", - "43 576p100H 16:9 720x576p @ 100Hz", - "44 576i50 4:3 720(1440)x576i @ 100Hz", - "45 576i50H 16:9 720(1440)x576i @ 100Hz", - "46 1080i60 16:9 1920x1080i @ 119.88/120Hz", - "47 720p120 16:9 1280x720p @ 119.88/120Hz", - "48 480p119 4:3 720x480p @ 119.88/120Hz", - "49 480p119H 16:9 720x480p @ 119.88/120Hz", - "50 480i59 4:3 720(1440)x480i @ 119.88/120Hz", - "51 480i59H 16:9 720(1440)x480i @ 119.88/120Hz", - "52 576p200 4:3 720x576p @ 200Hz", - "53 576p200H 16:9 720x576p @ 200Hz", - "54 576i100 4:3 720(1440)x576i @ 200Hz", - "55 576i100H 16:9 720(1440)x576i @ 200Hz", - "56 480p239 4:3 720x480p @ 239.76/240Hz", - "57 480p239H 16:9 720x480p @ 239.76/240Hz", - "58 480i119 4:3 720(1440)x480i @ 239.76/240Hz", - "59 480i119H 16:9 720(1440)x480i @ 239.76/240Hz", - "60 720p24 16:9 1280x720p @ 23.98/24Hz", - "61 720p25 16:9 1280x720p @ 25Hz", - "62 720p30 16:9 1280x720p @ 29.97/30Hz", - "63 1080p120 16:9 1920x1080 @ 119.88/120Hz", -}; - -int edid_dump_video_modes(u8 *edid_buf) -{ - int i, v1, v2, width, height, ret, aspect; - char *str_aspect[] = { "16:10", "4:3", "5:4", "16:9" }; - - switch (edid_buf[0]) { - case 0: - pr_info("block type 0: supported mode:\n"); - v1 = edid_buf[35] | edid_buf[36] << 8 | edid_buf[37] << 16; - /* Established timing */ - pr_info("established timing: {%02x, %02x, %02x}\n", - edid_buf[35], edid_buf[36], edid_buf[37]); - for (i = 0 ; i < 18; i++ ) { - v1 >>= 1; - if (v1 & 1) pr_info("%s\n", established_timing_str[i]); - }; - - pr_info("Standard timing identification:\n"); - /* Standard timing identification */ - for (i = 0; i < 8; i++) { - v1 = edid_buf[38+i*2]; - v2 = edid_buf[38+i*2+1]; - width = v1 * 8 + 248; - aspect = v2 >> 6; - switch (aspect) { - case 0: height = width * 10 / 16; break; - case 1: height = width * 3 / 4; break; - case 2: height = width * 4 / 5; break; - case 3: height = width * 9 / 16; break; - } - pr_info("%dx%d, %s, %d Hz\n", width, height, - str_aspect[aspect], (v2 & ~(3 << 6)) + 60); - } - ret = 0; - break; - case 2: - pr_info("block type 2: supported mode:\n"); - pr_info("edid_buf[4]=%x\n", edid_buf[4]); - for( i = 0; i < (edid_buf[4] & 0x1f); i++) { - pr_info("%s\n", vdb_modes_str[edid_buf[5+i] & 0x7f]); - } - ret = 0; - break; - - default: - ret = -EINVAL; - break; - } - return ret; -} - -bool edid_do_checksum(u8 *data) -{ - int i; - u8 sum = 0; - - for (i = 0; i < EDID_BLOCK_SIZE; i++) - sum += data[i]; - EDID_DBG("%s: result=%s\n", __func__, sum ? "fail" : "pass"); - return sum ? false : true; -} - -static bool edid_check_header(u8 *data) -{ - int ret, i = 0; - /* EDID 8 bytes header */ - static u8 header[] = {0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0}; - - for (i = 0; i < ARRAY_SIZE(header); i++) - if (data[i] != header[i]) - break; - ret = (i == ARRAY_SIZE(header)) ? true : false; - EDID_DBG("%s: result=%s\n", __func__, ret ? "pass" : "fail"); - - return ret; -} - -bool edid_check_hdmi_sink(struct hdmi_info *hdmi, int block) -{ - int ret = false, index = 4; - u8 *data = &hdmi->edid_buf[block * 128]; - /* block offset where long descriptors start */ - int long_desc_offset = data[LONG_DESCR_PTR_IDX]; - int tag_code, data_block_len; - - while (index < long_desc_offset) { - tag_code = (data[index] >> 5) & 0x7; - data_block_len = data[index++] & 0x1f; - if (tag_code == VENDOR_SPEC_D_BLOCK && - data[index] == 0x03 && - data[index + 1] == 0x0c && - data[index + 2] == 0x00) { - ret = true; - break; - } else - index += data_block_len; - } - hdmi->edid_info.hdmi_sink = ret; - EDID_DBG("%s: ret=%s\n", __func__, ret ? "yes" : "no"); - return ret; -} - -struct edid_black_list_info { - u8 mfr_model[4]; - u8 prefer_modes[3]; -}; - -struct edid_black_list_info edid_black_list[] = { - { {0x4c, 0x2d, 0xa5, 0x02}, {0, 0, 0x40} }, // 720p only - { {0x4c, 0x2d, 0x0d, 0x05}, {0, 0, 0x40} }, // 720p only - - //{ {0x5a, 0x63, 0x20, 0x2b}, {0, 0, 0x40} }, // Viewsonic test -}; - -/* By comparing the Manufacture(0x8, 0x9) and Model field(0xa, 0xb) of EDID, - * to check if the attached TV is a known less-compatibile one. - */ -int edid_fixup_compatibility_list(struct hdmi_info *hdmi) -{ - int i, ret = -1; - - /* FIXME: magic numbers...*/ - for (i = 0; i < ARRAY_SIZE(edid_black_list); i++) { - if (!memcmp(hdmi->edid_buf + 8, edid_black_list[i].mfr_model, 4)){ -#if 0 - EDID_DBG("%s: found in blacklist %d\n", __func__, i); - EDID_DBG("%s: old timing = {%02x, %02x, %02x}\n", - __func__, - hdmi->edid_buf[35], hdmi->edid_buf[36], - hdmi->edid_buf[37]); - memcpy(hdmi->edid_buf + 35, - edid_black_list[i].prefer_modes, 3); - EDID_DBG("%s: new timing = {%02x, %02x, %02x}\n", - __func__, - hdmi->edid_buf[35], hdmi->edid_buf[36], - hdmi->edid_buf[37]); -#else - EDID_DBG("%s: found in compatibility %d\n", __func__, i); - memcpy(hdmi->edid_buf + 35, - edid_black_list[i].prefer_modes, 3); -#endif - ret = i; - break; - } - } - - return ret; -} - -u8 edid_simple_parsing(struct hdmi_info *hdmi) -{ - u8 *edid_buf = hdmi->edid_buf; - int i, index, ret = -EINVAL; - struct edid_info_struct *edid_info = &hdmi->edid_info; - unsigned v1, width, height, aspect; - unsigned extensions; - - EDID_DBG("%s\n", __func__); - // FIXME: integrate with edid_check() - if (!edid_do_checksum(edid_buf)) { - pr_err("%s: checksum error\n", __func__); - //return EDID_CHECKSUM_ERROR; - } - if (!edid_check_header(edid_buf)) { - pr_err("%s: incorrect header\n", __func__); - return INCORRECT_EDID_HEADER; - } - edid_info->under_scan = ((edid_buf[MISC_SUPPORT_IDX]) >> 7) & 0x1; - edid_info->basic_audio = ((edid_buf[MISC_SUPPORT_IDX]) >> 6) & 0x1; - edid_info->ycbcr_4_4_4 = ((edid_buf[MISC_SUPPORT_IDX]) >> 5) & 0x1; - edid_info->ycbcr_4_2_2 = ((edid_buf[MISC_SUPPORT_IDX]) >> 4) & 0x1; - - // FIXME: 0x7e - extensions = edid_buf[0x7e]; - EDID_DBG("%s: extensions=%d\n", __func__, extensions); - if (!extensions) { - hdmi->edid_info.hdmi_sink = false; - return NO_861_EXTENSIONS; - } - //return; - - /* reset all supported */ - for (i = 0 ; i < ARRAY_SIZE(additional_timing_db); i++) - additional_timing_db[i].supported = false; - for (i = 0 ; i < ARRAY_SIZE(established_timing_db); i++) - established_timing_db[i].supported = false; - - /* Block 0: established timing */ - pr_info("established timing: {%02x, %02x, %02x}\n", - edid_buf[35], edid_buf[36], edid_buf[37]); - - v1 = edid_buf[35] | edid_buf[36] << 8 | (!!edid_buf[37]) << 16; - - for (i = 0 ; i < 17; i++ ) // 17 bits defined in established timing - established_timing_db[i].supported = ((v1 >>= 1) & 1) ; - -#if 0 - /* standard timing identification */ - for (i = 0; i < 8; i++) { - width = edid_buf[38 + i * 2] * 8 + 248; - v1 = edid_buf[38 + i * 2 + 1]; - switch (v1 >> 6) { - case 0: height = width * 10 / 16; aspect = ASPECT(16, 10); break; - case 1: height = width * 3 / 4; aspect = ASPECT(4, 3); break; - case 2: height = width * 4 / 5; aspect = ASPECT(5, 4); break; - case 3: height = width * 9 / 16; aspect = ASPECT(16, 9); break; - } - standard_timing_db[i].width = width; - standard_timing_db[i].height = height; - standard_timing_db[i].aspect = aspect; - standard_timing_db[i].refresh_rate = (v1 & ~(3 << 6)) + 60; - standard_timing_db[i].supported = true; - } -#endif - - if (extensions == 1) { - EDID_DBG("Block-1: additional timing\n"); - /* Block-1: additional timing */ - for( i = 0; i < (edid_buf[128 + 4] & 0x1f); i++) { - index = edid_buf[128 + 5 + i] & 0x7f; - additional_timing_db[index-1].supported = true; - EDID_DBG("%s\n", additional_timing_db[index-1].descrption); - } - edid_check_hdmi_sink(hdmi, 1); - } else { - EDID_DBG("Block-2: additional timing\n"); - for( i = 0; i < (edid_buf[384 + 4] & 0x1f); i++) { - index = edid_buf[384 + 5 + i] & 0x7f; - additional_timing_db[index-1].supported = true; - EDID_DBG("%s\n", additional_timing_db[index-1].descrption); - } - edid_check_hdmi_sink(hdmi, 3); - } - - edid_buf[35] = 0; - edid_buf[36] = 0; - edid_buf[37] = 0; - - /* edid_buf[37] bit4: 480p, bit5: 576p, bit6: 720p */ - if (additional_timing_db[CEA_MODE_720X480P_60HZ_4_3].supported || - additional_timing_db[CEA_MODE_720X480P_60HZ_16_9].supported) { - EDID_DBG("decide to support 480P\n"); - edid_buf[37] |= (1<<4); - } - - if (additional_timing_db[CEA_MODE_720X576P_50HZ_4_3].supported || - additional_timing_db[CEA_MODE_720X576P_50HZ_16_9].supported) { - EDID_DBG("decide to support 576P\n"); - edid_buf[37] |= (1<<5); - } - - if (additional_timing_db[CEA_MODE_1280X720P_60HZ_16_9].supported) { - EDID_DBG("decide to support 720P\n"); - edid_buf[37] |= (1<<6); - } - - if (established_timing_db[ESTABLISHED_MODE_800X600_60HZ].supported) { - EDID_DBG("decide to support 800x600\n"); - edid_buf[36] |= (1<<6); - } - - if (established_timing_db[ESTABLISHED_MODE_640X480_60HZ].supported) { - EDID_DBG("decide to support 640x480\n"); - edid_buf[35] |= (1<<5); - } - edid_fixup_compatibility_list(hdmi); - - return ret; -} - -// FIXME: modify the checking routines into inline function. -bool edid_is_video_mode_supported(struct video_mode *vmode) -{ - int i; - struct video_mode *vmode_db; - - vmode_db = established_timing_db; - for (i = 0, vmode_db = established_timing_db; - i < ARRAY_SIZE(established_timing_db); i++) - if ( (vmode->width == vmode_db[i].width) && - (vmode->height == vmode_db[i].height) && - (vmode->refresh_rate == vmode_db[i].refresh_rate ) && - (vmode_db[i].interlaced == PROGRESSIVE) && - (vmode_db[i].supported == true )) - return true; - for (i = 0, vmode_db = standard_timing_db; - i < ARRAY_SIZE(standard_timing_db); i++) - if ( (vmode->width == vmode_db[i].width) && - (vmode->height == vmode_db[i].height) && - (vmode->refresh_rate == vmode_db[i].refresh_rate ) && - (vmode_db[i].interlaced == PROGRESSIVE) && - (vmode_db[i].supported == true )) - return true; - for (i = 0, vmode_db = additional_timing_db; - i < ARRAY_SIZE(additional_timing_db); i++) - if ( (vmode->width == vmode_db[i].width) && - (vmode->height == vmode_db[i].height) && - (vmode->refresh_rate == vmode_db[i].refresh_rate ) && - (vmode_db[i].interlaced == PROGRESSIVE) && - (vmode_db[i].supported == true )) - return true; - return false; -} - -bool edid_check_sink_type(struct hdmi_info *hdmi) -{ - EDID_DBG("%s: ret=%d\n", __func__, hdmi->edid_info.hdmi_sink); - return hdmi->edid_info.hdmi_sink; -} - -int edid_dump_hex(u8 *src, int src_size, char *output, int output_size) -{ - char line[80]; - static char hextab[] = "0123456789abcdef"; - int i, j, n = 0, v, len, offset, line_size; - - len = src_size; - memset(line, ' ', 79); - line[79] = '\0'; - offset = strlen("0000 | "); - line_size = offset + 3 * 16 + 1; - for (i = 0; i < len / 16 ; i++) { - scnprintf(line, offset + 1, "%04x | ", (i << 4)); - for (j = 0; j < 16 ; j++) { - v = src[i * 16 + j]; - line[offset + j * 3] = hextab[v / 16]; - line[offset + j * 3 + 1] = hextab[v % 16]; - } - line[line_size - 1] = '\n'; - strncpy(output+ n, line, line_size); - if ((n + line_size) > output_size) - break; - else - n += line_size; - } - - return n; -} - -/*============================================================================*/ -static ssize_t edid_dbg_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static char hex_buff[2048]; -static ssize_t edid_buffered_read(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) -{ - int n; - int extensions; - struct hdmi_info *hdmi = (struct hdmi_info*)filp->private_data; - - extensions = hdmi->edid_buf[0x7e] + 1; - edid_dump_video_modes(hdmi->edid_buf);// fixme: crashed - if (extensions == 1) - edid_dump_video_modes(hdmi->edid_buf + 128); - else - edid_dump_video_modes(hdmi->edid_buf + 384); - //edid_simple_parsing(hdmi); // FIXME: crashed... - n = edid_dump_hex(hdmi->edid_buf, (hdmi->edid_buf[0x7e] + 1) * 128, - hex_buff, 2048); - return simple_read_from_buffer(buf, count, ppos, hex_buff, n); -} - -static struct file_operations edid_debugfs_fops[] = { - { - .open = edid_dbg_open, - .read = edid_buffered_read, - .write = NULL, - } -}; - -// TODO: error handling -int edid_debugfs_init(struct hdmi_info *hdmi) -{ - //int ret; - struct dentry *edid_dent; - - edid_dent = debugfs_create_dir("edid", hdmi->debug_dir); - if (IS_ERR(edid_dent)) - return PTR_ERR(edid_dent); - - debugfs_create_file("hex_dump", 0444, edid_dent, hdmi, - &edid_debugfs_fops[0]); - - return 0; -} - diff --git a/drivers/video/msm/hdmi/fb-hdmi.c b/drivers/video/msm/hdmi/fb-hdmi.c deleted file mode 100644 index 7daf6d1a..00000000 --- a/drivers/video/msm/hdmi/fb-hdmi.c +++ /dev/null @@ -1,716 +0,0 @@ -/* - * Copyright (C) 2009 HTC - * - * 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. - * - * Referenced from drivers/video/msm/msm_fb.c, Google Incorporated. - * - */ -#define DEBUG -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_HTC_HEADSET_MGR -#include -#endif - -#include "include/fb-hdmi.h" -#include "include/sil902x.h" - -#if 1 -#define HDMI_DBG(s...) printk("[hdmi/fb]" s) -#else -#define HDMI_DBG(s...) do {} while (0) -#endif - -struct update_info_t { - int left; - int top; - int eright; /* exclusive */ - int ebottom; /* exclusive */ - unsigned yoffset; -}; - -struct hdmifb_info { - struct fb_info *fb; - struct msm_panel_data *panel; - struct notifier_block fb_hdmi_event; - struct msmfb_callback dma_callback; - struct msmfb_callback vsync_callback; - struct update_info_t update_info; - struct early_suspend earlier_suspend; - struct early_suspend early_suspend; - spinlock_t update_lock; - int xres; - int yres; - unsigned long state; - atomic_t use_count; -}; - -static struct mdp_device *mdp; -static struct hdmi_device *hdmi; - -static unsigned PP[16]; - -void hdmi_pre_change(struct hdmi_info *hdmi); -void hdmi_post_change(struct hdmi_info *info, struct fb_var_screeninfo *var); - -static int hdmifb_open(struct fb_info *info, int user) -{ - return 0; -} - -static int hdmifb_release(struct fb_info *info, int user) -{ - return 0; -} - -static int hdmifb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) -{ - u32 size; - - if (mdp->check_output_format(mdp, var->bits_per_pixel)) - return -EINVAL; - if (hdmi->check_res(hdmi, var)) - return -EINVAL; - - size = var->xres_virtual * var->yres_virtual * - (var->bits_per_pixel >> 3); - if (size > info->fix.smem_len) - return -EINVAL; - return 0; -} - -static int hdmifb_set_par(struct fb_info *info) -{ - struct fb_var_screeninfo *var = &info->var; - struct fb_fix_screeninfo *fix = &info->fix; - struct hdmifb_info *hdmi_fb = info->par; - struct msm_panel_data *panel = hdmi_fb->panel; - struct msm_lcdc_timing *timing; - struct hdmi_info *hinfo = container_of(hdmi, struct hdmi_info, - hdmi_dev); - - HDMI_DBG("%s\n", __func__); - /* we only support RGB ordering for now */ - if (var->bits_per_pixel == 32 || var->bits_per_pixel == 24) { - var->red.offset = 0; - var->red.length = 8; - var->green.offset = 8; - var->green.length = 8; - var->blue.offset = 16; - var->blue.length = 8; - } else if (var->bits_per_pixel == 16) { - var->red.offset = 11; - var->red.length = 5; - var->green.offset = 5; - var->green.length = 6; - var->blue.offset = 0; - var->blue.length = 5; - } else - return -1; - - HDMI_DBG("set res (%d, %d)\n", var->xres, var->yres); - timing = hdmi->set_res(hdmi, var); - panel->adjust_timing(panel, timing, var->xres, var->yres); - hdmi_post_change(hinfo, var); - - mdp->set_output_format(mdp, var->bits_per_pixel); - - hdmi_fb->xres = var->xres; - hdmi_fb->yres = var->yres; - fix->line_length = var->xres * var->bits_per_pixel / 8; - return 0; -} - -/* core update function */ -static void -hdmifb_pan_update(struct fb_info *info, uint32_t left, uint32_t top, - uint32_t eright, uint32_t ebottom, uint32_t yoffset) -{ - struct hdmifb_info *hdmi_fb = info->par; - struct msm_panel_data *panel = hdmi_fb->panel; - unsigned long irq_flags; - - /* printk(KERN_DEBUG "%s\n", __func__); */ - if ((test_bit(fb_enabled, &hdmi_fb->state) == 0) || - (test_bit(hdmi_enabled, &hdmi_fb->state) == 0)) - return; - - spin_lock_irqsave(&hdmi_fb->update_lock, irq_flags); - hdmi_fb->update_info.left = left; - hdmi_fb->update_info.top = top; - hdmi_fb->update_info.eright = eright; - hdmi_fb->update_info.ebottom = ebottom; - hdmi_fb->update_info.yoffset = yoffset; - spin_unlock_irqrestore(&hdmi_fb->update_lock, irq_flags); - panel->request_vsync(panel, &hdmi_fb->vsync_callback); -} - -/* fb ops, fb_pan_display */ -static int -hdmifb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) -{ - /* full update */ - hdmifb_pan_update(info, 0, 0, info->var.xres, info->var.yres, - var->yoffset); - return 0; -} - -static void hdmifb_fillrect(struct fb_info *p, const struct fb_fillrect *rect) -{ - cfb_fillrect(p, rect); - hdmifb_pan_update(p, rect->dx, rect->dy, rect->dx + rect->width, - rect->dy + rect->height, 0); -} - -static void hdmifb_copyarea(struct fb_info *p, const struct fb_copyarea *area) -{ - cfb_copyarea(p, area); - hdmifb_pan_update(p, area->dx, area->dy, area->dx + area->width, - area->dy + area->height, 0); -} - -static void hdmifb_imageblit(struct fb_info *p, const struct fb_image *image) -{ - cfb_imageblit(p, image); - hdmifb_pan_update(p, image->dx, image->dy, image->dx + image->width, - image->dy + image->height, 0); -} - -static int hdmifb_change_mode(struct fb_info *info, unsigned int mode) -{ - struct hdmifb_info *hdmi_fb = info->par; - - /* printk(KERN_DEBUG "%s mode = %d\n", __func__, mode); */ - - if (mode) - set_bit(hdmi_mode, &hdmi_fb->state); - else - clear_bit(hdmi_mode, &hdmi_fb->state); - return 0; -} - -struct hdmifb_info *_hdmi_fb; -int hdmifb_get_mode(void) -{ - return test_bit(hdmi_mode, &_hdmi_fb->state); -} - -bool hdmifb_suspending = false; - -static int hdmifb_pause(struct fb_info *fb, unsigned int mode) -{ - int ret = 0; - struct hdmifb_info *hdmi_fb = fb->par; - struct msm_panel_data *panel = hdmi_fb->panel; - struct hdmi_info *info = container_of(hdmi, struct hdmi_info, - hdmi_dev); - - pr_info("%s: %d %s\n", __func__, atomic_read(&hdmi_fb->use_count), - mode == 1 ? "pause" : "resume"); - - if (mode == 1) { - hdmifb_suspending = false; - HDMI_DBG("%s: hdmifb_suspending = false\n", __func__); - /* pause */ - if (atomic_read(&hdmi_fb->use_count) == 0) - goto done; - if (atomic_dec_return(&hdmi_fb->use_count) == 0) { - hdmi_pre_change(info); - ret = panel->blank(panel); - clear_bit(hdmi_enabled, &hdmi_fb->state); -#ifdef CONFIG_HTC_HEADSET_MGR - switch_send_event(BIT_HDMI_AUDIO, 0); -#endif - } - } else if (mode == 0) { - /* resume */ - if (atomic_inc_return(&hdmi_fb->use_count) == 1) { - hdmi_pre_change(info); - ret = panel->unblank(panel); -/* - // set timing again to prevent TV been out of range - var = &fb->var; - timing = hdmi->set_res(hdmi, var); - panel->adjust_timing(panel, timing, var->xres, var->yres); - hdmi_post_change(info, var); -*/ - set_bit(hdmi_enabled, &hdmi_fb->state); -#ifdef CONFIG_HTC_HEADSET_MGR - switch_send_event(BIT_HDMI_AUDIO, 1); -#endif - } - } else - ret = -EINVAL; -done: - return ret; -} - -static int hdmifb_blit(struct fb_info *info, void __user *p) -{ - struct mdp_blit_req req; - struct mdp_blit_req_list req_list; - int i; - int ret; - - if (copy_from_user(&req_list, p, sizeof(req_list))) - return -EFAULT; - - for (i = 0; i < req_list.count; i++) { - struct mdp_blit_req_list *list = - (struct mdp_blit_req_list *)p; - if (copy_from_user(&req, &list->req[i], sizeof(req))) - return -EFAULT; - req.flags |= MDP_DITHER; - ret = mdp->blit(mdp, info, &req); - if (ret) - return ret; - } - return 0; -} - -enum ioctl_cmd_index { - CMD_SET_MODE, - CMD_GET_MODE, - CMD_DISABLE, - CMD_ENABLE, - CMD_GET_STATE, - CMD_BLIT, - CMD_CABLE_STAT, - CMD_ESTABLISH_TIMING, -}; - -static char *cmd_str[] = { - "HDMI_SET_MODE", - "HDMI_GET_MODE", - "HDMI_DISABLE", - "HDMI_ENABLE", - "HDMI_GET_STATE", - "HDMI_BLIT", - "HDMI_CABLE_STAT", - "HDMI_ESTABLISH_TIMING", -}; - -static int hdmifb_ioctl(struct fb_info *p, unsigned int cmd, unsigned long arg) -{ - struct hdmifb_info *hdmi_fb = p->par; - void __user *argp = (void __user *)arg; - unsigned int val; - int ret = -EINVAL; - struct hdmi_info *hinfo = container_of(hdmi, struct hdmi_info, - hdmi_dev); - -/* - if (cmd != HDMI_BLIT) - HDMI_DBG("%s, cmd=%d=%s\n", __func__, cmd - HDMI_SET_MODE, - cmd_str[cmd-HDMI_SET_MODE]); -*/ - - switch (cmd) { - case HDMI_SET_MODE: - get_user(val, (unsigned __user *) arg); - //pr_info("[hdmi] SET_MODE: %d\n", val); - ret = hdmifb_change_mode(p, val); - break; - case HDMI_GET_MODE: -/* - pr_info("[hdmi] GET_MODE: %d\n", - test_bit(hdmi_mode, &hdmi_fb->state)); -*/ - ret = put_user(test_bit(hdmi_mode, &hdmi_fb->state), - (unsigned __user *) arg); - break; - case HDMI_DISABLE: - get_user(val, (unsigned __user *) arg); - ret = hdmifb_pause(p, 1); - break; - case HDMI_ENABLE: - get_user(val, (unsigned __user *) arg); - ret = hdmifb_pause(p, 0); - break; - case HDMI_GET_STATE: - ret = put_user(test_bit(hdmi_enabled, &hdmi_fb->state), - (unsigned __user *) arg); - break; - case HDMI_BLIT: - if (test_bit(hdmi_enabled, &hdmi_fb->state)) - ret = hdmifb_blit(p, argp); - else - ret = -EPERM; - break; - case HDMI_CABLE_STAT: { - int connect; - ret = hdmi->get_cable_state(hdmi, &connect); - ret = put_user(connect, (unsigned __user *) arg); - break; - } - case HDMI_ESTABLISH_TIMING: { - u8 tmp[3]; - hdmi->get_establish_timing(hdmi, tmp); - ret = copy_to_user((unsigned __user *) arg, tmp, 3); - if (ret) - ret = -EFAULT; - break; - } - case HDMI_GET_EDID: - ret = copy_to_user((unsigned __user *) arg, - hinfo->edid_buf, 512); - break; - case HDMI_GET_DISPLAY_INFO: { - struct display_info dinfo; - u8 *ptr = hinfo->edid_buf; - dinfo.visible_width = - (((u32)ptr[68] & 0xf0) << 4) | ptr[66]; - dinfo.visible_height = - (((u32)ptr[68] & 0x0f) << 8) | ptr[67]; - dinfo.resolution_width = - (((u32)ptr[58] & 0xf0) << 4) | ptr[56]; - dinfo.resolution_height = - (((u32)ptr[61] & 0xf0) << 4) | ptr[59]; - ret = copy_to_user((unsigned __user *) arg, - &dinfo, sizeof(dinfo)); - break; - } - default: - printk(KERN_ERR "hdmi: unknown cmd, cmd = %d\n", cmd); - } - return ret; -} - -static struct fb_ops hdmi_fb_ops = { - .owner = THIS_MODULE, - .fb_open = hdmifb_open, - .fb_release = hdmifb_release, - .fb_check_var = hdmifb_check_var, - .fb_set_par = hdmifb_set_par, - .fb_pan_display = hdmifb_pan_display, - .fb_fillrect = hdmifb_fillrect, - .fb_copyarea = hdmifb_copyarea, - .fb_imageblit = hdmifb_imageblit, - .fb_ioctl = hdmifb_ioctl, -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void hdmifb_suspend(struct early_suspend *h) -{ - struct hdmifb_info *hdmi_fb = container_of(h, struct hdmifb_info, - early_suspend); - struct msm_panel_data *panel = hdmi_fb->panel; - - HDMI_DBG("%s, use_count=%d\n", __func__, - atomic_read(&hdmi_fb->use_count)); - hdmifb_suspending = true; - HDMI_DBG("%s: hdmifb_suspending = true\n", __func__); - if (atomic_read(&hdmi_fb->use_count) && - false == test_bit(hdmi_enabled, &hdmi_fb->state) - ) { - if (panel->blank) - panel->blank(panel); - } - - if (panel->suspend) - panel->suspend(panel); - - clear_bit(hdmi_enabled, &hdmi_fb->state); - clear_bit(fb_enabled, &hdmi_fb->state); -} - -static void hdmifb_resume(struct early_suspend *h) -{ - struct hdmifb_info *hdmi_fb = container_of(h, struct hdmifb_info, - early_suspend); - struct msm_panel_data *panel = hdmi_fb->panel; - - HDMI_DBG("%s\n", __func__); - if (panel->resume) - panel->resume(panel); - - atomic_set(&hdmi_fb->use_count, 0); - set_bit(fb_enabled, &hdmi_fb->state); -} -#endif - -#define BITS_PER_PIXEL 16 - -static void setup_fb_info(struct hdmifb_info *hdmi_fb) -{ - struct fb_info *fb_info = hdmi_fb->fb; - int r; - - /* finish setting up the fb_info struct */ - strncpy(fb_info->fix.id, "hdmi_fb", 16); - fb_info->fix.ypanstep = 1; - - fb_info->fbops = &hdmi_fb_ops; - fb_info->flags = FBINFO_DEFAULT; - - fb_info->fix.type = FB_TYPE_PACKED_PIXELS; - fb_info->fix.visual = FB_VISUAL_TRUECOLOR; - fb_info->fix.line_length = hdmi_fb->xres * 2; - - fb_info->var.xres = hdmi_fb->xres; - fb_info->var.yres = hdmi_fb->yres; - fb_info->var.width = hdmi_fb->panel->fb_data->width; - fb_info->var.height = hdmi_fb->panel->fb_data->height; - fb_info->var.xres_virtual = hdmi_fb->xres; - fb_info->var.yres_virtual = hdmi_fb->yres * 2; - fb_info->var.bits_per_pixel = BITS_PER_PIXEL; - fb_info->var.accel_flags = 0; - fb_info->var.yoffset = 0; - - fb_info->var.red.offset = 11; - fb_info->var.red.length = 5; - fb_info->var.red.msb_right = 0; - fb_info->var.green.offset = 5; - fb_info->var.green.length = 6; - fb_info->var.green.msb_right = 0; - fb_info->var.blue.offset = 0; - fb_info->var.blue.length = 5; - fb_info->var.blue.msb_right = 0; - - r = fb_alloc_cmap(&fb_info->cmap, 16, 0); - fb_info->pseudo_palette = PP; - - PP[0] = 0; - for (r = 1; r < 16; r++) - PP[r] = 0xffffffff; -} - -static int -setup_fbmem(struct hdmifb_info *hdmi_fb, struct platform_device *pdev) -{ - struct fb_info *fb = hdmi_fb->fb; - struct resource *res; - unsigned long size = hdmi_fb->xres * hdmi_fb->yres * - (BITS_PER_PIXEL >> 3) * 2; - unsigned char *fbram; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -EINVAL; - - /* check the resource is large enough to fit the fb */ - if (resource_size(res) < size) { - printk(KERN_ERR "allocated resource(%d) is too small(%lu)" - "for fb\n", resource_size(res), size); - return -ENOMEM; - } - - fb->fix.smem_start = res->start; - fb->fix.smem_len = resource_size(res); - - fbram = ioremap(res->start, resource_size(res)); - if (fbram == 0) { - printk(KERN_ERR "hdmi_fb: cannot allocate fbram!\n"); - return -ENOMEM; - } - - fb->screen_base = fbram; - memset(fbram, 0, resource_size(res)); - - printk(KERN_DEBUG "HDMI FB: 0x%x 0x%x\n", res->start, res->end); - return 0; -} - -/* Called from dma interrupt handler, must not sleep */ -static void hdmi_handle_dma(struct msmfb_callback *callback) -{ - /* printk(KERN_DEBUG "%s\n", __func__); */ -} - -/* Called from vsync interrupt handler, must not sleep */ -static void hdmi_handle_vsync(struct msmfb_callback *callback) -{ - uint32_t x, y, w, h; - unsigned yoffset; - unsigned addr; - unsigned long irq_flags; - struct fb_info *mirror_fb = registered_fb[0], *fb_hdmi; - struct hdmifb_info *hdmi = container_of(callback, struct hdmifb_info, - vsync_callback); - struct msm_panel_data *panel = hdmi->panel; - - spin_lock_irqsave(&hdmi->update_lock, irq_flags); - x = hdmi->update_info.left; - y = hdmi->update_info.top; - w = hdmi->update_info.eright - x; - h = hdmi->update_info.ebottom - y; - yoffset = hdmi->update_info.yoffset; - hdmi->update_info.left = hdmi->xres + 1; - hdmi->update_info.top = hdmi->yres + 1; - hdmi->update_info.eright = 0; - hdmi->update_info.ebottom = 0; - if (unlikely(w > hdmi->xres || h > hdmi->yres || - w == 0 || h == 0)) { - printk(KERN_INFO "invalid update: %d %d %d " - "%d\n", x, y, w, h); - goto error; - } - spin_unlock_irqrestore(&hdmi->update_lock, irq_flags); - - addr = ((hdmi->xres * (yoffset + y) + x) * 2); - if (test_bit(hdmi_mode, &hdmi->state) == 0) { - mdp->dma(mdp, addr + mirror_fb->fix.smem_start, - hdmi->xres * 2, w, h, x, y, &hdmi->dma_callback, - panel->interface_type); - } else { - fb_hdmi = hdmi->fb; - mdp->dma(mdp, addr + fb_hdmi->fix.smem_start, - hdmi->xres * 2, w, h, x, y, &hdmi->dma_callback, - panel->interface_type); - } - return; -error: - spin_unlock_irqrestore(&hdmi->update_lock, irq_flags); -} - -static int hdmifb_probe(struct platform_device *pdev) -{ - struct fb_info *info; - struct hdmifb_info *hdmi_fb; - struct msm_panel_data *panel = pdev->dev.platform_data; - int ret; - - printk(KERN_DEBUG "%s\n", __func__); - - if (!panel) { - pr_err("hdmi_fb_probe: no platform data\n"); - return -EINVAL; - } - - if (!panel->fb_data) { - pr_err("hdmi_fb_probe: no fb_data\n"); - return -EINVAL; - } - - info = framebuffer_alloc(sizeof(struct hdmifb_info), &pdev->dev); - if (!info) - return -ENOMEM; - - hdmi_fb = info->par; - _hdmi_fb = hdmi_fb; - hdmi_fb->fb = info; - hdmi_fb->panel = panel; - set_bit(hdmi_mode, &hdmi_fb->state); - hdmi_fb->dma_callback.func = hdmi_handle_dma; - hdmi_fb->vsync_callback.func = hdmi_handle_vsync; - hdmi_fb->xres = panel->fb_data->xres; - hdmi_fb->yres = panel->fb_data->yres; - spin_lock_init(&hdmi_fb->update_lock); - - ret = setup_fbmem(hdmi_fb, pdev); - if (ret) - goto error_setup_fbmem; - - setup_fb_info(hdmi_fb); - - ret = register_framebuffer(info); - if (ret) - goto error_register_fb; - - printk(KERN_INFO "hdmi_fb %d * %d initialed\n", - hdmi_fb->xres, hdmi_fb->yres); - -#ifdef CONFIG_HAS_EARLYSUSPEND - hdmi_fb->early_suspend.suspend = hdmifb_suspend; - hdmi_fb->early_suspend.resume = hdmifb_resume; - hdmi_fb->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; - register_early_suspend(&hdmi_fb->early_suspend); -#endif - /* blank panel explicitly because we turn on clk on initial */ - if (panel->blank) - panel->blank(panel); - set_bit(fb_enabled, &hdmi_fb->state); - return 0; - -error_register_fb: -error_setup_fbmem: - framebuffer_release(hdmi_fb->fb); - printk(KERN_ERR "msm probe fail with %d\n", ret); - return ret; -} - -static struct platform_driver hdmi_frame_buffer = { - .probe = hdmifb_probe, - .driver = {.name = "msm_hdmi"}, -}; - -static int hdmifb_add_mdp_device(struct device *dev, - struct class_interface *class_intf) -{ - /* might need locking if mulitple mdp devices */ - if (mdp) - return 0; - mdp = container_of(dev, struct mdp_device, dev); - return platform_driver_register(&hdmi_frame_buffer); -} - -static void hdmifb_remove_mdp_device(struct device *dev, - struct class_interface *class_intf) -{ - /* might need locking if mulitple mdp devices */ - if (dev != &mdp->dev) - return; - platform_driver_unregister(&hdmi_frame_buffer); - mdp = NULL; -} - -static struct class_interface hdmi_fb_interface = { - .add_dev = &hdmifb_add_mdp_device, - .remove_dev = &hdmifb_remove_mdp_device, -}; - -static int hdmifb_add_hdmi_device(struct device *dev, - struct class_interface *class_intf) -{ - dev_dbg(dev, "%s\n", __func__); - - if (hdmi) - return 0; - hdmi = container_of(dev, struct hdmi_device, dev); - return 0; -} - -static struct class_interface hdmi_interface = { - .add_dev = hdmifb_add_hdmi_device, -}; - -static int __init hdmifb_init(void) -{ - int rc; - - rc = register_mdp_client(&hdmi_fb_interface); - if (rc) - return rc; - - rc = register_hdmi_client(&hdmi_interface); - if (rc) - return rc; - return 0; -} - -module_init(hdmifb_init); diff --git a/drivers/video/msm/hdmi/hdmi_lcdc.c b/drivers/video/msm/hdmi/hdmi_lcdc.c deleted file mode 100644 index 2a9247fb..00000000 --- a/drivers/video/msm/hdmi/hdmi_lcdc.c +++ /dev/null @@ -1,633 +0,0 @@ -/* drivers/video/msm/hdmi_lcdc.c - * - * Copyright (c) 2009 Google Inc. - * Copyright (c) 2009 HTC - * - * 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include "../mdp_hw.h" -#include "../../../../arch/arm/mach-msm/proc_comm.h" -#include "../../../../arch/arm/mach-msm/clock.h" - - -#if 1 -#define HDMI_DBG(s...) printk("[hdmi/lcdc]" s) -#else -#define HDMI_DBG(s...) do {} while (0) -#endif - -struct mdp_lcdc_info { - struct mdp_info *mdp; - struct clk *mdp_clk; - struct clk *pclk; - struct clk *pad_pclk; - struct msm_panel_data fb_panel_data; - struct platform_device fb_pdev; - struct msm_lcdc_platform_data *pdata; - uint32_t fb_start; - - struct msmfb_callback frame_start_cb; - wait_queue_head_t vsync_waitq; - int got_vsync; - - struct { - uint32_t clk_rate; - uint32_t hsync_ctl; - uint32_t vsync_period; - uint32_t vsync_pulse_width; - uint32_t display_hctl; - uint32_t display_vstart; - uint32_t display_vend; - uint32_t hsync_skew; - uint32_t polarity; - } parms; - atomic_t blank_count; - struct mutex blank_lock; -}; -struct mdp_lcdc_info *_lcdc; - -static struct mdp_device *mdp_dev; - -#define panel_to_lcdc(p) container_of((p), struct mdp_lcdc_info, fb_panel_data) - -/* FIXME: arrange the clock manipulating to proper place, - integrate with the counter of fb_hdmi -*/ -int lcdc_enable_video(void) -{ - //struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); - struct mdp_lcdc_info *lcdc = _lcdc; - struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops; - - mutex_lock(&lcdc->blank_lock); - if (atomic_read(&lcdc->blank_count)) - goto end_enable_video; - HDMI_DBG("%s: enable clocks\n", __func__); - clk_enable(lcdc->mdp_clk); - clk_enable(lcdc->pclk); - clk_enable(lcdc->pad_pclk); - - /* TODO: need pre-test to see if it make any influence to HDCP, - * if ebi1_clk doesn't enabled here. - */ - //panel_ops->unblank(panel_ops); - - mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN); - atomic_inc(&lcdc->blank_count); - HDMI_DBG("%s, blank_count=%d\n", __func__, - atomic_read(&lcdc->blank_count)); -end_enable_video: - mutex_unlock(&lcdc->blank_lock); - - return 0; -} - -int lcdc_disable_video(void) -{ - struct mdp_lcdc_info *lcdc = _lcdc; - struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops; - - mutex_lock(&lcdc->blank_lock); - if (atomic_read(&lcdc->blank_count) == 0) - goto disable_video_done; - if (atomic_dec_return(&lcdc->blank_count) == 0) { - HDMI_DBG("%s: disable clocks\n", __func__); - panel_ops->blank(panel_ops); - mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN); - clk_disable(lcdc->pclk); - clk_disable(lcdc->pad_pclk); - clk_disable(lcdc->mdp_clk); - } -disable_video_done: - mutex_unlock(&lcdc->blank_lock); - HDMI_DBG("%s, blank_count=%d\n", __func__, - atomic_read(&lcdc->blank_count)); - return 0; -} - -static int lcdc_unblank(struct msm_panel_data *fb_panel) -{ - struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); - struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops; - - HDMI_DBG("%s\n", __func__); - -#if 0 - HDMI_DBG("%s: enable clocks\n", __func__); - clk_enable(lcdc->mdp_clk); - clk_enable(lcdc->pclk); - clk_enable(lcdc->pad_pclk); - - panel_ops->unblank(panel_ops); - - mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN); - atomic_set(&lcdc->blank_count, 1); -#else - lcdc_enable_video(); - /* TODO: need pre-test to see if it make any influence to HDCP, - * if ebi1_clk enabled here. - */ - panel_ops->unblank(panel_ops); -#endif - return 0; -} - -static int lcdc_blank(struct msm_panel_data *fb_panel) -{ - struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); - //struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops; - -#if 0 - mutex_lock(&lcdc->blank_lock); - if (atomic_read(&lcdc->blank_count) == 0) - goto blank_done; - if (atomic_dec_return(&lcdc->blank_count) == 0) { - HDMI_DBG("%s: disable clocks\n", __func__); - panel_ops->blank(panel_ops); - mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN); - clk_disable(lcdc->pclk); - clk_disable(lcdc->pad_pclk); - clk_disable(lcdc->mdp_clk); - } -blank_done: - mutex_unlock(&lcdc->blank_lock); - HDMI_DBG("%s, blank_count=%d\n", __func__, - atomic_read(&lcdc->blank_count)); -#else - lcdc_disable_video(); -#endif - return 0; -} - -static int lcdc_suspend(struct msm_panel_data *fb_panel) -{ - struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); - struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops; - - //pr_info("%s: suspending\n", __func__); - HDMI_DBG("%s\n", __func__); - - if (panel_ops->uninit) - panel_ops->uninit(panel_ops); - lcdc_disable_video(); - - return 0; -} - -static int lcdc_resume(struct msm_panel_data *fb_panel) -{ - struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); - struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops; - - //pr_info("%s: resuming\n", __func__); - HDMI_DBG("%s\n", __func__); - - if (panel_ops->init) { - if (panel_ops->init(panel_ops) < 0) - printk(KERN_ERR "LCD init fail!\n"); - } - - return 0; -} - -static int -lcdc_adjust_timing(struct msm_panel_data *fb_panel, - struct msm_lcdc_timing *timing, u32 xres, u32 yres) -{ - struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); - unsigned int hsync_period; - unsigned int hsync_start_x; - unsigned int hsync_end_x; - unsigned int vsync_period; - unsigned int display_vstart; - unsigned int display_vend; - uint32_t dma_cfg; - - clk_set_rate(lcdc->pclk, timing->clk_rate); - clk_set_rate(lcdc->pad_pclk, timing->clk_rate); - HDMI_DBG("%s, clk=%d, xres=%d, yres=%d,\n", __func__, - clk_get_rate(lcdc->pclk), xres, yres); - - hsync_period = (timing->hsync_pulse_width + timing->hsync_back_porch + - xres + timing->hsync_front_porch); - hsync_start_x = (timing->hsync_pulse_width + timing->hsync_back_porch); - hsync_end_x = hsync_period - timing->hsync_front_porch - 1; - - vsync_period = (timing->vsync_pulse_width + timing->vsync_back_porch + - yres + timing->vsync_front_porch); - vsync_period *= hsync_period; - - display_vstart = timing->vsync_pulse_width + timing->vsync_back_porch; - display_vstart *= hsync_period; - display_vstart += timing->hsync_skew; - - display_vend = timing->vsync_front_porch * hsync_period; - display_vend = vsync_period - display_vend + timing->hsync_skew - 1; - - /* register values we pre-compute at init time from the timing - * information in the panel info */ - lcdc->parms.hsync_ctl = (((hsync_period & 0xfff) << 16) | - (timing->hsync_pulse_width & 0xfff)); - lcdc->parms.vsync_period = vsync_period & 0xffffff; - lcdc->parms.vsync_pulse_width = (timing->vsync_pulse_width * - hsync_period) & 0xffffff; - - lcdc->parms.display_hctl = (((hsync_end_x & 0xfff) << 16) | - (hsync_start_x & 0xfff)); - lcdc->parms.display_vstart = display_vstart & 0xffffff; - lcdc->parms.display_vend = display_vend & 0xffffff; - lcdc->parms.hsync_skew = timing->hsync_skew & 0xfff; - lcdc->parms.polarity = ((timing->hsync_act_low << 0) | - (timing->vsync_act_low << 1) | - (timing->den_act_low << 2)); - lcdc->parms.clk_rate = timing->clk_rate; - - mdp_writel(lcdc->mdp, lcdc->parms.hsync_ctl, MDP_LCDC_HSYNC_CTL); - mdp_writel(lcdc->mdp, lcdc->parms.vsync_period, MDP_LCDC_VSYNC_PERIOD); - mdp_writel(lcdc->mdp, lcdc->parms.vsync_pulse_width, - MDP_LCDC_VSYNC_PULSE_WIDTH); - mdp_writel(lcdc->mdp, lcdc->parms.display_hctl, MDP_LCDC_DISPLAY_HCTL); - mdp_writel(lcdc->mdp, lcdc->parms.display_vstart, - MDP_LCDC_DISPLAY_V_START); - mdp_writel(lcdc->mdp, lcdc->parms.display_vend, MDP_LCDC_DISPLAY_V_END); - mdp_writel(lcdc->mdp, lcdc->parms.hsync_skew, MDP_LCDC_HSYNC_SKEW); - - mdp_writel(lcdc->mdp, 0, MDP_LCDC_BORDER_CLR); - mdp_writel(lcdc->mdp, 0x0, MDP_LCDC_UNDERFLOW_CTL); - mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_HCTL); - mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_V_START); - mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_V_END); - mdp_writel(lcdc->mdp, lcdc->parms.polarity, MDP_LCDC_CTL_POLARITY); - printk("solomon: polarity=%04x\n", mdp_readl(lcdc->mdp, MDP_LCDC_CTL_POLARITY)); - - /* config the dma_p block that drives the lcdc data */ - mdp_writel(lcdc->mdp, lcdc->fb_start, MDP_DMA_P_IBUF_ADDR); - mdp_writel(lcdc->mdp, (((yres & 0x7ff) << 16) | - (xres & 0x7ff)), - MDP_DMA_P_SIZE); - /* TODO: pull in the bpp info from somewhere else? */ - mdp_writel(lcdc->mdp, xres * 2, - MDP_DMA_P_IBUF_Y_STRIDE); - mdp_writel(lcdc->mdp, 0, MDP_DMA_P_OUT_XY); - - dma_cfg = (DMA_PACK_ALIGN_LSB | - DMA_PACK_PATTERN_RGB | - DMA_DITHER_EN); - dma_cfg |= DMA_OUT_SEL_LCDC; - dma_cfg |= DMA_IBUF_FORMAT_RGB565; - dma_cfg |= DMA_DSTC0G_8BITS | DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS; - - mdp_writel(lcdc->mdp, dma_cfg, MDP_DMA_P_CONFIG); - return 0; -} - -static int lcdc_hw_init(struct mdp_lcdc_info *lcdc) -{ - struct msm_panel_data *fb_panel = &lcdc->fb_panel_data; - uint32_t dma_cfg; - unsigned int clk_id, clk_rate; - - clk_enable(lcdc->mdp_clk); - clk_enable(lcdc->pclk); - clk_enable(lcdc->pad_pclk); - - clk_set_rate(lcdc->pclk, lcdc->parms.clk_rate); - clk_set_rate(lcdc->pad_pclk, lcdc->parms.clk_rate); - printk(KERN_DEBUG "pclk = %ld, pad_pclk = %ld\n", - clk_get_rate(lcdc->pclk), - clk_get_rate(lcdc->pad_pclk)); - - /* write the lcdc params */ - mdp_writel(lcdc->mdp, lcdc->parms.hsync_ctl, MDP_LCDC_HSYNC_CTL); - mdp_writel(lcdc->mdp, lcdc->parms.vsync_period, MDP_LCDC_VSYNC_PERIOD); - mdp_writel(lcdc->mdp, lcdc->parms.vsync_pulse_width, - MDP_LCDC_VSYNC_PULSE_WIDTH); - mdp_writel(lcdc->mdp, lcdc->parms.display_hctl, MDP_LCDC_DISPLAY_HCTL); - mdp_writel(lcdc->mdp, lcdc->parms.display_vstart, - MDP_LCDC_DISPLAY_V_START); - mdp_writel(lcdc->mdp, lcdc->parms.display_vend, MDP_LCDC_DISPLAY_V_END); - mdp_writel(lcdc->mdp, lcdc->parms.hsync_skew, MDP_LCDC_HSYNC_SKEW); - - mdp_writel(lcdc->mdp, 0, MDP_LCDC_BORDER_CLR); - mdp_writel(lcdc->mdp, 0, MDP_LCDC_UNDERFLOW_CTL); - mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_HCTL); - mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_V_START); - mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_V_END); - mdp_writel(lcdc->mdp, lcdc->parms.polarity, MDP_LCDC_CTL_POLARITY); - printk("solomon: polarity=%04x\n", mdp_readl(lcdc->mdp, MDP_LCDC_CTL_POLARITY)); - - /* config the dma_p block that drives the lcdc data */ - mdp_writel(lcdc->mdp, lcdc->fb_start, MDP_DMA_P_IBUF_ADDR); - mdp_writel(lcdc->mdp, (((fb_panel->fb_data->yres & 0x7ff) << 16) | - (fb_panel->fb_data->xres & 0x7ff)), - MDP_DMA_P_SIZE); - /* TODO: pull in the bpp info from somewhere else? */ - mdp_writel(lcdc->mdp, fb_panel->fb_data->xres * 2, - MDP_DMA_P_IBUF_Y_STRIDE); - mdp_writel(lcdc->mdp, 0, MDP_DMA_P_OUT_XY); - - dma_cfg = (DMA_PACK_ALIGN_LSB | - DMA_PACK_PATTERN_RGB | - DMA_DITHER_EN); - dma_cfg |= DMA_OUT_SEL_LCDC; - dma_cfg |= DMA_IBUF_FORMAT_RGB565; - dma_cfg |= DMA_DSTC0G_8BITS | DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS; - - mdp_writel(lcdc->mdp, dma_cfg, MDP_DMA_P_CONFIG); - - /* Send customized command to ARM9 for escalating DMA_P as tier-1 - * of AXI bus. - * Ref: SR#272509 - */ - clk_id = USB_PHY_CLK; - clk_rate = 0x1; - msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &clk_id, &clk_rate); - - return 0; -} - -static void lcdc_wait_vsync(struct msm_panel_data *panel) -{ - struct mdp_lcdc_info *lcdc = panel_to_lcdc(panel); - int ret; - - ret = wait_event_timeout(lcdc->vsync_waitq, lcdc->got_vsync, HZ / 2); - if (ret == 0) - pr_err("%s: timeout waiting for VSYNC\n", __func__); - lcdc->got_vsync = 0; -} - -static void lcdc_request_vsync(struct msm_panel_data *fb_panel, - struct msmfb_callback *vsync_cb) -{ - struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); - - /* the vsync callback will start the dma */ - vsync_cb->func(vsync_cb); - lcdc->got_vsync = 0; - mdp_out_if_req_irq(mdp_dev, MSM_LCDC_INTERFACE, MDP_LCDC_FRAME_START, - &lcdc->frame_start_cb); - lcdc_wait_vsync(fb_panel); -} - -static void lcdc_clear_vsync(struct msm_panel_data *fb_panel) -{ - struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); - lcdc->got_vsync = 0; - mdp_out_if_req_irq(mdp_dev, MSM_LCDC_INTERFACE, 0, NULL); -} - -/* called in irq context with mdp lock held, when mdp gets the - * MDP_LCDC_FRAME_START interrupt */ -static void lcdc_frame_start(struct msmfb_callback *cb) -{ - struct mdp_lcdc_info *lcdc; - - lcdc = container_of(cb, struct mdp_lcdc_info, frame_start_cb); - - lcdc->got_vsync = 1; - wake_up(&lcdc->vsync_waitq); -} - -static void lcdc_dma_start(void *priv, uint32_t addr, uint32_t stride, - uint32_t width, uint32_t height, uint32_t x, - uint32_t y) -{ - struct mdp_lcdc_info *lcdc = priv; - struct mdp_info *mdp = lcdc->mdp; - -#if 0 - if (mdp->dma_config_dirty) { - mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN); - mdelay(20); - mdp_dev->configure_dma(mdp_dev); - mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN); - } -#endif - mdp_writel(lcdc->mdp, stride, MDP_DMA_P_IBUF_Y_STRIDE); - mdp_writel(lcdc->mdp, addr, MDP_DMA_P_IBUF_ADDR); -} - -static void precompute_timing_parms(struct mdp_lcdc_info *lcdc) -{ - struct msm_lcdc_timing *timing = lcdc->pdata->timing; - struct msm_fb_data *fb_data = lcdc->pdata->fb_data; - unsigned int hsync_period; - unsigned int hsync_start_x; - unsigned int hsync_end_x; - unsigned int vsync_period; - unsigned int display_vstart; - unsigned int display_vend; - - hsync_period = (timing->hsync_pulse_width + timing->hsync_back_porch + - fb_data->xres + timing->hsync_front_porch); - hsync_start_x = (timing->hsync_pulse_width + timing->hsync_back_porch); - hsync_end_x = hsync_period - timing->hsync_front_porch - 1; - - vsync_period = (timing->vsync_pulse_width + timing->vsync_back_porch + - fb_data->yres + timing->vsync_front_porch); - vsync_period *= hsync_period; - - display_vstart = timing->vsync_pulse_width + timing->vsync_back_porch; - display_vstart *= hsync_period; - display_vstart += timing->hsync_skew; - - display_vend = timing->vsync_front_porch * hsync_period; - display_vend = vsync_period - display_vend + timing->hsync_skew - 1; - - /* register values we pre-compute at init time from the timing - * information in the panel info */ - lcdc->parms.hsync_ctl = (((hsync_period & 0xfff) << 16) | - (timing->hsync_pulse_width & 0xfff)); - lcdc->parms.vsync_period = vsync_period & 0xffffff; - lcdc->parms.vsync_pulse_width = (timing->vsync_pulse_width * - hsync_period) & 0xffffff; - - lcdc->parms.display_hctl = (((hsync_end_x & 0xfff) << 16) | - (hsync_start_x & 0xfff)); - lcdc->parms.display_vstart = display_vstart & 0xffffff; - lcdc->parms.display_vend = display_vend & 0xffffff; - lcdc->parms.hsync_skew = timing->hsync_skew & 0xfff; - lcdc->parms.polarity = ((timing->hsync_act_low << 0) | - (timing->vsync_act_low << 1) | - (timing->den_act_low << 2)); - lcdc->parms.clk_rate = timing->clk_rate; -} - -static int hdmi_lcdc_probe(struct platform_device *pdev) -{ - struct msm_lcdc_platform_data *pdata = pdev->dev.platform_data; - struct mdp_lcdc_info *lcdc; - int ret = 0; - - printk(KERN_DEBUG "%s\n", __func__); - - if (!pdata) { - pr_err("%s: no LCDC platform data found\n", __func__); - return -EINVAL; - } - - _lcdc = lcdc = kzalloc(sizeof(struct mdp_lcdc_info), GFP_KERNEL); - if (!lcdc) - return -ENOMEM; - - /* We don't actually own the clocks, the mdp does. */ - lcdc->mdp_clk = clk_get(mdp_dev->dev.parent, "mdp_clk"); - if (IS_ERR(lcdc->mdp_clk)) { - pr_err("%s: failed to get mdp_clk\n", __func__); - ret = PTR_ERR(lcdc->mdp_clk); - goto err_get_mdp_clk; - } - - lcdc->pclk = clk_get(mdp_dev->dev.parent, "lcdc_pclk_clk"); - if (IS_ERR(lcdc->pclk)) { - pr_err("%s: failed to get lcdc_pclk\n", __func__); - ret = PTR_ERR(lcdc->pclk); - goto err_get_pclk; - } - - lcdc->pad_pclk = clk_get(mdp_dev->dev.parent, "lcdc_pad_pclk_clk"); - if (IS_ERR(lcdc->pad_pclk)) { - pr_err("%s: failed to get lcdc_pad_pclk\n", __func__); - ret = PTR_ERR(lcdc->pad_pclk); - goto err_get_pad_pclk; - } - - init_waitqueue_head(&lcdc->vsync_waitq); - mutex_init(&lcdc->blank_lock); - lcdc->pdata = pdata; - lcdc->frame_start_cb.func = lcdc_frame_start; - - platform_set_drvdata(pdev, lcdc); - - mdp_out_if_register(mdp_dev, MSM_LCDC_INTERFACE, lcdc, MDP_DMA_P_DONE, - lcdc_dma_start); - - precompute_timing_parms(lcdc); - - lcdc->fb_start = pdata->fb_resource->start; - lcdc->mdp = container_of(mdp_dev, struct mdp_info, mdp_dev); - - lcdc->fb_panel_data.suspend = lcdc_suspend; - lcdc->fb_panel_data.resume = lcdc_resume; - lcdc->fb_panel_data.wait_vsync = lcdc_wait_vsync; - lcdc->fb_panel_data.request_vsync = lcdc_request_vsync; - lcdc->fb_panel_data.clear_vsync = lcdc_clear_vsync; - lcdc->fb_panel_data.blank = lcdc_blank; - lcdc->fb_panel_data.unblank = lcdc_unblank; - lcdc->fb_panel_data.adjust_timing = lcdc_adjust_timing; - lcdc->fb_panel_data.fb_data = pdata->fb_data; - lcdc->fb_panel_data.interface_type = MSM_LCDC_INTERFACE; - - ret = lcdc_hw_init(lcdc); - atomic_set(&lcdc->blank_count, 1); - if (ret) { - pr_err("%s: Cannot initialize the mdp_lcdc\n", __func__); - goto err_hw_init; - } - - lcdc->fb_pdev.name = "msm_hdmi"; - lcdc->fb_pdev.id = pdata->fb_id; - lcdc->fb_pdev.resource = pdata->fb_resource; - lcdc->fb_pdev.num_resources = 1; - lcdc->fb_pdev.dev.platform_data = &lcdc->fb_panel_data; - - ret = platform_device_register(&lcdc->fb_pdev); - if (ret) { - pr_err("%s: Cannot register msm_panel pdev\n", __func__); - goto err_plat_dev_reg; - } - - pr_info("%s: initialized\n", __func__); - - return 0; - -err_plat_dev_reg: -err_hw_init: - platform_set_drvdata(pdev, NULL); - clk_put(lcdc->pad_pclk); -err_get_pad_pclk: - clk_put(lcdc->pclk); -err_get_pclk: - clk_put(lcdc->mdp_clk); -err_get_mdp_clk: - kfree(lcdc); - return ret; -} - -static int hdmi_lcdc_remove(struct platform_device *pdev) -{ - struct mdp_lcdc_info *lcdc = platform_get_drvdata(pdev); - - platform_set_drvdata(pdev, NULL); - - clk_put(lcdc->pclk); - clk_put(lcdc->pad_pclk); - kfree(lcdc); - - return 0; -} - -static struct platform_driver mdp_lcdc_driver = { - .probe = hdmi_lcdc_probe, - .remove = hdmi_lcdc_remove, - .driver = { - .name = "msm_mdp_hdmi", - .owner = THIS_MODULE, - }, -}; - -static int mdp_lcdc_add_mdp_device(struct device *dev, - struct class_interface *class_intf) -{ - /* might need locking if mulitple mdp devices */ - if (mdp_dev) - return 0; - mdp_dev = container_of(dev, struct mdp_device, dev); - return platform_driver_register(&mdp_lcdc_driver); -} - -static void mdp_lcdc_remove_mdp_device(struct device *dev, - struct class_interface *class_intf) -{ - /* might need locking if mulitple mdp devices */ - if (dev != &mdp_dev->dev) - return; - platform_driver_unregister(&mdp_lcdc_driver); - mdp_dev = NULL; -} - -static struct class_interface mdp_lcdc_interface = { - .add_dev = &mdp_lcdc_add_mdp_device, - .remove_dev = &mdp_lcdc_remove_mdp_device, -}; - -static int __init mdp_lcdc_init(void) -{ - return register_mdp_client(&mdp_lcdc_interface); -} - -module_init(mdp_lcdc_init); diff --git a/drivers/video/msm/hdmi/include/edid.h b/drivers/video/msm/hdmi/include/edid.h deleted file mode 100644 index 1b7e4587..00000000 --- a/drivers/video/msm/hdmi/include/edid.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef _EDID_H_ -#define _EDID_H_ - -#define MAX_VIDEO_MODES 32 -struct edid_info_struct { - bool is_valid; - struct mutex access_lock; - bool under_scan; - bool basic_audio; - bool ycbcr_4_4_4; - bool ycbcr_4_2_2; - bool hdmi_sink; -}; - -#define EDID_BLOCK_SIZE 128 -#define EDID_HDR_NO_OF_FF 0x06 - -#define EDID_BLOCK_0_OFFSET 0x00 -#define EDID_BLOCK_1_OFFSET 0x80 -#define EDID_BLOCK_SIZE 128 -#define EDID_HDR_NO_OF_FF 0x06 -#define NUM_OF_EXTEN_ADDR 0x7E - -#define EDID_TAG_ADDR 0x00 -#define EDID_REV_ADDR 0x01 -#define EDID_TAG_IDX 0x02 -#define LONG_DESCR_PTR_IDX 0x02 -#define MISC_SUPPORT_IDX 0x03 - -#define ESTABLISHED_TIMING_INDEX 35 -#define NUM_OF_STANDARD_TIMINGS 8 -#define STANDARD_TIMING_OFFSET 38 -#define LONG_DESCR_LENi 18 -#define NUM_OF_DETAILED_DESCRIPTORS 4 - -#define DETAILED_TIMING_OFFSET 0x36 - -/* Offsets within a Long Descriptors Block */ -#define PIX_CLK_OFFSET 0 -#define H_ACTIVE_OFFSET 2 -#define H_BLANKING_OFFSET 3 -#define V_ACTIVE_OFFSET 5 -#define V_BLANKING_OFFSET 6 -#define H_SYNC_OFFSET 8 -#define H_SYNC_PW_OFFSET 9 -#define V_SYNC_OFFSET 10 -#define V_SYNC_PW_OFFSET 10 -#define H_IMAGE_SIZE_OFFSET 12 -#define V_IMAGE_SIZE_OFFSET 13 -#define H_BORDER_OFFSET 15 -#define V_BORDER_OFFSET 16 -#define FLAGS_OFFSET 17 - -#define AR16_10 0 -#define AR4_3 1 -#define AR5_4 2 -#define AR16_9 3 - -#define EDID_EXTENSION_TAG 0x02 -#define EDID_REV_THREE 0x03 -#define EDID_DATA_START 0x04 - -#define EDID_BLOCK_0 0x00 -#define EDID_BLOCK_2_3 0x01 - -#define AUDIO_DESCR_SIZE 3 - -/* Data Block Tag Codes */ -#define AUDIO_D_BLOCK 0x01 -#define VIDEO_D_BLOCK 0x02 -#define VENDOR_SPEC_D_BLOCK 0x03 -#define SPKR_ALLOC_D_BLOCK 0x04 -#define USE_EXTENDED_TAG 0x07 - -/* Extended Data Block Tag Codes */ -#define COLORIMETRY_D_BLOCK 0x05 - -#define VIDEO_CAPABILITY_D_BLOCK 0x00 -#define HDMI_SIGNATURE_LEN 0x03 - -#define CEC_PHYS_ADDR_LEN 0x02 -#endif diff --git a/drivers/video/msm/hdmi/include/fb-hdmi.h b/drivers/video/msm/hdmi/include/fb-hdmi.h deleted file mode 100644 index 3252ec12..00000000 --- a/drivers/video/msm/hdmi/include/fb-hdmi.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _FB_HDMI_H_ -#define _FB_HDMI_H_ - -#include -#include - -enum hd_res { - hd_720p = 0, /* 1280 * 720 */ - svga, /* 800 * 600 */ - pal, /* 720 * 576 */ - edtv, /* 720 * 480 */ - vga, /* 640 * 480 */ -}; - -struct msm_lcdc_timing; -struct hdmi_device { - struct device dev; - int (*check_res)(struct hdmi_device *, struct fb_var_screeninfo *); - struct msm_lcdc_timing *(*set_res)(struct hdmi_device *, - struct fb_var_screeninfo *); - int (*get_cable_state)(struct hdmi_device *, int *); - int (*get_establish_timing)(struct hdmi_device *, u8 *); -}; - -struct class_interface; -int register_hdmi_client(struct class_interface *class_intf); -#endif diff --git a/drivers/video/msm/hdmi/include/sil902x.h b/drivers/video/msm/hdmi/include/sil902x.h deleted file mode 100644 index 00edd9d5..00000000 --- a/drivers/video/msm/hdmi/include/sil902x.h +++ /dev/null @@ -1,399 +0,0 @@ -#ifndef __SIL902X_H_ -#define __SIL902X_H_ - -#include -#include "edid.h" - -struct hdmi_info { - struct hdmi_device hdmi_dev; - struct i2c_client *client; - struct msm_lcdc_panel_ops hdmi_lcdc_ops; - struct work_struct work; - struct delayed_work hdmi_delay_work; - struct mutex lock; - struct mutex lock2; - struct clk *ebi1_clk; - int (*power)(int on); - void (*hdmi_gpio_on)(void); - void (*hdmi_gpio_off)(void); - enum hd_res res; - // FIXME: move to edid_info_struct - u8 edid_buf[128 * 4]; - enum { - SLEEP, - AWAKE, - } sleeping; - bool polling; - bool cable_connected; - bool isr_enabled; - bool first; - struct completion hotplug_completion; - struct timer_list timer; - struct work_struct polling_work; - struct dentry *debug_dir; - struct edid_info_struct edid_info; - struct mutex polling_lock; - bool suspending; - bool user_playing; - bool video_streaming; -}; - -enum { - HDMI_PIXEL_DATA = 0x08, - HDMI_AVI_INFO_FRAME = 0x0c, - HDMI_AUDIO_INFO_FRAME = 0xbf, - HDMI_SYS_CTL = 0x1a, - HDMI_POWER = 0x1e, - HDMI_IDENTIFY = 0x1b, - HDMI_INT_EN = 0x3c, - HDMI_INT_STAT = 0x3d, - HDMI_EN_REG = 0xc7, -}; - -/* flag bitmap for register HDMI_INT_STAT */ -enum { - HOT_PLUG_PENDING = (1U << 0), - RX_PENDING = (1U << 1), - HOT_PLUG_STATE = (1U << 2), - RX_STATE = (1U << 3), - AUDIO_ERR = (1U << 4), - SECURITY_STATE = (1U << 5), - HDCP_VALUE = (1U << 6), - HDCP_AUTH = (1U << 7), -}; - -enum ErrorMessages { - INIT_SYSTEM_SUCCESSFUL, // 0 - - BLACK_BOX_OPEN_FAILURE, - BLACK_BOX_OPENED_SUCCESSFULLY, - HW_RESET_FAILURE, - TPI_ENABLE_FAILURE, - INTERRUPT_EN_FAILURE, - INTERRUPT_POLLING_FAILED, - - NO_SINK_CONNECTED, - DDC_BUS_REQ_FAILURE, - HDCP_FAILURE, - HDCP_OK, // 10 - RX_AUTHENTICATED, - SINK_DOES_NOT_SUPPORT_HDCP, - TX_DOES_NOT_SUPPORT_HDCP, - - ILLEGAL_AKSV, - SET_PROTECTION_FAILURE, - REVOKED_KEYS_FOUND, - REPEATER_AUTHENTICATED, - INT_STATUS_READ_FAILURE, - - PROTECTION_OFF_FAILED, - PROTECTION_ON_FAILED, // 20 - INTERRUPT_POLLING_OK, - - EDID_PARSING_FAILURE, - VIDEO_SETUP_FAILURE, - TPI_READ_FAILURE, - TPI_WRITE_FAILURE, - - INIT_VIDEO_FAILURE, - DE_CANNOT_BE_SET_WITH_EMBEDDED_SYNC, - SET_EMBEDDED_SYC_FAILURE, - V_MODE_NOT_SUPPORTED, - - AUD_MODE_NOT_SUPPORTED, // 30 - I2S_NOT_SET, - - EDID_READ_FAILURE, - EDID_CHECKSUM_ERROR, - INCORRECT_EDID_HEADER, - EDID_EXT_TAG_ERROR, - - EDID_REV_ADDR_ERROR, - EDID_V_DESCR_OVERFLOW, - INCORRECT_EDID_FILE, - UNKNOWN_EDID_TAG_CODE, - NO_DETAILED_DESCRIPTORS_IN_THIS_EDID_BLOCK, // 40 - CONFIG_DATA_VALID, - CONFIG_DATA_INVALID, - - GPIO_ACCESS_FAILED, - GPIO_CONFIG_ERROR, - - HP_EVENT_GOING_TO_SERVICE_LOOP, - EDID_PARSED_OK, - VIDEO_MODE_SET_OK, - AUDIO_MODE_SET_OK, - - I2S_MAPPING_SUCCESSFUL, - I2S_INPUT_CONFIG_SUCCESSFUL, // 50 - I2S_HEADER_SET_SUCCESSFUL, - INTERRUPT_POLLING_SUCCESSFUL, - - HPD_LOOP_EXITED_SUCCESSFULY, - HPD_LOOP_FAILED, - SINK_CONNECTED, - HP_EVENT_RETURNING_FROM_SERVICE_LOOP, - AVI_INFOFRAMES_SETTING_FAILED, - - TMDS_ENABLING_FAILED, - DE_SET_OK, - DE_SET_FAILED, - NO_861_EXTENSIONS, - - GO_OK, - IMAGE_PKTS_UPDATED_OK, - MONITORING_BLOCKED, - LINK_NORMAL, - LINK_LOST, - RENEGOTIATION_REQUIRED, - - LINK_SUSPENDED, - EDID_SHORT_DESCRIPTORS_PARSED_OK, - EDID_LONG_DESCRIPTORS_PARSED_OK, - DDC_BUS_RELEASE_FAILURE, - FAILED_GETTING_BKSV, - - PLL_SETUP_FAILUE, - ERR_RX_QUEUE_FULL, - ERR_TX_QUEUE_FULL, - GBD_SET_SUCCESSFULLY, - BACKDOOR_SETTING_FAILED, - ERR_TX_QUEUE_EMPTY -}; - -#define BIT_0 0x01 -#define BIT_1 0x02 -#define BIT_2 0x04 -#define BIT_3 0x08 -#define BIT_4 0x10 -#define BIT_5 0x20 -#define BIT_6 0x40 -#define BIT_7 0x80 - -#define INTERVAL_HDCP_POLLING (HZ / 25) - -#define REQUEST_RELEASE_DDC_BEFORE_HDCP -#define T_HDCP_ACTIVATION 500 -#define T_HDCP_DEACTIVATION 200 - -#define T_HPD_DELAY 10 -#define TPI_INTERRUPT_EN 0x3c -#define ALL 0xff -#define DUMMY 0xFD - -#define SiI_DEVICE_ID 0xB0 - -#define T_DDC_ACCESS 50 -// TPI Control Masks -// ================= -#define BIT_OUTPUT_MODE 0x01 -#define BIT_DDC_BUS_GRANT 0x02 -#define BIT_DDC_BUS_REQ 0x04 -#define BIT_TMDS_OUTPUT 0x10 - -#define TPI_INTERNAL_PAGE_REG 0xBC -#define TPI_REGISTER_OFFSET_REG 0xBD -#define TPI_REGISTER_VALUE_REG 0xBE - -/* HDCP Control Masks */ -#define BIT_PROTECT_LEVEL 0x01 -#define BIT_PROTECT_TYPE 0x02 -#define BIT_REPEATER 0x08 -#define BIT_LOCAL_PROTECT 0x40 -#define BIT_EXT_PROTECT 0x80 - -#define BITS_LINK_LOST 0x10 -#define BITS_RENEGOTIATION 0x20 - -#define BIT_TMDS_OUTPUT 0x10 - -#define BIT_AUDIO_MUTE 0x10 - -#define TPI_HDCP_REVISION_DATA_REG (0x30) -#define HDCP_MAJOR_REVISION_MASK (BIT_7 | BIT_6 | BIT_5 | BIT_4) -#define HDCP_MAJOR_REVISION_VALUE (0x10) - -#define HDCP_MINOR_REVISION_MASK (BIT_3 | BIT_2 | BIT_1 | BIT_0) -#define HDCP_MINOR_REVISION_VALUE (0x02) - -#define HDCP_REVISION 0x12 -#define SET_PROT_ATTEMPTS 0x05 - -#define AKSV_SIZE 5 -#define BYTE_SIZE 8 -#define NUM_OF_ONES_IN_KSV 20 - -// Interrupt Masks -//================ -#define HOT_PLUG_EVENT 0x01 -#define RX_SENSE_EVENT 0x02 -#define TPI_HOT_PLUG_STATE 0x04 -#define RX_SENSE_STATE 0x08 - -#define AUDIO_ERROR_EVENT 0x10 -#define SECURITY_CHANGE_EVENT 0x20 -#define V_READY_EVENT 0x40 -#define HDCP_CHANGE_EVENT 0x80 - -#define NON_MASKABLE_INT 0xFF - -/* Protection Levels */ -#define NO_PROTECTION 0x00 -#define LOCAL_PROTECTION 0x01 -#define EXTENDED_PROTECTION 0x03 - -#define LINK_NORMAL 0 -#define MAX_V_DESCRIPTORS 20 -#define MAX_A_DESCRIPTORS 10 -#define MAX_SPEAKER_CONFIGURATIONS 4 - -#define HDMI_DEBUGFS_ROOT "hdmi" - -/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /// -/*\ -| | HDCP Implementation -| | -| | HDCP link security logic is implemented in certain transmitters; unique -| | keys are embedded in each chip as part of the solution. The security -| | scheme is fully automatic and handled completely by the hardware. -\*/ -/// HDCP Query Data Register ============================================== /// - -#define TPI_HDCP_QUERY_DATA_REG (0x29) - -#define EXTENDED_LINK_PROTECTION_MASK (BIT_7) -#define EXTENDED_LINK_PROTECTION_NONE (0x00) -#define EXTENDED_LINK_PROTECTION_SECURE (0x80) - -#define LOCAL_LINK_PROTECTION_MASK (BIT_6) -#define LOCAL_LINK_PROTECTION_NONE (0x00) -#define LOCAL_LINK_PROTECTION_SECURE (0x40) - -#define LINK_STATUS_MASK (BIT_5 | BIT_4) -#define LINK_STATUS_NORMAL (0x00) -#define LINK_STATUS_LINK_LOST (0x10) -#define LINK_STATUS_RENEGOTIATION_REQ (0x20) -#define LINK_STATUS_LINK_SUSPENDED (0x30) - -#define HDCP_REPEATER_MASK (BIT_3) -#define HDCP_REPEATER_NO (0x00) -#define HDCP_REPEATER_YES (0x08) - -#define CONNECTOR_TYPE_MASK (BIT_2 | BIT_0) -#define CONNECTOR_TYPE_DVI (0x00) -#define CONNECTOR_TYPE_RSVD (0x01) -#define CONNECTOR_TYPE_HDMI (0x04) -#define CONNECTOR_TYPE_FUTURE (0x05) - -#define PROTECTION_TYPE_MASK (BIT_1) -#define PROTECTION_TYPE_NONE (0x00) -#define PROTECTION_TYPE_HDCP (0x02) - -/// HDCP Control Data Register ============================================ /// - -#define TPI_HDCP_CONTROL_DATA_REG (0x2A) - -#define PROTECTION_LEVEL_MASK (BIT_0) -#define PROTECTION_LEVEL_MIN (0x00) -#define PROTECTION_LEVEL_MAX (0x01) - -/*---------------------------------------------------------------------------*/ - -#if 0 -/* Caller: ChangeVideoMode(), HDCP_Poll(), HotPlugServiceLoop(), RestartHDCP() - */ -#define EnableTMDS(hdmi) ReadClearWriteTPI(hdmi, TPI_SYSTEM_CONTROL, BIT_TMDS_OUTPUT) // 0x1A[4] = 0 - -/* Caller: ChangeVideoMode(), HDCP_Poll(), TPI_Poll(), RestartHDCP(), - * OnHdmiCableDisconnected() - */ -#define DisableTMDS(hdmi) ReadSetWriteTPI(hdmi, TPI_SYSTEM_CONTROL, BIT_TMDS_OUTPUT) // 0x1A[4] = 1 -#else - -void EnableTMDS(struct hdmi_info *hdmi); -void DisableTMDS(struct hdmi_info *hdmi); - -#endif - -// FIXME: fix the global variables -extern u8 pvid_mode, vid_mode; -extern u8 LinkProtectionLevel; -extern u8 systemInitialized; -/*---------------------------------------------------------------------------*/ -int hdmi_read(struct i2c_client *client, u8 cmd); -int hdmi_write_byte(struct i2c_client *client, u8 reg, u8 val); -int hdmi_enable_int(struct i2c_client *client); -int hdmi_disable_int(struct i2c_client *client); -int hdmi_read_edid(struct hdmi_info *info, struct i2c_client *client); -int hdmi_standby(struct hdmi_info *hdmi); -int hdmi_wakeup(struct hdmi_info *hdmi); -int read_backdoor_register(struct hdmi_info *hdmi, u8 PageNum, u8 RegOffset); -void ReadSetWriteTPI(struct hdmi_info *hdmi, u8 Offset, u8 Pattern); -void ReadModifyWriteTPI(struct hdmi_info *hdmi, u8 Offset, u8 Mask, u8 Value); -void tpi_clear_interrupt(struct hdmi_info *hdmi, u8 pattern); -bool tpi_init(struct hdmi_info *hdmi); -void ReadClearWriteTPI(struct hdmi_info *hdmi, u8 Offset, u8 Pattern); -s32 ReadBlockTPI(struct hdmi_info *hdmi, u8 TPI_Offset, u16 NBytes, u8 *pData); -bool IsRepeater(struct hdmi_info *hdmi); -bool GetDDC_Access(struct hdmi_info *hdmi, u8* SysCtrlRegVal); -bool ReleaseDDC(struct hdmi_info *hdmi, u8 SysCtrlRegVal); -int tpi_read_backdoor_register(struct hdmi_info *hdmi, u8 PageNum, u8 RegOffset) -; -void tpi_write_backdoor_register(struct hdmi_info *hdmi, u8 PageNum, u8 RegOffset, u8 RegValue); - -int HotPlugServiceLoop(struct hdmi_info *hdmi); - -int hdmi_active9022(struct i2c_client *client); -int hdmi_active9022_dup(struct i2c_client *client); -bool avc_send_avi_info_frames(struct hdmi_info *hdmi); -bool avc_init_video(struct hdmi_info *hdmi, u8 mode, u8 TclkSel, bool Init); -//void hdcp_on(struct hdmi_info *hdmi); -void hdcp_off(struct hdmi_info *hdmi); -void hdcp_check_status(struct hdmi_info *hdmi, u8 InterruptStatusImage); -void hdcp_init(struct hdmi_info *hdmi); -int hdcp_debugfs_init(struct hdmi_info *hdmi); - -extern u8 EDID_TempData[]; -u8 edid_simple_parsing(struct hdmi_info *hdmi); - -int edid_dump_hex(u8 *src, int src_size, char *output, int output_size); -bool edid_is_video_mode_supported(struct video_mode *vmode); -int edid_debugfs_init(struct hdmi_info *hdmi); -bool edid_check_sink_type(struct hdmi_info *hdmi); -int HotPlugServiceLoop(struct hdmi_info *hdmi); -int tpi_prepare(struct hdmi_info *hdmi); - -//bool InitVideo(struct hdmi_info *hdmi, u8 Mode, u8 TclkSel, bool Init); -void avc_set_basic_audio(struct hdmi_info *hdmi); - -int hdmi_debugfs_init(struct hdmi_info *hdmi); -int tpi_debugfs_init(struct hdmi_info *hdmi); -ssize_t hdmi_dbgfs_open(struct inode *inode, struct file *file); - -void SetAudioMute(struct hdmi_info *hdmi, u8 audioMute); -void SetInputColorSpace(struct hdmi_info *hdmi, u8 inputColorSpace); - -void WriteBackDoorRegister(struct hdmi_info *hdmi, u8 PageNum, u8 RegOffset, u8 RegValue); - -#define TPI_INPUT_FORMAT 0x09 -#define TPI_OUTPUT_FORMAT 0x0A - -#define TPI_SYSTEM_CONTROL 0x1A - -#define TPI_DEVICE_POWER_STATE_CTRL_REG (0x1E) - -#define CTRL_PIN_CONTROL_MASK (BIT_4) -#define CTRL_PIN_TRISTATE (0x00) -#define CTRL_PIN_DRIVEN_TX_BRIDGE (0x10) - -#define TX_POWER_STATE_D0 (0x00) -#define TX_POWER_STATE_D1 (0x01) -#define TX_POWER_STATE_D2 (0x02) -#define TX_POWER_STATE_D3 (0x03) - -#define TPI_AUDIO_INTERFACE 0x26 - -#define TPI_HDCP_QUERY_DATA 0x29 -#define TPI_HDCP_CTRL 0x2A - -#endif diff --git a/drivers/video/msm/hdmi/include/tpi.h b/drivers/video/msm/hdmi/include/tpi.h deleted file mode 100644 index db0271fd..00000000 --- a/drivers/video/msm/hdmi/include/tpi.h +++ /dev/null @@ -1,411 +0,0 @@ -#ifndef _TPI_H_ -#define _TPI_H_ - -#define TPI_PIX_CLK_LSB (0x00) -#define TPI_PIX_CLK_MSB (0x01) - -#define TPI_VERT_FREQ_LSB (0x02) -#define TPI_VERT_FREQ_MSB (0x03) - -#define TPI_TOTAL_PIX_LSB (0x04) -#define TPI_TOTAL_PIX_MSB (0x05) - -#define TPI_TOTAL_LINES_LSB (0x06) -#define TPI_TOTAL_LINES_MSB (0x07) - -// Pixel Repetition Data -//====================== - -#define TPI_PIX_REPETITION (0x08) - -// TPI AVI Input and Output Format Data -//===================================== - -/// AVI Input Format Data ================================================= /// - -#define TPI_INPUT_FORMAT_REG (0x09) - -//Finish this... - -#define INPUT_COLOR_SPACE_MASK (BIT_1 | BIT_0) -#define INPUT_COLOR_SPACE_RGB (0x00) -#define INPUT_COLOR_SPACE_YCBCR444 (0x01) -#define INPUT_COLOR_SPACE_YCBCR422 (0x02) -#define INPUT_COLOR_SPACE_BLACK_MODE (0x03) - -/// AVI Output Format Data ================================================ /// - -#define TPI_OUTPUT_FORMAT_REG (0x0A) - -#define TPI_YC_Input_Mode (0x0B) - -// TPI AVI InfoFrame Data -//======================= - -#define TPI_AVI_BYTE_0 (0x0C) -#define TPI_AVI_BYTE_1 (0x0D) -#define TPI_AVI_BYTE_2 (0x0E) -#define TPI_AVI_BYTE_3 (0x0F) -#define TPI_AVI_BYTE_4 (0x10) -#define TPI_AVI_BYTE_5 (0x11) - -#define TPI_AUDIO_BYTE_0 (0xBF) - -#define TPI_INFO_FRM_DBYTE5 0xC8 -#define TPI_INFO_FRM_DBYTE6 0xC9 - -#define TPI_END_TOP_BAR_LSB (0x12) -#define TPI_END_TOP_BAR_MSB (0x13) - -#define TPI_START_BTM_BAR_LSB (0x14) -#define TPI_START_BTM_BAR_MSB (0x15) - -#define TPI_END_LEFT_BAR_LSB (0x16) -#define TPI_END_LEFT_BAR_MSB (0x17) - -#define TPI_END_RIGHT_BAR_LSB (0x18) -#define TPI_END_RIGHT_BAR_MSB (0x19) - -// Colorimetry -//============ -#define SET_EX_COLORIMETRY 0x0C // Set TPI_AVI_BYTE_2 to extended colorimetry and use - //TPI_AVI_BYTE_3 - -// ===================================================== // - -#define TPI_SYSTEM_CONTROL_DATA_REG (0x1A) - -#define LINK_INTEGRITY_MODE_MASK (BIT_6) -#define LINK_INTEGRITY_STATIC (0x00) -#define LINK_INTEGRITY_DYNAMIC (0x40) - -#define TMDS_OUTPUT_CONTROL_MASK (BIT_4) -#define TMDS_OUTPUT_CONTROL_ACTIVE (0x00) -#define TMDS_OUTPUT_CONTROL_POWER_DOWN (0x10) - -#define AV_MUTE_MASK (BIT_3) -#define AV_MUTE_NORMAL (0x00) -#define AV_MUTE_MUTED (0x08) - -#define DDC_BUS_REQUEST_MASK (BIT_2) -#define DDC_BUS_REQUEST_NOT_USING (0x00) -#define DDC_BUS_REQUEST_REQUESTED (0x04) - -#define DDC_BUS_GRANT_MASK (BIT_1) -#define DDC_BUS_GRANT_NOT_AVAILABLE (0x00) -#define DDC_BUS_GRANT_GRANTED (0x02) - -#define OUTPUT_MODE_MASK (BIT_0) -#define OUTPUT_MODE_DVI (0x00) -#define OUTPUT_MODE_HDMI (0x01) - - -// TPI Identification Registers -//============================= - -#define TPI_DEVICE_ID (0x1B) -#define TPI_DEVICE_REV_ID (0x1C) - -#define TPI_RESERVED2 (0x1D) - -// ===================================================== // - -#define TPI_DEVICE_POWER_STATE_CTRL_REG (0x1E) - -#define CTRL_PIN_CONTROL_MASK (BIT_4) -#define CTRL_PIN_TRISTATE (0x00) -#define CTRL_PIN_DRIVEN_TX_BRIDGE (0x10) - -#define TX_POWER_STATE_MASK (BIT_1 | BIT_0) -#define TX_POWER_STATE_D0 (0x00) -#define TX_POWER_STATE_D1 (0x01) -#define TX_POWER_STATE_D2 (0x02) -#define TX_POWER_STATE_D3 (0x03) - -// Configuration of I2S Interface -//=============================== - -#define TPI_I2S_EN (0x1F) -#define TPI_I2S_IN_CFG (0x20) - -// Available only when TPI 0x26[7:6]=10 to select I2S input -//========================================================= -#define TPI_I2S_CHST_0 (0x21) -#define TPI_I2S_CHST_1 (0x22) -#define TPI_I2S_CHST_2 (0x23) -#define TPI_I2S_CHST_3 (0x24) -#define TPI_I2S_CHST_4 (0x25) - - -// Available only when 0x26[7:6]=01 -//================================= -#define TPI_SPDIF_HEADER (0x24) -#define TPI_AUDIO_HANDLING (0x25) - - -// Audio Configuration Regiaters -//============================== -#define TPI_AUDIO_INTERFACE_REG (0x26) - -// Finish this... - -#define AUDIO_MUTE_MASK (BIT_4) -#define AUDIO_MUTE_NORMAL (0x00) -#define AUDIO_MUTE_MUTED (0x10) - - - - - - -#define TPI_AUDIO_SAMPLE_CTRL (0x27) - -#define TPI_SPEAKER_CFG (0xC7) -#define TPI_CHANNEL_COUNT (0xC4) - -/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /// - -/*\ -| | HDCP Implementation -| | -| | HDCP link security logic is implemented in certain transmitters; unique -| | keys are embedded in each chip as part of the solution. The security -| | scheme is fully automatic and handled completely by the hardware. -\*/ - -/// HDCP Query Data Register ============================================== /// - -#define TPI_HDCP_QUERY_DATA_REG (0x29) - -#define EXTENDED_LINK_PROTECTION_MASK (BIT_7) -#define EXTENDED_LINK_PROTECTION_NONE (0x00) -#define EXTENDED_LINK_PROTECTION_SECURE (0x80) - -#define LOCAL_LINK_PROTECTION_MASK (BIT_6) -#define LOCAL_LINK_PROTECTION_NONE (0x00) -#define LOCAL_LINK_PROTECTION_SECURE (0x40) - -#define LINK_STATUS_MASK (BIT_5 | BIT_4) -#define LINK_STATUS_NORMAL (0x00) -#define LINK_STATUS_LINK_LOST (0x10) -#define LINK_STATUS_RENEGOTIATION_REQ (0x20) -#define LINK_STATUS_LINK_SUSPENDED (0x30) - -#define HDCP_REPEATER_MASK (BIT_3) -#define HDCP_REPEATER_NO (0x00) -#define HDCP_REPEATER_YES (0x08) - -#define CONNECTOR_TYPE_MASK (BIT_2 | BIT_0) -#define CONNECTOR_TYPE_DVI (0x00) -#define CONNECTOR_TYPE_RSVD (0x01) -#define CONNECTOR_TYPE_HDMI (0x04) -#define CONNECTOR_TYPE_FUTURE (0x05) - -#define PROTECTION_TYPE_MASK (BIT_1) -#define PROTECTION_TYPE_NONE (0x00) -#define PROTECTION_TYPE_HDCP (0x02) - -/// HDCP Control Data Register ============================================ /// - -#define TPI_HDCP_CONTROL_DATA_REG (0x2A) - -#define PROTECTION_LEVEL_MASK (BIT_0) -#define PROTECTION_LEVEL_MIN (0x00) -#define PROTECTION_LEVEL_MAX (0x01) - -/// HDCP BKSV Registers =================================================== /// - -#define TPI_BKSV_1_REG (0x2B) -#define TPI_BKSV_2_REG (0x2C) -#define TPI_BKSV_3_REG (0x2D) -#define TPI_BKSV_4_REG (0x2E) -#define TPI_BKSV_5_REG (0x2F) - -/// HDCP Revision Data Register =========================================== /// - -#define TPI_HDCP_REVISION_DATA_REG (0x30) - -#define HDCP_MAJOR_REVISION_MASK (BIT_7 | BIT_6 | BIT_5 | BIT_4) -#define HDCP_MAJOR_REVISION_VALUE (0x10) - -#define HDCP_MINOR_REVISION_MASK (BIT_3 | BIT_2 | BIT_1 | BIT_0) -#define HDCP_MINOR_REVISION_VALUE (0x02) - -/// HDCP KSV and V' Value Data Register =================================== /// - -#define TPI_V_PRIME_SELECTOR_REG (0x31) - -/// V' Value Readback Registers =========================================== /// - -#define TPI_V_PRIME_7_0_REG (0x32) -#define TPI_V_PRIME_15_9_REG (0x33) -#define TPI_V_PRIME_23_16_REG (0x34) -#define TPI_V_PRIME_31_24_REG (0x35) - -/// HDCP AKSV Registers =================================================== /// - -#define TPI_AKSV_1_REG (0x36) -#define TPI_AKSV_2_REG (0x37) -#define TPI_AKSV_3_REG (0x38) -#define TPI_AKSV_4_REG (0x39) -#define TPI_AKSV_5_REG (0x3A) - -/*\ -| | Interrupt Service -| | -| | TPI can be configured to generate an interrupt to the host to notify it of -| | various events. The host can either poll for activity or use an interrupt -| | handler routine. TPI generates on a single interrupt (INT) to the host. -\*/ - -/// Interrupt Enable Register ============================================= /// - -#define TPI_INTERRUPT_ENABLE_REG (0x3C) - -#define HDCP_AUTH_STATUS_CHANGE_EN_MASK (BIT_7) -#define HDCP_AUTH_STATUS_CHANGE_DISABLE (0x00) -#define HDCP_AUTH_STATUS_CHANGE_ENABLE (0x80) - -#define HDCP_VPRIME_VALUE_READY_EN_MASK (BIT_6) -#define HDCP_VPRIME_VALUE_READY_DISABLE (0x00) -#define HDCP_VPRIME_VALUE_READY_ENABLE (0x40) - -#define HDCP_SECURITY_CHANGE_EN_MASK (BIT_5) -#define HDCP_SECURITY_CHANGE_DISABLE (0x00) -#define HDCP_SECURITY_CHANGE_ENABLE (0x20) - -#define AUDIO_ERROR_EVENT_EN_MASK (BIT_4) -#define AUDIO_ERROR_EVENT_DISABLE (0x00) -#define AUDIO_ERROR_EVENT_ENABLE (0x10) - -#define CPI_EVENT_NO_RX_SENSE_MASK (BIT_3) -#define CPI_EVENT_NO_RX_SENSE_DISABLE (0x00) -#define CPI_EVENT_NO_RX_SENSE_ENABLE (0x08) - -#define RECEIVER_SENSE_EVENT_EN_MASK (BIT_1) -#define RECEIVER_SENSE_EVENT_DISABLE (0x00) -#define RECEIVER_SENSE_EVENT_ENABLE (0x02) - -#define HOT_PLUG_EVENT_EN_MASK (BIT_0) -#define HOT_PLUG_EVENT_DISABLE (0x00) -#define HOT_PLUG_EVENT_ENABLE (0x01) - -/// Interrupt Status Register ============================================= /// - -#define TPI_INTERRUPT_STATUS_REG (0x3D) - -#define HDCP_AUTH_STATUS_CHANGE_EVENT_MASK (BIT_7) -#define HDCP_AUTH_STATUS_CHANGE_EVENT_NO (0x00) -#define HDCP_AUTH_STATUS_CHANGE_EVENT_YES (0x80) - -#define HDCP_VPRIME_VALUE_READY_EVENT_MASK (BIT_6) -#define HDCP_VPRIME_VALUE_READY_EVENT_NO (0x00) -#define HDCP_VPRIME_VALUE_READY_EVENT_YES (0x40) - -#define HDCP_SECURITY_CHANGE_EVENT_MASK (BIT_5) -#define HDCP_SECURITY_CHANGE_EVENT_NO (0x00) -#define HDCP_SECURITY_CHANGE_EVENT_YES (0x20) - -#define AUDIO_ERROR_EVENT_MASK (BIT_4) -#define AUDIO_ERROR_EVENT_NO (0x00) -#define AUDIO_ERROR_EVENT_YES (0x10) - -#define CPI_EVENT_MASK (BIT_3) -#define CPI_EVENT_NO (0x00) -#define CPI_EVENT_YES (0x08) -#define RX_SENSE_MASK (BIT_3) // This bit is dual purpose depending on the value of 0x3C[3] -#define RX_SENSE_NOT_ATTACHED (0x00) -#define RX_SENSE_ATTACHED (0x08) - -#define HOT_PLUG_PIN_STATE_MASK (BIT_2) -#define HOT_PLUG_PIN_STATE_LOW (0x00) -#define HOT_PLUG_PIN_STATE_HIGH (0x04) - -#define RECEIVER_SENSE_EVENT_MASK (BIT_1) -#define RECEIVER_SENSE_EVENT_NO (0x00) -#define RECEIVER_SENSE_EVENT_YES (0x02) - -#define HOT_PLUG_EVENT_MASK (BIT_0) -#define HOT_PLUG_EVENT_NO (0x00) -#define HOT_PLUG_EVENT_YES (0x01) - -/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /// - -// Sync Register Configuration and Sync Monitoring Registers -//========================================================== - -#define TPI_SYNC_GEN_CTRL (0x60) -#define TPI_SYNC_POLAR_DETECT (0x61) - -// Explicit Sync DE Generator Registers (TPI 0x60[7]=0) -//===================================================== - -#define TPI_DE_DLY (0x62) -#define TPI_DE_CTRL (0x63) -#define TPI_DE_TOP (0x64) - -#define TPI_RESERVED4 (0x65) - -#define TPI_DE_CNT_7_0 (0x66) -#define TPI_DE_CNT_11_8 (0x67) - -#define TPI_DE_LIN_7_0 (0x68) -#define TPI_DE_LIN_10_8 (0x69) - -#define TPI_DE_H_RES_7_0 (0x6A) -#define TPI_DE_H_RES_10_8 (0x6B) - -#define TPI_DE_V_RES_7_0 (0x6C) -#define TPI_DE_V_RES_10_8 (0x6D) - -// Embedded Sync Register Set (TPI 0x60[7]=1) -//=========================================== - -#define TPI_HBIT_TO_HSYNC_7_0 (0x62) -#define TPI_HBIT_TO_HSYNC_9_8 (0x63) -#define TPI_FIELD_2_OFFSET_7_0 (0x64) -#define TPI_FIELD_2_OFFSET_11_8 (0x65) -#define TPI_HWIDTH_7_0 (0x66) -#define TPI_HWIDTH_8_9 (0x67) -#define TPI_VBIT_TO_VSYNC (0x68) -#define TPI_VWIDTH (0x69) - -// TPI Enable Register -//==================== - -#define TPI_ENABLE (0xC7) - -// Misc InfoFrames -//================ -#define MISC_INFO_FRAMES_CTRL (0xBF) -#define MISC_INFO_FRAMES_TYPE (0xC0) -#define MISC_INFO_FRAMES_VER (0xC1) -#define MISC_INFO_FRAMES_LEN (0xC2) -#define MISC_INFO_FRAMES_CHKSUM (0xC3) - -// Backdoor Register Offsets -//========================== -#define INTERNAL_PAGE_0 0x00 -#define INTERNAL_PAGE_1 0x01 -#define DEVICE_ID_LOW_BYTE 0x02 -#define DEVICE_ID_HI_BYTE 0x03 -#define AUDIO_INPUT_LENGTH 0x24 - - -#define SW_RESET 0x05 -#define POWER_DOWN 0x6F - - -// Backdoor constants -//=================== - -#define DIV_BY_2 0x00 -#define MULT_BY_1 0x01 -#define MULT_BY_2 0x02 -#define MULT_BY_4 0x03 - -#define INTERNAL_PAGE_1 0x01 -#define INTERNAL_PAGE_2 0x02 -#define TMDS_CONT_REG 0x82 - -#endif diff --git a/drivers/video/msm/hdmi/silicon-image/Makefile b/drivers/video/msm/hdmi/silicon-image/Makefile deleted file mode 100644 index 37cda94e..00000000 --- a/drivers/video/msm/hdmi/silicon-image/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -sil-objs = \ - tpi.o \ - hdcp.o \ - av_config.o \ - debug-sil902x.o - -obj-$(CONFIG_MSM_HDMI) += sil.o diff --git a/drivers/video/msm/hdmi/silicon-image/av_config.c b/drivers/video/msm/hdmi/silicon-image/av_config.c deleted file mode 100644 index 2be7d950..00000000 --- a/drivers/video/msm/hdmi/silicon-image/av_config.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - * Copyright (C) 2009 HTC - * - * 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. - */ - -/* TODO: - * 1. Mutex while active - */ -#include -#include -#include "../include/fb-hdmi.h" -#include "../include/sil902x.h" -#include "../include/tpi.h" - -#if 1 -#define HDMI_DBG(s...) printk("[hdmi/avc]" s) -#else -#define HDMI_DBG(s...) do {} while (0) -#endif - -static u8 video_param[][8] = { - [hd_720p] = {0x01, 0x1d, 0x70, 0x17, 0x72, 0x06, 0xee, 0x02}, - [svga] = {0xa0, 0x0f, 0x70, 0x17, 0x20, 0x04, 0x74, 0x02}, - [pal] = {0x8c, 0x0a, 0x88, 0x13, 0x60, 0x03, 0x71, 0x02}, /* 576p50 */ - [edtv] = {0x8c, 0x0a, 0x70, 0x17, 0x5a, 0x03, 0x0d, 0x02},/* 480p60 */ - [vga] = {0x8c, 0x0a, 0x70, 0x17, 0x20, 0x03, 0x0d, 0x02}, -}; - -#if 0 -static u8 avi_info_frame[][14] = { - [hd_720p] = {0x32, 0x0d, 0xa8, 0x84, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00}, - [svga] = {0xd1, 0x0e, 0x08, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00}, - [pal] = {0x64, 0x0d, 0x68, 0x84, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00}, /* 576p50 */ - [edtv] = {0x73, 0x0d, 0x68, 0x84, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00}, - [vga] = {0x5E, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00}, -}; -#else -static u8 avi_info_frame[][14] = { - [hd_720p] = {0x43, 0x00, 0x28, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00}, - [svga] = {0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00}, - [pal] = {0x46, 0x00, 0x18, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00}, /* 576p50 */ - [edtv] = {0x55, 0x00, 0x18, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00}, - [vga] = {0x5E, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00}, -}; -#endif - -static u8 audio_info_frame[] = - { 0xc2, 0x84, 0x01, 0x0a, 0x71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - -#if 0 -int hdmi_active9022(struct i2c_client *client) -{ - int i, ret = -EIO; - struct hdmi_info *info = i2c_get_clientdata(client); - u8 *video_parm = &video_param[info->res][0]; - - HDMI_DBG("%s+\n", __func__); - mutex_lock(&info->polling_lock); - mutex_lock(&info->lock); - - //hdcp_off(info); - DisableTMDS(info); - msleep(128); - - /* choose video mode */ - ret = i2c_smbus_write_i2c_block_data(client, 0, 8, video_parm); - - /* wakeup Sil9022 to D0 state */ - ret = hdmi_write_byte(client, HDMI_POWER, 0); - - if (edid_check_sink_type(info)) { - /* HDMI Output */ - ReadModifyWriteTPI(info, TPI_SYSTEM_CONTROL, - OUTPUT_MODE_MASK, OUTPUT_MODE_HDMI); - /* audio configuration */ - ret = hdmi_write_byte(client, 0x26, 0x91); - ret = hdmi_write_byte(client, 0x25, 0x03); - ret = hdmi_write_byte(client, 0x27, 0x59); - ret = hdmi_write_byte(client, 0x28, 0x00); - ret = hdmi_write_byte(client, 0x1f, 0x80); - ret = hdmi_write_byte(client, 0x20, 0x90); - ret = hdmi_write_byte(client, 0x21, 0x00); - //ret = hdmi_write_byte(client, 0x24, 0x00);//0x00 for 44.1k - ret = hdmi_write_byte(client, 0x24, 0x02);//0x02 for 48k - ret = hdmi_write_byte(client, 0x25, 0x00); - ret = hdmi_write_byte(client, 0xbc, 0x02); - ret = hdmi_write_byte(client, 0xbd, 0x24); - ret = hdmi_write_byte(client, 0xbe, 0x92); - ret = hdmi_write_byte(client, 0xbc, 0x02); - ret = hdmi_write_byte(client, 0xbd, 0x2f); - ret = hdmi_write_byte(client, 0xbe, 0); - ret = hdmi_write_byte(client, 0x26, 0x81); - } else { - ReadModifyWriteTPI(info, TPI_SYSTEM_CONTROL, - OUTPUT_MODE_MASK, OUTPUT_MODE_DVI); - SetAudioMute(info, AUDIO_MUTE_MUTED); - } - ret = hdmi_write_byte(client, HDMI_PIXEL_DATA, 0x60); - - ret = i2c_smbus_write_i2c_block_data(client, HDMI_AUDIO_INFO_FRAME, - 15, audio_info_frame); - hdmi_write_byte(client, 0x09, 0); - hdmi_write_byte(client, 0x0a, 0); - for (i = 0; i < 14 ;i++) - hdmi_write_byte(client, 0xc + i, avi_info_frame[info->res][i]); - - EnableTMDS(info); - HDMI_DBG("%s-\n", __func__); - mutex_unlock(&info->lock); - mutex_unlock(&info->polling_lock); - - return ret; -} -#endif - -int avc_set_video_parm(struct hdmi_info *hdmi) -{ - int ret; - u8 *video_parm = video_param[hdmi->res]; - - ret = i2c_smbus_write_i2c_block_data(hdmi->client, 0, 8, video_parm); - - return ret; -} - -int avc_set_blank_screen(struct hdmi_info *hdmi) -{ - HDMI_DBG("%s+\n", __func__); - hdmi_write_byte(hdmi->client, 0x09, 0x03); - hdmi_write_byte(hdmi->client, 0x19, 0x00); - hdmi_write_byte(hdmi->client, 0x26, - hdmi_read(hdmi->client, 0x26) | 0x10); -} - -int hdmi_active9022_dup(struct i2c_client *client) -{ - int i, ret = -EIO; - struct hdmi_info *info = i2c_get_clientdata(client); - u8 *video_parm = &video_param[info->res][0]; - - HDMI_DBG("%s+\n", __func__); - - //hdcp_off(info); - DisableTMDS(info); - msleep(128); - - /* choose video mode */ - ret = i2c_smbus_write_i2c_block_data(client, 0, 8, video_parm); - - /* wakeup Sil9022 to D0 state */ - ret = hdmi_write_byte(client, HDMI_POWER, 0); - - if (edid_check_sink_type(info)) { - /* HDMI Output */ - ReadModifyWriteTPI(info, TPI_SYSTEM_CONTROL, - OUTPUT_MODE_MASK, OUTPUT_MODE_HDMI); - /* audio configuration */ - ret = hdmi_write_byte(client, 0x26, 0x91); - ret = hdmi_write_byte(client, 0x25, 0x03); - ret = hdmi_write_byte(client, 0x27, 0x59); - ret = hdmi_write_byte(client, 0x28, 0x00); - ret = hdmi_write_byte(client, 0x1f, 0x80); - ret = hdmi_write_byte(client, 0x20, 0x90); - ret = hdmi_write_byte(client, 0x21, 0x00); - //ret = hdmi_write_byte(client, 0x24, 0x00);//0x00 for 44.1k - ret = hdmi_write_byte(client, 0x24, 0x02);//0x02 for 48k - ret = hdmi_write_byte(client, 0x25, 0x00); - ret = hdmi_write_byte(client, 0xbc, 0x02); - ret = hdmi_write_byte(client, 0xbd, 0x24); - ret = hdmi_write_byte(client, 0xbe, 0x92); - ret = hdmi_write_byte(client, 0xbc, 0x02); - ret = hdmi_write_byte(client, 0xbd, 0x2f); - ret = hdmi_write_byte(client, 0xbe, 0); - ret = hdmi_write_byte(client, 0x26, 0x81); - } else { - ReadModifyWriteTPI(info, TPI_SYSTEM_CONTROL, - OUTPUT_MODE_MASK, OUTPUT_MODE_DVI); - SetAudioMute(info, AUDIO_MUTE_MUTED); - } - ret = hdmi_write_byte(client, HDMI_PIXEL_DATA, 0x60); - - ret = i2c_smbus_write_i2c_block_data(client, HDMI_AUDIO_INFO_FRAME, - 15, audio_info_frame); - hdmi_write_byte(client, 0x09, 0x03); - hdmi_write_byte(client, 0x0a, 0); - for (i = 0; i < 14 ;i++) - hdmi_write_byte(client, 0xc + i, avi_info_frame[info->res][i]); - - EnableTMDS(info); - - HDMI_DBG("%s-\n", __func__); - return ret; -} - -bool avc_send_avi_info_frames(struct hdmi_info *hdmi) -{ - int i; - - HDMI_DBG("%s res=%d\n", __func__, hdmi->res); - for (i = 0; i < 14 ;i++) - hdmi_write_byte(hdmi->client, 0xc + i, - avi_info_frame[hdmi->res][i]); - - return true; -} - -#if 0 -/* FIXME: intergrate with active9022 */ -bool InitVideo(struct hdmi_info *hdmi, u8 Mode, u8 TclkSel, bool Init) -{ - int Pattern, ret; - u8 *video_parm = &video_param[hdmi->res][0]; - - /* Use TPI 0x08[7:6] for 9022A/24A video clock multiplier */ - Pattern = (1 << 6) & 0xc0; - ReadSetWriteTPI(hdmi, TPI_PIX_REPETITION, Pattern); - - ret = i2c_smbus_write_block_data(hdmi->client, 0, 8, video_parm); - - /* input format */ - hdmi_write_byte(hdmi->client, 0x09, 0); - hdmi_write_byte(hdmi->client, 0x0a, 0); - if(Init) { - hdmi_write_byte(hdmi->client, 0x08, 0x60); - hdmi_write_byte(hdmi->client, 0x09, 0); - hdmi_write_byte(hdmi->client, 0x0a, 0); - hdmi_write_byte(hdmi->client, 0x60, 0x4); - } - - // termination ??? - //ret = (read_back_door_register(0x1, 0x82) & 0x3f ) | 0x25; - //write_back_door_register(); -#if 0 - for (i = 0; i < 14 ;i++) { - hdmi_write_byte(hdmi->client, 0xc + i, avi_info_frame[info->res][i]); - } -#endif - - return true; -} -#endif - -bool avc_init_video(struct hdmi_info *hdmi, u8 mode, u8 TclkSel, bool Init) -{ - int ret; - u8 *video_parm = &video_param[hdmi->res][0]; - - HDMI_DBG("%s\n", __func__); - /* Use TPI 0x08[7:6] for 9022A/24A video clock multiplier */ - hdmi_write_byte(hdmi->client, HDMI_PIXEL_DATA, 0x60); - - ret = i2c_smbus_write_i2c_block_data(hdmi->client, 0, 8, video_parm); - - /* input format */ - hdmi_write_byte(hdmi->client, TPI_INPUT_FORMAT_REG, 0x00); - hdmi_write_byte(hdmi->client, TPI_OUTPUT_FORMAT_REG, 0x00); -#if 0 - if (Init) { - hdmi_write_byte(hdmi->client, 0x08, 0x60); - hdmi_write_byte(hdmi->client, 0x09, 0); - hdmi_write_byte(hdmi->client, 0x0a, 0); - /* Default to External Sync mode + disable VSync adjustment */ - hdmi_write_byte(hdmi->client, 0x60, 0x4); - /* Disable DE generator by default */ - hdmi_write_byte(hdmi->client, 0x63, 0x0); - } - -#endif - ret = (tpi_read_backdoor_register(hdmi, INTERNAL_PAGE_1, TMDS_CONT_REG) - & 0x3f ) | 0x25; - tpi_write_backdoor_register(hdmi, INTERNAL_PAGE_1, TMDS_CONT_REG, ret); - - return true; -} - -void avc_set_basic_audio(struct hdmi_info *hdmi) -{ - int ret; - struct i2c_client *client = hdmi->client; - HDMI_DBG("%s\n", __func__); - - ret = hdmi_write_byte(client, 0x26, 0x91); - ret = hdmi_write_byte(client, 0x25, 0x03); - ret = hdmi_write_byte(client, 0x27, 0x59); - ret = hdmi_write_byte(client, 0x28, 0x00); - ret = hdmi_write_byte(client, 0x1f, 0x80); - ret = hdmi_write_byte(client, 0x20, 0x90); - ret = hdmi_write_byte(client, 0x21, 0x00); - //ret = hdmi_write_byte(client, 0x24, 0x00);//0x00 for 44.1k - ret = hdmi_write_byte(client, 0x24, 0x02);//0x02 for 48k - ret = hdmi_write_byte(client, 0x25, 0x00); - ret = hdmi_write_byte(client, 0xbc, 0x02); - ret = hdmi_write_byte(client, 0xbd, 0x24); - ret = hdmi_write_byte(client, 0xbe, 0x92); - ret = hdmi_write_byte(client, 0xbc, 0x02); - ret = hdmi_write_byte(client, 0xbd, 0x2f); - ret = hdmi_write_byte(client, 0xbe, 0); - ret = hdmi_write_byte(client, 0x26, 0x81); - - ret = i2c_smbus_write_i2c_block_data(client, HDMI_AUDIO_INFO_FRAME, - 15, audio_info_frame); -} - -/* simplifier version of ChangeVideoMode() */ -u8 avc_change_video_mode(struct hdmi_info *hdmi, int *resolution) -{ - HDMI_DBG("%s\n", __func__); - - hdcp_off(hdmi); - DisableTMDS(hdmi); - /* allow control InfoFrames to pass through to the sink device. */ - mdelay(128); - - // FIXME: video mode - avc_init_video(hdmi, vid_mode, 0, 0); - - hdmi_write_byte(hdmi->client, TPI_PIX_REPETITION, 0x60); - hdmi_write_byte(hdmi->client, TPI_INPUT_FORMAT, 0); - - if (edid_check_sink_type(hdmi)) - ReadSetWriteTPI(hdmi, 0x1a, 0x01); - else - ReadSetWriteTPI(hdmi, 0x1a, 0x00); - - /* FIXME: 720p/480p ?*/ - hdmi_write_byte(hdmi->client, TPI_OUTPUT_FORMAT, 0); - - /* set 0x60[7] = 0 for External Sync */ - ReadClearWriteTPI(hdmi, TPI_SYNC_GEN_CTRL, 0x80); - /* clear 0x63[6] = 0 to disable internal DE */ - ReadClearWriteTPI(hdmi, 0x63, 1 << 6); - - /* InfoFrames - only if output mode is HDMI */ - if (edid_check_sink_type(hdmi)) - avc_send_avi_info_frames(hdmi); - - /* SETTING UP AVI InfoFrames CLEARS 0x63 and 0x60[5] */ - hdmi_write_byte(hdmi->client, TPI_SYNC_GEN_CTRL, 1 << 2); - /* SETTING UP AVI InfoFrames CLEARS 0x63 */ - hdmi_write_byte(hdmi->client, 0x63, 0); - - /* YC Input Mode Select */ - hdmi_write_byte(hdmi->client, 0x0b, 0); // 0x0b - EnableTMDS(hdmi); - - return VIDEO_MODE_SET_OK; -} diff --git a/drivers/video/msm/hdmi/silicon-image/debug-sil902x.c b/drivers/video/msm/hdmi/silicon-image/debug-sil902x.c deleted file mode 100644 index 1c61b305..00000000 --- a/drivers/video/msm/hdmi/silicon-image/debug-sil902x.c +++ /dev/null @@ -1,109 +0,0 @@ -#include -#include - -#include -#include - -#include "../include/fb-hdmi.h" -#include "../include/sil902x.h" - -//#define HDMI_DEBUGFS - -#if defined(HDMI_DEBUGFS) -static spinlock_t hdmi_dbgfs_lock; -ssize_t hdmi_dbgfs_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t hdmi_dbgfs_read(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) -{ - static char line[80], buffer[80*8*4]; - static char hextab[] = "0123456789abcdefg"; - int i, j, n = 0, v, len, offset, line_size; - unsigned long irq_flags; - struct hdmi_info *hdmi = (struct hdmi_info*)filp->private_data; - - len = ((int)hdmi->edid_buf[0x7e]+1) * 128; - spin_lock_irqsave(&hdmi_dbgfs_lock, irq_flags); - memset(line, ' ', 79); - line[79] = '\0'; - offset = strlen("0000 | "); - line_size = offset + 3 * 16 + 1; - - for (i = 0; i < len / 16 ; i++) { - scnprintf(line, offset + 1, "%04x | ", (i << 4)); - for (j = 0; j < 16 ; j++) { - v = hdmi->edid_buf[i * 16 + j]; - line[offset + j * 3] = hextab[v / 16]; - line[offset + j * 3 + 1] = hextab[v % 16]; - } - line[line_size - 1] = '\n'; - strncpy(buffer + i * line_size, line, line_size); - n += line_size; - } - spin_unlock_irqrestore(&hdmi_dbgfs_lock, irq_flags); - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -#if 0 -static ssize_t hdmi_dbgfs_write(struct file *filp, const char __user *buf, - size_t count, loff_t *ppos) -{ - unsigned long v; - unsigned long irq_flags; - char buff[80]; - struct tv_reg_data *trd = (struct tv_reg_data *)filp->private_data; - - if (count >= sizeof(buff)) - return -EINVAL; - if (copy_from_user(&buff, buf, 80)) - return -EFAULT; - buff[count] = 0; - -#if 0 - spin_lock_irqsave(&hdmi_dbgfs_lock, irq_flags); - strict_strtoul(buff, 16, &v); - buff[strlen(buff)]=0; - writel(v, tvenc_base+trd->offset); - spin_unlock_irqrestore(&hdmi_dbgfs_lock, irq_flags); -#endif - - return count; -} -#endif - -static struct file_operations hdmi_fops[] = { - { - .open = hdmi_dbgfs_open, - .read = hdmi_dbgfs_read, - } -}; - -int hdmi_debugfs_init(struct hdmi_info *hdmi) -{ - HDMI_DBG("%s\n", __func__); - spin_lock_init(&hdmi_dbgfs_lock); - hdmi->debug_dir = debugfs_create_dir(HDMI_DEBUGFS_ROOT, 0); - if (IS_ERR(hdmi->debug_dir)) - return PTR_ERR(hdmi->debug_dir); - - // FIXME: error handling - debugfs_create_file("dummy", 0644, hdmi->debug_dir, hdmi, - &hdmi_fops[0]); - edid_debugfs_init(hdmi); - tpi_debugfs_init(hdmi); - hdcp_debugfs_init(hdmi); -/* - int ret; - if (!ret) { - pr_err("%s: failure on debugfs_create_file()\n", __func__); - return -1; - } -*/ - - return 0; -} -#endif diff --git a/drivers/video/msm/hdmi/silicon-image/hdcp.c b/drivers/video/msm/hdmi/silicon-image/hdcp.c deleted file mode 100644 index 474a84c5..00000000 --- a/drivers/video/msm/hdmi/silicon-image/hdcp.c +++ /dev/null @@ -1,354 +0,0 @@ -#include -#include -#include -#include - -#include "../include/fb-hdmi.h" -#include "../include/sil902x.h" -#include "../include/tpi.h" - -#if 1 -#define HDCP_DBG(fmt, arg...) printk( "[hdmi/hdcp]%s: " fmt, __func__, ##arg) -#else -#define HDCP_DBG(fmt...) do {} while (0) -#endif - -#define hdcp_err(fmt, arg...) pr_err( "[hdmi/hdcp]%s: " fmt, __func__, ##arg) - -//#define HDCP_DEBUG /* Remove this definition when releasing!!! */ -#if defined(HDCP_DEBUG) -#define HDCP_OVERWRITE_CONTROL 0x1 -#define HDCP_SUPPORT 0x2 -#define HDCP_AVALABLE 0x4 -static int hdcp_control = 0x7; -module_param_named(hdcp_control, hdcp_control, int, - S_IRUGO | S_IWUSR | S_IWGRP); -#endif - -bool HDCP_TxSupports; -bool HDCP_Started; -u8 HDCP_LinkProtectionLevel; - -////////////////////////////////////////////////////////////////////////////// -// FUNCTION : IsHDCP_Supported() -// PURPOSE : Check Tx revision number to find if this Tx supports HDCP -// by reading the HDCP revision number from TPI register 0x30. -// RETURNS : true if Tx supports HDCP. false if not. -////////////////////////////////////////////////////////////////////////////// -bool hdcp_check_support(struct hdmi_info *hdmi) -{ - u8 HDCP_Rev; - bool HDCP_Supported; - - HDCP_Supported = true; - /* Check Device ID */ - HDCP_Rev = hdmi_read(hdmi->client, TPI_HDCP_REVISION_DATA_REG); - if (HDCP_Rev != - (HDCP_MAJOR_REVISION_VALUE | HDCP_MINOR_REVISION_VALUE)) - HDCP_Supported = false; - - HDCP_DBG("ret=%d\n", HDCP_Supported); - return HDCP_Supported; -} - -////////////////////////////////////////////////////////////////////////////// -// FUNCTION : AreAKSV_OK() -// PURPOSE : Check if AKSVs contain 20 '0' and 20 '1' -// INPUT PARAMS : None -// OUTPUT PARAMS : None -// GLOBALS USED : TBD -// RETURNS : true if 20 zeros and 20 ones found in AKSV. false OTHERWISE -////////////////////////////////////////////////////////////////////////////// -static bool hdcp_check_aksv(struct hdmi_info *hdmi) -{ - int ret; - u8 B_Data[AKSV_SIZE]; - u8 i, j, NumOfOnes = 0; - - memset(B_Data, 0, AKSV_SIZE); -#if 0 - ReadBlockTPI(hdmi, TPI_AKSV_1_REG, AKSV_SIZE, B_Data); -#else - for (i = 0; i < 5; i++) { - B_Data[i] = hdmi_read(hdmi->client, TPI_AKSV_1_REG+i); - } -#endif - HDCP_DBG(" askv={%02x, %02x, %02x, %02x, %02x}\n", - B_Data[0], B_Data[1], B_Data[2], B_Data[3], B_Data[4]); - for (i=0; i < AKSV_SIZE; i++) - for (j=0; j < BYTE_SIZE; j++) { - if (B_Data[i] & 0x01) - NumOfOnes++; - B_Data[i] >>= 1; - } - if (NumOfOnes != NUM_OF_ONES_IN_KSV) - ret = false; - else ret = true; - - HDCP_DBG(":ret=%s\n", ret ? "true" : "false"); - - return true; -} - -////////////////////////////////////////////////////////////////////////////// -// FUNCTION : HDCP_On() -// PURPOSE : Switch hdcp on. -// INPUT PARAMS : None -// OUTPUT PARAMS: None -// GLOBALS USED : HDCP_Started set to true -// RETURNS : None -////////////////////////////////////////////////////////////////////////////// -//void hdcp_on(struct hdmi_info *hdmi) -void hdcp_on(struct hdmi_info *hdmi, const char *caller) -{ - HDCP_DBG(", caller=%s\n", caller); - hdmi_write_byte(hdmi->client, TPI_HDCP_CONTROL_DATA_REG, PROTECTION_LEVEL_MAX); - HDCP_Started = true; -} - -////////////////////////////////////////////////////////////////////////////// -// FUNCTION : HDCP_Off() -// PURPOSE : Switch hdcp off. -// GLOBALS USED : HDCP_Started set to false -// RETURNS : None -////////////////////////////////////////////////////////////////////////////// -void hdcp_off(struct hdmi_info *hdmi) -{ - HDCP_DBG("\n"); - - SetInputColorSpace(hdmi, INPUT_COLOR_SPACE_BLACK_MODE); - SetAudioMute(hdmi, AUDIO_MUTE_MUTED); - hdmi_write_byte(hdmi->client, TPI_HDCP_CONTROL_DATA_REG, PROTECTION_LEVEL_MIN); - HDCP_Started = false; - HDCP_LinkProtectionLevel = EXTENDED_LINK_PROTECTION_NONE | LOCAL_LINK_PROTECTION_NONE; -} - -void hdcp_init(struct hdmi_info *hdmi) -{ - HDCP_DBG("\n"); - - HDCP_TxSupports = false; - HDCP_Started = false; - HDCP_LinkProtectionLevel = EXTENDED_LINK_PROTECTION_NONE | LOCAL_LINK_PROTECTION_NONE; - - /* TX-related... need only be done once. */ - if (!hdcp_check_support(hdmi)) { - hdcp_err("TX does not support HDCP\n"); - return; - } - if (!hdcp_check_aksv(hdmi)) { - hdcp_err("Illegal AKSV\n"); - return; - } - HDCP_TxSupports = true; -} - -void hdcp_restart(struct hdmi_info *hdmi) -{ - HDCP_DBG("\n"); - DisableTMDS(hdmi); - hdcp_off(hdmi); - EnableTMDS(hdmi); -} - -void hdcp_check_status(struct hdmi_info *hdmi, u8 InterruptStatusImage) -{ - u8 QueryData, LinkStatus, RegImage, NewLinkProtectionLevel; - - if (HDCP_TxSupports == false) - return; - - if ((HDCP_LinkProtectionLevel == - (EXTENDED_LINK_PROTECTION_NONE | LOCAL_LINK_PROTECTION_NONE)) && - (HDCP_Started == false)) { - QueryData = hdmi_read(hdmi->client, TPI_HDCP_QUERY_DATA_REG); - /* Is HDCP avaialable */ - if (QueryData & PROTECTION_TYPE_MASK) { - hdcp_on(hdmi, __func__); - } - } - /* Check if Link Status has changed: */ - if (InterruptStatusImage & SECURITY_CHANGE_EVENT) { - HDCP_DBG("SECURITY_CHANGE_EVENT\n"); - LinkStatus = hdmi_read(hdmi->client, TPI_HDCP_QUERY_DATA_REG); - LinkStatus &= LINK_STATUS_MASK; - tpi_clear_interrupt(hdmi, SECURITY_CHANGE_EVENT); - switch (LinkStatus) { - case LINK_STATUS_NORMAL: - HDCP_DBG("Link = Normal\n"); - break; - case LINK_STATUS_LINK_LOST: - HDCP_DBG("Link = Lost\n"); - hdcp_restart(hdmi); - break; - case LINK_STATUS_RENEGOTIATION_REQ: - HDCP_DBG("Link = Renegotiation Required\n"); - hdcp_off(hdmi); - hdcp_on(hdmi, __func__); - break; - case LINK_STATUS_LINK_SUSPENDED: - HDCP_DBG("Link = Suspended\n"); - hdcp_on(hdmi, __func__); - break; - } - } - /* Check if HDCP state has changed: */ - if (InterruptStatusImage & HDCP_CHANGE_EVENT) { - HDCP_DBG("HDCP_CHANGE_EVENT\n"); - RegImage = hdmi_read(hdmi->client, TPI_HDCP_QUERY_DATA_REG); - NewLinkProtectionLevel = RegImage & - (EXTENDED_LINK_PROTECTION_MASK | LOCAL_LINK_PROTECTION_MASK); - if (NewLinkProtectionLevel != HDCP_LinkProtectionLevel) { - HDCP_LinkProtectionLevel = NewLinkProtectionLevel; - switch (HDCP_LinkProtectionLevel) { - case (EXTENDED_LINK_PROTECTION_NONE | LOCAL_LINK_PROTECTION_NONE): - HDCP_DBG("Protection = None\n"); - hdcp_restart(hdmi); - break; - case LOCAL_LINK_PROTECTION_SECURE: - SetAudioMute(hdmi, AUDIO_MUTE_NORMAL); - //SetInputColorSpace (hdmi, INPUT_COLOR_SPACE_YCBCR422); - SetInputColorSpace (hdmi, INPUT_COLOR_SPACE_RGB); - HDCP_DBG("Protection = Local, Video Unmuted\n"); - break; - case (EXTENDED_LINK_PROTECTION_SECURE | LOCAL_LINK_PROTECTION_SECURE): - HDCP_DBG("Protection = Extended\n"); - break; - default: - HDCP_DBG("Protection = Extended but not Local?\n"); - hdcp_restart(hdmi); - break; - } - } - tpi_clear_interrupt(hdmi, HDCP_CHANGE_EVENT); - } -} - -/*----------------------------------------------------------------------------*/ -#if defined(HDMI_DEBUGFS) -static ssize_t hdcp_supported_read(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) -{ - int n=0; - char buffer[80]; - //struct hdmi_info *hdmi = (struct hdmi_info*)filp->private_data; - - HDMI_DBG("%s\n", __func__); - //n = scnprintf(buffer, 80, "%d\n", is_hdcp_supported(hdmi)); - n++; - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static ssize_t hdcp_available_read(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) -{ - int n=0; - char buffer[80]; - //struct hdmi_info *hdmi = (struct hdmi_info*)filp->private_data; - - HDMI_DBG("%s\n", __func__); - //n = scnprintf(buffer, 80, "%d\n", is_hdcp_available(hdmi)); - n++; - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static ssize_t hdcp_on_read(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) -{ - struct hdmi_info *hdmi = (struct hdmi_info*)filp->private_data; - hdcp_on(hdmi, __func__); - return 0; -} - -static ssize_t hdcp_off_read(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) -{ - struct hdmi_info *hdmi = (struct hdmi_info*)filp->private_data; - hdcp_off(hdmi); - return 0; -} - -static ssize_t hdcp_restart_read(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) -{ - struct hdmi_info *hdmi = (struct hdmi_info*)filp->private_data; - hdcp_restart(hdmi); - return 0; -} - -static ssize_t hdcp_handle_read(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) -{ - //struct hdmi_info *hdmi = (struct hdmi_info*)filp->private_data; - //handle_hdcp(hdmi); - return 0; -} - -static ssize_t hdcp_poll_read(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) -{ - //struct hdmi_info *hdmi = (struct hdmi_info*)filp->private_data; - //hdcp_poll(hdmi); - return 0; -} - -static ssize_t hdcp_aksv_read(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) -{ - struct hdmi_info *hdmi = (struct hdmi_info*)filp->private_data; - hdcp_check_aksv(hdmi); - return 0; -} - -static ssize_t hdcp_bksv_read(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) -{ - //struct hdmi_info *hdmi = (struct hdmi_info*)filp->private_data; - //hdcp_check_bksv(hdmi); - return 0; -} - -static struct file_operations hdcp_debugfs_fops[] = { - { .open = hdmi_dbgfs_open, .read = hdcp_supported_read, }, - { .open = hdmi_dbgfs_open, .read = hdcp_available_read, }, - { .open = hdmi_dbgfs_open, .read = hdcp_on_read, }, - { .open = hdmi_dbgfs_open, .read = hdcp_off_read, }, - { .open = hdmi_dbgfs_open, .read = hdcp_restart_read, }, - { .open = hdmi_dbgfs_open, .read = hdcp_poll_read, }, - { .open = hdmi_dbgfs_open, .read = hdcp_aksv_read, }, - { .open = hdmi_dbgfs_open, .read = hdcp_bksv_read, }, -}; - -// mutex ? -int hdcp_debugfs_init(struct hdmi_info *hdmi) -{ - struct dentry *hdcp_dent; - - hdcp_dent = debugfs_create_dir("hdcp", hdmi->debug_dir); - if (IS_ERR(hdcp_dent)) - return PTR_ERR(hdcp_dent); - - //FIXME: error handling - debugfs_create_file("supported", 0444, hdcp_dent, hdmi, - &hdcp_debugfs_fops[0]); - debugfs_create_file("available", 0444, hdcp_dent, hdmi, - &hdcp_debugfs_fops[1]); - debugfs_create_file("on", 0444, hdcp_dent, hdmi, - &hdcp_debugfs_fops[2]); - debugfs_create_file("off", 0444, hdcp_dent, hdmi, - &hdcp_debugfs_fops[3]); - debugfs_create_file("restart", 0444, hdcp_dent, hdmi, - &hdcp_debugfs_fops[4]); - debugfs_create_file("poll", 0444, hdcp_dent, hdmi, - &hdcp_debugfs_fops[5]); - debugfs_create_file("aksv", 0444, hdcp_dent, hdmi, - &hdcp_debugfs_fops[6]); - debugfs_create_file("bksv", 0444, hdcp_dent, hdmi, - &hdcp_debugfs_fops[7]); - - return 0; -} -#endif - diff --git a/drivers/video/msm/hdmi/silicon-image/tpi.c b/drivers/video/msm/hdmi/silicon-image/tpi.c deleted file mode 100644 index c8d3cf3f..00000000 --- a/drivers/video/msm/hdmi/silicon-image/tpi.c +++ /dev/null @@ -1,960 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -// FIXME: remove this if unnecessary in the future -#ifdef CONFIG_HTC_HEADSET_MGR -#include -#endif - -#if 1 -#define HDMI_DBG(s...) printk("[hdmi/tpi]" s) -#else -#define HDMI_DBG(s...) do {} while (0) -#endif - -#include "../include/fb-hdmi.h" -#include "../include/sil902x.h" -#include "../include/tpi.h" - -#define NEW_INTEGRATE -#define DBG_POLLING 0x1 -static int debug_mask; -module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); - -#define DLOG(mask, fmt, args...) \ -do { \ - if (debug_mask & mask) \ - printk(KERN_INFO "[hdmi/sil]: "fmt, ##args); \ -} while (0) - -#define X1 0x01 -#define AFTER_INIT 1 - -void HotPlugService (struct hdmi_info *hdmi); -// FIXME: should be decide by detection -static bool dsRxPoweredUp; -static bool edidDataValid; -static bool tmdsPoweredUp; -u8 pvid_mode, vid_mode = 16; -u8 systemInitialized; - -void tpi_clear_interrupt(struct hdmi_info *hdmi, u8 pattern) -{ - /* write "1" to clear interrupt bit, and 0 won't effect origin value. */ - hdmi_write_byte(hdmi->client, TPI_INTERRUPT_STATUS_REG, pattern); -} - -////////////////////////////////////////////////////////////////////////////// -// FUNCTION : EnableInterrupts() -// PURPOSE : Enable the interrupts specified in the input parameter -// INPUT PARAMS : A bit pattern with "1" for each interrupt that needs to be -// set in the Interrupt Enable Register (TPI offset 0x3C) -// OUTPUT PARAMS : void -// GLOBALS USED : None -// RETURNS : TRUE -////////////////////////////////////////////////////////////////////////////// -bool tpi_enable_interrupts(struct hdmi_info *hdmi, u8 Interrupt_Pattern) -{ - HDMI_DBG("%s, reg=%02x, pat=%02x\n", __func__, TPI_INTERRUPT_EN, Interrupt_Pattern); - ReadSetWriteTPI(hdmi, TPI_INTERRUPT_EN, Interrupt_Pattern); - return true; -} - -static void tpi_disable_interrupts(struct hdmi_info *hdmi, u8 pattern) -{ -/* - HDMI_DBG("%s, reg=%02x, pat=%02x\n", __func__, - TPI_INTERRUPT_EN, pattern); -*/ - ReadClearWriteTPI(hdmi, TPI_INTERRUPT_EN, pattern); -} - -static void tpi_clear_pending_event(struct hdmi_info *hdmi) -{ - int retry = 100; - - if (hdmi->sleeping == SLEEP) return; - while (retry--) { - hdmi_write_byte(hdmi->client, 0x3c, 1); - hdmi_write_byte(hdmi->client, 0x3d, 1); - if (hdmi_read(hdmi->client, 0x3d) & 0x01) - msleep(1); - else - break; - } - if (retry < 19) HDMI_DBG("%s: retry=%d\n", __func__, 19 - retry); -} - -////////////////////////////////////////////////////////////////////////////// -// FUNCTION : ReadBackDoorRegister() -// PURPOSE : Read a 922x register value from a backdoor register -// Write: -// 1. 0xBC => Internal page num -// 2. 0xBD => Backdoor register offset -// Read: -// 3. 0xBE => Returns the backdoor register value -// INPUT PARAMS : Internal page number, backdoor register offset, pointer to -// buffer to store read value -// OUTPUT PARAMS: Buffer that stores the read value -// RETURNS : TRUE -// NOTE : This workaround is needed for the 9220/2 only. -////////////////////////////////////////////////////////////////////////////// -int tpi_read_backdoor_register(struct hdmi_info *hdmi, u8 PageNum, u8 RegOffset) -{ - // FIXME: error handling - struct i2c_client *client = hdmi->client; - - /* Internal page */ - hdmi_write_byte(client, TPI_INTERNAL_PAGE_REG, PageNum); - /* Indexed register */ - hdmi_write_byte(client, TPI_REGISTER_OFFSET_REG, RegOffset); - /* Read value into buffer */ - return hdmi_read(client, TPI_REGISTER_VALUE_REG); -} - -void tpi_write_backdoor_register(struct hdmi_info *hdmi, u8 PageNum, u8 RegOffset, u8 RegValue) { - /* Internal page */ - hdmi_write_byte(hdmi->client, TPI_INTERNAL_PAGE_REG, PageNum); - /* Indexed register */ - hdmi_write_byte(hdmi->client, TPI_REGISTER_OFFSET_REG, RegOffset); - /* Read value into buffer */ - hdmi_write_byte(hdmi->client, TPI_REGISTER_VALUE_REG, RegValue); -} - -#define TPI_INTERNAL_PAGE_REG 0xBC -#define TPI_INDEXED_OFFSET_REG 0xBD -#define TPI_INDEXED_VALUE_REG 0xBE -#define INDEXED_PAGE_0 0x01 -#define INDEXED_PAGE_1 0x02 -#define INDEXED_PAGE_2 0x03 - -void ReadModifyWriteIndexedRegister(struct hdmi_info *hdmi, u8 PageNum, u8 RegOffset, u8 Mask, u8 Value) -{ - u8 Tmp; - - hdmi_write_byte(hdmi->client, TPI_INTERNAL_PAGE_REG, PageNum); - hdmi_write_byte(hdmi->client, TPI_INDEXED_OFFSET_REG, RegOffset); - Tmp = hdmi_read(hdmi->client, TPI_INDEXED_VALUE_REG); - - Tmp &= ~Mask; - Tmp |= (Value & Mask); - - hdmi_write_byte(hdmi->client, TPI_INDEXED_VALUE_REG, Tmp); -} - -void ReadSetWriteTPI(struct hdmi_info *hdmi, u8 Offset, u8 Pattern) -{ - u8 Tmp; - struct i2c_client *client = hdmi->client; - - Tmp = hdmi_read(client, Offset); - Tmp |= Pattern; - hdmi_write_byte(client, Offset, Tmp); -} - -int tpi_set_bit(struct hdmi_info *hdmi, u8 reg, u8 pattern) -{ - return hdmi_write_byte(hdmi->client, reg, - hdmi_read(hdmi->client, reg) | pattern); -} -//// -void ReadModifyWriteTPI(struct hdmi_info *hdmi, u8 Offset, u8 Mask, u8 Value) -{ - u8 Tmp; - struct i2c_client *client = hdmi->client; - - Tmp = hdmi_read(client, Offset); - Tmp &= ~Mask; - Tmp |= (Value & Mask); - hdmi_write_byte(client, Offset, Tmp); -} -//// -void ReadClearWriteTPI(struct hdmi_info *hdmi, u8 Offset, u8 Pattern) -{ - u8 Tmp; - - Tmp = hdmi_read(hdmi->client, Offset); - Tmp &= ~Pattern; - hdmi_write_byte(hdmi->client, Offset, Tmp); -} -void tpi_clear_bit(struct hdmi_info *hdmi, u8 reg, u8 pattern) -{ - hdmi_write_byte(hdmi->client, reg, - hdmi_read(hdmi->client, reg) & pattern); -} -//// - -/* Caller: ChangeVideoMode(), HDCP_Poll(), HotPlugServiceLoop(), RestartHDCP() - */ - -void EnableTMDS(struct hdmi_info *hdmi) -{ - u8 val; -#if 1 - /* 0x1A[4] = 0 */ - ReadClearWriteTPI(hdmi, TPI_SYSTEM_CONTROL, BIT_TMDS_OUTPUT); - - if (edid_check_sink_type(hdmi)) - hdmi_write_byte(hdmi->client, 0x26, - hdmi_read(hdmi->client, 0x26) & ~0x10); - -#else - struct i2c_client *client = hdmi->i2c_client; - - val = hdmi_read(client, TPI_SYSTEM_CONTROL); - hdmi_write_byte(client, TPI_SYSTEM_CONTROL, val & ~BIT_TMDS_OUTPUT); - HDMI_DBG("%s, reg 0x1a: %02x->%02x\n", __func__, - val, val & ~BIT_TMDS_OUTPUT); -#endif - -} - -/* Caller: ChangeVideoMode(), HDCP_Poll(), TPI_Poll(), RestartHDCP(), - * OnHdmiCableDisconnected() - */ - -void DisableTMDS(struct hdmi_info *hdmi) -{ - /* 0x1A[4] = 1 */ - //ReadClearWriteTPI(hdmi, TPI_SYSTEM_CONTROL, BIT_TMDS_OUTPUT); - ReadSetWriteTPI(hdmi, TPI_SYSTEM_CONTROL, BIT_TMDS_OUTPUT); -} -static void OnDownstreamRxPoweredDown(struct hdmi_info *hdmi) -{ - HDMI_DBG("%s\n", __func__); - dsRxPoweredUp = false; - hdcp_off(hdmi); -} - -static void OnDownstreamRxPoweredUp(struct hdmi_info *hdmi) -{ - HDMI_DBG("%s\n", __func__); - dsRxPoweredUp = true; - HotPlugService(hdmi); -#ifdef CONFIG_HTC_HEADSET_MGR - /* send cable in event */ - switch_send_event(BIT_HDMI_CABLE, 1); - HDMI_DBG("Cable inserted.\n"); -#endif - pvid_mode = vid_mode; - hdmi_active9022_dup(hdmi->client); -} - -bool GetDDC_Access(struct hdmi_info *hdmi, u8* SysCtrlRegVal) -{ - u8 sysCtrl, TPI_ControlImage, DDCReqTimeout = T_DDC_ACCESS; - - HDMI_DBG("%s\n", __func__); - /* Read and store original value. Will be passed into ReleaseDDC() */ - sysCtrl = hdmi_read(hdmi->client, TPI_SYSTEM_CONTROL); - *SysCtrlRegVal = sysCtrl; - - sysCtrl |= BIT_DDC_BUS_REQ; - hdmi_write_byte(hdmi->client, TPI_SYSTEM_CONTROL, sysCtrl); - - /* Loop till 0x1A[1] reads "1" */ - while (DDCReqTimeout--) { - TPI_ControlImage = hdmi_read(hdmi->client, TPI_SYSTEM_CONTROL); - - /* When 0x1A[1] reads "1" */ - if (TPI_ControlImage & BIT_DDC_BUS_GRANT) { - sysCtrl |= BIT_DDC_BUS_GRANT; - /* lock host DDC bus access (0x1A[2:1] = 11) */ - hdmi_write_byte(hdmi->client, TPI_SYSTEM_CONTROL, sysCtrl); - return true; - } - /* 0x1A[2] = "1" - Requst the DDC bus */ - hdmi_write_byte(hdmi->client, TPI_SYSTEM_CONTROL, sysCtrl); - mdelay(200); - } - - /* Failure... restore original value. */ - hdmi_write_byte(hdmi->client, TPI_SYSTEM_CONTROL, sysCtrl); - return false; -} - -bool ReleaseDDC(struct hdmi_info *hdmi, u8 SysCtrlRegVal) -{ - u8 DDCReqTimeout = T_DDC_ACCESS, TPI_ControlImage; - - HDMI_DBG("%s\n", __func__); - /* Just to be sure bits [2:1] are 0 before it is written */ - SysCtrlRegVal &= ~(0x6); - /* Loop till 0x1A[1] reads "0" */ - while (DDCReqTimeout--) { - /* Cannot use ReadClearWriteTPI() here. A read of - * TPI_SYSTEM_CONTROL is invalid while DDC is granted. - * Doing so will return 0xFF, and cause an invalid value to be - * written back. - */ - /* 0x1A[2:1] = "0" - release the DDC bus */ - //ReadClearWriteTPI(TPI_SYSTEM_CONTROL,BITS_2_1); - - hdmi_write_byte(hdmi->client, TPI_SYSTEM_CONTROL, SysCtrlRegVal); - TPI_ControlImage = hdmi_read(hdmi->client, TPI_SYSTEM_CONTROL); - /* When 0x1A[2:1] read "0" */ - if (!(TPI_ControlImage & 0x6)) - return true; - } - - /* Failed to release DDC bus control */ - return false; -} - -int tpi_read_edid(struct hdmi_info *hdmi) -{ - u8 SysCtrlReg; - int ret, edid_blocks = 0; - struct i2c_msg msg; - u8 i2c_buff[2]; - u8 pbuf[] = {1, 0, 1, 128} ; - - struct i2c_msg paging_msg[] = { - { - .addr = 0x30, .flags = 0, .len = 1, .buf = &pbuf[0], - }, - { - .addr = 0x50, .flags = 0, .len = 1, .buf = &pbuf[1], - }, - { //Block-2 - .addr = 0x50, .flags = I2C_M_RD, .len = 128, .buf = &hdmi->edid_buf[256], - }, - { - .addr = 0x30, .flags = 0, .len = 1, .buf = &pbuf[2], - }, - { - .addr = 0x50, .flags = 0, .len = 1, .buf = &pbuf[3], - }, - { //Block-3 - .addr = 0x50, .flags = I2C_M_RD, .len = 128, .buf = &hdmi->edid_buf[384], - }, - }; - - HDMI_DBG("%s\n", __func__); -#if 0 - DisableTMDS(hdmi); -#else - u8 val; - val = hdmi_read(hdmi->client, TPI_SYSTEM_CONTROL); - //hdmi_write_byte(hdmi->client, TPI_SYSTEM_CONTROL, val|BIT_4|BIT_6); - hdmi_write_byte(hdmi->client, TPI_SYSTEM_CONTROL, val|BIT_4); -#endif - - if (!GetDDC_Access(hdmi, &SysCtrlReg)) { - pr_err("%s: DDC bus request failed\n", __func__); - return DDC_BUS_REQ_FAILURE; - } - - // Block-0 - memset(hdmi->edid_buf, 0, 512); - - msg.addr = 0x50; - msg.flags = 0; - msg.len = 1; - msg.buf = hdmi->edid_buf; - ret = i2c_transfer(hdmi->client->adapter, &msg, 1); - if (ret < 0) - dev_err(&hdmi->client->dev, "%s: i2c transfer error\n", __func__); - - msg.addr = 0x50; - msg.flags = I2C_M_RD; - msg.len = 128; - msg.buf = hdmi->edid_buf; - ret = i2c_transfer(hdmi->client->adapter, &msg, 1); - if (ret < 0) { - dev_err(&hdmi->client->dev, "%s: i2c transfer error\n", __func__); - goto end_read_edid; - } else { - if (hdmi->edid_buf[0x7e] <= 3) - edid_blocks = hdmi->edid_buf[0x7e] ; - - dev_info(&hdmi->client->dev, "EDID blocks = %d\n", edid_blocks); - - if (edid_blocks == 0 ) { - goto end_read_edid; - } - // Block-1 - msg.addr = 0x50; - msg.flags = 0; - msg.len = 1; - i2c_buff[0] = 128; - msg.buf = i2c_buff; - ret = i2c_transfer(hdmi->client->adapter, &msg, 1); - - msg.addr = 0x50; - msg.flags = I2C_M_RD; - msg.len = 128; - msg.buf = &hdmi->edid_buf[128]; - ret = i2c_transfer(hdmi->client->adapter, &msg, 1); - } - - if (edid_blocks > 1) { - // block 2/3 - i2c_transfer(hdmi->client->adapter, paging_msg, 3); - i2c_transfer(hdmi->client->adapter, &paging_msg[3], 3); - } - -end_read_edid: - if (!ReleaseDDC(hdmi, SysCtrlReg)) { - pr_err("%s: DDC bus release failed\n", __func__); - return DDC_BUS_REQ_FAILURE; - } - - edid_simple_parsing(hdmi); - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// -// FUNCTION : HotPlugService() -// PURPOSE : Implement Hot Plug Service Loop activities -// INPUT PARAMS : None -// OUTPUT PARAMS: void -// GLOBALS USED : LinkProtectionLevel -// RETURNS : An error code that indicates success or cause of failure -////////////////////////////////////////////////////////////////////////////// - -extern bool HDCP_TxSupports; -static bool tmdsPoweredUp; -void HotPlugService (struct hdmi_info *hdmi) -{ - HDMI_DBG("%s\n", __func__); - - mutex_lock(&hdmi->lock); - tpi_disable_interrupts(hdmi, 0xFF); - -/* - // use 1st mode supported by sink - //vid_mode = EDID_Data.VideoDescriptor[0]; - vid_mode = 0; -*/ - avc_init_video(hdmi, vid_mode, X1, AFTER_INIT); - - hdmi_write_byte(hdmi->client, HDMI_POWER, 0); - if (edid_check_sink_type(hdmi)) - avc_send_avi_info_frames(hdmi); - - /* This check needs to be changed to if HDCP is required by the content - once support has been added by RX-side library. */ - if (HDCP_TxSupports == true) { - HDMI_DBG("TMDS -> Enabled\n"); - /* turn on black mode will lost around 3 secs frames thus remove it */ - //SetInputColorSpace(hdmi, INPUT_COLOR_SPACE_BLACK_MODE); -#if 1 - ReadModifyWriteTPI(hdmi, TPI_SYSTEM_CONTROL, - LINK_INTEGRITY_MODE_MASK | TMDS_OUTPUT_CONTROL_MASK, - LINK_INTEGRITY_DYNAMIC | TMDS_OUTPUT_CONTROL_ACTIVE); -#else - ReadModifyWriteTPI(hdmi, TPI_SYSTEM_CONTROL, - LINK_INTEGRITY_MODE_MASK | TMDS_OUTPUT_CONTROL_MASK, - LINK_INTEGRITY_DYNAMIC); -#endif - tmdsPoweredUp = true; - } else { - EnableTMDS(hdmi); - } - - if (edid_check_sink_type(hdmi)) - avc_set_basic_audio(hdmi); - else - SetAudioMute(hdmi, AUDIO_MUTE_MUTED); - - tpi_enable_interrupts(hdmi, HOT_PLUG_EVENT | RX_SENSE_EVENT | - AUDIO_ERROR_EVENT | SECURITY_CHANGE_EVENT | - V_READY_EVENT | HDCP_CHANGE_EVENT); - - //complete(&hdmi->hotplug_completion); - mutex_unlock(&hdmi->lock); -} - -static bool tpi_start(struct hdmi_info *hdmi) -{ - u8 devID = 0x00; - u16 wID = 0x0000; - - hdmi_write_byte(hdmi->client, TPI_ENABLE, 0x00); // Write "0" to 72:C7 to start HW TPI mode - mdelay(100); - - devID = tpi_read_backdoor_register(hdmi, 0x00, 0x03); - wID = devID; - wID <<= 8; - devID = tpi_read_backdoor_register(hdmi, 0x00, 0x02); - wID |= devID; - devID = hdmi_read(hdmi->client, TPI_DEVICE_ID); - HDMI_DBG("%s, ID=%04X\n", __func__, (u32)wID); - - if (devID == SiI_DEVICE_ID) { - return true; - } - - pr_err("%s: Unsupported TX\n", __func__); - return false; -} - -bool tpi_init(struct hdmi_info *hdmi) -{ - tmdsPoweredUp = false; - hdmi->cable_connected = false; - dsRxPoweredUp = false; - edidDataValid = false; - - /* Enable HW TPI mode, check device ID */ - if (tpi_start(hdmi)) { - hdcp_init(hdmi); - return true; - } - return 0; -} - -void SetAudioMute(struct hdmi_info *hdmi, u8 audioMute) -{ - ReadModifyWriteTPI(hdmi, TPI_AUDIO_INTERFACE_REG, AUDIO_MUTE_MASK, audioMute); -} - -void SetInputColorSpace(struct hdmi_info *hdmi, u8 inputColorSpace) -{ - ReadModifyWriteTPI(hdmi, TPI_INPUT_FORMAT_REG, INPUT_COLOR_SPACE_MASK, inputColorSpace); - /* Must be written for previous write to take effect. Just write read value unmodified. */ - ReadModifyWriteTPI(hdmi, TPI_END_RIGHT_BAR_MSB, 0x00, 0x00); -} - -static char edid_hex_buff[2048]; -int lcdc_enable_video(void); -int lcdc_disable_video(void); -void tpi_cable_conn(struct hdmi_info *hdmi) -{ - HDMI_DBG("%s\n", __func__); - - hdmi->cable_connected = true; - tpi_write_backdoor_register(hdmi, INTERNAL_PAGE_0, 0xCE, 0x00); // Clear BStatus - tpi_write_backdoor_register(hdmi, INTERNAL_PAGE_0, 0xCF, 0x00); - -//----------------------------------------------- - hdmi_write_byte(hdmi->client, 0x09, 0x03); - hdmi_write_byte(hdmi->client, 0x19, 0x00); // go to blank mode, avoid screen noise - -/* - HDMI_DBG("solomon: H/V total=%02x, %02x, %02x, %02x\n", - hdmi_read(hdmi->client, 0x6a), - hdmi_read(hdmi->client, 0x6b), - hdmi_read(hdmi->client, 0x6c), - hdmi_read(hdmi->client, 0x6d) - ); -*/ - - lcdc_enable_video(); - msleep(160); -/* - //clk_set_rate(hdmi->ebi1_clk, 120000000); - HDMI_DBG("solomon: H/V total=%02x, %02x, %02x, %02x\n", - hdmi_read(hdmi->client, 0x6a), - hdmi_read(hdmi->client, 0x6b), - hdmi_read(hdmi->client, 0x6c), - hdmi_read(hdmi->client, 0x6d) - ); -*/ - EnableTMDS(hdmi); - -//----------------------------------------------- - - tpi_read_edid(hdmi); - memset(edid_hex_buff, 0, 2048); - edid_dump_hex(hdmi->edid_buf, 256, edid_hex_buff, 2048); - printk("EDID data:\n%s\n=====", edid_hex_buff); - /* select output mode (HDMI/DVI) according to sink capabilty */ - if (edid_check_sink_type(hdmi)) - ReadModifyWriteTPI(hdmi, TPI_SYSTEM_CONTROL, OUTPUT_MODE_MASK, OUTPUT_MODE_HDMI); - else - ReadModifyWriteTPI(hdmi, TPI_SYSTEM_CONTROL, OUTPUT_MODE_MASK, OUTPUT_MODE_DVI); - - hdmi->first = false; -#if 0 -#ifdef CONFIG_HTC_HEADSET_MGR - /* send cable in event */ - switch_send_event(BIT_HDMI_CABLE, 1); - HDMI_DBG("Cable inserted.\n"); -#endif -#endif -} - -void tpi_cable_disconn(struct hdmi_info *hdmi, bool into_d3) -{ - HDMI_DBG("%s, into_d3=%d\n", __func__, into_d3); - - hdmi->cable_connected = false; - dsRxPoweredUp = false; - edidDataValid = false; - hdcp_off(hdmi); - DisableTMDS(hdmi); -#if 1 - /* wait for debounce */ - msleep(20); - tpi_clear_pending_event(hdmi); -#else - reg = hdmi_read(hdmi->client, 0x3d); - if (!(reg & 0x0c)) - tpi_clear_pending_event(hdmi); -#endif - if (into_d3) { - mutex_lock(&hdmi->lock); - HDMI_DBG("%s, playing=%d\n", __func__, hdmi->user_playing); - if (false == hdmi->user_playing) - lcdc_disable_video(); - clk_set_rate(hdmi->ebi1_clk, 0); - hdmi_standby(hdmi); - hdmi->power(2); - memset(hdmi->edid_buf, 0, 512); - mutex_unlock(&hdmi->lock); - } -#ifdef CONFIG_HTC_HEADSET_MGR - HDMI_DBG("Cable unplugged.\n"); - switch_send_event(BIT_HDMI_CABLE, 0); -#endif -} - -static char *str_debug_interrupt[] = { - "HOT_PLUG_EVENT\t\t\t", - "RECEIVER_SENSE_EVENT\t\t", - "HOT_PLUG_PIN_STATE\t\t", - "RX_SENSE_MASK\t\t\t", - "AUDIO_ERROR_EVENT\t\t", - "HDCP_SECURITY_CHANGE_EVENT\t", - "HDCP_VPRIME_VALUE_READY_EVENT\t", - "HDCP_AUTH_STATUS_CHANGE_EVENT\t", -}; - -void tpi_debug_interrupt(struct hdmi_info *hdmi, u8 old_status, u8 new_status) -{ - int i, diff, on_off; - HDMI_DBG("%s: status changed, %02x to %02x\n", __func__, - old_status, new_status); - for (i = 7; i >= 0; i--) { - diff = (old_status ^ new_status) & (1 << i); - if (!diff) - continue; - on_off = new_status & (1 << i); - HDMI_DBG("%d-%s->%s\n", i, str_debug_interrupt[i], - on_off ? "on" : "off"); - } -} -////////////////////////////////////////////////////////////////////////////// -// FUNCTION : TPI_Poll () -// PURPOSE : Poll Interrupt Status register for new interrupts -// INPUT PARAMS : None -// OUTPUT PARAMS: None -// GLOBALS USED : LinkProtectionLevel -// RETURNS : None -////////////////////////////////////////////////////////////////////////////// -static u8 last_status = 0; -static void tpi_poll(struct hdmi_info *hdmi) -{ - u8 status, orig_status; - int retry = 20; - - mutex_lock(&hdmi->polling_lock); - orig_status = status = hdmi_read(hdmi->client, TPI_INTERRUPT_STATUS_REG); - if (last_status != status) { - tpi_debug_interrupt(hdmi, last_status, status); - } - last_status = status; - DLOG(DBG_POLLING, "%s, INT_STAT=%02x\n", __func__, status); -#if 0 - if (status & HOT_PLUG_EVENT) { -#else - if (hdmi->first || status & HOT_PLUG_EVENT) { - if (hdmi->first) hdmi->first = false; -#endif - // Enable HPD interrupt bit - ReadSetWriteTPI(hdmi, TPI_INTERRUPT_ENABLE_REG, HOT_PLUG_EVENT); - // Repeat this loop while cable is bouncing: - do { - //DLOG(DBG_POLLING, "TPI: Interrupt status image - 2= %02x\n", status); - hdmi_write_byte(hdmi->client, TPI_INTERRUPT_STATUS_REG, HOT_PLUG_EVENT); - // Delay for metastability protection and to help filter out connection bouncing - mdelay(T_HPD_DELAY); - // Read Interrupt status register - status = hdmi_read(hdmi->client, TPI_INTERRUPT_STATUS_REG); - //DLOG(DBG_POLLING, "TPI: Interrupt status image - 3= %02x\n", status); - if (!retry--) { - HDMI_DBG("%s: retry failed\n", __func__); - break; - } - - } while (status & HOT_PLUG_EVENT);// loop as long as HP interrupts recur - DLOG(DBG_POLLING, "int status: %02x, after debouncing: %02x\n", - orig_status, status); - - //DLOG(DBG_POLLING, "TPI->hdmiCableConnected = %d\n", hdmi->cable_connected); - if (((status & HOT_PLUG_STATE) >> 2) != hdmi->cable_connected) { - DLOG(DBG_POLLING, "cable status changed: from %d to %d\n", - hdmi->cable_connected, !!(status & HOT_PLUG_STATE)); - //DLOG(DBG_POLLING, "TPI-> CONDITION\n"); - if (hdmi->cable_connected == true) - tpi_cable_disconn(hdmi, status & 0x8 ? false : true); - else { - tpi_cable_conn(hdmi); - ReadModifyWriteIndexedRegister(hdmi, INDEXED_PAGE_0, 0x0A, 0x08, 0x08); - } - if (hdmi->cable_connected == false) { - mutex_unlock(&hdmi->polling_lock); - return; - } - } else if ( false == hdmi->cable_connected) - /* only occur while booting without cable attached. */ - tpi_cable_disconn(hdmi, true); - } - - // Check rx power - if (((status & RX_SENSE_STATE) >> 3) != dsRxPoweredUp) - { - if (hdmi->cable_connected == true) { - if (dsRxPoweredUp == true) - OnDownstreamRxPoweredDown(hdmi); - else - OnDownstreamRxPoweredUp(hdmi); - } - tpi_clear_interrupt(hdmi, RX_SENSE_EVENT); - } - - // Check if Audio Error event has occurred: - if (status & AUDIO_ERROR_EVENT) - // The hardware handles the event without need for host intervention (PR, p. 31) - tpi_clear_interrupt(hdmi, AUDIO_ERROR_EVENT); - - if (hdmi->video_streaming) { - if ((hdmi->cable_connected == true) && (dsRxPoweredUp == true)) - hdcp_check_status(hdmi, status); - } - mutex_unlock(&hdmi->polling_lock); -} - -static void tpi_work_func(struct work_struct *work) -{ - u8 reg = 0; - struct hdmi_info *hdmi = - container_of(work, struct hdmi_info, polling_work); - - if (hdmi->sleeping == SLEEP) { - mutex_lock(&hdmi->lock); - hdmi->power(3); - hdmi_wakeup(hdmi); - tpi_init(hdmi); - hdcp_off(hdmi); - mutex_unlock(&hdmi->lock); - } - - tpi_poll(hdmi); -#if 1 - mutex_lock(&hdmi->lock); - if (hdmi->sleeping == AWAKE) - reg = hdmi_read(hdmi->client, 0x3d) & 0x0c; - if (hdmi->cable_connected || reg) { - hdmi->polling = true; - mod_timer(&hdmi->timer, jiffies + INTERVAL_HDCP_POLLING); - } else { - enable_irq(hdmi->client->irq); - hdmi->isr_enabled = true; - hdmi->polling = false; - } - mutex_unlock(&hdmi->lock); -#else - if (hdmi->sleeping == AWAKE) { - reg = hdmi_read(hdmi->client, 0x3d); - if (reg & 0x0c) { - hdmi->polling = true; - mod_timer(&hdmi->timer, jiffies + INTERVAL_HDCP_POLLING); - } else { - tpi_clear_pending_event(hdmi); - } - } - - if (hdmi->cable_connected ) { - hdmi->polling = true; - mod_timer(&hdmi->timer, jiffies + INTERVAL_HDCP_POLLING); - } else { - enable_irq(hdmi->client->irq); - hdmi->isr_enabled = true; - hdmi->polling = false; - } -#endif -/* - HDMI_DBG("after polling: reg=%02x, conn=%d, isr=%d, polling=%d\n", - reg, hdmi->cable_connected, hdmi->isr_enabled, hdmi->polling); -*/ -} - -static void tpi_timer_func(unsigned long arg) -{ - struct hdmi_info *hdmi = (struct hdmi_info *) arg; - - schedule_work(&hdmi->polling_work); -} - -int tpi_prepare(struct hdmi_info *hdmi) -{ - HDMI_DBG("%s\n", __func__); - init_timer(&hdmi->timer); - hdmi->timer.data = (unsigned long)hdmi; - hdmi->timer.function = tpi_timer_func; - hdmi->cable_connected = false; - - init_completion(&hdmi->hotplug_completion); - INIT_WORK(&hdmi->polling_work, tpi_work_func); - - return 0; -} - -/*============================================================================*/ -#if defined(HDMI_DEBUGFS) -static ssize_t tpi_dbg_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t tpi_ddc_request_read(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) -{ - //struct hdmi_info *hdmi = (struct hdmi_info*)filp->private_data; - return 0; -} - -static ssize_t tpi_ddc_request_write(struct file *filp, const char __user *buf, - size_t count, loff_t *ppos) -{ - return 0; -} - -static ssize_t tpi_isr_read(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) -{ - int n = 0; - char buffer[4]; - struct hdmi_info *hdmi = (struct hdmi_info*)filp->private_data; - - HDMI_DBG("%s\n", __func__); - n = scnprintf(buffer, 4, "%d\n", hdmi->isr_enabled); - n++; - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static ssize_t tpi_polling_read(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) -{ - int n = 0; - char buffer[4]; - struct hdmi_info *hdmi = (struct hdmi_info*)filp->private_data; - - HDMI_DBG("%s\n", __func__); - n = scnprintf(buffer, 4, "%d\n", hdmi->polling); - n++; - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static ssize_t tpi_int_status_read(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) -{ - int n = 0; - char buffer[8]; - struct hdmi_info *hdmi = (struct hdmi_info*)filp->private_data; - - HDMI_DBG("%s\n", __func__); - n = scnprintf(buffer, 8, "%02x\n", hdmi_read(hdmi->client, 0x3d)); - n++; - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static ssize_t tpi_int_enable_read(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) -{ - int n = 0; - char buffer[8]; - struct hdmi_info *hdmi = (struct hdmi_info*)filp->private_data; - - HDMI_DBG("%s\n", __func__); - n = scnprintf(buffer, 8, "%02x\n", hdmi_read(hdmi->client, 0x3c)); - n++; - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static ssize_t tpi_avc_read(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) -{ - int n = 0; - char buffer[8]; - struct hdmi_info *hdmi = (struct hdmi_info*)filp->private_data; - - HDMI_DBG("%s\n", __func__); -/* - n = scnprintf(buffer, 8, "%02x\n", hdmi_read(hdmi->client, 0x3c)); - n++; - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -*/ - hdmi_active9022(hdmi->client); - return 0; -} - -static struct file_operations tpi_debugfs_fops[] = { - { - .open = tpi_dbg_open, - .read = tpi_ddc_request_read, - .write = tpi_ddc_request_write, - }, - { - .open = tpi_dbg_open, - .read = tpi_isr_read, - }, - { - .open = tpi_dbg_open, - .read = tpi_polling_read, - }, - { - .open = tpi_dbg_open, - .read = tpi_int_status_read, - }, - { - .open = tpi_dbg_open, - .read = tpi_int_enable_read, - }, - { - .open = tpi_dbg_open, - .read = tpi_avc_read, - }, -}; - -int tpi_debugfs_init(struct hdmi_info *hdmi) -{ - struct dentry *tpi_dent; - - tpi_dent = debugfs_create_dir("tpi", hdmi->debug_dir); - if (IS_ERR(tpi_dent)) - return PTR_ERR(tpi_dent); - - //FIXME: error handling - debugfs_create_file("ddc_request", 0644, tpi_dent, hdmi, - &tpi_debugfs_fops[0]); - debugfs_create_file("isr_enabled", 0444, tpi_dent, hdmi, - &tpi_debugfs_fops[1]); - debugfs_create_file("polling", 0444, tpi_dent, hdmi, - &tpi_debugfs_fops[2]); - debugfs_create_file("int_stat", 0444, tpi_dent, hdmi, - &tpi_debugfs_fops[3]); - debugfs_create_file("int_ena", 0444, tpi_dent, hdmi, - &tpi_debugfs_fops[4]); - debugfs_create_file("avc", 0444, tpi_dent, hdmi, - &tpi_debugfs_fops[5]); - - return 0; -} -#endif diff --git a/drivers/video/msm/hdmi/transmitter.c b/drivers/video/msm/hdmi/transmitter.c deleted file mode 100644 index 5b094b82..00000000 --- a/drivers/video/msm/hdmi/transmitter.c +++ /dev/null @@ -1,1019 +0,0 @@ -/* - * Copyright (C) 2009 HTC Corporation. - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "include/fb-hdmi.h" -#include "include/sil902x.h" - -#ifdef CONFIG_HTC_HEADSET_MGR -#include -#endif - -#if 1 -#define HDMI_DBG(s...) printk("[hdmi/tx]" s) -#else -#define HDMI_DBG(s...) do {} while (0) -#endif - -#define HDMI_NAME "SiL902x-hdmi" -//#define HDMI_DEBUGFS - -static struct class *hdmi_class; - -enum { - ESTABLISHED_TIMING_OFFSET = 35, - LONG_DESCR_LEN = 18, - NUM_DETAILED_DESC = 4, - NUM_STANDARD_TIMING = 8, -}; - -#if 1 -int hdmi_read(struct i2c_client *client, u8 cmd) -#else -#define hdmi_read(client, cmd) _hdmi_read(client, cmd, __func__) -int _hdmi_read(struct i2c_client *client, u8 cmd, const char *caller) -#endif -{ - int ret = -EIO, retry = 10; - - while (retry--) { - ret = i2c_smbus_read_byte_data(client, cmd); - if (ret >= 0) - break; - msleep(1); - } -/* - if (retry!=9) - HDMI_DBG("%s, retry=%d, caller=%s\n", __func__, 10-retry, - caller); -*/ - - return ret; -} - -int tpi_readb(struct hdmi_info *hdmi, u8 reg) -{ - int i, ret = -EIO, retrial = 10, timeout = 1; - struct i2c_client *client = hdmi->client; - - for (i = 1 ; i < retrial ; i++) { - ret = i2c_smbus_read_byte_data(client, reg); - if (ret >= 0) - break; - msleep(timeout++); - } - return ret; -} - -int tpi_readb_oneshoot(struct hdmi_info *hdmi, u8 reg) -{ - return i2c_smbus_read_byte_data(hdmi->client, reg); -} - -#if 1 -int hdmi_write_byte(struct i2c_client *client, u8 reg, u8 val) -#else -#define hdmi_write_byte(client, reg, val) \ - _hdmi_write_byte(client, reg, val, __func__) -int _hdmi_write_byte(struct i2c_client *client, u8 reg, u8 val, const char *caller) -#endif -{ - int ret = -EIO, retry = 10; - - while (retry--) { - ret = i2c_smbus_write_byte_data(client, reg, val); - if (ret == 0) - break; - msleep(1); - } -/* - if (retry!=9) HDMI_DBG("%s, retry=%d, caller=%s\n", __func__, - 10 - retry, caller); -*/ - - return ret; -} - -int tpi_writeb(struct hdmi_info *hdmi, u8 reg, u8 val) -{ - int i, ret = -EIO, retrial = 10, timeout = 1; - struct i2c_client *client = hdmi->client; - - for (i = 1 ; i < retrial ; i++) { - ret = i2c_smbus_write_byte_data(client, reg, val); - if (ret == 0) - break; - msleep(timeout); - } - return ret; -} - -int tpi_writeb_oneshot(struct hdmi_info *hdmi, u8 reg, u8 val) -{ - return i2c_smbus_write_byte_data(hdmi->client, reg, val); -} - -int hdmi_enable_int(struct i2c_client *client) -{ - u8 data; - - HDMI_DBG("%s\n", __func__); - data = hdmi_read(client, HDMI_INT_EN); - return hdmi_write_byte(client, HDMI_INT_EN, data | 0x01); -} - -int hdmi_disable_int(struct i2c_client *client) -{ - u8 data; - - HDMI_DBG("%s\n", __func__); - data = hdmi_read(client, HDMI_INT_EN); - return hdmi_write_byte(client, HDMI_INT_EN, data & 0xfe); -} - -/* - * Tx is brought to low-power state, off audio codec. - * i2c alive. Still be able to response to INT. - */ -int hdmi_standby(struct hdmi_info *hdmi) -{ - u8 data; - int ret; - struct i2c_client *client = hdmi->client; - - HDMI_DBG("%s\n", __func__); -#if 0 - /* D2 sleep mode */ - data = hdmi_read(client, HDMI_POWER); - return hdmi_write_byte(client, HDMI_POWER, (data & 0xfc) | 0x02); -#else - if (SLEEP == hdmi->sleeping) - return 0; - /* D3 sleep mode */ - hdmi->sleeping = SLEEP; - hdmi->cable_connected = false; - data = hdmi_write_byte(client, 0x3c, hdmi_read(client, 0x3c) | 1); - data = hdmi_write_byte(client, 0x3c, hdmi_read(client, 0x3c) & ~2); - HDMI_DBG("%s: INT_EN=%02x\n", __func__, hdmi_read(client, 0x3c)); - data = hdmi_read(client, HDMI_POWER); - data |= 4; - ret = hdmi_write_byte(client, HDMI_POWER, data ); - if (ret) - dev_err(&client->dev, - "error on entering D3 sleep mode: into cold mode\n"); -#if 0 - ret = hdmi_write_byte(client, HDMI_POWER, 7); -#else - tpi_writeb_oneshot(hdmi, HDMI_POWER, 7); -#endif -/* - if (ret) - dev_err(&client->dev, - "error on entering D3 sleep mode: set D3 mode\n"); -*/ -#endif - return ret; -} - -int hdmi_wakeup(struct hdmi_info *hdmi) -{ - int err = -EIO; - int ret; - u8 data; - struct i2c_client *client = hdmi->client; - - HDMI_DBG("%s\n", __func__); -#if 0 - data = hdmi_read(client, HDMI_POWER); - err = hdmi_write_byte(client, HDMI_POWER, data & 0xfc); - if (err) - goto exit; -#else - /* Exiting D3 sleep mode */ - ret = hdmi_write_byte(client, 0xc7, 0); - if (ret) - dev_err(&client->dev, - "error on exiting D3 sleep mode: 0xc7=0\n"); - - data = hdmi_read(client, HDMI_POWER); - data = ( data & 0xfc ) ; - ret = hdmi_write_byte(client, HDMI_POWER, data ); - if (ret) - dev_err(&client->dev, - "error on exiting D3 sleep mode: 0x1e=0\n"); - /* Enable insternal TMDS source termination */ - hdmi_write_byte(client, 0xbc, 0x01); - hdmi_write_byte(client, 0xbd, 0x82); - data = hdmi_read(client, 0xbe); - hdmi_write_byte(client, 0xbe, data | 0x01); - - hdmi->sleeping = AWAKE; -#endif - -/* - data = hdmi_read(client, HDMI_SYS_CTL); - dev_info(&client->dev, "%s, HDMI_SYS_CTL=0x%x\n", __func__, data); - err = hdmi_write_byte(client, HDMI_SYS_CTL, 0x01); - if (err) - goto exit; -*/ - return 0; -exit: - dev_err(&client->dev, "%s: fail, err = %d\n", __func__, err); - return err; -} - -static int -hdmi_check_res(struct hdmi_device *hdmi_device, struct fb_var_screeninfo *var) -{ - if (((var->xres == 1280) && (var->yres == 720)) || - ((var->xres == 800) && (var->yres == 600)) || - ((var->xres == 720) && (var->yres == 576)) || - ((var->xres == 720) && (var->yres == 480)) || - ((var->xres == 640) && (var->yres == 480))) { - dev_info(&hdmi_device->dev, "resolution check successfully\n"); - /* check pixel clock also */ - return 0; - } - - return -EINVAL; -} - -static struct msm_lcdc_timing hdmi_lcdc_timing[] = { - [hd_720p] = { - .clk_rate = 74250000, - .hsync_pulse_width = 40, - .hsync_back_porch = 220, - .hsync_front_porch = 110, - .hsync_skew = 0, - .vsync_pulse_width = 5, - .vsync_back_porch = 20, - .vsync_front_porch = 5, - .vsync_act_low = 0, - .hsync_act_low = 0, - .den_act_low = 0, - }, - [svga] = { - .clk_rate = 40000000, - .hsync_pulse_width = 128, - .hsync_back_porch = 88, - .hsync_front_porch = 40, - .hsync_skew = 0, - .vsync_pulse_width = 4, - .vsync_back_porch = 23, - .vsync_front_porch = 1, - .vsync_act_low = 0, - .hsync_act_low = 0, - .den_act_low = 0, - }, - [pal] = { - .clk_rate = 27027000, - .hsync_pulse_width = 64, - .hsync_back_porch = 68, - .hsync_front_porch = 12, - .hsync_skew = 0, - .vsync_pulse_width = 5, - .vsync_back_porch = 39, - .vsync_front_porch = 5, - .vsync_act_low = 1, - .hsync_act_low = 1, - .den_act_low = 0, - }, - [edtv] = { - .clk_rate = 27027000, - .hsync_pulse_width = 62, - .hsync_back_porch = 60, - .hsync_front_porch = 16, - .hsync_skew = 0, - .vsync_pulse_width = 6, - .vsync_back_porch = 30, - .vsync_front_porch = 9, -#if 1 - .vsync_act_low = 1, - .hsync_act_low = 1, -#else - .vsync_act_low = 0, - .hsync_act_low = 0, -#endif - - .den_act_low = 0, - }, - [vga] = { - .clk_rate = 25175000, - .hsync_pulse_width = 96, - .hsync_back_porch = 48, - .hsync_front_porch = 16, - .hsync_skew = 0, - .vsync_pulse_width = 2, - //.vsync_pulse_width = 3, - .vsync_back_porch = 33, - .vsync_front_porch = 10, - .vsync_act_low = 1, - .hsync_act_low = 1, - .den_act_low = 0, - }, -}; - -static struct msm_lcdc_timing * -hdmi_set_res(struct hdmi_device *hdmi_device, struct fb_var_screeninfo *var) -{ - struct hdmi_info *info = container_of(hdmi_device, struct hdmi_info, - hdmi_dev); - - printk(KERN_DEBUG "%s, info->res=%d=(%d x %d)\n", - __func__, info->res, var->xres, var->yres); - if ((var->xres == 1280) && (var->yres == 720)) - info->res = hd_720p; - else if ((var->xres == 800) && (var->yres == 600)) - info->res = svga; - else if ((var->xres == 720) && (var->yres == 576)) - info->res = pal; - else if ((var->xres == 720) && (var->yres == 480)) - info->res = edtv; - else if ((var->xres == 640) && (var->yres == 480)) - info->res = vga; - else - return ERR_PTR(-EINVAL); -/* - if (info->user_playing) - avc_send_avi_info_frames(info); -*/ - return &hdmi_lcdc_timing[info->res]; -} - -static int hdmi_get_cable_state(struct hdmi_device *hdmi_device, int *connect) -{ -#if 0 - struct hdmi_info *info = container_of(hdmi_device, struct hdmi_info, - hdmi_dev); - struct i2c_client *client = info->client; - u8 status; - - *connect = 0; - status = hdmi_read(client, HDMI_INT_STAT); - if (status & HOT_PLUG_STATE) - *connect = 1; -#else - struct hdmi_info *hdmi = - container_of(hdmi_device, struct hdmi_info, hdmi_dev); - *connect = hdmi->cable_connected; -#endif - HDMI_DBG("%s, state=%s\n", __func__, *connect ? "on" : "off" ); - return 0; -} - -static int -hdmi_get_established_timing(struct hdmi_device *hdmi_device, u8 *byte) -{ - struct hdmi_info *info = container_of(hdmi_device, struct hdmi_info, - hdmi_dev); - - HDMI_DBG("%s\n", __func__); - memcpy(byte, &info->edid_buf[ESTABLISHED_TIMING_OFFSET], 3); - return 0; -} - -#if 0 -// FIXME: remove the parameter: data -static u8 hdmi_request_ddc(struct i2c_client *client, int request, u8 data) -{ - int retry = 10; - - HDMI_DBG("%s, request=%d\n", __func__, request); - if (request) { - data = hdmi_read(client, HDMI_SYS_CTL); - hdmi_write_byte(client, HDMI_SYS_CTL, (data | 0x04)); - msleep(1); - hdmi_write_byte(client, HDMI_SYS_CTL, (data | 0x06)); - msleep(1); - } else { - hdmi_write_byte(client, HDMI_SYS_CTL, (data & 0xf9)); - hdmi_write_byte(client, HDMI_SYS_CTL, (data & 0xf9)); - /* make sure bit [2:1] = 00 */ - data = hdmi_read(client, HDMI_SYS_CTL); - while ((data & 0x03) & retry--) - msleep(1); - } - return data; -} - -#else -// FIXME: remove the static varible. if caller need to presev the reg, -// it should use hdmi_read() first. -static u8 hdmi_request_ddc(struct i2c_client *client, int request) -{ - int retry = 10; - static u8 val = 0; - u8 tmp; - - HDMI_DBG("%s, request=%d\n", __func__, request); - - if (request) { - val = hdmi_read(client, HDMI_SYS_CTL); - hdmi_write_byte(client, HDMI_SYS_CTL, (val | 0x04)); - msleep(1); - hdmi_write_byte(client, HDMI_SYS_CTL, (val | 0x06)); - msleep(1); - - } else { - do { - hdmi_write_byte(client, HDMI_SYS_CTL, (val & 0xf9)); - tmp = hdmi_read(client, HDMI_SYS_CTL); - msleep(1); - /* make sure bit [2:1] = 00 */ - } while ((tmp & 0x06) & retry--) ; - } - - return 0; -} -#endif - -static uint8_t timing_id[][3] = { - { 0x81, 0xc0, 1 << 6 }, /* 1280x720 */ - { 0x3b, 0x80, 1 << 5 }, /* 720x576 */ - { 0x3b, 0x00, 1 << 4 }, /* 720x480 */ -}; - -//---------------------------------------------------------------------- -static irqreturn_t hdmi_irq_handler(int irq, void *data) -{ - struct hdmi_info *hdmi = (struct hdmi_info *) data; - HDMI_DBG("%s\n", __func__); - - disable_irq_nosync(hdmi->client->irq); - hdmi->isr_enabled = false; - hdmi->first = true; - if (!hdmi->cable_connected) { - hdmi->timer.expires = jiffies + INTERVAL_HDCP_POLLING; - add_timer(&hdmi->timer); - } - - return IRQ_HANDLED; -} -/* ---------------------------------------------------------------- */ -extern bool hdmifb_suspending; -static int hdmi_panel_blank(struct msm_lcdc_panel_ops *ops) -{ - struct hdmi_info *info = container_of(ops, struct hdmi_info, - hdmi_lcdc_ops); - - HDMI_DBG("%s\n", __func__); - - info->user_playing = false; - info->video_streaming= false; -#if 0 - /* if called from suspending */ - if (hdmifb_suspending) { - /* to avoid timer been revoked after standby */ - HDMI_DBG("suspending=true, disable timer\n"); - cancel_work_sync(&info->polling_work); - del_timer(&info->timer); - - HDMI_DBG("%s\n", __func__); - mutex_lock(&info->lock); - hdmi_standby(info); - info->power(2); - mutex_unlock(&info->lock); - } -#endif - return 0; -} - -static int hdmi_panel_unblank(struct msm_lcdc_panel_ops *ops) -{ - struct hdmi_info *info = container_of(ops, struct hdmi_info, - hdmi_lcdc_ops); - struct i2c_client *client = info->client; - - HDMI_DBG("%s\n", __func__); - clk_set_rate(info->ebi1_clk, 120000000); - if (info->suspending == true) { - HDMI_DBG("%s :actived before panel_init\n", __func__); - msleep(500); - } - - info->user_playing = true; - - return 0; -} - -static int hdmi_panel_init(struct msm_lcdc_panel_ops *ops) -{ - u8 conn; - struct hdmi_info *hd = container_of(ops, struct hdmi_info, - hdmi_lcdc_ops); - struct i2c_client *client = hd->client; - - HDMI_DBG("%s\n", __func__); - - if (hd->hdmi_gpio_on) - hd->hdmi_gpio_on(); - /* Turn-on 5V to ensure hot-plug detection */ - hd->power(5); - -#if 0 - /* For D2 sleep mode */ - hd->power(1); - - ret = hdmi_write_byte(client, HDMI_EN_REG, 0x00); - if (ret < 0) - goto fail; - - hdmi_disable_int(client); - - data = hdmi_read(client, HDMI_POWER); - if (data & 0xfc) { - dev_info(&client->dev, "power state = %d\n", data & 0xfc); - } else { - dev_info(&client->dev, "bring HDMI back\n"); - hdmi_enable_int(client); - HDMI_DBG("hotplug state=%d\n", hd->cable_connected); - } -#else - if (hd->polling) { - mutex_lock(&hd->lock); - hd->power(3); - hdmi_wakeup(hd); - hd->first = true; - mod_timer(&hd->timer, jiffies + INTERVAL_HDCP_POLLING); - conn = hdmi_read(client, HDMI_INT_STAT) & HOT_PLUG_STATE; - tpi_init(hd); -#ifdef CONFIG_HTC_HEADSET_MGR - switch_send_event(BIT_HDMI_AUDIO, conn); -#endif - mutex_unlock(&hd->lock); - } - hd->suspending = false; -#endif - return 0; -/* -fail: - return ret; -*/ -} - -static int hdmi_panel_uninit(struct msm_lcdc_panel_ops *ops) -{ - struct hdmi_info *info = container_of(ops, struct hdmi_info, - hdmi_lcdc_ops); - HDMI_DBG("%s\n", __func__); - - if (info->hdmi_gpio_off) - info->hdmi_gpio_off(); -#if 0 - /* For D2 sleep mode */ - info->power(0); -#endif - - if (hdmifb_suspending) { - /* to avoid timer been revoked after standby */ - HDMI_DBG("suspending=true, disable timer\n"); - cancel_work_sync(&info->polling_work); - del_timer(&info->timer); - flush_scheduled_work(); - - HDMI_DBG("%s\n", __func__); - mutex_lock(&info->lock); - hdmi_standby(info); - info->power(4); - mutex_unlock(&info->lock); - } - info->suspending = true; - - return 0; -} - -int avc_set_video_parm(struct hdmi_info *hdmi); -int avc_set_blank_screen(struct hdmi_info *hdmi); -void hdmi_pre_change(struct hdmi_info *hdmi) { - if (hdmi->sleeping == SLEEP) - return; - mutex_lock(&hdmi->polling_lock); - HDMI_DBG("%s\n", __func__); - avc_set_blank_screen(hdmi); - hdcp_off(hdmi); - mutex_unlock(&hdmi->polling_lock); -} - -void hdmi_post_change(struct hdmi_info *info, struct fb_var_screeninfo *var) -{ - u8 data[4]; - int i, ret, retry = 10; - struct msm_lcdc_timing *timing; - unsigned h_total, v_total, h_curr, v_curr; - - if (info->sleeping == SLEEP) - return; - - mutex_lock(&info->polling_lock); - HDMI_DBG("%s\n", __func__); - timing = &hdmi_lcdc_timing[info->res]; - - h_total = var->xres + timing->hsync_pulse_width + - timing->hsync_back_porch + timing->hsync_front_porch; - v_total = var->yres + timing->vsync_pulse_width + - timing->vsync_back_porch + timing->vsync_front_porch; - /* Waiting for video stream until steady */ - for (i = 0; i < retry ; i++) { - /* TODO: error handling. */ - /* Read current horizontal/vertical info of video */ - data[0] = hdmi_read(info->client, 0x6a); - data[1] = hdmi_read(info->client, 0x6b); - data[2] = hdmi_read(info->client, 0x6c); - data[3] = hdmi_read(info->client, 0x6d); - h_curr = ((int)data[1]) << 8 | data[0]; - v_curr = ((int)data[3]) << 8 | data[2]; - if (h_curr == h_total && v_curr == v_total) - break; - msleep(17); - } - - avc_set_video_parm(info); - avc_send_avi_info_frames(info); - info->video_streaming = true; - - mutex_unlock(&info->polling_lock); -} - -static struct msm_fb_data hdmi_lcdc_fb_data = { -#if 1 - .xres = 1280, - .yres = 720, -#else - .xres = 720, - .yres = 480, -#endif - .width = 94, - .height = 57, - .output_format = 0, -}; - -static struct msm_lcdc_platform_data hdmi_lcdc_platform_data = { - .timing = &hdmi_lcdc_timing[hd_720p], - .fb_id = 0, - .fb_data = &hdmi_lcdc_fb_data, -}; - -static struct platform_device hdmi_lcdc_device = { - .name = "msm_mdp_hdmi", - .id = -1, -}; - -int register_hdmi_client(struct class_interface *interface) -{ - if (!hdmi_class) { - pr_err("mdp: no hdmi_class when register hdmi client\n"); - return -ENODEV; - } - interface->class = hdmi_class; - return class_interface_register(interface); -} - -#if defined(OLD_DEBUGFS) -static spinlock_t hdmi_dbgfs_lock; -ssize_t hdmi_dbgfs_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t hdmi_edid_read(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) -{ - static char line[80], buffer[80*8*4]; - static char hextab[] = "0123456789abcdef"; - int i, j, n = 0, v, len, offset, line_size; - unsigned long irq_flags; - struct hdmi_info *hdmi = (struct hdmi_info*)filp->private_data; - - len = ((int)hdmi->edid_buf[0x7e]+1) * 128; - spin_lock_irqsave(&hdmi_dbgfs_lock, irq_flags); - memset(line, ' ', 79); - line[79] = '\0'; - offset = strlen("0000 | "); - line_size = offset + 3 * 16 + 1; - - for (i = 0; i < len / 16 ; i++) { - scnprintf(line, offset + 1, "%04x | ", (i << 4)); - for (j = 0; j < 16 ; j++) { - v = hdmi->edid_buf[i * 16 + j]; - line[offset + j * 3] = hextab[v / 16]; - line[offset + j * 3 + 1] = hextab[v % 16]; - } - line[line_size - 1] = '\n'; - strncpy(buffer + i * line_size, line, line_size); - n += line_size; - } - spin_unlock_irqrestore(&hdmi_dbgfs_lock, irq_flags); - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -#if 0 -static ssize_t hdmi_dbgfs_write(struct file *filp, const char __user *buf, - size_t count, loff_t *ppos) -{ - unsigned long v; - unsigned long irq_flags; - char buff[80]; - struct tv_reg_data *trd = (struct tv_reg_data *)filp->private_data; - - if (count >= sizeof(buff)) - return -EINVAL; - if (copy_from_user(&buff, buf, 80)) - return -EFAULT; - buff[count] = 0; - - spin_lock_irqsave(&hdmi_dbgfs_lock, irq_flags); - strict_strtoul(buff, 16, &v); - buff[strlen(buff)]=0; - writel(v, tvenc_base+trd->offset); - spin_unlock_irqrestore(&hdmi_dbgfs_lock, irq_flags); - - return count; -} -#endif - -static ssize_t hdmi_cable_read(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) -{ - int n; - char buffer[80]; - struct hdmi_info *hdmi = (struct hdmi_info*)filp->private_data; - - n = scnprintf(buffer, 80, "%d\n", hdmi->cable_connected); - n++; - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static ssize_t hdmi_sleeping_read(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) -{ - int n; - char buffer[80]; - struct hdmi_info *hdmi = (struct hdmi_info*)filp->private_data; - - n = scnprintf(buffer, 80, "%d\n", hdmi->sleeping); - n++; - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -int hdmifb_get_mode(void); -static ssize_t hdmi_fb_mode_read(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) -{ - int n; - char buffer[80]; - struct hdmi_info *hdmi = (struct hdmi_info*)filp->private_data; - - n = scnprintf(buffer, 80, "%d\n", hdmifb_get_mode()); - n++; - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static ssize_t hdmi_isr_read(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) -{ - int n; - char buffer[80]; - struct hdmi_info *hdmi = (struct hdmi_info*)filp->private_data; - - n = scnprintf(buffer, 80, "%d\n", hdmi->isr_enabled); - n++; - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static struct file_operations hdmi_fops[] = { - { - .open = hdmi_dbgfs_open, - .read = hdmi_edid_read, - }, - { /* cable*/ - .open = hdmi_dbgfs_open, - .read = hdmi_cable_read, - }, - { /* sleeping */ - .open = hdmi_dbgfs_open, - .read = hdmi_sleeping_read, - }, - { /* fb_mode */ - .open = hdmi_dbgfs_open, - .read = hdmi_fb_mode_read, - }, - { /* isr_enabled */ - .open = hdmi_dbgfs_open, - .read = hdmi_isr_read, - }, - -}; - -static int hdmi_debugfs_init(struct hdmi_info *hdmi) -{ - struct dentry *dent_hdmi; - int ret; - - spin_lock_init(&hdmi_dbgfs_lock); - dent_hdmi = debugfs_create_dir("hdmi", 0); - if (IS_ERR(dent_hdmi)) - return PTR_ERR(dent_hdmi); - debugfs_create_file("edid", 0644, dent_hdmi, hdmi, &hdmi_fops[0]); - debugfs_create_file("cable", 0444, dent_hdmi, hdmi, &hdmi_fops[1]); - debugfs_create_file("sleeping", 0444, dent_hdmi, hdmi, &hdmi_fops[2]); - debugfs_create_file("fb_mode", 0444, dent_hdmi, hdmi, &hdmi_fops[3]); - debugfs_create_file("isr", 0444, dent_hdmi, hdmi, &hdmi_fops[4]); - - return 0; -} -#endif - -static int __init hdmi_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct hdmi_info *hd; - struct hdmi_platform_data *pdata; - int ret = -EIO; - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - dev_err(&client->dev, "No supported I2C func\n"); - ret = -ENOTSUPP; - goto exit; - } - - hd = kzalloc(sizeof(*hd), GFP_KERNEL); - if (hd == NULL) { - ret = -ENOMEM; - goto exit; - } - - hd->client = client; - i2c_set_clientdata(client, hd); - mutex_init(&hd->lock); - mutex_init(&hd->lock2); - mutex_init(&hd->polling_lock); - - hd->ebi1_clk = clk_get(NULL, "ebi1_clk"); - if (IS_ERR(hd->ebi1_clk)) { - dev_err(&client->dev, "get ebi1 clk fail\n"); - goto fail_get_ebi1; - } - - pdata = client->dev.platform_data; - if (unlikely(!pdata) || unlikely(!pdata->power)) { - dev_err(&client->dev, "No platform data\n"); - ret = -ENXIO; - goto fail_power; - } else { - if (pdata->hdmi_gpio_on) - pdata->hdmi_gpio_on(); - hd->power = pdata->power; - ret = hd->power(1); - if (ret) { - dev_err(&client->dev, "hdmi power on failed\n"); - ret = -EIO; - goto fail_power; - } - } - - ret = hdmi_write_byte(client, HDMI_EN_REG, 0x00); - if (ret < 0) { - ret = -EIO; - goto fail_hdmi_init; - } - - ret = hdmi_read(client, HDMI_IDENTIFY); - if (ret < 0) { - ret = -EIO; - goto fail_hdmi_init; - } else if (ret != 0xb0) { - dev_err(&client->dev, "can not recognize, 0x%x\n", ret); - ret = -ENXIO; - goto fail_hdmi_init; - } - - hdmi_disable_int(client); - - hd->user_playing = false; - tpi_prepare(hd); - ret = request_irq(client->irq, hdmi_irq_handler, IRQF_TRIGGER_LOW, - client->name, hd); - if (ret) { - /* HDMI did not care if interrupt fail */ - dev_err(&client->dev, "request irq fail, err = %d\n", ret); - } else { - ret = hdmi_enable_int(client); - if (ret) { - free_irq(client->irq, hd); - ret = -ENOTSUPP; - } - } - - dev_info(&client->dev, "hdmi is on line with irq %s\n", - ret ? "Disabled" : "Enabled"); - - /* set up "panel" */ - hd->hdmi_lcdc_ops.init = hdmi_panel_init; - hd->hdmi_lcdc_ops.uninit = hdmi_panel_uninit; - hd->hdmi_lcdc_ops.blank = hdmi_panel_blank; - hd->hdmi_lcdc_ops.unblank = hdmi_panel_unblank; - hd->hdmi_gpio_on = pdata->hdmi_gpio_on; - hd->hdmi_gpio_off = pdata->hdmi_gpio_off; - - hdmi_lcdc_platform_data.panel_ops = &hd->hdmi_lcdc_ops; - hdmi_lcdc_platform_data.fb_resource = &pdata->hdmi_res; - hdmi_lcdc_device.dev.platform_data = &hdmi_lcdc_platform_data; - ret = platform_device_register(&hdmi_lcdc_device); - if (ret) - goto fail_hdmi_init; - - hd->hdmi_dev.check_res = hdmi_check_res; - hd->hdmi_dev.set_res = hdmi_set_res; - hd->hdmi_dev.get_cable_state = hdmi_get_cable_state; - hd->hdmi_dev.get_establish_timing = hdmi_get_established_timing; - - hd->hdmi_dev.dev.parent = &client->dev; - hd->hdmi_dev.dev.class = hdmi_class; - //snprintf(hd->hdmi_dev.dev.bus_id, BUS_ID_SIZE, "hdmi%d", 0); - dev_set_name(&hd->hdmi_dev.dev, "hdmi%d", 0); - ret = device_register(&hd->hdmi_dev.dev); - if (ret) - dev_err(&client->dev, "device register fail\n"); - -#if defined(HDMI_DEBUGFS) - hdmi_debugfs_init(hd); -#endif - /* check any pending interrupt */ - hdmi_irq_handler(client->irq, hd); - return 0; - -fail_hdmi_init: -fail_get_ebi1: - clk_put(hd->ebi1_clk); -fail_power: - kfree(hd); -exit: - dev_err(&client->dev, "%s fail, err = %d\n", __func__, ret); - return ret; -} - -/* -------------------------------------------------------------------- */ - -static const struct i2c_device_id hdmi_id[] = { - {HDMI_NAME, 0}, - { } -}; - -static struct i2c_driver hdmi_driver = { - .probe = hdmi_probe, - /*.remove = hdmi_remove,*/ - .id_table = hdmi_id, - .driver = { - .name = HDMI_NAME, - }, -}; - -static int __init hdmi_init(void) -{ - hdmi_class = class_create(THIS_MODULE, "msm_hdmi"); - if (IS_ERR(hdmi_class)) { - printk(KERN_ERR "Error creating hdmi class\n"); - return PTR_ERR(hdmi_class); - } - return i2c_add_driver(&hdmi_driver); -} - -static void __exit hdmi_exit(void) -{ - i2c_del_driver(&hdmi_driver); -} - -module_init(hdmi_init); -module_exit(hdmi_exit); - -MODULE_DESCRIPTION("Sil902x hdmi driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c index 0c39572c..22bf4ec7 100644 --- a/drivers/video/msm/mddi.c +++ b/drivers/video/msm/mddi.c @@ -44,9 +44,7 @@ #define CMD_GET_CLIENT_STATUS 0x0602 static uint32_t mddi_debug_flags; -#ifdef CONFIG_MSM_MDP40 -static struct clk *mdp_clk; -#endif + union mddi_rev { unsigned char raw[MDDI_REV_BUFFER_SIZE]; struct mddi_rev_packet hdr; @@ -102,11 +100,9 @@ struct mddi_info { char client_name[20]; struct platform_device client_pdev; - unsigned type; }; static void mddi_init_rev_encap(struct mddi_info *mddi); -static void mddi_skew_calibration(struct mddi_info *mddi); #define mddi_readl(r) readl(mddi->base + (MDDI_##r)) #define mddi_writel(v, r) writel((v), mddi->base + (MDDI_##r)) @@ -164,7 +160,7 @@ static void mddi_handle_rev_data(struct mddi_info *mddi, union mddi_rev *rev) printk(KERN_INFO "rev: got reg %x = %x without " " pending read\n", rev->reg.register_address, - rev->reg.u.reg_data); + rev->reg.register_data_list); break; } if (ri->reg != rev->reg.register_address) { @@ -172,12 +168,12 @@ static void mddi_handle_rev_data(struct mddi_info *mddi, union mddi_rev *rev) "wrong register, expected " "%x\n", rev->reg.register_address, - rev->reg.u.reg_data, ri->reg); + rev->reg.register_data_list, ri->reg); break; } mddi->reg_read = NULL; ri->status = 0; - ri->result = rev->reg.u.reg_data; + ri->result = rev->reg.register_data_list; complete(&ri->done); break; default: @@ -401,6 +397,9 @@ static uint16_t mddi_init_registers(struct mddi_info *mddi) mddi_writel(0x0003, SPM); /* subframes per media */ mddi_writel(0x0005, TA1_LEN); mddi_writel(MDDI_HOST_TA2_LEN, TA2_LEN); + mddi_writel(0x0096, DRIVE_HI); + /* 0x32 normal, 0x50 for Toshiba display */ + mddi_writel(0x0050, DRIVE_LO); mddi_writel(0x003C, DISP_WAKE); /* wakeup counter */ mddi_writel(MDDI_HOST_REV_RATE_DIV, REV_RATE_DIV); @@ -419,26 +418,8 @@ static uint16_t mddi_init_registers(struct mddi_info *mddi) } /* Recommendation from PAD hw team */ - if (mddi->type == MSM_MDP_MDDI_TYPE_II) - mddi_writel(0x402a850f, PAD_CTL); - else - mddi_writel(0xa850f, PAD_CTL); + mddi_writel(0xa850f, PAD_CTL); -#if defined (CONFIG_ARCH_QSD8X50) || defined (CONFIG_ARCH_MSM7X30) - /* Only for novatek driver IC*/ - mddi_writel(0x00C8, DRIVE_HI); - /* 0x32 normal, 0x50 for Toshiba display */ - mddi_writel(0x0050, DRIVE_LO); - mddi_writel(0x00320000, PAD_IO_CTL); - if (mddi->type == MSM_MDP_MDDI_TYPE_II) - mddi_writel(0x40884020, PAD_CAL); - else - mddi_writel(0x00220020, PAD_CAL); -#else - mddi_writel(0x0096, DRIVE_HI); - /* 0x32 normal, 0x50 for Toshiba display */ - mddi_writel(0x0050, DRIVE_LO); -#endif /* Need an even number for counts */ mddi_writel(0x60006, DRIVER_START_CNT); @@ -469,9 +450,6 @@ static void mddi_suspend(struct msm_mddi_client_data *cdata) mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); /* turn off the clock */ clk_disable(mddi->clk); -#if CONFIG_MSM_MDP40 - clk_disable(mdp_clk); -#endif wake_unlock(&mddi->idle_lock); } @@ -484,18 +462,11 @@ static void mddi_resume(struct msm_mddi_client_data *cdata) /* turn on the client */ if (mddi->power_client) mddi->power_client(&mddi->client_data, 1); -#if CONFIG_MSM_MDP40 - clk_enable(mdp_clk); -#endif /* turn on the clock */ clk_enable(mddi->clk); /* set up the local registers */ mddi->rev_data_curr = 0; mddi_init_registers(mddi); -/* FIXME: Workaround for Novatek - if (mddi->type == MSM_MDP_MDDI_TYPE_II) - mddi_skew_calibration(mddi); -*/ mddi_writel(mddi->int_enable, INTEN); mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD); mddi_writel(MDDI_CMD_SEND_RTD, CMD); @@ -522,44 +493,37 @@ static int __init mddi_get_client_caps(struct mddi_info *mddi) mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD); mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); - /*FIXME: mddi host can't get caps on MDDI type 2*/ - if (mddi->type == MSM_MDP_MDDI_TYPE_I) { - for (j = 0; j < 3; j++) { - /* the toshiba vga panel does not respond to get - * caps unless you SEND_RTD, but the first SEND_RTD - * will fail... - */ - for (i = 0; i < 4; i++) { - uint32_t stat; - mddi_writel(MDDI_CMD_SEND_RTD, CMD); - mdelay(1); - mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); - stat = mddi_readl(STAT); - printk(KERN_INFO "mddi cmd send rtd: int %x, stat %x, " - "rtd val %x\n", mddi_readl(INT), stat, - mddi_readl(RTD_VAL)); - if ((stat & MDDI_STAT_RTD_MEAS_FAIL) == 0) { - mdelay(1); - break; - } - msleep(1); - } + for (j = 0; j < 3; j++) { + /* the toshiba vga panel does not respond to get + * caps unless you SEND_RTD, but the first SEND_RTD + * will fail... + */ + for (i = 0; i < 4; i++) { + uint32_t stat; - mddi_writel(CMD_GET_CLIENT_CAP, CMD); - mdelay(1); + mddi_writel(MDDI_CMD_SEND_RTD, CMD); mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); - wait_event_timeout(mddi->int_wait, mddi->flags & FLAG_HAVE_CAPS, + stat = mddi_readl(STAT); + printk(KERN_INFO "mddi cmd send rtd: int %x, stat %x, " + "rtd val %x\n", mddi_readl(INT), stat, + mddi_readl(RTD_VAL)); + if ((stat & MDDI_STAT_RTD_MEAS_FAIL) == 0) + break; + msleep(1); + } + + mddi_writel(CMD_GET_CLIENT_CAP, CMD); + mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); + wait_event_timeout(mddi->int_wait, mddi->flags & FLAG_HAVE_CAPS, HZ / 100); - if (mddi->flags & FLAG_HAVE_CAPS) - break; - printk(KERN_INFO KERN_ERR "mddi_init, timeout waiting for " + if (mddi->flags & FLAG_HAVE_CAPS) + break; + printk(KERN_INFO KERN_ERR "mddi_init, timeout waiting for " "caps\n"); - } - return (mddi->flags & FLAG_HAVE_CAPS); - } else - return 1; + } + return mddi->flags & FLAG_HAVE_CAPS; } /* link must be active when this is called */ @@ -600,84 +564,51 @@ int mddi_check_status(struct mddi_info *mddi) } -/* - * mddi_remote_write_vals - send the register access packet - * - * @cdata: mddi layer dedicated structure, holding info needed by mddi - * @val : parameters - * @reg : cmd - * @nr_bytes: size of parameters in bytes - * - * jay, Nov 13, 08' - * extend the single parameter to multiple. - */ -void mddi_remote_write_vals(struct msm_mddi_client_data *cdata, uint8_t * val, - uint32_t reg, unsigned int nr_bytes) +void mddi_remote_write(struct msm_mddi_client_data *cdata, uint32_t val, + uint32_t reg) { struct mddi_info *mddi = container_of(cdata, struct mddi_info, client_data); struct mddi_llentry *ll; struct mddi_register_access *ra; - dma_addr_t bus_addr = 0; + /* unsigned s; */ mutex_lock(&mddi->reg_write_lock); ll = mddi->reg_write_data; ra = &(ll->u.r); - ra->length = 14 + nr_bytes; + ra->length = 14 + 4; ra->type = TYPE_REGISTER_ACCESS; ra->client_id = 0; - ra->read_write_info = MDDI_WRITE | (nr_bytes / 4); + ra->read_write_info = MDDI_WRITE | 1; ra->crc16 = 0; ra->register_address = reg; + ra->register_data_list = val; ll->flags = 1; - /* register access packet header occupies 14 bytes */ ll->header_count = 14; - ll->data_count = nr_bytes; /* num of bytes in the data field */ - - if (nr_bytes == 4) { - uint32_t *prm = (uint32_t *)val; - - ll->data = mddi->reg_write_addr + - offsetof(struct mddi_llentry, u.r.u.reg_data); - ra->u.reg_data = *prm; - } else { - int dma_retry = 5; - - while (dma_retry--) { - bus_addr = dma_map_single(NULL, (void *)val, nr_bytes, - DMA_TO_DEVICE); - if (dma_mapping_error(NULL, bus_addr) == 0) - break; - msleep(1); - } - if (dma_retry == 0) { - printk(KERN_ERR "%s: dma map fail!\n", __func__); - return; - } - - ll->data = bus_addr; - ra->u.reg_data_list = (uint32_t *)bus_addr; - } + ll->data_count = 4; + ll->data = mddi->reg_write_addr + offsetof(struct mddi_llentry, + u.r.register_data_list); ll->next = 0; ll->reserved = 0; - /* inform mddi to start */ - mddi_writel(mddi->reg_write_addr, PRI_PTR); - mddi_wait_interrupt(mddi, MDDI_INT_PRI_LINK_LIST_DONE); - if (bus_addr) - dma_unmap_single(NULL, bus_addr, nr_bytes, DMA_TO_DEVICE); - mutex_unlock(&mddi->reg_write_lock); -} + /* s = mddi_readl(STAT); */ + /* printk(KERN_INFO "mddi_remote_write(%x, %x), stat = %x\n", val, + * reg, s); */ -void mddi_remote_write(struct msm_mddi_client_data *cdata, uint32_t val, - uint32_t reg) -{ - uint8_t * p = (uint8_t *)&val; - mddi_remote_write_vals(cdata, p, reg, 4); + mddi_writel(mddi->reg_write_addr, PRI_PTR); + + /* s = mddi_readl(STAT); */ + /* printk(KERN_INFO "mddi_remote_write(%x, %x) sent, stat = %x\n", + * val, reg, s); */ + + mddi_wait_interrupt(mddi, MDDI_INT_PRI_LINK_LIST_DONE); + /* printk(KERN_INFO "mddi_remote_write(%x, %x) done, stat = %x\n", + * val, reg, s); */ + mutex_unlock(&mddi->reg_write_lock); } uint32_t mddi_remote_read(struct msm_mddi_client_data *cdata, uint32_t reg) @@ -716,7 +647,6 @@ uint32_t mddi_remote_read(struct msm_mddi_client_data *cdata, uint32_t reg) ri.reg = reg; ri.status = -1; - ri.result = -1; do { init_completion(&ri.done); @@ -781,16 +711,7 @@ static int __init mddi_clk_setup(struct platform_device *pdev, unsigned long clk_rate) { int ret; -#ifdef CONFIG_MSM_MDP40 - mdp_clk = clk_get(&pdev->dev, "mdp_clk"); - if (IS_ERR(mdp_clk)) { - printk(KERN_INFO "mddi: failed to get mdp clk"); - return PTR_ERR(mdp_clk); - } - ret = clk_enable(mdp_clk); - if (ret) - goto fail; -#endif + /* set up the clocks */ mddi->clk = clk_get(&pdev->dev, "mddi_clk"); if (IS_ERR(mddi->clk)) { @@ -803,7 +724,6 @@ static int __init mddi_clk_setup(struct platform_device *pdev, ret = clk_set_rate(mddi->clk, clk_rate); if (ret) goto fail; - printk(KERN_DEBUG "mddi runs at %ld\n", clk_get_rate(mddi->clk)); return 0; fail: @@ -831,18 +751,6 @@ static int __init mddi_rev_data_setup(struct mddi_info *mddi) return 0; } -static void mddi_skew_calibration(struct mddi_info *mddi) -{ - struct msm_mddi_platform_data *pdata = mddi->client_pdev.dev.platform_data; - - clk_set_rate( mddi->clk, 50000000); - mdelay(1); - mddi_writel(MDDI_CMD_SKEW_CALIBRATION, CMD); - mdelay(1); - clk_set_rate( mddi->clk, pdata->clk_rate); - mdelay(1); -} - static int __init mddi_probe(struct platform_device *pdev) { struct msm_mddi_platform_data *pdata = pdev->dev.platform_data; @@ -871,8 +779,6 @@ static int __init mddi_probe(struct platform_device *pdev) printk(KERN_INFO "mddi: init() base=0x%p irq=%d\n", mddi->base, mddi->irq); mddi->power_client = pdata->power_client; - if (pdata->type != NULL) - mddi->type = pdata->type; mutex_init(&mddi->reg_write_lock); mutex_init(&mddi->reg_read_lock); @@ -905,10 +811,9 @@ static int __init mddi_probe(struct platform_device *pdev) } /* turn on the mddi client bridge chip */ - #if 0 /*advised by SKY*/ if (mddi->power_client) mddi->power_client(&mddi->client_data, 1); - #endif + /* initialize the mddi registers */ mddi_set_auto_hibernate(&mddi->client_data, 0); mddi_writel(MDDI_CMD_RESET, CMD); @@ -929,19 +834,11 @@ static int __init mddi_probe(struct platform_device *pdev) printk(KERN_INFO "mddi powerdown: stat %x\n", mddi_readl(STAT)); msleep(100); printk(KERN_INFO "mddi powerdown: stat %x\n", mddi_readl(STAT)); - goto dummy_client; + return 0; } - mddi_set_auto_hibernate(&mddi->client_data, 1); - /* - * FIXME: User kernel defconfig to link dedicated mddi client driver. - */ -#if 0 - if ( mddi->caps.Mfr_Name == 0 && mddi->caps.Product_Code == 0) -#else - if (mddi->caps.Mfr_Name == 0 ) -#endif + if (mddi->caps.Mfr_Name == 0 && mddi->caps.Product_Code == 0) pdata->fixup(&mddi->caps.Mfr_Name, &mddi->caps.Product_Code); mddi->client_pdev.id = 0; @@ -959,17 +856,8 @@ static int __init mddi_probe(struct platform_device *pdev) } } - if (i >= pdata->num_clients) { -dummy_client: - mddi->client_data.private_client_data = - pdata->client_platform_data[0].client_data; - mddi->client_pdev.name = - pdata->client_platform_data[0].name; - mddi->client_pdev.id = - pdata->client_platform_data[0].id; + if (i >= pdata->num_clients) mddi->client_pdev.name = "mddi_c_dummy"; - clk_disable(mddi->clk); - } printk(KERN_INFO "mddi: registering panel %s\n", mddi->client_pdev.name); @@ -977,7 +865,6 @@ dummy_client: mddi->client_data.resume = mddi_resume; mddi->client_data.activate_link = mddi_activate_link; mddi->client_data.remote_write = mddi_remote_write; - mddi->client_data.remote_write_vals = mddi_remote_write_vals; mddi->client_data.remote_read = mddi_remote_read; mddi->client_data.auto_hibernate = mddi_set_auto_hibernate; mddi->client_data.fb_resource = pdata->fb_resource; diff --git a/drivers/video/msm/mddi_client_epson.c b/drivers/video/msm/mddi_client_epson.c deleted file mode 100644 index 577b09c8..00000000 --- a/drivers/video/msm/mddi_client_epson.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright (C) 2008 HTC Corporation. - * - * 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 -#include -#include -#include -#include -#include -#include -#include - -static DECLARE_WAIT_QUEUE_HEAD(epson_vsync_wait); - -struct panel_info { - struct msm_mddi_client_data *client_data; - struct platform_device pdev; - struct msm_panel_data panel_data; - struct msmfb_callback *epson_callback; - struct wake_lock idle_lock; - int epson_got_int; -}; - -static struct platform_device mddi_eps_cabc = { - .name = "eps_cabc", - .id = 0, -}; - -static void epson_request_vsync(struct msm_panel_data *panel_data, - struct msmfb_callback *callback) -{ - struct panel_info *panel = container_of(panel_data, struct panel_info, - panel_data); - struct msm_mddi_client_data *client_data = panel->client_data; - - panel->epson_callback = callback; - if (panel->epson_got_int) { - panel->epson_got_int = 0; - client_data->activate_link(client_data); - } -} - -static void epson_clear_vsync(struct msm_panel_data *panel_data) -{ - struct panel_info *panel = container_of(panel_data, struct panel_info, - panel_data); - struct msm_mddi_client_data *client_data = panel->client_data; - - client_data->activate_link(client_data); -} - -static void epson_wait_vsync(struct msm_panel_data *panel_data) -{ - struct panel_info *panel = container_of(panel_data, struct panel_info, - panel_data); - struct msm_mddi_client_data *client_data = panel->client_data; - - if (panel->epson_got_int) { - panel->epson_got_int = 0; - client_data->activate_link(client_data); /* clears interrupt */ - } - if (wait_event_timeout(epson_vsync_wait, panel->epson_got_int, - HZ/2) == 0) - printk(KERN_ERR "timeout waiting for VSYNC\n"); - panel->epson_got_int = 0; - /* interrupt clears when screen dma starts */ -} - -static int epson_suspend(struct msm_panel_data *panel_data) -{ - struct panel_info *panel = container_of(panel_data, struct panel_info, - panel_data); - struct msm_mddi_client_data *client_data = panel->client_data; - - struct msm_mddi_bridge_platform_data *bridge_data = - client_data->private_client_data; - int ret; - - wake_lock(&panel->idle_lock); - ret = bridge_data->uninit(bridge_data, client_data); - wake_unlock(&panel->idle_lock); - if (ret) { - printk(KERN_INFO "mddi epson client: non zero return from " - "uninit\n"); - return ret; - } - client_data->suspend(client_data); - return 0; -} - -static int epson_resume(struct msm_panel_data *panel_data) -{ - struct panel_info *panel = container_of(panel_data, struct panel_info, - panel_data); - struct msm_mddi_client_data *client_data = panel->client_data; - - struct msm_mddi_bridge_platform_data *bridge_data = - client_data->private_client_data; - int ret; - - wake_lock(&panel->idle_lock); - client_data->resume(client_data); - wake_unlock(&panel->idle_lock); - ret = bridge_data->init(bridge_data, client_data); - if (ret) - return ret; - return 0; -} - -static int epson_blank(struct msm_panel_data *panel_data) -{ - struct panel_info *panel = container_of(panel_data, struct panel_info, - panel_data); - struct msm_mddi_client_data *client_data = panel->client_data; - struct msm_mddi_bridge_platform_data *bridge_data = - client_data->private_client_data; - - return bridge_data->blank(bridge_data, client_data); -} - -static int epson_unblank(struct msm_panel_data *panel_data) -{ - struct panel_info *panel = container_of(panel_data, struct panel_info, - panel_data); - struct msm_mddi_client_data *client_data = panel->client_data; - struct msm_mddi_bridge_platform_data *bridge_data = - client_data->private_client_data; - - return bridge_data->unblank(bridge_data, client_data); -} - -static irqreturn_t epson_vsync_interrupt(int irq, void *data) -{ - struct panel_info *panel = data; - - panel->epson_got_int = 1; - if (panel->epson_callback) { - panel->epson_callback->func(panel->epson_callback); - panel->epson_callback = 0; - } - wake_up(&epson_vsync_wait); - return IRQ_HANDLED; -} - -static int setup_vsync(struct panel_info *panel, - int init) -{ - int ret; - int gpio = 98; - unsigned int irq; - - if (!init) { - ret = 0; - goto uninit; - } - ret = gpio_request(gpio, "vsync"); - if (ret) - goto err_request_gpio_failed; - - ret = gpio_direction_input(gpio); - if (ret) - goto err_gpio_direction_input_failed; - - ret = irq = gpio_to_irq(gpio); - if (ret < 0) - goto err_get_irq_num_failed; - - ret = request_irq(irq, epson_vsync_interrupt, IRQF_TRIGGER_FALLING, - "vsync", panel); - if (ret) - goto err_request_irq_failed; - printk(KERN_INFO "vsync on gpio %d now %d\n", - gpio, gpio_get_value(gpio)); - return 0; - -uninit: - free_irq(gpio_to_irq(gpio), panel); -err_request_irq_failed: -err_get_irq_num_failed: -err_gpio_direction_input_failed: - gpio_free(gpio); -err_request_gpio_failed: - return ret; -} - -static int mddi_epson_probe(struct platform_device *pdev) -{ - int ret; - struct msm_mddi_client_data *client_data = pdev->dev.platform_data; - struct msm_mddi_bridge_platform_data *bridge_data = - client_data->private_client_data; - struct panel_data *panel_data = &bridge_data->panel_conf; - struct panel_info *panel = - kzalloc(sizeof(struct panel_info), GFP_KERNEL); - if (!panel) - return -ENOMEM; - platform_set_drvdata(pdev, panel); - - printk(KERN_DEBUG "%s\n", __func__); - - if (panel_data->caps & MSMFB_CAP_CABC) { - printk(KERN_INFO "CABC enabled\n"); - mddi_eps_cabc.dev.platform_data = client_data; - platform_device_register(&mddi_eps_cabc); - } - - ret = setup_vsync(panel, 1); - if (ret) { - dev_err(&pdev->dev, "mddi_bridge_setup_vsync failed\n"); - return ret; - } - - panel->client_data = client_data; - panel->panel_data.suspend = epson_suspend; - panel->panel_data.resume = epson_resume; - panel->panel_data.wait_vsync = epson_wait_vsync; - panel->panel_data.request_vsync = epson_request_vsync; - panel->panel_data.clear_vsync = epson_clear_vsync; - panel->panel_data.blank = epson_blank; - panel->panel_data.unblank = epson_unblank; - panel->panel_data.fb_data = &bridge_data->fb_data; - panel->panel_data.caps = ~MSMFB_CAP_PARTIAL_UPDATES; - - panel->pdev.name = "msm_panel"; - panel->pdev.id = pdev->id; - panel->pdev.resource = client_data->fb_resource; - panel->pdev.num_resources = 1; - panel->pdev.dev.platform_data = &panel->panel_data; - platform_device_register(&panel->pdev); - wake_lock_init(&panel->idle_lock, WAKE_LOCK_IDLE, "eps_idle_lock"); - - return 0; -} - -static int mddi_epson_remove(struct platform_device *pdev) -{ - struct panel_info *panel = platform_get_drvdata(pdev); - - setup_vsync(panel, 0); - kfree(panel); - return 0; -} - -static struct platform_driver mddi_client_d263_0000 = { - .probe = mddi_epson_probe, - .remove = mddi_epson_remove, - .driver = { .name = "mddi_c_4ca3_0000" }, -}; - -static int __init mddi_client_epson_init(void) -{ - platform_driver_register(&mddi_client_d263_0000); - return 0; -} - -module_init(mddi_client_epson_init); - diff --git a/drivers/video/msm/mddi_client_novb9f6_5582.c b/drivers/video/msm/mddi_client_novb9f6_5582.c deleted file mode 100644 index defd92de..00000000 --- a/drivers/video/msm/mddi_client_novb9f6_5582.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright (C) 2008 HTC Corporation. - * - * 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 -#include -#include -#include -#include -#include -#include -#include - -static DECLARE_WAIT_QUEUE_HEAD(novtec_vsync_wait); - -struct panel_info { - struct msm_mddi_client_data *client_data; - struct platform_device pdev; - struct msm_panel_data panel_data; - struct msmfb_callback *novtec_callback; - struct wake_lock idle_lock; - int novtec_got_int; -}; - -static struct platform_device mddi_nov_cabc = { - .name = "nov_cabc", - .id = 0, -}; - -static void novtec_request_vsync(struct msm_panel_data *panel_data, - struct msmfb_callback *callback) -{ - struct panel_info *panel = container_of(panel_data, struct panel_info, - panel_data); - struct msm_mddi_client_data *client_data = panel->client_data; - - panel->novtec_callback = callback; - if (panel->novtec_got_int) { - panel->novtec_got_int = 0; - client_data->activate_link(client_data); - } -} - -static void novtec_clear_vsync(struct msm_panel_data *panel_data) -{ - struct panel_info *panel = container_of(panel_data, struct panel_info, - panel_data); - struct msm_mddi_client_data *client_data = panel->client_data; - - client_data->activate_link(client_data); -} - -static void novtec_wait_vsync(struct msm_panel_data *panel_data) -{ - struct panel_info *panel = container_of(panel_data, struct panel_info, - panel_data); - struct msm_mddi_client_data *client_data = panel->client_data; - - if (panel->novtec_got_int) { - panel->novtec_got_int = 0; - client_data->activate_link(client_data); /* clears interrupt */ - } - if (wait_event_timeout(novtec_vsync_wait, panel->novtec_got_int, - HZ/2) == 0) - printk(KERN_ERR "timeout waiting for VSYNC\n"); - panel->novtec_got_int = 0; - /* interrupt clears when screen dma starts */ -} - -static int novtec_suspend(struct msm_panel_data *panel_data) -{ - struct panel_info *panel = container_of(panel_data, struct panel_info, - panel_data); - struct msm_mddi_client_data *client_data = panel->client_data; - - struct msm_mddi_bridge_platform_data *bridge_data = - client_data->private_client_data; - int ret; - - wake_lock(&panel->idle_lock); - ret = bridge_data->uninit(bridge_data, client_data); - wake_unlock(&panel->idle_lock); - if (ret) { - printk(KERN_INFO "mddi novtec client: non zero return from " - "uninit\n"); - return ret; - } - client_data->suspend(client_data); - return 0; -} - -static int novtec_resume(struct msm_panel_data *panel_data) -{ - struct panel_info *panel = container_of(panel_data, struct panel_info, - panel_data); - struct msm_mddi_client_data *client_data = panel->client_data; - - struct msm_mddi_bridge_platform_data *bridge_data = - client_data->private_client_data; - int ret; - - wake_lock(&panel->idle_lock); - client_data->resume(client_data); - wake_unlock(&panel->idle_lock); - ret = bridge_data->init(bridge_data, client_data); - if (ret) - return ret; - return 0; -} - -static int novtec_blank(struct msm_panel_data *panel_data) -{ - struct panel_info *panel = container_of(panel_data, struct panel_info, - panel_data); - struct msm_mddi_client_data *client_data = panel->client_data; - struct msm_mddi_bridge_platform_data *bridge_data = - client_data->private_client_data; - - return bridge_data->blank(bridge_data, client_data); -} - -static int novtec_unblank(struct msm_panel_data *panel_data) -{ - struct panel_info *panel = container_of(panel_data, struct panel_info, - panel_data); - struct msm_mddi_client_data *client_data = panel->client_data; - struct msm_mddi_bridge_platform_data *bridge_data = - client_data->private_client_data; - - return bridge_data->unblank(bridge_data, client_data); -} - -static irqreturn_t novtec_vsync_interrupt(int irq, void *data) -{ - struct panel_info *panel = data; - - panel->novtec_got_int = 1; - if (panel->novtec_callback) { - mdelay(3); - panel->novtec_callback->func(panel->novtec_callback); - panel->novtec_callback = 0; - } - wake_up(&novtec_vsync_wait); - return IRQ_HANDLED; -} - -static int setup_vsync(struct panel_info *panel, - int init) -{ - int ret; - int gpio = 98; - unsigned int irq; - - if (!init) { - ret = 0; - goto uninit; - } - ret = gpio_request(gpio, "vsync"); - if (ret) - goto err_request_gpio_failed; - - ret = gpio_direction_input(gpio); - if (ret) - goto err_gpio_direction_input_failed; - - ret = irq = gpio_to_irq(gpio); - if (ret < 0) - goto err_get_irq_num_failed; - - ret = request_irq(irq, novtec_vsync_interrupt, IRQF_TRIGGER_FALLING, - "vsync", panel); - if (ret) - goto err_request_irq_failed; - printk(KERN_INFO "vsync on gpio %d now %d\n", - gpio, gpio_get_value(gpio)); - return 0; - -uninit: - free_irq(gpio_to_irq(gpio), panel); -err_request_irq_failed: -err_get_irq_num_failed: -err_gpio_direction_input_failed: - gpio_free(gpio); -err_request_gpio_failed: - return ret; -} - -static int mddi_novtec_probe(struct platform_device *pdev) -{ - int ret; - struct msm_mddi_client_data *client_data = pdev->dev.platform_data; - struct msm_mddi_bridge_platform_data *bridge_data = - client_data->private_client_data; - struct panel_data *panel_data = &bridge_data->panel_conf; - struct panel_info *panel = - kzalloc(sizeof(struct panel_info), GFP_KERNEL); - - if (!panel) - return -ENOMEM; - platform_set_drvdata(pdev, panel); - - printk(KERN_DEBUG "%s\n", __func__); - - if (panel_data->caps & MSMFB_CAP_CABC) { - printk(KERN_INFO "CABC enabled\n"); - mddi_nov_cabc.dev.platform_data = client_data; - platform_device_register(&mddi_nov_cabc); - } - - ret = setup_vsync(panel, 1); - if (ret) { - dev_err(&pdev->dev, "mddi_bridge_setup_vsync failed\n"); - return ret; - } - - panel->client_data = client_data; - panel->panel_data.suspend = novtec_suspend; - panel->panel_data.resume = novtec_resume; - panel->panel_data.wait_vsync = novtec_wait_vsync; - panel->panel_data.request_vsync = novtec_request_vsync; - panel->panel_data.clear_vsync = novtec_clear_vsync; - panel->panel_data.blank = novtec_blank; - panel->panel_data.unblank = novtec_unblank; - panel->panel_data.fb_data = &bridge_data->fb_data; - panel->panel_data.caps = MSMFB_CAP_PARTIAL_UPDATES; - - panel->pdev.name = "msm_panel"; - panel->pdev.id = pdev->id; - panel->pdev.resource = client_data->fb_resource; - panel->pdev.num_resources = 1; - panel->pdev.dev.platform_data = &panel->panel_data; - platform_device_register(&panel->pdev); - wake_lock_init(&panel->idle_lock, WAKE_LOCK_IDLE, "nov_idle_lock"); - - return 0; -} - -static int mddi_novtec_remove(struct platform_device *pdev) -{ - struct panel_info *panel = platform_get_drvdata(pdev); - - setup_vsync(panel, 0); - kfree(panel); - return 0; -} - -static struct platform_driver mddi_client_d263_0000 = { - .probe = mddi_novtec_probe, - .remove = mddi_novtec_remove, - .driver = { .name = "mddi_c_b9f6_5582" }, -}; - -static int __init mddi_client_novtec_init(void) -{ - platform_driver_register(&mddi_client_d263_0000); - return 0; -} - -module_init(mddi_client_novtec_init); - diff --git a/drivers/video/msm/mddi_hw.h b/drivers/video/msm/mddi_hw.h index 16e80126..45cc01fc 100644 --- a/drivers/video/msm/mddi_hw.h +++ b/drivers/video/msm/mddi_hw.h @@ -53,8 +53,6 @@ #define MDDI_MF_CNT 0x0084 #define MDDI_CURR_REV_PTR 0x0088 #define MDDI_CORE_VER 0x008c -#define MDDI_PAD_IO_CTL 0x00a0 -#define MDDI_PAD_CAL 0x00a4 #define MDDI_INT_PRI_PTR_READ 0x0001 #define MDDI_INT_SEC_PTR_READ 0x0002 @@ -114,7 +112,9 @@ #define MDDI_CMD_LINK_ACTIVE 0x0900 #define MDDI_CMD_PERIODIC_REV_ENCAP 0x0A00 #define MDDI_CMD_FORCE_NEW_REV_PTR 0x0C00 -#define MDDI_CMD_SKEW_CALIBRATION 0x0D00 + + + #define MDDI_VIDEO_REV_PKT_SIZE 0x40 #define MDDI_CLIENT_CAPABILITY_REV_PKT_SIZE 0x60 #define MDDI_MAX_REV_PKT_SIZE 0x60 @@ -125,17 +125,9 @@ /* 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_ARCH_QSD8X50) || defined (CONFIG_ARCH_MSM7X30) -#define MDDI_HOST_TA2_LEN 0x001a -#else #define MDDI_HOST_TA2_LEN 0x000c -#endif - -#if defined (CONFIG_ARCH_QSD8X50) || defined (CONFIG_ARCH_MSM7X30) -#define MDDI_HOST_REV_RATE_DIV 0x0004 -#else #define MDDI_HOST_REV_RATE_DIV 0x0002 -#endif + struct __attribute__((packed)) mddi_rev_packet { uint16_t length; @@ -292,12 +284,8 @@ struct __attribute__((packed)) mddi_register_access { uint16_t crc16; - union { - uint32_t reg_data; - uint32_t *reg_data_list; - } u; - - uint16_t crc_data; + uint32_t register_data_list; + /* list of 4-byte register data values for/from client registers */ }; struct __attribute__((packed)) mddi_llentry { diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c index 5e21cf86..ad07c945 100644 --- a/drivers/video/msm/mdp.c +++ b/drivers/video/msm/mdp.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -28,11 +29,11 @@ #include #include +#include #include #include "mdp_hw.h" #include "mdp_ppp.h" -#include struct class *mdp_class; @@ -41,18 +42,6 @@ struct class *mdp_class; static DECLARE_WAIT_QUEUE_HEAD(mdp_ppp_waitqueue); static unsigned int mdp_irq_mask; struct clk *mdp_clk_to_disable_later = 0; -static struct mdp_blit_req *timeout_req; -#ifdef CONFIG_FB_MSM_OVERLAY -extern int mdp4_overlay_get(struct mdp_device *mdp_dev, struct fb_info *info, struct mdp_overlay *req); -extern int mdp4_overlay_set(struct mdp_device *mdp_dev, struct fb_info *info, struct mdp_overlay *req); -extern int mdp4_overlay_unset(struct mdp_device *mdp_dev, struct fb_info *info, int ndx); -extern int mdp4_overlay_play(struct mdp_device *mdp_dev, struct fb_info *info, struct msmfb_overlay_data *req, - struct file **pp_src_file); -extern void mdp4_mddi_overlay(void *priv, uint32_t addr, uint32_t stride, - uint32_t width, uint32_t height, uint32_t x, - uint32_t y); -#include "mdp4.h" -#endif DEFINE_MUTEX(mdp_mutex); static int locked_enable_mdp_irq(struct mdp_info *mdp, uint32_t mask) @@ -62,14 +51,16 @@ static int locked_enable_mdp_irq(struct mdp_info *mdp, uint32_t mask) /* if the mask bits are already set return an error, this interrupt * is already enabled */ if (mdp_irq_mask & mask) { - pr_err("mdp irq already on %x %x\n", mdp_irq_mask, mask); +// pr_err("mdp irq already on %x %x\n", mdp_irq_mask, mask); return -1; } /* if the mdp irq is not already enabled enable it */ if (!mdp_irq_mask) { - clk_enable(mdp->clk); - enable_irq(mdp->irq); + clk_set_rate(mdp->ebi1_clk, 128000000); + clk_enable(mdp->clk); + + enable_irq(mdp->irq); } /* clear out any previous irqs for the requested mask*/ @@ -95,6 +86,8 @@ static int enable_mdp_irq(struct mdp_info *mdp, uint32_t mask) static int locked_disable_mdp_irq(struct mdp_info *mdp, uint32_t mask) { + if (!mask) return 1; + /* this interrupt is already disabled! */ if (!(mdp_irq_mask & mask)) { printk(KERN_ERR "mdp irq already off %x %x\n", @@ -109,9 +102,11 @@ static int locked_disable_mdp_irq(struct mdp_info *mdp, uint32_t mask) /* if no one is waiting on the interrupt, disable it */ if (!mdp_irq_mask) { disable_irq_nosync(mdp->irq); + if (mdp->clk) clk_disable(mdp->clk); clk_set_rate(mdp->ebi1_clk, 0); + } return 0; } @@ -138,21 +133,13 @@ static irqreturn_t mdp_isr(int irq, void *data) status = mdp_readl(mdp, MDP_INTR_STATUS); mdp_writel(mdp, status, MDP_INTR_CLEAR); - - -#if defined(CONFIG_MACH_HTCLEO) + status &= ~0x10000; // Cotulla -#endif // pr_info("%s: status=%08x (irq_mask=%08x)\n", __func__, status, // mdp_irq_mask); status &= mdp_irq_mask; -#ifdef CONFIG_MSM_MDP40 - if (mdp->mdp_dev.overrides & MSM_MDP4_MDDI_DMA_SWITCH) { - if(status && mdp->out_if[MSM_MDDI_PMDH_INTERFACE].dma_cb != NULL) - status |= (INTR_OVERLAY0_DONE | MDP_DMA_S_DONE); - } -#endif + for (i = 0; i < MSM_MDP_NUM_INTERFACES; ++i) { struct mdp_out_interface *out_if = &mdp->out_if[i]; if (status & out_if->dma_mask) { @@ -195,16 +182,20 @@ static int mdp_wait(struct mdp_info *mdp, uint32_t mask, wait_queue_head_t *wq) unsigned long irq_flags; // pr_info("%s: WAITING for 0x%x\n", __func__, mask); - wait_event_timeout(*wq, !mdp_check_mask(mdp, mask), HZ); + wait_event_timeout(*wq, !mdp_check_mask(mdp, mask), HZ); // Cotulla TEST spin_lock_irqsave(&mdp->lock, irq_flags); if (mdp_irq_mask & mask) { - locked_disable_mdp_irq(mdp, mask); pr_warning("%s: timeout waiting for mdp to complete 0x%x\n", __func__, mask); - if(timeout_req) - mdp_dump_blit(timeout_req); - + printk("GLBL_CLK_ENA: %08X\n", readl(MSM_CLK_CTL_BASE + 0x0000)); + printk("GLBL_CLK_STATE: %08X\n", readl(MSM_CLK_CTL_BASE + 0x0004)); + printk("GLBL_SLEEP_EN: %08X\n", readl(MSM_CLK_CTL_BASE + 0x001C)); + printk("GLBL_CLK_ENA_2: %08X\n", readl(MSM_CLK_CTL_BASE + 0x0220)); + printk("GLBL_CLK_STATE_2: %08X\n", readl(MSM_CLK_CTL_BASE + 0x0224)); + printk("GLBL_CLK_SLEEP_EN_2: %08X\n", readl(MSM_CLK_CTL_BASE + 0x023C)); + mdp_ppp_dump_debug(mdp); + locked_disable_mdp_irq(mdp, mask); ret = -ETIMEDOUT; } else { // pr_info("%s: SUCCESS waiting for 0x%x\n", __func__, mask); @@ -226,7 +217,6 @@ void mdp_dma_wait(struct mdp_device *mdp_dev, int interface) case MSM_MDDI_PMDH_INTERFACE: case MSM_MDDI_EMDH_INTERFACE: case MSM_LCDC_INTERFACE: - case MSM_TV_INTERFACE: BUG_ON(!mdp->out_if[interface].registered); mask = mdp->out_if[interface].dma_mask; wq = &mdp->out_if[interface].dma_waitqueue; @@ -253,15 +243,15 @@ static int mdp_ppp_wait(struct mdp_info *mdp) return mdp_wait(mdp, DL0_ROI_DONE, &mdp_ppp_waitqueue); } -static void mdp_dmas_to_mddi(void *priv, uint32_t addr, uint32_t stride, - uint32_t width, uint32_t height, uint32_t x, uint32_t y) +static void mdp_dma_to_mddi(void *priv, uint32_t addr, uint32_t stride, + uint32_t width, uint32_t height, uint32_t x, + uint32_t y) { struct mdp_info *mdp = priv; uint32_t dma2_cfg; - uint32_t video_packet_parameter; - uint16_t ld_param = 1; - + uint16_t ld_param = 0; /* 0=PRIM, 1=SECD, 2=EXT */ + printk("MDDI start\n"); if(machine_is_htcleo()) { dma2_cfg = DMA_PACK_ALIGN_MSB | DMA_PACK_PATTERN_RGB; @@ -271,120 +261,30 @@ static void mdp_dmas_to_mddi(void *priv, uint32_t addr, uint32_t stride, dma2_cfg |= DMA_OUT_SEL_LCDC; dma2_cfg |= DMA_IBUF_FORMAT_RGB565; - - } else { + + /* 655 16BPP */ + dma2_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS; + } + else { dma2_cfg = DMA_PACK_TIGHT | DMA_PACK_ALIGN_LSB | + DMA_PACK_PATTERN_RGB | DMA_OUT_SEL_AHB | DMA_IBUF_NONCONTIGUOUS; dma2_cfg |= mdp->format; - #if defined CONFIG_MSM_MDP22 || defined CONFIG_MSM_MDP30 - if (mdp->format == DMA_IBUF_FORMAT_RGB888_OR_ARGB8888) - #else - if (mdp->format == DMA_IBUF_FORMAT_XRGB8888) - #endif - dma2_cfg |= DMA_PACK_PATTERN_BGR; - else - dma2_cfg |= DMA_PACK_PATTERN_RGB; + dma2_cfg |= DMA_OUT_SEL_MDDI; - dma2_cfg |= DMA_OUT_SEL_MDDI; + dma2_cfg |= DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY; - dma2_cfg |= DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY; + dma2_cfg |= DMA_DITHER_EN; - dma2_cfg |= DMA_DITHER_EN; - } - - if (mdp->mdp_dev.color_format == MSM_MDP_OUT_IF_FMT_RGB565) { - dma2_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS; - video_packet_parameter = MDDI_VDO_PACKET_DESC_RGB565; - } else if (mdp->mdp_dev.color_format == MSM_MDP_OUT_IF_FMT_RGB666) { + /* 666 18BPP */ dma2_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS; - video_packet_parameter = MDDI_VDO_PACKET_DESC_RGB666; } - /* setup size, address, and stride */ - mdp_writel(mdp, (height << 16) | (width), MDP_DMA_S_SIZE); - mdp_writel(mdp, addr, MDP_DMA_S_IBUF_ADDR); - mdp_writel(mdp, stride, MDP_DMA_S_IBUF_Y_STRIDE); - - /* set y & x offset and MDDI transaction parameters */ - mdp_writel(mdp, (y << 16) | (x), MDP_DMA_S_OUT_XY); - mdp_writel(mdp, ld_param, MDP_MDDI_PARAM_WR_SEL); - if (mdp->mdp_dev.overrides & MSM_MDP_PANEL_IGNORE_PIXEL_DATA) { - mdp_writel(mdp, (video_packet_parameter << 16) | 0xE3, - MDP_MDDI_PARAM); - } - else { - mdp_writel(mdp, (video_packet_parameter << 16) | MDDI_VDO_PACKET_PRIM, - MDP_MDDI_PARAM); - } - - mdp_writel(mdp, dma2_cfg, MDP_DMA_S_CONFIG); - mdp_writel(mdp, 0, MDP_DMA_S_START); -} - -static void mdp_dma_to_mddi(void *priv, uint32_t addr, uint32_t stride, - uint32_t width, uint32_t height, uint32_t x, - uint32_t y) -{ - struct mdp_info *mdp = priv; - uint32_t dma2_cfg = 0; - uint32_t video_packet_parameter = 0; - uint16_t ld_param = 0; /* 0=PRIM, 1=SECD, 2=EXT */ - -#if !defined(CONFIG_MSM_MDP30) - dma2_cfg = DMA_PACK_TIGHT | - DMA_PACK_ALIGN_LSB | - DMA_OUT_SEL_AHB | - DMA_IBUF_NONCONTIGUOUS; - -#endif - dma2_cfg |= mdp->format; - -#if defined CONFIG_MSM_MDP22 || defined CONFIG_MSM_MDP30 - if (mdp->format == DMA_IBUF_FORMAT_RGB888_OR_ARGB8888) -#else - if (mdp->format == DMA_IBUF_FORMAT_XRGB8888) -#endif - dma2_cfg |= DMA_PACK_PATTERN_BGR; - else - dma2_cfg |= DMA_PACK_PATTERN_RGB; - - dma2_cfg |= DMA_OUT_SEL_MDDI; - - dma2_cfg |= DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY; - -#if !defined(CONFIG_MSM_MDP30) - dma2_cfg |= DMA_DITHER_EN; -#endif - - if (mdp->mdp_dev.color_format == MSM_MDP_OUT_IF_FMT_RGB565) { - dma2_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS; - video_packet_parameter = MDDI_VDO_PACKET_DESC_RGB565; - } else if (mdp->mdp_dev.color_format == MSM_MDP_OUT_IF_FMT_RGB666) { - dma2_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS; - video_packet_parameter = MDDI_VDO_PACKET_DESC_RGB666; - } - - -#if defined(CONFIG_MSM_MDP30) || defined(CONFIG_MSM_MDP302) - writel(height << 16 | width, mdp->base + 0x90004); - writel(addr, mdp->base + 0x90008); - writel(stride, mdp->base + 0x9000c); - - /* set y & x offset and MDDI transaction parameters */ - writel(y << 16 | x, mdp->base + 0x90010); - writel(ld_param, mdp->base + 0x00090); - writel((video_packet_parameter << 16) | MDDI_VDO_PACKET_PRIM, - mdp->base + 0x00094); - - writel(dma2_cfg, mdp->base + 0x90000); - - /* start DMA2 */ - writel(0, mdp->base + 0x0044); -#elif defined(CONFIG_MSM_MDP22) +#ifdef CONFIG_MSM_MDP22 /* setup size, address, and stride */ mdp_writel(mdp, (height << 16) | (width), MDP_CMD_DEBUG_ACCESS_BASE + 0x0184); @@ -394,7 +294,7 @@ static void mdp_dma_to_mddi(void *priv, uint32_t addr, uint32_t stride, /* set y & x offset and MDDI transaction parameters */ mdp_writel(mdp, (y << 16) | (x), MDP_CMD_DEBUG_ACCESS_BASE + 0x0194); mdp_writel(mdp, ld_param, MDP_CMD_DEBUG_ACCESS_BASE + 0x01a0); - mdp_writel(mdp, (video_packet_parameter << 16) | MDDI_VDO_PACKET_PRIM, + mdp_writel(mdp, (MDDI_VDO_PACKET_DESC << 16) | MDDI_VDO_PACKET_PRIM, MDP_CMD_DEBUG_ACCESS_BASE + 0x01a4); mdp_writel(mdp, dma2_cfg, MDP_CMD_DEBUG_ACCESS_BASE + 0x0180); @@ -410,7 +310,7 @@ static void mdp_dma_to_mddi(void *priv, uint32_t addr, uint32_t stride, /* set y & x offset and MDDI transaction parameters */ mdp_writel(mdp, (y << 16) | (x), MDP_DMA_P_OUT_XY); mdp_writel(mdp, ld_param, MDP_MDDI_PARAM_WR_SEL); - mdp_writel(mdp, (video_packet_parameter << 16) | MDDI_VDO_PACKET_PRIM, + mdp_writel(mdp, (MDDI_VDO_PACKET_DESC << 16) | MDDI_VDO_PACKET_PRIM, MDP_MDDI_PARAM); mdp_writel(mdp, dma2_cfg, MDP_DMA_P_CONFIG); @@ -426,7 +326,7 @@ void mdp_dma(struct mdp_device *mdp_dev, uint32_t addr, uint32_t stride, struct mdp_out_interface *out_if; unsigned long flags; - if (interface < 0 || interface >= MSM_MDP_NUM_INTERFACES || + if (interface < 0 || interface > MSM_MDP_NUM_INTERFACES || !mdp->out_if[interface].registered) { pr_err("%s: Unknown interface: %d\n", __func__, interface); BUG(); @@ -435,7 +335,7 @@ void mdp_dma(struct mdp_device *mdp_dev, uint32_t addr, uint32_t stride, spin_lock_irqsave(&mdp->lock, flags); if (locked_enable_mdp_irq(mdp, out_if->dma_mask)) { - pr_err("%s: busy\n", __func__); +// pr_err("%s: busy\n", __func__); goto done; } @@ -517,14 +417,14 @@ int mdp_check_output_format(struct mdp_device *mdp_dev, int bpp) int mdp_set_output_format(struct mdp_device *mdp_dev, int bpp) { struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev); - uint32_t format, pack_pattern = DMA_PACK_PATTERN_RGB; + uint32_t format, pack_pattern; switch (bpp) { case 16: format = DMA_IBUF_FORMAT_RGB565; pack_pattern = DMA_PACK_PATTERN_RGB; break; -#if defined CONFIG_MSM_MDP22 || defined CONFIG_MSM_MDP30 +#ifdef CONFIG_MSM_MDP22 case 24: case 32: format = DMA_IBUF_FORMAT_RGB888_OR_ARGB8888; @@ -580,8 +480,8 @@ static void dump_req(struct mdp_blit_req *req, } int mdp_blit_and_wait(struct mdp_info *mdp, struct mdp_blit_req *req, - struct file *src_file, unsigned long src_start, unsigned long src_len, - struct file *dst_file, unsigned long dst_start, unsigned long dst_len) + struct file *src_file, unsigned long src_start, unsigned long src_len, + struct file *dst_file, unsigned long dst_start, unsigned long dst_len) { int ret; enable_mdp_irq(mdp, DL0_ROI_DONE); @@ -595,13 +495,17 @@ int mdp_blit_and_wait(struct mdp_info *mdp, struct mdp_blit_req *req, ret = mdp_ppp_wait(mdp); if (unlikely(ret)) { printk(KERN_ERR "%s: failed!\n", __func__); - pr_err("original request:\n"); - dump_req(mdp->req, src_start, src_len, dst_start, dst_len); +// pr_err("original request:\n"); +// dump_req(mdp->req, src_start, src_len, dst_start, dst_len); pr_err("dead request:\n"); dump_req(req, src_start, src_len, dst_start, dst_len); - BUG(); + //BUG(); return ret; } +// Cotulla: Disable each request dump to prevent spam in logs +// pr_err("good request:\n"); +// dump_req(req, src_start, src_len, dst_start, dst_len); + return 0; } @@ -613,7 +517,9 @@ int mdp_blit(struct mdp_device *mdp_dev, struct fb_info *fb, struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev); struct file *src_file = 0, *dst_file = 0; -#if defined(CONFIG_MSM_MDP31) || defined(CONFIG_MSM_MDP302) + printk("+MDP_BLIT: %08X\n", req->flags); + +#ifdef CONFIG_MSM_MDP31 if (req->flags & MDP_ROT_90) { if (unlikely(((req->dst_rect.h == 1) && ((req->src_rect.w != 1) || @@ -661,11 +567,10 @@ int mdp_blit(struct mdp_device *mdp_dev, struct fb_info *fb, } mutex_lock(&mdp_mutex); - timeout_req = req; /* transp_masking unimplemented */ req->transp_mask = MDP_TRANSP_NOP; mdp->req = req; -#if !defined(CONFIG_MSM_MDP31) && !defined(CONFIG_MSM_MDP302) +#ifndef CONFIG_MSM_MDP31 if (unlikely((req->transp_mask != MDP_TRANSP_NOP || req->alpha != MDP_ALPHA_NOP || HAS_ALPHA(req->src.format)) && @@ -717,37 +622,7 @@ end: put_img(src_file); put_img(dst_file); mutex_unlock(&mdp_mutex); - return ret; -} - -int mdp_fb_mirror(struct mdp_device *mdp_dev, - struct fb_info *src_fb, struct fb_info *dst_fb, - struct mdp_blit_req *req) -{ - int ret; - struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev); - - if (!src_fb || !dst_fb) - return -EINVAL; - - enable_mdp_irq(mdp, DL0_ROI_DONE); - ret = mdp_ppp_blit(mdp, req, - -1, src_fb->fix.smem_start, src_fb->fix.smem_len, - -1, dst_fb->fix.smem_start, dst_fb->fix.smem_len); - if (ret) - goto err_bad_blit; - - ret = mdp_ppp_wait(mdp); - if (ret) { - pr_err("mdp_ppp_wait error\n"); - goto err_wait_failed; - } - return 0; - -err_bad_blit: - disable_mdp_irq(mdp, DL0_ROI_DONE); - -err_wait_failed: + printk("-MDP_BLIT\n"); return ret; } @@ -815,7 +690,7 @@ int mdp_out_if_req_irq(struct mdp_device *mdp_dev, int interface, if (mask) { ret = locked_enable_mdp_irq(mdp, mask); if (ret) { - pr_err("%s: busy\n", __func__); +// pr_err("%s: busy\n", __func__); goto done; } mdp->out_if[interface].irq_mask = mask; @@ -841,26 +716,11 @@ int register_mdp_client(struct class_interface *cint) return class_interface_register(cint); } -#ifdef CONFIG_MSM_MDP40 -void mdp_hw_init(struct mdp_info *mdp) -{ - mdp_irq_mask = 0; - mdp_writel(mdp, 0, MDP_INTR_ENABLE); -} -#else #include "mdp_csc_table.h" -void mdp_check_tearing(struct mdp_info *mdp, struct msm_mdp_platform_data *pdata) -{ - mdp_writel(mdp, pdata->sync_config, MDP_SYNC_CONFIG_0); - mdp_writel(mdp, 1, MDP_TEAR_CHECK_EN); - mdp_writel(mdp, pdata->sync_thresh, MDP_SYNC_THRESH_0); - mdp_writel(mdp, pdata->sync_start_pos, MDP_PRIM_START_POS); -} void mdp_hw_init(struct mdp_info *mdp) { int n; - int lcdc_enabled; mdp_irq_mask = 0; @@ -871,7 +731,6 @@ void mdp_hw_init(struct mdp_info *mdp) mdp_writel(mdp, 1, MDP_EBI2_PORTMAP_MODE); #ifndef CONFIG_MSM_MDP22 - lcdc_enabled = mdp_readl(mdp, MDP_LCDC_EN); /* disable lcdc */ mdp_writel(mdp, 0, MDP_LCDC_EN); /* enable auto clock gating for all blocks by default */ @@ -922,19 +781,15 @@ void mdp_hw_init(struct mdp_info *mdp) #ifndef CONFIG_MSM_MDP31 mdp_writel(mdp, 0x04000400, MDP_COMMAND_CONFIG); #endif -#ifndef CONFIG_MSM_MDP22 - if(lcdc_enabled) - mdp_writel(mdp, 1, MDP_LCDC_EN); -#endif } -#endif //CONFIG_MSM_MDP40 + int mdp_probe(struct platform_device *pdev) { struct resource *resource; - int ret = -EINVAL; + int ret; struct mdp_info *mdp; - struct msm_mdp_platform_data *pdata = pdev->dev.platform_data; + resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!resource) { @@ -966,49 +821,13 @@ int mdp_probe(struct platform_device *pdev) mdp->mdp_dev.dma = mdp_dma; mdp->mdp_dev.dma_wait = mdp_dma_wait; mdp->mdp_dev.blit = mdp_blit; -#ifdef CONFIG_FB_MSM_OVERLAY - mdp->mdp_dev.overlay_get = mdp4_overlay_get; - mdp->mdp_dev.overlay_set = mdp4_overlay_set; - mdp->mdp_dev.overlay_unset = mdp4_overlay_unset; - mdp->mdp_dev.overlay_play = mdp4_overlay_play; -#endif mdp->mdp_dev.set_grp_disp = mdp_set_grp_disp; mdp->mdp_dev.set_output_format = mdp_set_output_format; mdp->mdp_dev.check_output_format = mdp_check_output_format; mdp->mdp_dev.configure_dma = mdp_configure_dma; - if (pdata == NULL || pdata->overrides == 0) - mdp->mdp_dev.overrides = 0; - else if(pdata->overrides) - mdp->mdp_dev.overrides = pdata->overrides; - - if (pdata == NULL || pdata->color_format == 0) - mdp->mdp_dev.color_format = MSM_MDP_OUT_IF_FMT_RGB565; - else if(pdata->color_format) - mdp->mdp_dev.color_format = pdata->color_format; - - if (pdata == NULL || pdata->dma_channel == MDP_DMA_P) { -#ifdef CONFIG_MSM_MDP40 - if (mdp->mdp_dev.overrides & MSM_MDP4_MDDI_DMA_SWITCH) { - ret = mdp_out_if_register(&mdp->mdp_dev, - MSM_MDDI_PMDH_INTERFACE, mdp, INTR_OVERLAY0_DONE - | MDP_DMA_S_DONE, mdp4_mddi_overlay); - } else { - ret = mdp_out_if_register(&mdp->mdp_dev, - MSM_MDDI_PMDH_INTERFACE, mdp, INTR_OVERLAY0_DONE, - mdp4_mddi_overlay); - } -#else - ret = mdp_out_if_register(&mdp->mdp_dev, - MSM_MDDI_PMDH_INTERFACE, mdp, MDP_DMA_P_DONE, - mdp_dma_to_mddi); -#endif - } else if (pdata->dma_channel == MDP_DMA_S) { - ret = mdp_out_if_register(&mdp->mdp_dev, - MSM_MDDI_PMDH_INTERFACE, mdp, MDP_DMA_S_DONE, - mdp_dmas_to_mddi); - } - + ret = mdp_out_if_register(&mdp->mdp_dev, MSM_MDDI_PMDH_INTERFACE, mdp, + MDP_DMA_P_DONE, mdp_dma_to_mddi); if (ret) goto error_mddi_pmdh_register; @@ -1034,28 +853,8 @@ int mdp_probe(struct platform_device *pdev) clk_enable(mdp->clk); mdp_clk_to_disable_later = mdp->clk; -#ifdef CONFIG_MSM_MDP40 - //MDP_DISP_INTF_SEL - if (mdp_readl(mdp, 0xc0000)) - mdp_writel(mdp, 0x8, 0x0038); - else - mdp_writel(mdp, 0xa, 0x0038); //mddi - //FIXME: should select mddi or lcdc interface - //mdp_writel(mdp, 0x8, 0x0038); //lcdc -#endif - -#ifdef CONFIG_MSM_MDP40 -extern void mdp4_hw_init(struct mdp_info *mdp); - mdp4_hw_init(mdp); -#else mdp_hw_init(mdp); -#endif -#if defined CONFIG_MSM_MDP302 - /* enable the tearing check in MDP */ - if(pdata != NULL && pdata->tearing_check) - mdp_check_tearing(mdp, pdata); -#endif /* register mdp device */ mdp->mdp_dev.dev.parent = &pdev->dev; mdp->mdp_dev.dev.class = mdp_class; diff --git a/drivers/video/msm/mdp_hw.h b/drivers/video/msm/mdp_hw.h index c9784f2b..d80be50e 100644 --- a/drivers/video/msm/mdp_hw.h +++ b/drivers/video/msm/mdp_hw.h @@ -74,52 +74,23 @@ void mdp_ppp_dump_debug(const struct mdp_info *mdp); #define mdp_writel(mdp, value, offset) writel(value, mdp->base + offset) #define mdp_readl(mdp, offset) readl(mdp->base + offset) -#ifdef CONFIG_MSM_MDP302 -#define MDP_SYNC_CONFIG_0 ( 0x00300) -#define MDP_SYNC_CONFIG_1 ( 0x00304) -#define MDP_SYNC_CONFIG_2 ( 0x00308) -#else -#define MDP_SYNC_CONFIG_0 ( 0x00000) -#define MDP_SYNC_CONFIG_1 ( 0x00004) -#define MDP_SYNC_CONFIG_2 ( 0x00008) -#endif - -#define MDP_SYNC_STATUS_0 ( 0x0000c) -#define MDP_SYNC_STATUS_1 ( 0x00010) -#define MDP_SYNC_STATUS_2 ( 0x00014) - -#ifdef CONFIG_MSM_MDP302 -#define MDP_SYNC_THRESH_0 ( 0x00200) -#define MDP_SYNC_THRESH_1 ( 0x00204) -#else -#define MDP_SYNC_THRESH_0 ( 0x00018) -#define MDP_SYNC_THRESH_1 ( 0x0001c) -#endif -#ifdef CONFIG_MSM_MDP40 -#define MDP_INTR_ENABLE ( 0x0050) -#define MDP_INTR_STATUS ( 0x0054) -#define MDP_INTR_CLEAR ( 0x0058) -#define MDP_EBI2_LCD0 ( 0x0060) -#define MDP_EBI2_LCD1 ( 0x0064) -#define MDP_EBI2_PORTMAP_MODE ( 0x0070) - -#define MDP_DMA_P_HIST_INTR_STATUS ( 0x95014) -#define MDP_DMA_P_HIST_INTR_CLEAR ( 0x95018) -#define MDP_DMA_P_HIST_INTR_ENABLE ( 0x9501C) -#else -#define MDP_INTR_ENABLE ( 0x00020) -#define MDP_INTR_STATUS ( 0x00024) -#define MDP_INTR_CLEAR ( 0x00028) -#define MDP_EBI2_LCD0 ( 0x0003c) -#define MDP_EBI2_LCD1 ( 0x00040) -#define MDP_EBI2_PORTMAP_MODE ( 0x0005c) -#endif -#define MDP_DISPLAY0_START ( 0x00030) -#define MDP_DISPLAY1_START ( 0x00034) -#define MDP_DISPLAY_STATUS ( 0x00038) -/* CONFIG_MSM_MDP302 */ -#define MDP_TEAR_CHECK_EN ( 0x0020c) -#define MDP_PRIM_START_POS ( 0x00210) +#define MDP_SYNC_CONFIG_0 (0x00000) +#define MDP_SYNC_CONFIG_1 (0x00004) +#define MDP_SYNC_CONFIG_2 (0x00008) +#define MDP_SYNC_STATUS_0 (0x0000c) +#define MDP_SYNC_STATUS_1 (0x00010) +#define MDP_SYNC_STATUS_2 (0x00014) +#define MDP_SYNC_THRESH_0 (0x00018) +#define MDP_SYNC_THRESH_1 (0x0001c) +#define MDP_INTR_ENABLE (0x00020) +#define MDP_INTR_STATUS (0x00024) +#define MDP_INTR_CLEAR (0x00028) +#define MDP_DISPLAY0_START (0x00030) +#define MDP_DISPLAY1_START (0x00034) +#define MDP_DISPLAY_STATUS (0x00038) +#define MDP_EBI2_LCD0 (0x0003c) +#define MDP_EBI2_LCD1 (0x00040) +#define MDP_EBI2_PORTMAP_MODE (0x0005c) #ifndef CONFIG_MSM_MDP31 #define MDP_DISPLAY0_ADDR (0x00054) @@ -257,11 +228,7 @@ void mdp_ppp_dump_debug(const struct mdp_info *mdp); #define MDP_TEST_CAPTURED_DCLK (0xd0210) #define MDP_TEST_MISR_CAPT_VAL_DCLK (0xd0214) -#ifdef CONFIG_MSM_MDP40 -#define MDP_DMA_P_START (0x000c) -#else #define MDP_DMA_P_START (0x00044) -#endif #define MDP_DMA_P_CONFIG (0x90000) #define MDP_DMA_P_SIZE (0x90004) #define MDP_DMA_P_IBUF_ADDR (0x90008) @@ -269,30 +236,6 @@ void mdp_ppp_dump_debug(const struct mdp_info *mdp); #define MDP_DMA_P_OUT_XY (0x90010) #define MDP_DMA_P_COLOR_CORRECT_CONFIG (0x90070) -#define MDP_DMA_S_START (0x00048) -#define MDP_DMA_S_CONFIG (0xa0000) -#define MDP_DMA_S_SIZE (0xa0004) -#define MDP_DMA_S_IBUF_ADDR (0xa0008) -#define MDP_DMA_S_IBUF_Y_STRIDE (0xa000c) -#define MDP_DMA_S_OUT_XY (0xa0010) - -#ifdef CONFIG_MSM_MDP40 -#define MDP_LCDC_EN (0xc0000) -#define MDP_LCDC_HSYNC_CTL (0xc0004) -#define MDP_LCDC_VSYNC_PERIOD (0xc0008) -#define MDP_LCDC_VSYNC_PULSE_WIDTH (0xc000c) -#define MDP_LCDC_DISPLAY_HCTL (0xc0010) -#define MDP_LCDC_DISPLAY_V_START (0xc0014) -#define MDP_LCDC_DISPLAY_V_END (0xc0018) -#define MDP_LCDC_ACTIVE_HCTL (0xc001c) -#define MDP_LCDC_ACTIVE_V_START (0xc0020) -#define MDP_LCDC_ACTIVE_V_END (0xc0024) -#define MDP_LCDC_BORDER_CLR (0xc0028) -#define MDP_LCDC_UNDERFLOW_CTL (0xc002c) -#define MDP_LCDC_HSYNC_SKEW (0xc0030) -#define MDP_LCDC_TEST_CTL (0xc0034) -#define MDP_LCDC_CTL_POLARITY (0xc0038) -#else #define MDP_LCDC_EN (0xe0000) #define MDP_LCDC_HSYNC_CTL (0xe0004) #define MDP_LCDC_VSYNC_PERIOD (0xe0008) @@ -308,7 +251,6 @@ void mdp_ppp_dump_debug(const struct mdp_info *mdp); #define MDP_LCDC_HSYNC_SKEW (0xe0030) #define MDP_LCDC_TEST_CTL (0xe0034) #define MDP_LCDC_CTL_POLARITY (0xe0038) -#endif #define MDP_PPP_SCALE_STATUS (0x50000) #define MDP_PPP_BLEND_STATUS (0x70000) @@ -320,30 +262,15 @@ void mdp_ppp_dump_debug(const struct mdp_info *mdp); #define DL0_ROI_DONE (1<<0) #define TV_OUT_DMA3_DONE (1<<6) #define TV_ENC_UNDERRUN (1<<7) -#define TV_OUT_FRAME_START (1<<13) #ifdef CONFIG_MSM_MDP22 #define MDP_DMA_P_DONE (1 << 2) -#define MDP_DMA_S_DONE (1 << 3) #else /* CONFIG_MSM_MDP31 */ - -#ifdef CONFIG_MSM_MDP40 -#define MDP_DMA_P_DONE (1 << 4) -#else #define MDP_DMA_P_DONE (1 << 14) -#endif - -#define MDP_DMA_S_DONE (1 << 2) #define MDP_LCDC_UNDERFLOW (1 << 16) - -#ifdef CONFIG_MSM_MDP40 -#define MDP_LCDC_FRAME_START (1 << 7) -#else #define MDP_LCDC_FRAME_START (1 << 15) #endif -#endif - #define MDP_TOP_LUMA 16 #define MDP_TOP_CHROMA 0 #define MDP_BOTTOM_LUMA 19 @@ -367,15 +294,9 @@ void mdp_ppp_dump_debug(const struct mdp_info *mdp); (((a)<<(bit*3))|((x)<<(bit*2))|((y)< #include -#include + #include #include "mdp_hw.h" -#ifdef CONFIG_MSM_MDP40 -#include "mdp4.h" -#endif -#if 0 -#define D(fmt, args...) printk(KERN_INFO "Dispaly: " fmt, ##args) -#else -#define D(fmt, args...) do {} while (0) -#endif - -#if defined(CONFIG_ARCH_MSM7227) -#define LCDC_MUX_CTL (MSM_TGPIO1_BASE + 0x278) -#endif struct mdp_lcdc_info { struct mdp_info *mdp; struct clk *mdp_clk; @@ -56,7 +44,7 @@ struct mdp_lcdc_info { struct msmfb_callback frame_start_cb; wait_queue_head_t vsync_waitq; int got_vsync; - unsigned color_format; + struct { uint32_t clk_rate; uint32_t hsync_ctl; @@ -72,10 +60,6 @@ struct mdp_lcdc_info { static struct mdp_device *mdp_dev; -#ifdef CONFIG_MSM_MDP40 -static struct mdp4_overlay_pipe *lcdc_pipe; -#endif - #define panel_to_lcdc(p) container_of((p), struct mdp_lcdc_info, fb_panel_data) static int lcdc_unblank(struct msm_panel_data *fb_panel) @@ -84,7 +68,6 @@ static int lcdc_unblank(struct msm_panel_data *fb_panel) struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops; pr_info("%s: ()\n", __func__); - panel_ops->unblank(panel_ops); return 0; @@ -103,49 +86,27 @@ static int lcdc_blank(struct msm_panel_data *fb_panel) static int lcdc_suspend(struct msm_panel_data *fb_panel) { - int status; struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); - struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops; pr_info("%s: suspending\n", __func__); -#if defined(CONFIG_ARCH_MSM7227) - writel(0x0, LCDC_MUX_CTL); - status = readl(LCDC_MUX_CTL); - D("suspend_lcdc_mux_ctl = %x\n", status); -#endif mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN); clk_disable(lcdc->pad_pclk); clk_disable(lcdc->pclk); clk_disable(lcdc->mdp_clk); - if (panel_ops->uninit) - panel_ops->uninit(panel_ops); return 0; } static int lcdc_resume(struct msm_panel_data *fb_panel) { - unsigned int status; struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); - struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops; pr_info("%s: resuming\n", __func__); - if (panel_ops->init) { - if (panel_ops->init(panel_ops) < 0) - printk(KERN_ERR "LCD init fail!\n"); - } - clk_enable(lcdc->mdp_clk); clk_enable(lcdc->pclk); clk_enable(lcdc->pad_pclk); -#if defined(CONFIG_ARCH_MSM7227) - writel(0x1, LCDC_MUX_CTL); - status = readl(LCDC_MUX_CTL); - D("resume_lcdc_mux_ctl = %x\n",status); -#endif - mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN); return 0; @@ -163,6 +124,8 @@ static int lcdc_hw_init(struct mdp_lcdc_info *lcdc) clk_set_rate(lcdc->pclk, lcdc->parms.clk_rate); clk_set_rate(lcdc->pad_pclk, lcdc->parms.clk_rate); +// mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN); // Cotulla + /* write the lcdc params */ mdp_writel(lcdc->mdp, lcdc->parms.hsync_ctl, MDP_LCDC_HSYNC_CTL); mdp_writel(lcdc->mdp, lcdc->parms.vsync_period, MDP_LCDC_VSYNC_PERIOD); @@ -175,7 +138,7 @@ static int lcdc_hw_init(struct mdp_lcdc_info *lcdc) mdp_writel(lcdc->mdp, lcdc->parms.hsync_skew, MDP_LCDC_HSYNC_SKEW); mdp_writel(lcdc->mdp, 0, MDP_LCDC_BORDER_CLR); - mdp_writel(lcdc->mdp, 0xff, MDP_LCDC_UNDERFLOW_CTL); + mdp_writel(lcdc->mdp, 0xFFFFFF | 0x80000000, MDP_LCDC_UNDERFLOW_CTL); // Cotulla mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_HCTL); mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_V_START); mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_V_END); @@ -189,28 +152,38 @@ static int lcdc_hw_init(struct mdp_lcdc_info *lcdc) mdp_writel(lcdc->mdp, 0, MDP_DMA_P_OUT_XY); + dma_cfg = mdp_readl(lcdc->mdp, MDP_DMA_P_CONFIG); + + + dma_cfg |= (DMA_PACK_ALIGN_LSB | + DMA_PACK_PATTERN_RGB | + DMA_DITHER_EN); + dma_cfg |= DMA_OUT_SEL_LCDC; + dma_cfg &= ~DMA_DST_BITS_MASK; + if(machine_is_htcleo()) { dma_cfg = DMA_PACK_ALIGN_MSB | DMA_PACK_PATTERN_RGB; dma_cfg |= DMA_OUT_SEL_LCDC; dma_cfg &= ~DMA_DST_BITS_MASK; - } else { - dma_cfg = mdp_readl(lcdc->mdp, MDP_DMA_P_CONFIG); - if (lcdc->pdata->overrides & MSM_MDP_LCDC_DMA_PACK_ALIGN_LSB) - dma_cfg &= ~DMA_PACK_ALIGN_MSB; - else - dma_cfg |= DMA_PACK_ALIGN_MSB; - - dma_cfg |= (DMA_PACK_PATTERN_RGB | + } + else { + dma_cfg |= (DMA_PACK_ALIGN_LSB | + DMA_PACK_PATTERN_RGB | DMA_DITHER_EN); dma_cfg |= DMA_OUT_SEL_LCDC; dma_cfg &= ~DMA_DST_BITS_MASK; } - if(lcdc->color_format == MSM_MDP_OUT_IF_FMT_RGB565) - dma_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS; - else if (lcdc->color_format == MSM_MDP_OUT_IF_FMT_RGB666) + + /* enable the lcdc timing generation */ + mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN); + + + if (fb_panel->fb_data->output_format == MSM_MDP_OUT_IF_FMT_RGB666) dma_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS; + else + dma_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS; mdp_writel(lcdc->mdp, dma_cfg, MDP_DMA_P_CONFIG); @@ -220,12 +193,14 @@ static int lcdc_hw_init(struct mdp_lcdc_info *lcdc) return 0; } + static void lcdc_wait_vsync(struct msm_panel_data *panel) { struct mdp_lcdc_info *lcdc = panel_to_lcdc(panel); int ret; + + ret = wait_event_timeout(lcdc->vsync_waitq, lcdc->got_vsync, HZ / 2); - ret = wait_event_timeout(lcdc->vsync_waitq, lcdc->got_vsync, HZ / 2); if (!ret && !lcdc->got_vsync) pr_err("%s: timeout waiting for VSYNC\n", __func__); lcdc->got_vsync = 0; @@ -258,13 +233,13 @@ static void lcdc_request_vsync(struct msm_panel_data *fb_panel, // vsync_cb->func(vsync_cb); } else - { - lcdc->got_vsync = 0; - mdp_out_if_req_irq(mdp_dev, MSM_LCDC_INTERFACE, MDP_LCDC_FRAME_START, - &lcdc->frame_start_cb); - lcdc_wait_vsync(fb_panel); - } + { + lcdc->got_vsync = 0; + mdp_out_if_req_irq(mdp_dev, MSM_LCDC_INTERFACE, MDP_LCDC_FRAME_START, &lcdc->frame_start_cb); + lcdc_wait_vsync(fb_panel); + } // CotullaFIX end + } static void lcdc_clear_vsync(struct msm_panel_data *fb_panel) @@ -291,11 +266,13 @@ static void lcdc_dma_start(void *priv, uint32_t addr, uint32_t stride, uint32_t y) { struct mdp_lcdc_info *lcdc = priv; + +// printk("DMA start\n"); struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev); if (mdp->dma_config_dirty) { mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN); - mdelay(30); + mdelay(20); mdp_dev->configure_dma(mdp_dev); mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN); } @@ -303,35 +280,6 @@ static void lcdc_dma_start(void *priv, uint32_t addr, uint32_t stride, mdp_writel(lcdc->mdp, addr, MDP_DMA_P_IBUF_ADDR); } -#ifdef CONFIG_MSM_MDP40 -static void lcdc_overlay_start(void *priv, uint32_t addr, uint32_t stride, - uint32_t width, uint32_t height, uint32_t x, - uint32_t y) -{ - struct mdp_lcdc_info *lcdc = priv; - struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev); - - struct mdp4_overlay_pipe *pipe; - pipe = lcdc_pipe; - pipe->srcp0_addr = addr; - - if (mdp->dma_config_dirty) - { - if(mdp->format == DMA_IBUF_FORMAT_RGB565) { - pipe->src_format = MDP_RGB_565; - pipe->srcp0_ystride = pipe->src_width * 2; - } else if(mdp->format == DMA_IBUF_FORMAT_XRGB8888) { - pipe->src_format = MDP_RGBA_8888; - pipe->srcp0_ystride = pipe->src_width * 4; - } - mdp4_overlay_format2pipe(pipe); - mdp->dma_config_dirty = false; - } - mdp4_overlay_rgb_setup(pipe); - mdp4_overlay_reg_flush(pipe, 1); /* rgb1 and mixer0 */ - -} -#endif static void precompute_timing_parms(struct mdp_lcdc_info *lcdc) { struct msm_lcdc_timing *timing = lcdc->pdata->timing; @@ -343,21 +291,21 @@ static void precompute_timing_parms(struct mdp_lcdc_info *lcdc) unsigned int display_vstart; unsigned int display_vend; - hsync_period = (timing->hsync_pulse_width + timing->hsync_back_porch + + hsync_period = (timing->hsync_back_porch + fb_data->xres + timing->hsync_front_porch); - hsync_start_x = (timing->hsync_pulse_width + timing->hsync_back_porch); + hsync_start_x = timing->hsync_back_porch; hsync_end_x = hsync_start_x + fb_data->xres - 1; - vsync_period = (timing->vsync_pulse_width + timing->vsync_back_porch + + vsync_period = (timing->vsync_back_porch + fb_data->yres + timing->vsync_front_porch); vsync_period *= hsync_period; - display_vstart = timing->vsync_pulse_width + timing->vsync_back_porch; + display_vstart = timing->vsync_back_porch; display_vstart *= hsync_period; display_vstart += timing->hsync_skew; - display_vend = (timing->vsync_pulse_width + timing->vsync_back_porch + - fb_data->yres) * hsync_period; + display_vend = (timing->vsync_back_porch + fb_data->yres) * + hsync_period; display_vend += timing->hsync_skew - 1; /* register values we pre-compute at init time from the timing @@ -384,10 +332,6 @@ static int mdp_lcdc_probe(struct platform_device *pdev) struct msm_lcdc_platform_data *pdata = pdev->dev.platform_data; struct mdp_lcdc_info *lcdc; int ret = 0; -#ifdef CONFIG_MSM_MDP40 - struct mdp4_overlay_pipe *pipe; - int ptype; -#endif if (!pdata) { pr_err("%s: no LCDC platform data found\n", __func__); @@ -425,61 +369,25 @@ static int mdp_lcdc_probe(struct platform_device *pdev) lcdc->frame_start_cb.func = lcdc_frame_start; platform_set_drvdata(pdev, lcdc); -#ifdef CONFIG_MSM_MDP40 - mdp_out_if_register(mdp_dev, MSM_LCDC_INTERFACE, lcdc, INTR_OVERLAY0_DONE, - lcdc_overlay_start); -#else + mdp_out_if_register(mdp_dev, MSM_LCDC_INTERFACE, lcdc, MDP_DMA_P_DONE, lcdc_dma_start); -#endif + precompute_timing_parms(lcdc); lcdc->fb_start = pdata->fb_resource->start; lcdc->mdp = container_of(mdp_dev, struct mdp_info, mdp_dev); - if(lcdc->mdp->mdp_dev.color_format) - lcdc->color_format = lcdc->mdp->mdp_dev.color_format; - else - lcdc->color_format = MSM_MDP_OUT_IF_FMT_RGB565; - -#ifdef CONFIG_MSM_MDP40 - if (lcdc_pipe == NULL) { - ptype = mdp4_overlay_format2type(MDP_RGB_565); - pipe = mdp4_overlay_pipe_alloc(ptype); - pipe->mixer_stage = MDP4_MIXER_STAGE_BASE; - pipe->mixer_num = MDP4_MIXER0; - pipe->src_format = MDP_RGB_565; - mdp4_overlay_format2pipe(pipe); - pipe->mdp = lcdc->mdp; - - lcdc_pipe = pipe; /* keep it */ - } else { - pipe = lcdc_pipe; - } - - pipe->src_height = pdata->fb_data->yres; - pipe->src_width = pdata->fb_data->xres; - pipe->src_h = pdata->fb_data->yres; - pipe->src_w = pdata->fb_data->xres; - pipe->src_y = 0; - pipe->src_x = 0; - pipe->srcp0_addr = (uint32_t) lcdc->fb_start; - pipe->srcp0_ystride = pdata->fb_data->xres * 2; - - mdp4_overlay_dmap_xy(pipe); - mdp4_overlay_dmap_cfg(pipe, 1); - - mdp4_overlay_rgb_setup(pipe); - - mdp4_mixer_stage_up(pipe); - - mdp4_overlayproc_cfg(pipe); - mdp4_overlay_reg_flush(pipe, 1); -#endif lcdc->fb_panel_data.suspend = lcdc_suspend; lcdc->fb_panel_data.resume = lcdc_resume; lcdc->fb_panel_data.wait_vsync = lcdc_wait_vsync; +//#if defined(CONFIG_MACH_HTCLEO) + // Temporarily disable vsync to prevent a scheduler bug, need + // to be looked into further. +// lcdc->fb_panel_data.request_vsync = 0; +//#else lcdc->fb_panel_data.request_vsync = lcdc_request_vsync; +//#endif lcdc->fb_panel_data.clear_vsync = lcdc_clear_vsync; lcdc->fb_panel_data.blank = lcdc_blank; lcdc->fb_panel_data.unblank = lcdc_unblank; @@ -487,6 +395,7 @@ static int mdp_lcdc_probe(struct platform_device *pdev) lcdc->fb_panel_data.interface_type = MSM_LCDC_INTERFACE; ret = lcdc_hw_init(lcdc); +// ret = 0; if (ret) { pr_err("%s: Cannot initialize the mdp_lcdc\n", __func__); goto err_hw_init; @@ -498,6 +407,8 @@ static int mdp_lcdc_probe(struct platform_device *pdev) lcdc->fb_pdev.num_resources = 1; lcdc->fb_pdev.dev.platform_data = &lcdc->fb_panel_data; + if (pdata->panel_ops->init) + pdata->panel_ops->init(pdata->panel_ops); ret = platform_device_register(&lcdc->fb_pdev); if (ret) { diff --git a/drivers/video/msm/mdp_ppp.c b/drivers/video/msm/mdp_ppp.c index 334e2ebb..7912a90f 100644 --- a/drivers/video/msm/mdp_ppp.c +++ b/drivers/video/msm/mdp_ppp.c @@ -52,19 +52,19 @@ static uint32_t dst_img_cfg[] = { PPP_ARRAY1(CFG, DST) }; -static uint32_t bytes_per_pixel[] = { +static const uint32_t bytes_per_pixel[] = { [MDP_RGB_565] = 2, - [MDP_RGB_888] = 3, [MDP_XRGB_8888] = 4, + [MDP_Y_CBCR_H2V2] = 1, [MDP_ARGB_8888] = 4, + [MDP_RGB_888] = 3, + [MDP_Y_CRCB_H2V2] = 1, + [MDP_YCRYCB_H2V1] = 2, + [MDP_Y_CRCB_H2V1] = 1, + [MDP_Y_CBCR_H2V1] = 1, [MDP_RGBA_8888] = 4, [MDP_BGRA_8888] = 4, [MDP_RGBX_8888] = 4, - [MDP_Y_CBCR_H2V1] = 1, - [MDP_Y_CBCR_H2V2] = 1, - [MDP_Y_CRCB_H2V1] = 1, - [MDP_Y_CRCB_H2V2] = 1, - [MDP_YCRYCB_H2V1] = 2 }; static uint32_t dst_op_chroma[] = { @@ -268,7 +268,7 @@ static void blit_blend(struct mdp_blit_req *req, struct ppp_regs *regs) req->alpha &= 0xff; /* ALPHA BLEND */ if (HAS_ALPHA(req->src.format)) { -#if !defined(CONFIG_MACH_HTCLEO) +#if 0 regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON; if (req->flags & MDP_BLEND_FG_PREMULT) { #ifdef CONFIG_MSM_MDP31 @@ -282,7 +282,7 @@ static void blit_blend(struct mdp_blit_req *req, struct ppp_regs *regs) regs->op |= PPP_OP_BLEND_CONSTANT_ALPHA; req->alpha = 0xff; #endif - } else { + } els { regs->op |= PPP_OP_BLEND_SRCPIXEL_ALPHA; } #else @@ -499,21 +499,19 @@ static int send_blit(const struct mdp_info *mdp, struct mdp_blit_req *req, #ifdef CONFIG_MSM_MDP31 mdp_writel_dbg(mdp, regs->bg_xy, MDP_PPP_BG_XY); mdp_writel_dbg(mdp, regs->bg_img_sz, MDP_PPP_BG_IMAGE_SIZE); - mdp_writel_dbg(mdp, regs->bg_alpha_sel, - MDP_PPP_BLEND_BG_ALPHA_SEL); - -#if defined(CONFIG_MACH_HTCLEO) - mdp_writel_dbg(mdp, 0, MDP_TFETCH_TEST_MODE); -#endif + mdp_writel_dbg(mdp, regs->bg_alpha_sel, MDP_PPP_BLEND_BG_ALPHA_SEL); + + mdp_writel_dbg(mdp, 0, MDP_TFETCH_TEST_MODE); + #endif } - if( src_file != -1 && dst_file != -1 ) - flush_imgs(req, regs, src_file, dst_file); + flush_imgs(req, regs, src_file, dst_file); mdp_writel_dbg(mdp, 0x1000, MDP_DISPLAY0_START); return 0; } -void mdp_dump_blit(struct mdp_blit_req *req) +#if PPP_DUMP_BLITS +static void mdp_dump_blit(struct mdp_blit_req *req) { pr_info("%s: src: w=%d h=%d f=0x%x offs=0x%x mem_id=%d\n", __func__, req->src.width, req->src.height, req->src.format, @@ -531,6 +529,7 @@ void mdp_dump_blit(struct mdp_blit_req *req) pr_info("%s: transp_max=0x%08x\n", __func__, req->transp_mask); pr_info("%s: flags=%08x\n", __func__, req->flags); } +#endif int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req, struct file *src_file, unsigned long src_start, unsigned long src_len, @@ -656,6 +655,13 @@ int mdp_get_bytes_per_pixel(int format) void mdp_ppp_dump_debug(const struct mdp_info *mdp) { + mdp_dump_register(mdp, MDP_CMD_STATUS); + mdp_dump_register(mdp, MDP_DMA_P_CONFIG); + mdp_dump_register(mdp, MDP_DISPLAY_STATUS); + mdp_dump_register(mdp, MDP_DMA_P_IBUF_Y_STRIDE); + mdp_dump_register(mdp, MDP_DMA_P_IBUF_ADDR); + mdp_dump_register(mdp, MDP_LCDC_UNDERFLOW_CTL); + mdp_dump_register(mdp, MDP_TFETCH_TEST_MODE); mdp_dump_register(mdp, MDP_TFETCH_STATUS); mdp_dump_register(mdp, MDP_TFETCH_TILE_COUNT); mdp_dump_register(mdp, MDP_TFETCH_FETCH_COUNT); @@ -667,235 +673,3 @@ void mdp_ppp_dump_debug(const struct mdp_info *mdp) mdp_dump_register(mdp, MDP_INTR_STATUS); mdp_dump_register(mdp, MDP_INTR_ENABLE); } - - -/* Splits a blit into two horizontal stripes. Used to work around MDP bugs */ -int mdp_ppp_blit_split_height(struct mdp_info *mdp, const struct mdp_blit_req *req, - struct file *src_file, unsigned long src_start, unsigned long src_len, - struct file *dst_file, unsigned long dst_start, unsigned long dst_len) -{ - int ret; - struct mdp_blit_req splitreq; - int s_x_0, s_x_1, s_w_0, s_w_1, s_y_0, s_y_1, s_h_0, s_h_1; - int d_x_0, d_x_1, d_w_0, d_w_1, d_y_0, d_y_1, d_h_0, d_h_1; - - splitreq = *req; - /* break dest roi at height*/ - d_x_0 = d_x_1 = req->dst_rect.x; - d_w_0 = d_w_1 = req->dst_rect.w; - d_y_0 = req->dst_rect.y; - if (req->dst_rect.h % 32 == 3) - d_h_1 = (req->dst_rect.h - 3) / 2 - 1; - else - d_h_1 = (req->dst_rect.h - 1) / 2 - 1; - d_h_0 = req->dst_rect.h - d_h_1; - d_y_1 = d_y_0 + d_h_0; - if (req->dst_rect.h == 3) { - d_h_1 = 2; - d_h_0 = 2; - d_y_1 = d_y_0 + 1; - } - /* break source roi */ - if (splitreq.flags & MDP_ROT_90) { - s_y_0 = s_y_1 = req->src_rect.y; - s_h_0 = s_h_1 = req->src_rect.h; - s_x_0 = req->src_rect.x; - s_w_1 = (req->src_rect.w * d_h_1) / req->dst_rect.h; - s_w_0 = req->src_rect.w - s_w_1; - s_x_1 = s_x_0 + s_w_0; - if (d_h_1 >= 8 * s_w_1) { - s_w_1++; - s_x_1--; - } - } else { - s_x_0 = s_x_1 = req->src_rect.x; - s_w_0 = s_w_1 = req->src_rect.w; - s_y_0 = req->src_rect.y; - s_h_1 = (req->src_rect.h * d_h_1) / req->dst_rect.h; - s_h_0 = req->src_rect.h - s_h_1; - s_y_1 = s_y_0 + s_h_0; - if (d_h_1 >= 8 * s_h_1) { - s_h_1++; - s_y_1--; - } - } - - /* blit first region */ - if (((splitreq.flags & MDP_ROT_MASK) == MDP_ROT_90) || - ((splitreq.flags & MDP_ROT_MASK) == 0x0)) { - splitreq.src_rect.h = s_h_0; - splitreq.src_rect.y = s_y_0; - splitreq.dst_rect.h = d_h_0; - splitreq.dst_rect.y = d_y_0; - splitreq.src_rect.x = s_x_0; - splitreq.src_rect.w = s_w_0; - splitreq.dst_rect.x = d_x_0; - splitreq.dst_rect.w = d_w_0; - } else { - splitreq.src_rect.h = s_h_0; - splitreq.src_rect.y = s_y_0; - splitreq.dst_rect.h = d_h_1; - splitreq.dst_rect.y = d_y_1; - splitreq.src_rect.x = s_x_0; - splitreq.src_rect.w = s_w_0; - splitreq.dst_rect.x = d_x_1; - splitreq.dst_rect.w = d_w_1; - } - ret = mdp_blit_and_wait(mdp, &splitreq, - src_file, src_start, src_len, - dst_file, dst_start, dst_len); - if (ret) - return ret; - - /* blit second region */ - if (((splitreq.flags & MDP_ROT_MASK) == MDP_ROT_90) || - ((splitreq.flags & MDP_ROT_MASK) == 0x0)) { - splitreq.src_rect.h = s_h_1; - splitreq.src_rect.y = s_y_1; - splitreq.dst_rect.h = d_h_1; - splitreq.dst_rect.y = d_y_1; - splitreq.src_rect.x = s_x_1; - splitreq.src_rect.w = s_w_1; - splitreq.dst_rect.x = d_x_1; - splitreq.dst_rect.w = d_w_1; - } else { - splitreq.src_rect.h = s_h_1; - splitreq.src_rect.y = s_y_1; - splitreq.dst_rect.h = d_h_0; - splitreq.dst_rect.y = d_y_0; - splitreq.src_rect.x = s_x_1; - splitreq.src_rect.w = s_w_1; - splitreq.dst_rect.x = d_x_0; - splitreq.dst_rect.w = d_w_0; - } - ret = mdp_blit_and_wait(mdp, &splitreq, - src_file, src_start, src_len, - dst_file, dst_start, dst_len); - return ret; -} - -/* Splits a blit into two vertical stripes. Used to work around MDP bugs */ -int mdp_ppp_blit_split_width(struct mdp_info *mdp, const struct mdp_blit_req *req, - struct file *src_file, unsigned long src_start, unsigned long src_len, - struct file *dst_file, unsigned long dst_start, unsigned long dst_len) -{ - int ret; - struct mdp_blit_req splitreq; - int s_x_0, s_x_1, s_w_0, s_w_1, s_y_0, s_y_1, s_h_0, s_h_1; - int d_x_0, d_x_1, d_w_0, d_w_1, d_y_0, d_y_1, d_h_0, d_h_1; - splitreq = *req; - - /* break dest roi at width*/ - d_y_0 = d_y_1 = req->dst_rect.y; - d_h_0 = d_h_1 = req->dst_rect.h; - d_x_0 = req->dst_rect.x; - if (req->dst_rect.w % 32 == 6) - d_w_1 = req->dst_rect.w / 2 - 1; - else if (req->dst_rect.w % 2 == 0) - d_w_1 = req->dst_rect.w / 2; - else if (req->dst_rect.w % 32 == 3) - d_w_1 = (req->dst_rect.w - 3) / 2 - 1; - else - d_w_1 = (req->dst_rect.w - 1) / 2 - 1; - d_w_0 = req->dst_rect.w - d_w_1; - d_x_1 = d_x_0 + d_w_0; - if (req->dst_rect.w == 3) { - d_w_1 = 2; - d_w_0 = 2; - d_x_1 = d_x_0 + 1; - } - - /* break src roi at height or width*/ - if (splitreq.flags & MDP_ROT_90) { - s_x_0 = s_x_1 = req->src_rect.x; - s_w_0 = s_w_1 = req->src_rect.w; - s_y_0 = req->src_rect.y; - s_h_1 = (req->src_rect.h * d_w_1) / req->dst_rect.w; - s_h_0 = req->src_rect.h - s_h_1; - s_y_1 = s_y_0 + s_h_0; - if (d_w_1 >= 8 * s_h_1) { - s_h_1++; - s_y_1--; - } - } else { - s_y_0 = s_y_1 = req->src_rect.y; - s_h_0 = s_h_1 = req->src_rect.h; - s_x_0 = req->src_rect.x; - s_w_1 = (req->src_rect.w * d_w_1) / req->dst_rect.w; - s_w_0 = req->src_rect.w - s_w_1; - s_x_1 = s_x_0 + s_w_0; - if (d_w_1 >= 8 * s_w_1) { - s_w_1++; - s_x_1--; - } - } - - /* blit first region */ - if (((splitreq.flags & MDP_ROT_MASK) == MDP_ROT_270) || - ((splitreq.flags & MDP_ROT_MASK) == 0x0)) { - splitreq.src_rect.h = s_h_0; - splitreq.src_rect.y = s_y_0; - splitreq.dst_rect.h = d_h_0; - splitreq.dst_rect.y = d_y_0; - splitreq.src_rect.x = s_x_0; - splitreq.src_rect.w = s_w_0; - splitreq.dst_rect.x = d_x_0; - splitreq.dst_rect.w = d_w_0; - } else { - splitreq.src_rect.h = s_h_0; - splitreq.src_rect.y = s_y_0; - splitreq.dst_rect.h = d_h_1; - splitreq.dst_rect.y = d_y_1; - splitreq.src_rect.x = s_x_0; - splitreq.src_rect.w = s_w_0; - splitreq.dst_rect.x = d_x_1; - splitreq.dst_rect.w = d_w_1; - } - - if (unlikely((splitreq.dst_rect.h != 1) && - ((splitreq.dst_rect.h % 32 == 3) || - (splitreq.dst_rect.h % 32) == 1))) - ret = mdp_ppp_blit_split_height(mdp, &splitreq, - src_file, src_start, src_len, - dst_file, dst_start, dst_len); - else - ret = mdp_blit_and_wait(mdp, &splitreq, - src_file, src_start, src_len, - dst_file, dst_start, dst_len); - if (ret) - return ret; - - /* blit second region */ - if (((splitreq.flags & MDP_ROT_MASK) == MDP_ROT_270) || - ((splitreq.flags & MDP_ROT_MASK) == 0x0)) { - splitreq.src_rect.h = s_h_1; - splitreq.src_rect.y = s_y_1; - splitreq.dst_rect.h = d_h_1; - splitreq.dst_rect.y = d_y_1; - splitreq.src_rect.x = s_x_1; - splitreq.src_rect.w = s_w_1; - splitreq.dst_rect.x = d_x_1; - splitreq.dst_rect.w = d_w_1; - } else { - splitreq.src_rect.h = s_h_1; - splitreq.src_rect.y = s_y_1; - splitreq.dst_rect.h = d_h_0; - splitreq.dst_rect.y = d_y_0; - splitreq.src_rect.x = s_x_1; - splitreq.src_rect.w = s_w_1; - splitreq.dst_rect.x = d_x_0; - splitreq.dst_rect.w = d_w_0; - } - - if (unlikely((splitreq.dst_rect.h != 1) && - ((splitreq.dst_rect.h % 32 == 3) || - (splitreq.dst_rect.h % 32) == 1))) - ret = mdp_ppp_blit_split_height(mdp, &splitreq, - src_file, src_start, src_len, - dst_file, dst_start, dst_len); - else - ret = mdp_blit_and_wait(mdp, &splitreq, - src_file, src_start, src_len, - dst_file, dst_start, dst_len); - return ret; -} \ No newline at end of file diff --git a/drivers/video/msm/mdp_ppp.h b/drivers/video/msm/mdp_ppp.h index 357a7f06..dda21eca 100644 --- a/drivers/video/msm/mdp_ppp.h +++ b/drivers/video/msm/mdp_ppp.h @@ -16,7 +16,6 @@ #define _VIDEO_MSM_MDP_PPP_H_ #include -#define PPP_DUMP_BLITS 0 struct ppp_regs { uint32_t src0; @@ -69,10 +68,11 @@ int mdp_ppp_cfg_scale(const struct mdp_info *mdp, struct ppp_regs *regs, struct mdp_rect *src_rect, struct mdp_rect *dst_rect, uint32_t src_format, uint32_t dst_format); int mdp_ppp_load_blur(const struct mdp_info *mdp); -void mdp_dump_blit(struct mdp_blit_req *req); +#ifndef CONFIG_MSM_MDP31 +int mdp_ppp_cfg_edge_cond(struct mdp_blit_req *req, struct ppp_regs *regs); +#else -#if defined(CONFIG_MSM_MDP31) || defined(CONFIG_MSM_MDP302) int mdp_ppp_blit_split_width(struct mdp_info *mdp, const struct mdp_blit_req *req, struct file *src_file, unsigned long src_start, unsigned long src_len, struct file *dst_file, unsigned long dst_start, unsigned long dst_len); @@ -80,9 +80,6 @@ int mdp_ppp_blit_split_height(struct mdp_info *mdp, const struct mdp_blit_req *r struct file *src_file, unsigned long src_start, unsigned long src_len, struct file *dst_file, unsigned long dst_start, unsigned long dst_len); -#if defined(CONFIG_MSM_MDP302) -int mdp_ppp_cfg_edge_cond(struct mdp_blit_req *req, struct ppp_regs *regs); -#else static inline int mdp_ppp_cfg_edge_cond(struct mdp_blit_req *req, struct ppp_regs *regs) { @@ -90,10 +87,6 @@ static inline int mdp_ppp_cfg_edge_cond(struct mdp_blit_req *req, } #endif -#else -int mdp_ppp_cfg_edge_cond(struct mdp_blit_req *req, struct ppp_regs *regs); -#endif - int mdp_get_bytes_per_pixel(int format); int mdp_blit_and_wait(struct mdp_info *mdp, struct mdp_blit_req *req, struct file *src_file, unsigned long src_start, unsigned long src_len, diff --git a/drivers/video/msm/mdp_ppp31.c b/drivers/video/msm/mdp_ppp31.c index cc7b513c..9e0a3a60 100644 --- a/drivers/video/msm/mdp_ppp31.c +++ b/drivers/video/msm/mdp_ppp31.c @@ -331,4 +331,233 @@ void mdp_ppp_init_scale(const struct mdp_info *mdp) load_table(mdp, scale, 0); } +/* Splits a blit into two horizontal stripes. Used to work around MDP bugs */ +int mdp_ppp_blit_split_height(struct mdp_info *mdp, const struct mdp_blit_req *req, + struct file *src_file, unsigned long src_start, unsigned long src_len, + struct file *dst_file, unsigned long dst_start, unsigned long dst_len) +{ + int ret; + struct mdp_blit_req splitreq; + int s_x_0, s_x_1, s_w_0, s_w_1, s_y_0, s_y_1, s_h_0, s_h_1; + int d_x_0, d_x_1, d_w_0, d_w_1, d_y_0, d_y_1, d_h_0, d_h_1; + splitreq = *req; + /* break dest roi at height*/ + d_x_0 = d_x_1 = req->dst_rect.x; + d_w_0 = d_w_1 = req->dst_rect.w; + d_y_0 = req->dst_rect.y; + if (req->dst_rect.h % 32 == 3) + d_h_1 = (req->dst_rect.h - 3) / 2 - 1; + else + d_h_1 = (req->dst_rect.h - 1) / 2 - 1; + d_h_0 = req->dst_rect.h - d_h_1; + d_y_1 = d_y_0 + d_h_0; + if (req->dst_rect.h == 3) { + d_h_1 = 2; + d_h_0 = 2; + d_y_1 = d_y_0 + 1; + } + /* break source roi */ + if (splitreq.flags & MDP_ROT_90) { + s_y_0 = s_y_1 = req->src_rect.y; + s_h_0 = s_h_1 = req->src_rect.h; + s_x_0 = req->src_rect.x; + s_w_1 = (req->src_rect.w * d_h_1) / req->dst_rect.h; + s_w_0 = req->src_rect.w - s_w_1; + s_x_1 = s_x_0 + s_w_0; + if (d_h_1 >= 8 * s_w_1) { + s_w_1++; + s_x_1--; + } + } else { + s_x_0 = s_x_1 = req->src_rect.x; + s_w_0 = s_w_1 = req->src_rect.w; + s_y_0 = req->src_rect.y; + s_h_1 = (req->src_rect.h * d_h_1) / req->dst_rect.h; + s_h_0 = req->src_rect.h - s_h_1; + s_y_1 = s_y_0 + s_h_0; + if (d_h_1 >= 8 * s_h_1) { + s_h_1++; + s_y_1--; + } + } + + /* blit first region */ + if (((splitreq.flags & MDP_ROT_MASK) == MDP_ROT_90) || + ((splitreq.flags & MDP_ROT_MASK) == 0x0)) { + splitreq.src_rect.h = s_h_0; + splitreq.src_rect.y = s_y_0; + splitreq.dst_rect.h = d_h_0; + splitreq.dst_rect.y = d_y_0; + splitreq.src_rect.x = s_x_0; + splitreq.src_rect.w = s_w_0; + splitreq.dst_rect.x = d_x_0; + splitreq.dst_rect.w = d_w_0; + } else { + splitreq.src_rect.h = s_h_0; + splitreq.src_rect.y = s_y_0; + splitreq.dst_rect.h = d_h_1; + splitreq.dst_rect.y = d_y_1; + splitreq.src_rect.x = s_x_0; + splitreq.src_rect.w = s_w_0; + splitreq.dst_rect.x = d_x_1; + splitreq.dst_rect.w = d_w_1; + } + ret = mdp_blit_and_wait(mdp, &splitreq, + src_file, src_start, src_len, + dst_file, dst_start, dst_len); + if (ret) + return ret; + + /* blit second region */ + if (((splitreq.flags & MDP_ROT_MASK) == MDP_ROT_90) || + ((splitreq.flags & MDP_ROT_MASK) == 0x0)) { + splitreq.src_rect.h = s_h_1; + splitreq.src_rect.y = s_y_1; + splitreq.dst_rect.h = d_h_1; + splitreq.dst_rect.y = d_y_1; + splitreq.src_rect.x = s_x_1; + splitreq.src_rect.w = s_w_1; + splitreq.dst_rect.x = d_x_1; + splitreq.dst_rect.w = d_w_1; + } else { + splitreq.src_rect.h = s_h_1; + splitreq.src_rect.y = s_y_1; + splitreq.dst_rect.h = d_h_0; + splitreq.dst_rect.y = d_y_0; + splitreq.src_rect.x = s_x_1; + splitreq.src_rect.w = s_w_1; + splitreq.dst_rect.x = d_x_0; + splitreq.dst_rect.w = d_w_0; + } + ret = mdp_blit_and_wait(mdp, &splitreq, + src_file, src_start, src_len, + dst_file, dst_start, dst_len); + return ret; +} + +/* Splits a blit into two vertical stripes. Used to work around MDP bugs */ +int mdp_ppp_blit_split_width(struct mdp_info *mdp, const struct mdp_blit_req *req, + struct file *src_file, unsigned long src_start, unsigned long src_len, + struct file *dst_file, unsigned long dst_start, unsigned long dst_len) +{ + int ret; + struct mdp_blit_req splitreq; + int s_x_0, s_x_1, s_w_0, s_w_1, s_y_0, s_y_1, s_h_0, s_h_1; + int d_x_0, d_x_1, d_w_0, d_w_1, d_y_0, d_y_1, d_h_0, d_h_1; + splitreq = *req; + + /* break dest roi at width*/ + d_y_0 = d_y_1 = req->dst_rect.y; + d_h_0 = d_h_1 = req->dst_rect.h; + d_x_0 = req->dst_rect.x; + if (req->dst_rect.w % 32 == 6) + d_w_1 = req->dst_rect.w / 2 - 1; + else if (req->dst_rect.w % 2 == 0) + d_w_1 = req->dst_rect.w / 2; + else if (req->dst_rect.w % 32 == 3) + d_w_1 = (req->dst_rect.w - 3) / 2 - 1; + else + d_w_1 = (req->dst_rect.w - 1) / 2 - 1; + d_w_0 = req->dst_rect.w - d_w_1; + d_x_1 = d_x_0 + d_w_0; + if (req->dst_rect.w == 3) { + d_w_1 = 2; + d_w_0 = 2; + d_x_1 = d_x_0 + 1; + } + + /* break src roi at height or width*/ + if (splitreq.flags & MDP_ROT_90) { + s_x_0 = s_x_1 = req->src_rect.x; + s_w_0 = s_w_1 = req->src_rect.w; + s_y_0 = req->src_rect.y; + s_h_1 = (req->src_rect.h * d_w_1) / req->dst_rect.w; + s_h_0 = req->src_rect.h - s_h_1; + s_y_1 = s_y_0 + s_h_0; + if (d_w_1 >= 8 * s_h_1) { + s_h_1++; + s_y_1--; + } + } else { + s_y_0 = s_y_1 = req->src_rect.y; + s_h_0 = s_h_1 = req->src_rect.h; + s_x_0 = req->src_rect.x; + s_w_1 = (req->src_rect.w * d_w_1) / req->dst_rect.w; + s_w_0 = req->src_rect.w - s_w_1; + s_x_1 = s_x_0 + s_w_0; + if (d_w_1 >= 8 * s_w_1) { + s_w_1++; + s_x_1--; + } + } + + /* blit first region */ + if (((splitreq.flags & MDP_ROT_MASK) == MDP_ROT_270) || + ((splitreq.flags & MDP_ROT_MASK) == 0x0)) { + splitreq.src_rect.h = s_h_0; + splitreq.src_rect.y = s_y_0; + splitreq.dst_rect.h = d_h_0; + splitreq.dst_rect.y = d_y_0; + splitreq.src_rect.x = s_x_0; + splitreq.src_rect.w = s_w_0; + splitreq.dst_rect.x = d_x_0; + splitreq.dst_rect.w = d_w_0; + } else { + splitreq.src_rect.h = s_h_0; + splitreq.src_rect.y = s_y_0; + splitreq.dst_rect.h = d_h_1; + splitreq.dst_rect.y = d_y_1; + splitreq.src_rect.x = s_x_0; + splitreq.src_rect.w = s_w_0; + splitreq.dst_rect.x = d_x_1; + splitreq.dst_rect.w = d_w_1; + } + + if (unlikely((splitreq.dst_rect.h != 1) && + ((splitreq.dst_rect.h % 32 == 3) || + (splitreq.dst_rect.h % 32) == 1))) + ret = mdp_ppp_blit_split_height(mdp, &splitreq, + src_file, src_start, src_len, + dst_file, dst_start, dst_len); + else + ret = mdp_blit_and_wait(mdp, &splitreq, + src_file, src_start, src_len, + dst_file, dst_start, dst_len); + if (ret) + return ret; + + /* blit second region */ + if (((splitreq.flags & MDP_ROT_MASK) == MDP_ROT_270) || + ((splitreq.flags & MDP_ROT_MASK) == 0x0)) { + splitreq.src_rect.h = s_h_1; + splitreq.src_rect.y = s_y_1; + splitreq.dst_rect.h = d_h_1; + splitreq.dst_rect.y = d_y_1; + splitreq.src_rect.x = s_x_1; + splitreq.src_rect.w = s_w_1; + splitreq.dst_rect.x = d_x_1; + splitreq.dst_rect.w = d_w_1; + } else { + splitreq.src_rect.h = s_h_1; + splitreq.src_rect.y = s_y_1; + splitreq.dst_rect.h = d_h_0; + splitreq.dst_rect.y = d_y_0; + splitreq.src_rect.x = s_x_1; + splitreq.src_rect.w = s_w_1; + splitreq.dst_rect.x = d_x_0; + splitreq.dst_rect.w = d_w_0; + } + + if (unlikely((splitreq.dst_rect.h != 1) && + ((splitreq.dst_rect.h % 32 == 3) || + (splitreq.dst_rect.h % 32) == 1))) + ret = mdp_ppp_blit_split_height(mdp, &splitreq, + src_file, src_start, src_len, + dst_file, dst_start, dst_len); + else + ret = mdp_blit_and_wait(mdp, &splitreq, + src_file, src_start, src_len, + dst_file, dst_start, dst_len); + return ret; +} diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c index aa27389d..b9fc778e 100644 --- a/drivers/video/msm/msm_fb.c +++ b/drivers/video/msm/msm_fb.c @@ -32,11 +32,6 @@ #include #include #include -#include - -extern void start_drawing_late_resume(struct early_suspend *h); -static void msmfb_resume_handler(struct early_suspend *h); -static void msmfb_resume(struct work_struct *work); #define MSMFB_DEBUG 1 #ifdef CONFIG_FB_MSM_LOGO @@ -61,12 +56,13 @@ extern int load_565rle_image(char *filename); #define DLOG(mask, fmt, args...) \ do { \ - if ((msmfb_debug_mask | SUSPEND_RESUME) & mask) \ + if (msmfb_debug_mask & mask) \ printk(KERN_INFO "msmfb: "fmt, ##args); \ } while (0) #define BITS_PER_PIXEL(info) (info->fb->var.bits_per_pixel) #define BYTES_PER_PIXEL(info) (info->fb->var.bits_per_pixel >> 3) + static int msmfb_debug_mask; module_param_named(msmfb_debug_mask, msmfb_debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); @@ -100,59 +96,12 @@ struct msmfb_info { wait_queue_head_t frame_wq; struct workqueue_struct *resume_workqueue; struct work_struct resume_work; - struct work_struct msmfb_resume_work; struct msmfb_callback dma_callback; struct msmfb_callback vsync_callback; struct hrtimer fake_vsync; ktime_t vsync_request_time; - unsigned fb_resumed; }; -#ifdef CONFIG_FB_MSM_OVERLAY -#define USE_OVERLAY 1 -struct overlay_waitevent{ - uint32_t waked_up; - wait_queue_head_t event_wait; -}; -static struct overlay_waitevent overlay_event; -DEFINE_MUTEX(overlay_event_lock); -#endif - -#if (defined(CONFIG_USB_FUNCTION_PROJECTOR) || defined(CONFIG_USB_ANDROID_PROJECTOR)) -static spinlock_t fb_data_lock = SPIN_LOCK_UNLOCKED; -static struct msm_fb_info msm_fb_data; -int msmfb_get_var(struct msm_fb_info *tmp) -{ - unsigned long flags; - spin_lock_irqsave(&fb_data_lock, flags); - memcpy(tmp, &msm_fb_data, sizeof(msm_fb_data)); - spin_unlock_irqrestore(&fb_data_lock, flags); - return 0; -} - -/* projector need this, and very much */ -int msmfb_get_fb_area(void) -{ - int area; - unsigned long flags; - spin_lock_irqsave(&fb_data_lock, flags); - area = msm_fb_data.msmfb_area; - spin_unlock_irqrestore(&fb_data_lock, flags); - return area; -} - -static void msmfb_set_var(unsigned char *addr, int area) -{ - unsigned long flags; - - spin_lock_irqsave(&fb_data_lock, flags); - msm_fb_data.fb_addr = addr; - msm_fb_data.msmfb_area = area; - spin_unlock_irqrestore(&fb_data_lock, flags); - -} -#endif - static int msmfb_open(struct fb_info *info, int user) { return 0; @@ -299,18 +248,6 @@ static void msmfb_pan_update(struct fb_info *info, uint32_t left, uint32_t top, DLOG(SHOW_UPDATES, "update %d %d %d %d %d %d\n", left, top, eright, ebottom, yoffset, pan_display); - -#if !defined(CONFIG_MACH_HTCLEO) - // For some reason we need to remove it here, state is 1, we have to look later to this problem - if (msmfb->sleeping != AWAKE) - DLOG(SUSPEND_RESUME, "pan_update in state(%d)\n", msmfb->sleeping); -#endif - -#if (defined(CONFIG_USB_FUNCTION_PROJECTOR) || defined(CONFIG_USB_ANDROID_PROJECTOR)) - /* Jay, 8/1/09' */ - msmfb_set_var(msmfb->fb->screen_base, yoffset); -#endif - restart: spin_lock_irqsave(&msmfb->update_lock, irq_flags); @@ -327,8 +264,8 @@ restart: sleeping = msmfb->sleeping; /* on a full update, if the last frame has not completed, wait for it */ - if (pan_display && (msmfb->frame_requested != msmfb->frame_done || - sleeping == UPDATING)) { + if ((pan_display && msmfb->frame_requested != msmfb->frame_done) || + sleeping == UPDATING) { int ret; spin_unlock_irqrestore(&msmfb->update_lock, irq_flags); ret = wait_event_interruptible_timeout(msmfb->frame_wq, @@ -428,6 +365,7 @@ static void power_on_panel(struct work_struct *work) container_of(work, struct msmfb_info, resume_work); struct msm_panel_data *panel = msmfb->panel; unsigned long irq_flags; + mutex_lock(&msmfb->panel_init_lock); DLOG(SUSPEND_RESUME, "turning on panel\n"); if (msmfb->sleeping == UPDATING) { @@ -447,34 +385,6 @@ error: mutex_unlock(&msmfb->panel_init_lock); } -static BLOCKING_NOTIFIER_HEAD(display_chain_head); -int register_display_notifier(struct notifier_block *nb) -{ - return blocking_notifier_chain_register(&display_chain_head, nb); -} -static int display_notifier_callback(struct notifier_block *nfb, - unsigned long action, - void *ignored) -{ - struct msmfb_info *msm_fb = (struct msmfb_info *)ignored; - - switch (action) { - case NOTIFY_MSM_FB: - printk(KERN_DEBUG "NOTIFY_MSM_FB\n"); - msmfb_resume(&msm_fb->early_suspend); - break; - case NOTIFY_POWER: - /* nothing to do */ - break; - default: - printk(KERN_ERR "%s: unknown action in 0x%lx\n", - __func__, action); - return NOTIFY_BAD; - } - return NOTIFY_OK; -} - -/* -------------------------------------------------------------------------- */ #ifdef CONFIG_HAS_EARLYSUSPEND /* turn off the panel */ static void msmfb_earlier_suspend(struct early_suspend *h) @@ -491,12 +401,12 @@ static void msmfb_earlier_suspend(struct early_suspend *h) spin_unlock_irqrestore(&msmfb->update_lock, irq_flags); wait_event_timeout(msmfb->frame_wq, msmfb->frame_requested == msmfb->frame_done, HZ/10); -#ifndef CONFIG_MSM_MDP40 + mdp->dma(mdp, virt_to_phys(msmfb->black), 0, msmfb->fb->var.xres, msmfb->fb->var.yres, 0, 0, NULL, panel->interface_type); mdp->dma_wait(mdp, panel->interface_type); -#endif + /* turn off the panel */ panel->blank(panel); } @@ -507,31 +417,14 @@ static void msmfb_suspend(struct early_suspend *h) early_suspend); struct msm_panel_data *panel = msmfb->panel; /* suspend the panel */ -#ifdef CONFIG_FB_MSM_OVERLAY - /*check whether overlay done*/ - wait_event_interruptible_timeout( - overlay_event.event_wait, - (overlay_event.waked_up == ~USE_OVERLAY), - 10*HZ); - pr_info("wait event : %X\n", overlay_event.waked_up); -#endif panel->suspend(panel); - msmfb->fb_resumed = 0; mutex_unlock(&msmfb->panel_init_lock); } -static void msmfb_resume_handler(struct early_suspend *h) +static void msmfb_resume(struct early_suspend *h) { struct msmfb_info *msmfb = container_of(h, struct msmfb_info, - early_suspend); - queue_work(msmfb->resume_workqueue, &msmfb->msmfb_resume_work); - wait_event_interruptible_timeout(msmfb->frame_wq, msmfb->fb_resumed==1,HZ/2); -} - -static void msmfb_resume(struct work_struct *work) -{ - struct msmfb_info *msmfb = - container_of(work, struct msmfb_info, msmfb_resume_work); + early_suspend); struct msm_panel_data *panel = msmfb->panel; unsigned long irq_flags; @@ -545,9 +438,6 @@ static void msmfb_resume(struct work_struct *work) msmfb->sleeping = WAKING; DLOG(SUSPEND_RESUME, "ready, waiting for full update\n"); spin_unlock_irqrestore(&msmfb->update_lock, irq_flags); - start_drawing_late_resume(NULL); - msmfb->fb_resumed = 1; - wake_up(&msmfb->frame_wq); } #endif @@ -593,6 +483,7 @@ static int msmfb_set_par(struct fb_info *info) return -1; mdp->set_output_format(mdp, var->bits_per_pixel); fix->line_length = var->xres * var->bits_per_pixel / 8; + return 0; } @@ -611,13 +502,16 @@ int msmfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) var->reserved[1] >> 16, var->reserved[2] & 0xffff, var->reserved[2] >> 16); #endif +// printk("+PAN_DISP1\n"); msmfb_pan_update(info, var->reserved[1] & 0xffff, var->reserved[1] >> 16, var->reserved[2] & 0xffff, var->reserved[2] >> 16, var->yoffset, 1); +// printk("-PAN_DISP1\n"); } else { - msmfb_pan_update(info, 0, 0, info->var.xres, info->var.yres, - var->yoffset, 1); +// printk("+PAN_DISP2\n"); + msmfb_pan_update(info, 0, 0, info->var.xres, info->var.yres, var->yoffset, 1); +// printk("-PAN_DISP2\n"); } return 0; } @@ -672,91 +566,6 @@ static int msmfb_blit(struct fb_info *info, } return 0; } -#ifdef CONFIG_FB_MSM_OVERLAY -static int msmfb_overlay_get(struct fb_info *info, void __user *p) -{ - struct mdp_overlay req; - int ret; - - if (copy_from_user(&req, p, sizeof(req))) - return -EFAULT; - - ret = mdp->overlay_get(mdp, info, &req); - - if (ret) { - printk(KERN_ERR "%s: ioctl failed \n", - __func__); - return ret; - } - if (copy_to_user(p, &req, sizeof(req))) { - printk(KERN_ERR "%s: copy2user failed \n", - __func__); - return -EFAULT; - } - - return 0; -} - -static int msmfb_overlay_set(struct fb_info *info, void __user *p) -{ - struct mdp_overlay req; - int ret; - - if (copy_from_user(&req, p, sizeof(req))) - return -EFAULT; - - ret = mdp->overlay_set(mdp, info, &req); - if (ret) { - printk(KERN_ERR "%s:ioctl failed \n", - __func__); - return ret; - } - - if (copy_to_user(p, &req, sizeof(req))) { - printk(KERN_ERR "%s: copy2user failed \n", - __func__); - return -EFAULT; - } - - return 0; -} - -static int msmfb_overlay_unset(struct fb_info *info, unsigned long *argp) -{ - int ret, ndx; - - ret = copy_from_user(&ndx, argp, sizeof(ndx)); - if (ret) { - printk(KERN_ERR "%s:msmfb_overlay_unset ioctl failed \n", - __func__); - return ret; - } - - return mdp->overlay_unset(mdp, info, ndx); -} - -static int msmfb_overlay_play(struct fb_info *info, unsigned long *argp) -{ - int ret; - struct msmfb_overlay_data req; - struct file *p_src_file = 0; - - ret = copy_from_user(&req, argp, sizeof(req)); - if (ret) { - printk(KERN_ERR "%s:msmfb_overlay_play ioctl failed \n", - __func__); - return ret; - } - - ret = mdp->overlay_play(mdp, info, &req, &p_src_file); - - if (p_src_file) - put_pmem_file(p_src_file); - - return ret; -} - -#endif DEFINE_MUTEX(mdp_ppp_lock); @@ -771,13 +580,14 @@ static int msmfb_ioctl(struct fb_info *p, unsigned int cmd, unsigned long arg) switch (cmd) { case MSMFB_GRP_DISP: + printk("GRP_DISP\n"); mdp->set_grp_disp(mdp, arg); break; case MSMFB_BLIT: #if PRINT_BLIT_TIME t1 = ktime_get(); #endif - ret = msmfb_blit(p, argp); + ret = msmfb_blit(p, argp); if (ret) return ret; #if PRINT_BLIT_TIME @@ -786,38 +596,6 @@ static int msmfb_ioctl(struct fb_info *p, unsigned int cmd, unsigned long arg) ktime_to_ns(t2) - ktime_to_ns(t1)); #endif break; -#ifdef CONFIG_FB_MSM_OVERLAY - case MSMFB_OVERLAY_GET: - printk("CONFIG_FB_MSM_OVERLAY\n"); - //down(&mdp_ppp_lock); - ret = msmfb_overlay_get(p, argp); - //up(&mdp_ppp_lock); - break; - case MSMFB_OVERLAY_SET: - printk("MSMFB_OVERLAY_SET\n"); - //down(&mdp_ppp_lock); - ret = msmfb_overlay_set(p, argp); - mutex_lock(&overlay_event_lock); - overlay_event.waked_up = USE_OVERLAY; - mutex_unlock(&overlay_event_lock); - //up(&mdp_ppp_lock); - break; - case MSMFB_OVERLAY_UNSET: - printk("MSMFB_OVERLAY_UNSET\n"); - //down(&mdp_ppp_lock); - ret = msmfb_overlay_unset(p, argp); - mutex_lock(&overlay_event_lock); - overlay_event.waked_up = ~USE_OVERLAY; - wake_up(&overlay_event.event_wait); - mutex_unlock(&overlay_event_lock); - //up(&mdp_ppp_lock); - break; - case MSMFB_OVERLAY_PLAY: - //down(&mdp_ppp_lock); - ret = msmfb_overlay_play(p, argp); - //up(&mdp_ppp_lock); - break; -#endif default: printk(KERN_INFO "msmfb unknown ioctl: %d\n", cmd); return -EINVAL; @@ -880,8 +658,6 @@ static struct file_operations debug_fops = { }; #endif -#define BITS_PER_PIXEL 16 - static void setup_fb_info(struct msmfb_info *msmfb) { struct fb_info *fb_info = msmfb->fb; @@ -897,14 +673,13 @@ static void setup_fb_info(struct msmfb_info *msmfb) fb_info->fix.type = FB_TYPE_PACKED_PIXELS; fb_info->fix.visual = FB_VISUAL_TRUECOLOR; fb_info->fix.line_length = msmfb->xres * 2; - fb_info->var.xres = msmfb->xres; fb_info->var.yres = msmfb->yres; fb_info->var.width = msmfb->panel->fb_data->width; fb_info->var.height = msmfb->panel->fb_data->height; fb_info->var.xres_virtual = msmfb->xres; fb_info->var.yres_virtual = msmfb->yres * 2; - fb_info->var.bits_per_pixel = BITS_PER_PIXEL; + fb_info->var.bits_per_pixel = 16; fb_info->var.accel_flags = 0; fb_info->var.yoffset = 0; @@ -913,11 +688,8 @@ static void setup_fb_info(struct msmfb_info *msmfb) /* set the param in the fixed screen, so userspace can't * change it. This will be used to check for the * capability. */ - - /* FIX ME: every panel support partial update? fb_info->fix.reserved[0] = 0x5444; fb_info->fix.reserved[1] = 0x5055; - */ /* This preloads the value so that if userspace doesn't * change it, it will be a full update */ @@ -945,14 +717,6 @@ static void setup_fb_info(struct msmfb_info *msmfb) PP[0] = 0; for (r = 1; r < 16; r++) PP[r] = 0xffffffff; - - /* Jay add, 7/1/09' */ -#if (defined(CONFIG_USB_FUNCTION_PROJECTOR) || defined(CONFIG_USB_ANDROID_PROJECTOR)) - msm_fb_data.xres = msmfb->xres; - msm_fb_data.yres = msmfb->yres; - printk(KERN_INFO "setup_fb_info msmfb->xres %d, msmfb->yres %d\n", - msmfb->xres,msmfb->yres); -#endif } static int setup_fbmem(struct msmfb_info *msmfb, struct platform_device *pdev) @@ -1017,17 +781,12 @@ static int msmfb_probe(struct platform_device *pdev) if (ret) goto error_setup_fbmem; -#if (defined(CONFIG_USB_FUNCTION_PROJECTOR) || defined(CONFIG_USB_ANDROID_PROJECTOR)) - /* Jay, 8/1/09' */ - msmfb_set_var(msmfb->fb->screen_base, 0); -#endif - setup_fb_info(msmfb); spin_lock_init(&msmfb->update_lock); mutex_init(&msmfb->panel_init_lock); init_waitqueue_head(&msmfb->frame_wq); - msmfb->resume_workqueue = create_rt_workqueue("panel_on"); + msmfb->resume_workqueue = create_workqueue("panel_on"); if (msmfb->resume_workqueue == NULL) { printk(KERN_ERR "failed to create panel_on workqueue\n"); ret = -ENOMEM; @@ -1040,9 +799,8 @@ static int msmfb_probe(struct platform_device *pdev) wake_lock_init(&msmfb->idle_lock, WAKE_LOCK_IDLE, "msmfb_idle_lock"); #ifdef CONFIG_HAS_EARLYSUSPEND - INIT_WORK(&msmfb->msmfb_resume_work, msmfb_resume); msmfb->early_suspend.suspend = msmfb_suspend; - msmfb->early_suspend.resume = msmfb_resume_handler; + msmfb->early_suspend.resume = msmfb_resume; msmfb->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; register_early_suspend(&msmfb->early_suspend); @@ -1064,6 +822,7 @@ static int msmfb_probe(struct platform_device *pdev) hrtimer_init(&msmfb->fake_vsync, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + msmfb->fake_vsync.function = msmfb_fake_vsync; ret = register_framebuffer(fb); @@ -1072,13 +831,6 @@ static int msmfb_probe(struct platform_device *pdev) msmfb->sleeping = WAKING; -#ifdef CONFIG_FB_MSM_OVERLAY - /*init wait event*/ - init_waitqueue_head(&overlay_event.event_wait); - /*init waked_up value*/ - overlay_event.waked_up = ~USE_OVERLAY; -#endif - #ifdef CONFIG_FB_MSM_LOGO if (!load_565rle_image(INIT_IMAGE_FILE)) { /* Flip buffer */ @@ -1090,8 +842,6 @@ static int msmfb_probe(struct platform_device *pdev) msmfb->yres, 0, 1); } #endif - /* Jay, 29/12/08' */ - display_notifier(display_notifier_callback, NOTIFY_MSM_FB); return 0; error_register_framebuffer: @@ -1104,35 +854,9 @@ error_setup_fbmem: return ret; } -static void msmfb_shutdown(struct platform_device *pdev) -{ - struct msm_panel_data *panel = pdev->dev.platform_data; - struct fb_info *fb; - struct msmfb_info *msmfb; - - printk(KERN_INFO "%s\n", __func__); - fb = registered_fb[0]; - if (!fb) { - printk(KERN_ERR "fb0 unavailable.\n"); - return; - } - msmfb = fb->par; - - mdp->dma(mdp, virt_to_phys(msmfb->black), 0, - msmfb->fb->var.xres, msmfb->fb->var.yres, 0, 0, - NULL, panel->interface_type); - - if (panel->blank) - panel->blank(panel); - - if (panel->shutdown) - panel->shutdown(panel); -} - static struct platform_driver msm_panel_driver = { /* need to write remove */ .probe = msmfb_probe, - .shutdown = msmfb_shutdown, .driver = {.name = "msm_panel"}, };