diff options
author | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2011-09-20 09:49:49 +0300 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2012-02-22 10:55:29 +0200 |
commit | 8dc50ec7755650859a7bfc17de8846ef1efa24a4 (patch) | |
tree | af51e4a1be8cd30bb8f67c40611c74c664a064d4 /drivers/video/omap | |
parent | fdcb68884b3b0def9cc410d07adbafe7c3a9e537 (diff) |
OMAPFB: Remove OMAP2/3 support from old omapfb driver
Old omapfb driver (drivers/video/omap/) is no longer used for OMAP2+
devices, and thus we can remove OMAP2+ support from it and make it an
OMAP1 omapfb driver.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video/omap')
-rw-r--r-- | drivers/video/omap/Kconfig | 9 | ||||
-rw-r--r-- | drivers/video/omap/Makefile | 5 | ||||
-rw-r--r-- | drivers/video/omap/dispc.c | 1547 | ||||
-rw-r--r-- | drivers/video/omap/dispc.h | 46 | ||||
-rw-r--r-- | drivers/video/omap/omapfb.h | 4 | ||||
-rw-r--r-- | drivers/video/omap/omapfb_main.c | 16 | ||||
-rw-r--r-- | drivers/video/omap/rfbi.c | 598 |
7 files changed, 5 insertions, 2220 deletions
diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig index ab234d59711..1e7536d9a8f 100644 --- a/drivers/video/omap/Kconfig +++ b/drivers/video/omap/Kconfig @@ -1,11 +1,10 @@ config FB_OMAP tristate "OMAP frame buffer support (EXPERIMENTAL)" - depends on FB && (OMAP2_DSS = "n") - depends on ARCH_OMAP1 || ARCH_OMAP2 || ARCH_OMAP3 + depends on FB + depends on ARCH_OMAP1 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select TWL4030_CORE if MACH_OMAP_2430SDP help Frame buffer driver for OMAP based boards. @@ -42,7 +41,7 @@ config FB_OMAP_LCD_MIPID config FB_OMAP_BOOTLOADER_INIT bool "Check bootloader initialization" - depends on FB_OMAP || FB_OMAP2 + depends on FB_OMAP help Say Y here if you want to enable checking if the bootloader has already initialized the display controller. In this case the @@ -61,7 +60,7 @@ config FB_OMAP_CONSISTENT_DMA_SIZE config FB_OMAP_DMA_TUNE bool "Set DMA SDRAM access priority high" - depends on FB_OMAP && ARCH_OMAP1 + depends on FB_OMAP help On systems in which video memory is in system memory (SDRAM) this will speed up graphics DMA operations. diff --git a/drivers/video/omap/Makefile b/drivers/video/omap/Makefile index 7042a4ac707..79653750448 100644 --- a/drivers/video/omap/Makefile +++ b/drivers/video/omap/Makefile @@ -1,5 +1,5 @@ # -# Makefile for the new OMAP framebuffer device driver +# Makefile for the OMAP1 framebuffer device driver # obj-$(CONFIG_FB_OMAP) += omapfb.o @@ -7,11 +7,8 @@ obj-$(CONFIG_FB_OMAP) += omapfb.o objs-yy := omapfb_main.o objs-y$(CONFIG_ARCH_OMAP1) += lcdc.o -objs-y$(CONFIG_ARCH_OMAP2) += dispc.o -objs-y$(CONFIG_ARCH_OMAP3) += dispc.o objs-$(CONFIG_ARCH_OMAP1)$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += sossi.o -objs-$(CONFIG_ARCH_OMAP2)$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += rfbi.o objs-y$(CONFIG_FB_OMAP_LCDC_HWA742) += hwa742.o diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c deleted file mode 100644 index 6f61e781f15..00000000000 --- a/drivers/video/omap/dispc.c +++ /dev/null @@ -1,1547 +0,0 @@ -/* - * OMAP2 display controller support - * - * Copyright (C) 2005 Nokia Corporation - * Author: Imre Deak <imre.deak@nokia.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/dma-mapping.h> -#include <linux/mm.h> -#include <linux/vmalloc.h> -#include <linux/clk.h> -#include <linux/io.h> -#include <linux/platform_device.h> -#include <linux/slab.h> - -#include <plat/sram.h> -#include <plat/board.h> - -#include "omapfb.h" -#include "dispc.h" - -#define MODULE_NAME "dispc" - -#define DSS_BASE 0x48050000 -#define DSS_SYSCONFIG 0x0010 - -#define DISPC_BASE 0x48050400 - -/* DISPC common */ -#define DISPC_REVISION 0x0000 -#define DISPC_SYSCONFIG 0x0010 -#define DISPC_SYSSTATUS 0x0014 -#define DISPC_IRQSTATUS 0x0018 -#define DISPC_IRQENABLE 0x001C -#define DISPC_CONTROL 0x0040 -#define DISPC_CONFIG 0x0044 -#define DISPC_CAPABLE 0x0048 -#define DISPC_DEFAULT_COLOR0 0x004C -#define DISPC_DEFAULT_COLOR1 0x0050 -#define DISPC_TRANS_COLOR0 0x0054 -#define DISPC_TRANS_COLOR1 0x0058 -#define DISPC_LINE_STATUS 0x005C -#define DISPC_LINE_NUMBER 0x0060 -#define DISPC_TIMING_H 0x0064 -#define DISPC_TIMING_V 0x0068 -#define DISPC_POL_FREQ 0x006C -#define DISPC_DIVISOR 0x0070 -#define DISPC_SIZE_DIG 0x0078 -#define DISPC_SIZE_LCD 0x007C - -#define DISPC_DATA_CYCLE1 0x01D4 -#define DISPC_DATA_CYCLE2 0x01D8 -#define DISPC_DATA_CYCLE3 0x01DC - -/* DISPC GFX plane */ -#define DISPC_GFX_BA0 0x0080 -#define DISPC_GFX_BA1 0x0084 -#define DISPC_GFX_POSITION 0x0088 -#define DISPC_GFX_SIZE 0x008C -#define DISPC_GFX_ATTRIBUTES 0x00A0 -#define DISPC_GFX_FIFO_THRESHOLD 0x00A4 -#define DISPC_GFX_FIFO_SIZE_STATUS 0x00A8 -#define DISPC_GFX_ROW_INC 0x00AC -#define DISPC_GFX_PIXEL_INC 0x00B0 -#define DISPC_GFX_WINDOW_SKIP 0x00B4 -#define DISPC_GFX_TABLE_BA 0x00B8 - -/* DISPC Video plane 1/2 */ -#define DISPC_VID1_BASE 0x00BC -#define DISPC_VID2_BASE 0x014C - -/* Offsets into DISPC_VID1/2_BASE */ -#define DISPC_VID_BA0 0x0000 -#define DISPC_VID_BA1 0x0004 -#define DISPC_VID_POSITION 0x0008 -#define DISPC_VID_SIZE 0x000C -#define DISPC_VID_ATTRIBUTES 0x0010 -#define DISPC_VID_FIFO_THRESHOLD 0x0014 -#define DISPC_VID_FIFO_SIZE_STATUS 0x0018 -#define DISPC_VID_ROW_INC 0x001C -#define DISPC_VID_PIXEL_INC 0x0020 -#define DISPC_VID_FIR 0x0024 -#define DISPC_VID_PICTURE_SIZE 0x0028 -#define DISPC_VID_ACCU0 0x002C -#define DISPC_VID_ACCU1 0x0030 - -/* 8 elements in 8 byte increments */ -#define DISPC_VID_FIR_COEF_H0 0x0034 -/* 8 elements in 8 byte increments */ -#define DISPC_VID_FIR_COEF_HV0 0x0038 -/* 5 elements in 4 byte increments */ -#define DISPC_VID_CONV_COEF0 0x0074 - -#define DISPC_IRQ_FRAMEMASK 0x0001 -#define DISPC_IRQ_VSYNC 0x0002 -#define DISPC_IRQ_EVSYNC_EVEN 0x0004 -#define DISPC_IRQ_EVSYNC_ODD 0x0008 -#define DISPC_IRQ_ACBIAS_COUNT_STAT 0x0010 -#define DISPC_IRQ_PROG_LINE_NUM 0x0020 -#define DISPC_IRQ_GFX_FIFO_UNDERFLOW 0x0040 -#define DISPC_IRQ_GFX_END_WIN 0x0080 -#define DISPC_IRQ_PAL_GAMMA_MASK 0x0100 -#define DISPC_IRQ_OCP_ERR 0x0200 -#define DISPC_IRQ_VID1_FIFO_UNDERFLOW 0x0400 -#define DISPC_IRQ_VID1_END_WIN 0x0800 -#define DISPC_IRQ_VID2_FIFO_UNDERFLOW 0x1000 -#define DISPC_IRQ_VID2_END_WIN 0x2000 -#define DISPC_IRQ_SYNC_LOST 0x4000 - -#define DISPC_IRQ_MASK_ALL 0x7fff - -#define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \ - DISPC_IRQ_VID1_FIFO_UNDERFLOW | \ - DISPC_IRQ_VID2_FIFO_UNDERFLOW | \ - DISPC_IRQ_SYNC_LOST) - -#define RFBI_CONTROL 0x48050040 - -#define MAX_PALETTE_SIZE (256 * 16) - -#define FLD_MASK(pos, len) (((1 << len) - 1) << pos) - -#define MOD_REG_FLD(reg, mask, val) \ - dispc_write_reg((reg), (dispc_read_reg(reg) & ~(mask)) | (val)); - -#define OMAP2_SRAM_START 0x40200000 -/* Maximum size, in reality this is smaller if SRAM is partially locked. */ -#define OMAP2_SRAM_SIZE 0xa0000 /* 640k */ - -/* We support the SDRAM / SRAM types. See OMAPFB_PLANE_MEMTYPE_* in omapfb.h */ -#define DISPC_MEMTYPE_NUM 2 - -#define RESMAP_SIZE(_page_cnt) \ - ((_page_cnt + (sizeof(unsigned long) * 8) - 1) / 8) -#define RESMAP_PTR(_res_map, _page_nr) \ - (((_res_map)->map) + (_page_nr) / (sizeof(unsigned long) * 8)) -#define RESMAP_MASK(_page_nr) \ - (1 << ((_page_nr) & (sizeof(unsigned long) * 8 - 1))) - -struct resmap { - unsigned long start; - unsigned page_cnt; - unsigned long *map; -}; - -#define MAX_IRQ_HANDLERS 4 - -static struct { - void __iomem *base; - - struct omapfb_mem_desc mem_desc; - struct resmap *res_map[DISPC_MEMTYPE_NUM]; - atomic_t map_count[OMAPFB_PLANE_NUM]; - - dma_addr_t palette_paddr; - void *palette_vaddr; - - int ext_mode; - - struct { - u32 irq_mask; - void (*callback)(void *); - void *data; - } irq_handlers[MAX_IRQ_HANDLERS]; - struct completion frame_done; - - int fir_hinc[OMAPFB_PLANE_NUM]; - int fir_vinc[OMAPFB_PLANE_NUM]; - - struct clk *dss_ick, *dss1_fck; - struct clk *dss_54m_fck; - - enum omapfb_update_mode update_mode; - struct omapfb_device *fbdev; - - struct omapfb_color_key color_key; -} dispc; - -static void enable_lcd_clocks(int enable); - -static void inline dispc_write_reg(int idx, u32 val) -{ - __raw_writel(val, dispc.base + idx); -} - -static u32 inline dispc_read_reg(int idx) -{ - u32 l = __raw_readl(dispc.base + idx); - return l; -} - -/* Select RFBI or bypass mode */ -static void enable_rfbi_mode(int enable) -{ - void __iomem *rfbi_control; - u32 l; - - l = dispc_read_reg(DISPC_CONTROL); - /* Enable RFBI, GPIO0/1 */ - l &= ~((1 << 11) | (1 << 15) | (1 << 16)); - l |= enable ? (1 << 11) : 0; - /* RFBI En: GPIO0/1=10 RFBI Dis: GPIO0/1=11 */ - l |= 1 << 15; - l |= enable ? 0 : (1 << 16); - dispc_write_reg(DISPC_CONTROL, l); - - /* Set bypass mode in RFBI module */ - rfbi_control = ioremap(RFBI_CONTROL, SZ_1K); - if (!rfbi_control) { - pr_err("Unable to ioremap rfbi_control\n"); - return; - } - l = __raw_readl(rfbi_control); - l |= enable ? 0 : (1 << 1); - __raw_writel(l, rfbi_control); - iounmap(rfbi_control); -} - -static void set_lcd_data_lines(int data_lines) -{ - u32 l; - int code = 0; - - switch (data_lines) { - case 12: - code = 0; - break; - case 16: - code = 1; - break; - case 18: - code = 2; - break; - case 24: - code = 3; - break; - default: - BUG(); - } - - l = dispc_read_reg(DISPC_CONTROL); - l &= ~(0x03 << 8); - l |= code << 8; - dispc_write_reg(DISPC_CONTROL, l); -} - -static void set_load_mode(int mode) -{ - BUG_ON(mode & ~(DISPC_LOAD_CLUT_ONLY | DISPC_LOAD_FRAME_ONLY | - DISPC_LOAD_CLUT_ONCE_FRAME)); - MOD_REG_FLD(DISPC_CONFIG, 0x03 << 1, mode << 1); -} - -void omap_dispc_set_lcd_size(int x, int y) -{ - BUG_ON((x > (1 << 11)) || (y > (1 << 11))); - enable_lcd_clocks(1); - MOD_REG_FLD(DISPC_SIZE_LCD, FLD_MASK(16, 11) | FLD_MASK(0, 11), - ((y - 1) << 16) | (x - 1)); - enable_lcd_clocks(0); -} -EXPORT_SYMBOL(omap_dispc_set_lcd_size); - -void omap_dispc_set_digit_size(int x, int y) -{ - BUG_ON((x > (1 << 11)) || (y > (1 << 11))); - enable_lcd_clocks(1); - MOD_REG_FLD(DISPC_SIZE_DIG, FLD_MASK(16, 11) | FLD_MASK(0, 11), - ((y - 1) << 16) | (x - 1)); - enable_lcd_clocks(0); -} -EXPORT_SYMBOL(omap_dispc_set_digit_size); - -static void setup_plane_fifo(int plane, int ext_mode) -{ - const u32 ftrs_reg[] = { DISPC_GFX_FIFO_THRESHOLD, - DISPC_VID1_BASE + DISPC_VID_FIFO_THRESHOLD, - DISPC_VID2_BASE + DISPC_VID_FIFO_THRESHOLD }; - const u32 fsz_reg[] = { DISPC_GFX_FIFO_SIZE_STATUS, - DISPC_VID1_BASE + DISPC_VID_FIFO_SIZE_STATUS, - DISPC_VID2_BASE + DISPC_VID_FIFO_SIZE_STATUS }; - int low, high; - u32 l; - - BUG_ON(plane > 2); - - l = dispc_read_reg(fsz_reg[plane]); - l &= FLD_MASK(0, 11); - if (ext_mode) { - low = l * 3 / 4; - high = l; - } else { - low = l / 4; - high = l * 3 / 4; - } - MOD_REG_FLD(ftrs_reg[plane], FLD_MASK(16, 12) | FLD_MASK(0, 12), - (high << 16) | low); -} - -void omap_dispc_enable_lcd_out(int enable) -{ - enable_lcd_clocks(1); - MOD_REG_FLD(DISPC_CONTROL, 1, enable ? 1 : 0); - enable_lcd_clocks(0); -} -EXPORT_SYMBOL(omap_dispc_enable_lcd_out); - -void omap_dispc_enable_digit_out(int enable) -{ - enable_lcd_clocks(1); - MOD_REG_FLD(DISPC_CONTROL, 1 << 1, enable ? 1 << 1 : 0); - enable_lcd_clocks(0); -} -EXPORT_SYMBOL(omap_dispc_enable_digit_out); - -static inline int _setup_plane(int plane, int channel_out, - u32 paddr, int screen_width, - int pos_x, int pos_y, int width, int height, - int color_mode) -{ - const u32 at_reg[] = { DISPC_GFX_ATTRIBUTES, - DISPC_VID1_BASE + DISPC_VID_ATTRIBUTES, - DISPC_VID2_BASE + DISPC_VID_ATTRIBUTES }; - const u32 ba_reg[] = { DISPC_GFX_BA0, DISPC_VID1_BASE + DISPC_VID_BA0, - DISPC_VID2_BASE + DISPC_VID_BA0 }; - const u32 ps_reg[] = { DISPC_GFX_POSITION, - DISPC_VID1_BASE + DISPC_VID_POSITION, - DISPC_VID2_BASE + DISPC_VID_POSITION }; - const u32 sz_reg[] = { DISPC_GFX_SIZE, - DISPC_VID1_BASE + DISPC_VID_PICTURE_SIZE, - DISPC_VID2_BASE + DISPC_VID_PICTURE_SIZE }; - const u32 ri_reg[] = { DISPC_GFX_ROW_INC, - DISPC_VID1_BASE + DISPC_VID_ROW_INC, - DISPC_VID2_BASE + DISPC_VID_ROW_INC }; - const u32 vs_reg[] = { 0, DISPC_VID1_BASE + DISPC_VID_SIZE, - DISPC_VID2_BASE + DISPC_VID_SIZE }; - - int chout_shift, burst_shift; - int chout_val; - int color_code; - int bpp; - int cconv_en; - int set_vsize; - u32 l; - -#ifdef VERBOSE - dev_dbg(dispc.fbdev->dev, "plane %d channel %d paddr %#08x scr_width %d" - " pos_x %d pos_y %d width %d height %d color_mode %d\n", - plane, channel_out, paddr, screen_width, pos_x, pos_y, - width, height, color_mode); -#endif - - set_vsize = 0; - switch (plane) { - case OMAPFB_PLANE_GFX: - burst_shift = 6; - chout_shift = 8; - break; - case OMAPFB_PLANE_VID1: - case OMAPFB_PLANE_VID2: - burst_shift = 14; - chout_shift = 16; - set_vsize = 1; - break; - default: - return -EINVAL; - } - - switch (channel_out) { - case OMAPFB_CHANNEL_OUT_LCD: - chout_val = 0; - break; - case OMAPFB_CHANNEL_OUT_DIGIT: - chout_val = 1; - break; - default: - return -EINVAL; - } - - cconv_en = 0; - switch (color_mode) { - case OMAPFB_COLOR_RGB565: - color_code = DISPC_RGB_16_BPP; - bpp = 16; - break; - case OMAPFB_COLOR_YUV422: - if (plane == 0) - return -EINVAL; - color_code = DISPC_UYVY_422; - cconv_en = 1; - bpp = 16; - break; - case OMAPFB_COLOR_YUY422: - if (plane == 0) - return -EINVAL; - color_code = DISPC_YUV2_422; - cconv_en = 1; - bpp = 16; - break; - default: - return -EINVAL; - } - - l = dispc_read_reg(at_reg[plane]); - - l &= ~(0x0f << 1); - l |= color_code << 1; - l &= ~(1 << 9); - l |= cconv_en << 9; - - l &= ~(0x03 << burst_shift); - l |= DISPC_BURST_8x32 << burst_shift; - - l &= ~(1 << chout_shift); - l |= chout_val << chout_shift; - - dispc_write_reg(at_reg[plane], l); - - dispc_write_reg(ba_reg[plane], paddr); - MOD_REG_FLD(ps_reg[plane], - FLD_MASK(16, 11) | FLD_MASK(0, 11), (pos_y << 16) | pos_x); - - MOD_REG_FLD(sz_reg[plane], FLD_MASK(16, 11) | FLD_MASK(0, 11), - ((height - 1) << 16) | (width - 1)); - - if (set_vsize) { - /* Set video size if set_scale hasn't set it */ - if (!dispc.fir_vinc[plane]) - MOD_REG_FLD(vs_reg[plane], - FLD_MASK(16, 11), (height - 1) << 16); - if (!dispc.fir_hinc[plane]) - MOD_REG_FLD(vs_reg[plane], - FLD_MASK(0, 11), width - 1); - } - - dispc_write_reg(ri_reg[plane], (screen_width - width) * bpp / 8 + 1); - - return height * screen_width * bpp / 8; -} - -static int omap_dispc_setup_plane(int plane, int channel_out, - unsigned long offset, - int screen_width, - int pos_x, int pos_y, int width, int height, - int color_mode) -{ - u32 paddr; - int r; - - if ((unsigned)plane > dispc.mem_desc.region_cnt) - return -EINVAL; - paddr = dispc.mem_desc.region[plane].paddr + offset; - enable_lcd_clocks(1); - r = _setup_plane(plane, channel_out, paddr, - screen_width, - pos_x, pos_y, width, height, color_mode); - enable_lcd_clocks(0); - return r; -} - -static void write_firh_reg(int plane, int reg, u32 value) -{ - u32 base; - - if (plane == 1) - base = DISPC_VID1_BASE + DISPC_VID_FIR_COEF_H0; - else - base = DISPC_VID2_BASE + DISPC_VID_FIR_COEF_H0; - dispc_write_reg(base + reg * 8, value); -} - -static void write_firhv_reg(int plane, int reg, u32 value) -{ - u32 base; - - if (plane == 1) - base = DISPC_VID1_BASE + DISPC_VID_FIR_COEF_HV0; - else - base = DISPC_VID2_BASE + DISPC_VID_FIR_COEF_HV0; - dispc_write_reg(base + reg * 8, value); -} - -static void set_upsampling_coef_table(int plane) -{ - const u32 coef[][2] = { - { 0x00800000, 0x00800000 }, - { 0x0D7CF800, 0x037B02FF }, - { 0x1E70F5FF, 0x0C6F05FE }, - { 0x335FF5FE, 0x205907FB }, - { 0xF74949F7, 0x00404000 }, - { 0xF55F33FB, 0x075920FE }, - { 0xF5701EFE, 0x056F0CFF }, - { 0xF87C0DFF, 0x027B0300 }, - }; - int i; - - for (i = 0; i < 8; i++) { - write_firh_reg(plane, i, coef[i][0]); - write_firhv_reg(plane, i, coef[i][1]); - } -} - -static int omap_dispc_set_scale(int plane, - int orig_width, int orig_height, - int out_width, int out_height) -{ - const u32 at_reg[] = { 0, DISPC_VID1_BASE + DISPC_VID_ATTRIBUTES, - DISPC_VID2_BASE + DISPC_VID_ATTRIBUTES }; - const u32 vs_reg[] = { 0, DISPC_VID1_BASE + DISPC_VID_SIZE, - DISPC_VID2_BASE + DISPC_VID_SIZE }; - const u32 fir_reg[] = { 0, DISPC_VID1_BASE + DISPC_VID_FIR, - DISPC_VID2_BASE + DISPC_VID_FIR }; - - u32 l; - int fir_hinc; - int fir_vinc; - - if ((unsigned)plane > OMAPFB_PLANE_NUM) - return -ENODEV; - - if (plane == OMAPFB_PLANE_GFX && - (out_width != orig_width || out_height != orig_height)) - return -EINVAL; - - enable_lcd_clocks(1); - if (orig_width < out_width) { - /* - * Upsampling. - * Currently you can only scale both dimensions in one way. - */ - if (orig_height > out_height || - orig_width * 8 < out_width || - orig_height * 8 < out_height) { - enable_lcd_clocks(0); - return -EINVAL; - } - set_upsampling_coef_table(plane); - } else if (orig_width > out_width) { - /* Downsampling not yet supported - */ - - enable_lcd_clocks(0); - return -EINVAL; - } - if (!orig_width || orig_width == out_width) - fir_hinc = 0; - else - fir_hinc = 1024 * orig_width / out_width; - if (!orig_height || orig_height == out_height) - fir_vinc = 0; - else - fir_vinc = 1024 * orig_height / out_height; - dispc.fir_hinc[plane] = fir_hinc; - dispc.fir_vinc[plane] = fir_vinc; - - MOD_REG_FLD(fir_reg[plane], - FLD_MASK(16, 12) | FLD_MASK(0, 12), - ((fir_vinc & 4095) << 16) | - (fir_hinc & 4095)); - - dev_dbg(dispc.fbdev->dev, "out_width %d out_height %d orig_width %d " - "orig_height %d fir_hinc %d fir_vinc %d\n", - out_width, out_height, orig_width, orig_height, - fir_hinc, fir_vinc); - - MOD_REG_FLD(vs_reg[plane], - FLD_MASK(16, 11) | FLD_MASK(0, 11), - ((out_height - 1) << 16) | (out_width - 1)); - - l = dispc_read_reg(at_reg[plane]); - l &= ~(0x03 << 5); - l |= fir_hinc ? (1 << 5) : 0; - l |= fir_vinc ? (1 << 6) : 0; - dispc_write_reg(at_reg[plane], l); - - enable_lcd_clocks(0); - return 0; -} - -static int omap_dispc_enable_plane(int plane, int enable) -{ - const u32 at_reg[] = { DISPC_GFX_ATTRIBUTES, - DISPC_VID1_BASE + DISPC_VID_ATTRIBUTES, - DISPC_VID2_BASE + DISPC_VID_ATTRIBUTES }; - if ((unsigned int)plane > dispc.mem_desc.region_cnt) - return -EINVAL; - - enable_lcd_clocks(1); - MOD_REG_FLD(at_reg[plane], 1, enable ? 1 : 0); - enable_lcd_clocks(0); - - return 0; -} - -static int omap_dispc_set_color_key(struct omapfb_color_key *ck) -{ - u32 df_reg, tr_reg; - int shift, val; - - switch (ck->channel_out) { - case OMAPFB_CHANNEL_OUT_LCD: - df_reg = DISPC_DEFAULT_COLOR0; - tr_reg = DISPC_TRANS_COLOR0; - shift = 10; - break; - case OMAPFB_CHANNEL_OUT_DIGIT: - df_reg = DISPC_DEFAULT_COLOR1; - tr_reg = DISPC_TRANS_COLOR1; - shift = 12; - break; - default: - return -EINVAL; - } - switch (ck->key_type) { - case OMAPFB_COLOR_KEY_DISABLED: - val = 0; - break; - case OMAPFB_COLOR_KEY_GFX_DST: - val = 1; - break; - case OMAPFB_COLOR_KEY_VID_SRC: - val = 3; - break; - default: - return -EINVAL; - } - enable_lcd_clocks(1); - MOD_REG_FLD(DISPC_CONFIG, FLD_MASK(shift, 2), val << shift); - - if (val != 0) - dispc_write_reg(tr_reg, ck->trans_key); - dispc_write_reg(df_reg, ck->background); - enable_lcd_clocks(0); - - dispc.color_key = *ck; - - return 0; -} - -static int omap_dispc_get_color_key(struct omapfb_color_key *ck) -{ - *ck = dispc.color_key; - return 0; -} - -static void load_palette(void) -{ -} - -static int omap_dispc_set_update_mode(enum omapfb_update_mode mode) -{ - int r = 0; - - if (mode != dispc.update_mode) { - switch (mode) { - case OMAPFB_AUTO_UPDATE: - case OMAPFB_MANUAL_UPDATE: - enable_lcd_clocks(1); - omap_dispc_enable_lcd_out(1); - dispc.update_mode = mode; - break; - case OMAPFB_UPDATE_DISABLED: - init_completion(&dispc.frame_done); - omap_dispc_enable_lcd_out(0); - if (!wait_for_completion_timeout(&dispc.frame_done, - msecs_to_jiffies(500))) { - dev_err(dispc.fbdev->dev, - "timeout waiting for FRAME DONE\n"); - } - dispc.update_mode = mode; - enable_lcd_clocks(0); - break; - default: - r = -EINVAL; - } - } - - return r; -} - -static void omap_dispc_get_caps(int plane, struct omapfb_caps *caps) -{ - caps->ctrl |= OMAPFB_CAPS_PLANE_RELOCATE_MEM; - if (plane > 0) - caps->ctrl |= OMAPFB_CAPS_PLANE_SCALE; - caps->plane_color |= (1 << OMAPFB_COLOR_RGB565) | - (1 << OMAPFB_COLOR_YUV422) | - (1 << OMAPFB_COLOR_YUY422); - if (plane == 0) - caps->plane_color |= (1 << OMAPFB_COLOR_CLUT_8BPP) | - (1 << OMAPFB_COLOR_CLUT_4BPP) | - (1 << OMAPFB_COLOR_CLUT_2BPP) | - (1 << OMAPFB_COLOR_CLUT_1BPP) | - (1 << OMAPFB_COLOR_RGB444); -} - -static enum omapfb_update_mode omap_dispc_get_update_mode(void) -{ - return dispc.update_mode; -} - -static void setup_color_conv_coef(void) -{ - u32 mask = FLD_MASK(16, 11) | FLD_MASK(0, 11); - int cf1_reg = DISPC_VID1_BASE + DISPC_VID_CONV_COEF0; - int cf2_reg = DISPC_VID2_BASE + DISPC_VID_CONV_COEF0; - int at1_reg = DISPC_VID1_BASE + DISPC_VID_ATTRIBUTES; - int at2_reg = DISPC_VID2_BASE + DISPC_VID_ATTRIBUTES; - const struct color_conv_coef { - int ry, rcr, rcb, gy, gcr, gcb, by, bcr, bcb; - int full_range; - } ctbl_bt601_5 = { - 298, 409, 0, 298, -208, -100, 298, 0, 517, 0, - }; - const struct color_conv_coef *ct; -#define CVAL(x, y) (((x & 2047) << 16) | (y & 2047)) - - ct = &ctbl_bt601_5; - - MOD_REG_FLD(cf1_reg, mask, CVAL(ct->rcr, ct->ry)); - MOD_REG_FLD(cf1_reg + 4, mask, CVAL(ct->gy, ct->rcb)); - MOD_REG_FLD(cf1_reg + 8, mask, CVAL(ct->gcb, ct->gcr)); - MOD_REG_FLD(cf1_reg + 12, mask, CVAL(ct->bcr, ct->by)); - MOD_REG_FLD(cf1_reg + 16, mask, CVAL(0, ct->bcb)); - - MOD_REG_FLD(cf2_reg, mask, CVAL(ct->rcr, ct->ry)); - MOD_REG_FLD(cf2_reg + 4, mask, CVAL(ct->gy, ct->rcb)); - MOD_REG_FLD(cf2_reg + 8, mask, CVAL(ct->gcb, ct->gcr)); - MOD_REG_FLD(cf2_reg + 12, mask, CVAL(ct->bcr, ct->by)); - MOD_REG_FLD(cf2_reg + 16, mask, CVAL(0, ct->bcb)); -#undef CVAL - - MOD_REG_FLD(at1_reg, (1 << 11), ct->full_range); - MOD_REG_FLD(at2_reg, (1 << 11), ct->full_range); -} - -static void calc_ck_div(int is_tft, int pck, int *lck_div, int *pck_div) -{ - unsigned long fck, lck; - - *lck_div = 1; - pck = max(1, pck); - fck = clk_get_rate(dispc.dss1_fck); - lck = fck; - *pck_div = (lck + pck - 1) / pck; - if (is_tft) - *pck_div = max(2, *pck_div); - else - *pck_div = max(3, *pck_div); - if (*pck_div > 255) { - *pck_div = 255; - lck = pck * *pck_div; - *lck_div = fck / lck; - BUG_ON(*lck_div < 1); - if (*lck_div > 255) { - *lck_div = 255; - dev_warn(dispc.fbdev->dev, "pixclock %d kHz too low.\n", - pck / 1000); - } - } -} - -static void set_lcd_tft_mode(int enable) -{ - u32 mask; - - mask = 1 << 3; - MOD_REG_FLD(DISPC_CONTROL, mask, enable ? mask : 0); -} - -static void set_lcd_timings(void) -{ - u32 l; - int lck_div, pck_div; - struct lcd_panel *panel = dispc.fbdev->panel; - int is_tft = panel->config & OMAP_LCDC_PANEL_TFT; - unsigned long fck; - - l = dispc_read_reg(DISPC_TIMING_H); - l &= ~(FLD_MASK(0, 6) | FLD_MASK(8, 8) | FLD_MASK(20, 8)); - l |= ( max(1, (min(64, panel->hsw))) - 1 ) << 0; - l |= ( max(1, (min(256, panel->hfp))) - 1 ) << 8; - l |= ( max(1, (min(256, panel->hbp))) - 1 ) << 20; - dispc_write_reg(DISPC_TIMING_H, l); - - l = dispc_read_reg(DISPC_TIMING_V); - l &= ~(FLD_MASK(0, 6) | FLD_MASK(8, 8) | FLD_MASK(20, 8)); - l |= ( max(1, (min(64, panel->vsw))) - 1 ) << 0; - l |= ( max(0, (min(255, panel->vfp))) - 0 ) << 8; - l |= ( max(0, (min(255, panel->vbp))) - 0 ) << 20; - dispc_write_reg(DISPC_TIMING_V, l); - - l = dispc_read_reg(DISPC_POL_FREQ); - l &= ~FLD_MASK(12, 6); - l |= (panel->config & OMAP_LCDC_SIGNAL_MASK) << 12; - l |= panel->acb & 0xff; - dispc_write_reg(DISPC_POL_FREQ, l); - - calc_ck_div(is_tft, panel->pixel_clock * 1000, &lck_div, &pck_div); - - l = dispc_read_reg(DISPC_DIVISOR); - l &= ~(FLD_MASK(16, 8) | FLD_MASK(0, 8)); - l |= (lck_div << 16) | (pck_div << 0); - dispc_write_reg(DISPC_DIVISOR, l); - - /* update panel info with the exact clock */ - fck = clk_get_rate(dispc.dss1_fck); - panel->pixel_clock = fck / lck_div / pck_div / 1000; -} - -static void recalc_irq_mask(void) -{ - int i; - unsigned long irq_mask = DISPC_IRQ_MASK_ERROR; - - for (i = 0; i < MAX_IRQ_HANDLERS; i++) { - if (!dispc.irq_handlers[i].callback) - continue; - - irq_mask |= dispc.irq_handlers[i].irq_mask; - } - - enable_lcd_clocks(1); - MOD_REG_FLD(DISPC_IRQENABLE, 0x7fff, irq_mask); - enable_lcd_clocks(0); -} - -int omap_dispc_request_irq(unsigned long irq_mask, void (*callback)(void *data), - void *data) -{ - int i; - - BUG_ON(callback == NULL); - - for (i = 0; i < MAX_IRQ_HANDLERS; i++) { - if (dispc.irq_handlers[i].callback) - continue; - - dispc.irq_handlers[i].irq_mask = irq_mask; - dispc.irq_handlers[i].callback = callback; - dispc.irq_handlers[i].data = data; - recalc_irq_mask(); - - return 0; - } - - return -EBUSY; -} -EXPORT_SYMBOL(omap_dispc_request_irq); - -void omap_dispc_free_irq(unsigned long irq_mask, void (*callback)(void *data), - void *data) -{ - int i; - - for (i = 0; i < MAX_IRQ_HANDLERS; i++) { - if (dispc.irq_handlers[i].callback == callback && - dispc.irq_handlers[i].data == data) { - dispc.irq_handlers[i].irq_mask = 0; - dispc.irq_handlers[i].callback = NULL; - dispc.irq_handlers[i].data = NULL; - recalc_irq_mask(); - return; - } - } - - BUG(); -} -EXPORT_SYMBOL(omap_dispc_free_irq); - -static irqreturn_t omap_dispc_irq_handler(int irq, void *dev) -{ - u32 stat; - int i = 0; - - enable_lcd_clocks(1); - - stat = dispc_read_reg(DISPC_IRQSTATUS); - if (stat & DISPC_IRQ_FRAMEMASK) - complete(&dispc.frame_done); - - if (stat & DISPC_IRQ_MASK_ERROR) { - if (printk_ratelimit()) { - dev_err(dispc.fbdev->dev, "irq error status %04x\n", - stat & 0x7fff); - } - } - - for (i = 0; i < MAX_IRQ_HANDLERS; i++) { - if (unlikely(dispc.irq_handlers[i].callback && - (stat & dispc.irq_handlers[i].irq_mask))) - dispc.irq_handlers[i].callback( - dispc.irq_handlers[i].data); - } - - dispc_write_reg(DISPC_IRQSTATUS, stat); - - enable_lcd_clocks(0); - - return IRQ_HANDLED; -} - -static int get_dss_clocks(void) -{ - dispc.dss_ick = clk_get(&dispc.fbdev->dssdev->dev, "ick"); - if (IS_ERR(dispc.dss_ick)) { - dev_err(dispc.fbdev->dev, "can't get ick\n"); - return PTR_ERR(dispc.dss_ick); - } - - dispc.dss1_fck = clk_get(&dispc.fbdev->dssdev->dev, "fck"); - if (IS_ERR(dispc.dss1_fck)) { - dev_err(dispc.fbdev->dev, "can't get dss1_fck\n"); - clk_put(dispc.dss_ick); - return PTR_ERR(dispc.dss1_fck); - } - - dispc.dss_54m_fck = clk_get(&dispc.fbdev->dssdev->dev, "tv_clk"); - if (IS_ERR(dispc.dss_54m_fck)) { - dev_err(dispc.fbdev->dev, "can't get tv_fck\n"); - clk_put(dispc.dss_ick); - clk_put(dispc.dss1_fck); - return PTR_ERR(dispc.dss_54m_fck); - } - - return 0; -} - -static void put_dss_clocks(void) -{ - clk_put(dispc.dss_54m_fck); - clk_put(dispc.dss1_fck); - clk_put(dispc.dss_ick); -} - -static void enable_lcd_clocks(int enable) -{ - if (enable) { - clk_enable(dispc.dss_ick); - clk_enable(dispc.dss1_fck); - } else { - clk_disable(dispc.dss1_fck); - clk_disable(dispc.dss_ick); - } -} - -static void enable_digit_clocks(int enable) -{ - if (enable) - clk_enable(dispc.dss_54m_fck); - else - clk_disable(dispc.dss_54m_fck); -} - -static void omap_dispc_suspend(void) -{ - if (dispc.update_mode == OMAPFB_AUTO_UPDATE) { - init_completion(&dispc.frame_done); - omap_dispc_enable_lcd_out(0); - if (!wait_for_completion_timeout(&dispc.frame_done, - msecs_to_jiffies(500))) { - dev_err(dispc.fbdev->dev, - "timeout waiting for FRAME DONE\n"); - } - enable_lcd_clocks(0); - } -} - -static void omap_dispc_resume(void) -{ - if (dispc.update_mode == OMAPFB_AUTO_UPDATE) { - enable_lcd_clocks(1); - if (!dispc.ext_mode) { - set_lcd_timings(); - load_palette(); - } - omap_dispc_enable_lcd_out(1); - } -} - - -static int omap_dispc_update_window(struct fb_info *fbi, - struct omapfb_update_window *win, - void (*complete_callback)(void *arg), - void *complete_callback_data) -{ - return dispc.update_mode == OMAPFB_UPDATE_DISABLED ? -ENODEV : 0; -} - -static int mmap_kern(struct omapfb_mem_region *region) -{ - struct vm_struct *kvma; - struct vm_area_struct vma; - pgprot_t pgprot; - unsigned long vaddr; - - kvma = get_vm_area(region->size, VM_IOREMAP); - if (kvma == NULL) { - dev_err(dispc.fbdev->dev, "can't get kernel vm area\n"); - return -ENOMEM; - } - vma.vm_mm = &init_mm; - - vaddr = (unsigned long)kvma->addr; - - pgprot = pgprot_writecombine(pgprot_kernel); - vma.vm_start = vaddr; - vma.vm_end = vaddr + region->size; - if (io_remap_pfn_range(&vma, vaddr, region->paddr >> PAGE_SHIFT, - region->size, pgprot) < 0) { - dev_err(dispc.fbdev->dev, "kernel mmap for FBMEM failed\n"); - return -EAGAIN; - } - region->vaddr = (void *)vaddr; - - return 0; -} - -static void mmap_user_open(struct vm_area_struct *vma) -{ - int plane = (int)vma->vm_private_data; - - atomic_inc(&dispc.map_count[plane]); -} - -static void mmap_user_close(struct vm_area_struct *vma) -{ - int plane = (int)vma->vm_private_data; - - atomic_dec(&dispc.map_count[plane]); -} - -static const struct vm_operations_struct mmap_user_ops = { - .open = mmap_user_open, - .close = mmap_user_close, -}; - -static int omap_dispc_mmap_user(struct fb_info *info, - struct vm_area_struct *vma) -{ - struct omapfb_plane_struct *plane = info->par; - unsigned long off; - unsigned long start; - u32 len; - - if (vma->vm_end - vma->vm_start == 0) - return 0; - if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) - return -EINVAL; - off = vma->vm_pgoff << PAGE_SHIFT; - - start = info->fix.smem_start; - len = info->fix.smem_len; - if (off >= len) - return -EINVAL; - if ((vma->vm_end - vma->vm_start + off) > len) - return -EINVAL; - off += start; - vma-> |