diff options
author | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2014-02-13 17:31:38 +0400 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2014-04-17 09:10:19 +0400 |
commit | f7018c21350204c4cf628462f229d44d03545254 (patch) | |
tree | 408787177164cf51cc06f7aabdb04fcff8d2b6aa /drivers/video/omap | |
parent | c26ef3eb3c11274bad1b64498d0a134f85755250 (diff) | |
download | linux-f7018c21350204c4cf628462f229d44d03545254.tar.xz |
video: move fbdev to drivers/video/fbdev
The drivers/video directory is a mess. It contains generic video related
files, directories for backlight, console, linux logo, lots of fbdev
device drivers, fbdev framework files.
Make some order into the chaos by creating drivers/video/fbdev
directory, and move all fbdev related files there.
No functionality is changed, although I guess it is possible that some
subtle Makefile build order related issue could be created by this
patch.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Rob Clark <robdclark@gmail.com>
Acked-by: Jingoo Han <jg1.han@samsung.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/video/omap')
-rw-r--r-- | drivers/video/omap/Kconfig | 52 | ||||
-rw-r--r-- | drivers/video/omap/Makefile | 26 | ||||
-rw-r--r-- | drivers/video/omap/hwa742.c | 1059 | ||||
-rw-r--r-- | drivers/video/omap/lcd_ams_delta.c | 225 | ||||
-rw-r--r-- | drivers/video/omap/lcd_h3.c | 127 | ||||
-rw-r--r-- | drivers/video/omap/lcd_htcherald.c | 118 | ||||
-rw-r--r-- | drivers/video/omap/lcd_inn1510.c | 113 | ||||
-rw-r--r-- | drivers/video/omap/lcd_inn1610.c | 134 | ||||
-rw-r--r-- | drivers/video/omap/lcd_mipid.c | 615 | ||||
-rw-r--r-- | drivers/video/omap/lcd_osk.c | 133 | ||||
-rw-r--r-- | drivers/video/omap/lcd_palmte.c | 110 | ||||
-rw-r--r-- | drivers/video/omap/lcd_palmtt.c | 116 | ||||
-rw-r--r-- | drivers/video/omap/lcd_palmz71.c | 112 | ||||
-rw-r--r-- | drivers/video/omap/lcdc.c | 856 | ||||
-rw-r--r-- | drivers/video/omap/lcdc.h | 9 | ||||
-rw-r--r-- | drivers/video/omap/omapfb.h | 246 | ||||
-rw-r--r-- | drivers/video/omap/omapfb_main.c | 1971 | ||||
-rw-r--r-- | drivers/video/omap/sossi.c | 693 |
18 files changed, 0 insertions, 6715 deletions
diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig deleted file mode 100644 index 0bc3a936ce2b..000000000000 --- a/drivers/video/omap/Kconfig +++ /dev/null @@ -1,52 +0,0 @@ -config FB_OMAP - tristate "OMAP frame buffer support" - depends on FB - depends on ARCH_OMAP1 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - Frame buffer driver for OMAP based boards. - -config FB_OMAP_LCDC_EXTERNAL - bool "External LCD controller support" - depends on FB_OMAP - help - Say Y here, if you want to have support for boards with an - external LCD controller connected to the SoSSI/RFBI interface. - -config FB_OMAP_LCDC_HWA742 - bool "Epson HWA742 LCD controller support" - depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL - help - Say Y here if you want to have support for the external - Epson HWA742 LCD controller. - -config FB_OMAP_MANUAL_UPDATE - bool "Default to manual update mode" - depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL - help - Say Y here, if your user-space applications are capable of - notifying the frame buffer driver when a change has occurred in - the frame buffer content and thus a reload of the image data to - the external frame buffer is required. If unsure, say N. - -config FB_OMAP_LCD_MIPID - bool "MIPI DBI-C/DCS compatible LCD support" - depends on FB_OMAP && SPI_MASTER - help - Say Y here if you want to have support for LCDs compatible with - the Mobile Industry Processor Interface DBI-C/DCS - specification. (Supported LCDs: Philips LPH8923, Sharp LS041Y3) - -config FB_OMAP_DMA_TUNE - bool "Set DMA SDRAM access priority high" - depends on FB_OMAP - help - On systems in which video memory is in system memory - (SDRAM) this will speed up graphics DMA operations. - If you have such a system and want to use rotation - answer yes. Answer no if you have a dedicated video - memory, or don't use any of the accelerated features. - - diff --git a/drivers/video/omap/Makefile b/drivers/video/omap/Makefile deleted file mode 100644 index 1927faffb5bc..000000000000 --- a/drivers/video/omap/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -# -# Makefile for the OMAP1 framebuffer device driver -# - -obj-$(CONFIG_FB_OMAP) += omapfb.o - -objs-yy := omapfb_main.o lcdc.o - -objs-y$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += sossi.o - -objs-y$(CONFIG_FB_OMAP_LCDC_HWA742) += hwa742.o - -objs-y$(CONFIG_MACH_AMS_DELTA) += lcd_ams_delta.o -objs-y$(CONFIG_MACH_OMAP_H3) += lcd_h3.o -objs-y$(CONFIG_MACH_OMAP_PALMTE) += lcd_palmte.o -objs-y$(CONFIG_MACH_OMAP_PALMTT) += lcd_palmtt.o -objs-y$(CONFIG_MACH_OMAP_PALMZ71) += lcd_palmz71.o -objs-$(CONFIG_ARCH_OMAP16XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1610.o -objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1510.o -objs-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o - -objs-y$(CONFIG_FB_OMAP_LCD_MIPID) += lcd_mipid.o -objs-y$(CONFIG_MACH_HERALD) += lcd_htcherald.o - -omapfb-objs := $(objs-yy) - diff --git a/drivers/video/omap/hwa742.c b/drivers/video/omap/hwa742.c deleted file mode 100644 index a4ee65b8f918..000000000000 --- a/drivers/video/omap/hwa742.c +++ /dev/null @@ -1,1059 +0,0 @@ -/* - * Epson HWA742 LCD controller driver - * - * Copyright (C) 2004-2005 Nokia Corporation - * Authors: Juha Yrjölä <juha.yrjola@nokia.com> - * Imre Deak <imre.deak@nokia.com> - * YUV support: Jussi Laako <jussi.laako@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/module.h> -#include <linux/mm.h> -#include <linux/fb.h> -#include <linux/delay.h> -#include <linux/clk.h> -#include <linux/interrupt.h> - -#include "omapfb.h" - -#define HWA742_REV_CODE_REG 0x0 -#define HWA742_CONFIG_REG 0x2 -#define HWA742_PLL_DIV_REG 0x4 -#define HWA742_PLL_0_REG 0x6 -#define HWA742_PLL_1_REG 0x8 -#define HWA742_PLL_2_REG 0xa -#define HWA742_PLL_3_REG 0xc -#define HWA742_PLL_4_REG 0xe -#define HWA742_CLK_SRC_REG 0x12 -#define HWA742_PANEL_TYPE_REG 0x14 -#define HWA742_H_DISP_REG 0x16 -#define HWA742_H_NDP_REG 0x18 -#define HWA742_V_DISP_1_REG 0x1a -#define HWA742_V_DISP_2_REG 0x1c -#define HWA742_V_NDP_REG 0x1e -#define HWA742_HS_W_REG 0x20 -#define HWA742_HP_S_REG 0x22 -#define HWA742_VS_W_REG 0x24 -#define HWA742_VP_S_REG 0x26 -#define HWA742_PCLK_POL_REG 0x28 -#define HWA742_INPUT_MODE_REG 0x2a -#define HWA742_TRANSL_MODE_REG1 0x2e -#define HWA742_DISP_MODE_REG 0x34 -#define HWA742_WINDOW_TYPE 0x36 -#define HWA742_WINDOW_X_START_0 0x38 -#define HWA742_WINDOW_X_START_1 0x3a -#define HWA742_WINDOW_Y_START_0 0x3c -#define HWA742_WINDOW_Y_START_1 0x3e -#define HWA742_WINDOW_X_END_0 0x40 -#define HWA742_WINDOW_X_END_1 0x42 -#define HWA742_WINDOW_Y_END_0 0x44 -#define HWA742_WINDOW_Y_END_1 0x46 -#define HWA742_MEMORY_WRITE_LSB 0x48 -#define HWA742_MEMORY_WRITE_MSB 0x49 -#define HWA742_MEMORY_READ_0 0x4a -#define HWA742_MEMORY_READ_1 0x4c -#define HWA742_MEMORY_READ_2 0x4e -#define HWA742_POWER_SAVE 0x56 -#define HWA742_NDP_CTRL 0x58 - -#define HWA742_AUTO_UPDATE_TIME (HZ / 20) - -/* Reserve 4 request slots for requests in irq context */ -#define REQ_POOL_SIZE 24 -#define IRQ_REQ_POOL_SIZE 4 - -#define REQ_FROM_IRQ_POOL 0x01 - -#define REQ_COMPLETE 0 -#define REQ_PENDING 1 - -struct update_param { - int x, y, width, height; - int color_mode; - int flags; -}; - -struct hwa742_request { - struct list_head entry; - unsigned int flags; - - int (*handler)(struct hwa742_request *req); - void (*complete)(void *data); - void *complete_data; - - union { - struct update_param update; - struct completion *sync; - } par; -}; - -struct { - enum omapfb_update_mode update_mode; - enum omapfb_update_mode update_mode_before_suspend; - - struct timer_list auto_update_timer; - int stop_auto_update; - struct omapfb_update_window auto_update_window; - unsigned te_connected:1; - unsigned vsync_only:1; - - struct hwa742_request req_pool[REQ_POOL_SIZE]; - struct list_head pending_req_list; - struct list_head free_req_list; - struct semaphore req_sema; - spinlock_t req_lock; - - struct extif_timings reg_timings, lut_timings; - - int prev_color_mode; - int prev_flags; - int window_type; - - u32 max_transmit_size; - u32 extif_clk_period; - unsigned long pix_tx_time; - unsigned long line_upd_time; - - - struct omapfb_device *fbdev; - struct lcd_ctrl_extif *extif; - const struct lcd_ctrl *int_ctrl; - - struct clk *sys_ck; -} hwa742; - -struct lcd_ctrl hwa742_ctrl; - -static u8 hwa742_read_reg(u8 reg) -{ - u8 data; - - hwa742.extif->set_bits_per_cycle(8); - hwa742.extif->write_command(®, 1); - hwa742.extif->read_data(&data, 1); - - return data; -} - -static void hwa742_write_reg(u8 reg, u8 data) -{ - hwa742.extif->set_bits_per_cycle(8); - hwa742.extif->write_command(®, 1); - hwa742.extif->write_data(&data, 1); -} - -static void set_window_regs(int x_start, int y_start, int x_end, int y_end) -{ - u8 tmp[8]; - u8 cmd; - - x_end--; - y_end--; - tmp[0] = x_start; - tmp[1] = x_start >> 8; - tmp[2] = y_start; - tmp[3] = y_start >> 8; - tmp[4] = x_end; - tmp[5] = x_end >> 8; - tmp[6] = y_end; - tmp[7] = y_end >> 8; - - hwa742.extif->set_bits_per_cycle(8); - cmd = HWA742_WINDOW_X_START_0; - - hwa742.extif->write_command(&cmd, 1); - - hwa742.extif->write_data(tmp, 8); -} - -static void set_format_regs(int conv, int transl, int flags) -{ - if (flags & OMAPFB_FORMAT_FLAG_DOUBLE) { - hwa742.window_type = ((hwa742.window_type & 0xfc) | 0x01); -#ifdef VERBOSE - dev_dbg(hwa742.fbdev->dev, "hwa742: enabled pixel doubling\n"); -#endif - } else { - hwa742.window_type = (hwa742.window_type & 0xfc); -#ifdef VERBOSE - dev_dbg(hwa742.fbdev->dev, "hwa742: disabled pixel doubling\n"); -#endif - } - - hwa742_write_reg(HWA742_INPUT_MODE_REG, conv); - hwa742_write_reg(HWA742_TRANSL_MODE_REG1, transl); - hwa742_write_reg(HWA742_WINDOW_TYPE, hwa742.window_type); -} - -static void enable_tearsync(int y, int width, int height, int screen_height, - int force_vsync) -{ - u8 b; - - b = hwa742_read_reg(HWA742_NDP_CTRL); - b |= 1 << 2; - hwa742_write_reg(HWA742_NDP_CTRL, b); - - if (likely(hwa742.vsync_only || force_vsync)) { - hwa742.extif->enable_tearsync(1, 0); - return; - } - - if (width * hwa742.pix_tx_time < hwa742.line_upd_time) { - hwa742.extif->enable_tearsync(1, 0); - return; - } - - if ((width * hwa742.pix_tx_time / 1000) * height < - (y + height) * (hwa742.line_upd_time / 1000)) { - hwa742.extif->enable_tearsync(1, 0); - return; - } - - hwa742.extif->enable_tearsync(1, y + 1); -} - -static void disable_tearsync(void) -{ - u8 b; - - hwa742.extif->enable_tearsync(0, 0); - - b = hwa742_read_reg(HWA742_NDP_CTRL); - b &= ~(1 << 2); - hwa742_write_reg(HWA742_NDP_CTRL, b); -} - -static inline struct hwa742_request *alloc_req(void) -{ - unsigned long flags; - struct hwa742_request *req; - int req_flags = 0; - - if (!in_interrupt()) - down(&hwa742.req_sema); - else - req_flags = REQ_FROM_IRQ_POOL; - - spin_lock_irqsave(&hwa742.req_lock, flags); - BUG_ON(list_empty(&hwa742.free_req_list)); - req = list_entry(hwa742.free_req_list.next, - struct hwa742_request, entry); - list_del(&req->entry); - spin_unlock_irqrestore(&hwa742.req_lock, flags); - - INIT_LIST_HEAD(&req->entry); - req->flags = req_flags; - - return req; -} - -static inline void free_req(struct hwa742_request *req) -{ - unsigned long flags; - - spin_lock_irqsave(&hwa742.req_lock, flags); - - list_move(&req->entry, &hwa742.free_req_list); - if (!(req->flags & REQ_FROM_IRQ_POOL)) - up(&hwa742.req_sema); - - spin_unlock_irqrestore(&hwa742.req_lock, flags); -} - -static void process_pending_requests(void) -{ - unsigned long flags; - - spin_lock_irqsave(&hwa742.req_lock, flags); - - while (!list_empty(&hwa742.pending_req_list)) { - struct hwa742_request *req; - void (*complete)(void *); - void *complete_data; - - req = list_entry(hwa742.pending_req_list.next, - struct hwa742_request, entry); - spin_unlock_irqrestore(&hwa742.req_lock, flags); - - if (req->handler(req) == REQ_PENDING) - return; - - complete = req->complete; - complete_data = req->complete_data; - free_req(req); - - if (complete) - complete(complete_data); - - spin_lock_irqsave(&hwa742.req_lock, flags); - } - - spin_unlock_irqrestore(&hwa742.req_lock, flags); -} - -static void submit_req_list(struct list_head *head) -{ - unsigned long flags; - int process = 1; - - spin_lock_irqsave(&hwa742.req_lock, flags); - if (likely(!list_empty(&hwa742.pending_req_list))) - process = 0; - list_splice_init(head, hwa742.pending_req_list.prev); - spin_unlock_irqrestore(&hwa742.req_lock, flags); - - if (process) - process_pending_requests(); -} - -static void request_complete(void *data) -{ - struct hwa742_request *req = (struct hwa742_request *)data; - void (*complete)(void *); - void *complete_data; - - complete = req->complete; - complete_data = req->complete_data; - - free_req(req); - - if (complete) - complete(complete_data); - - process_pending_requests(); -} - -static int send_frame_handler(struct hwa742_request *req) -{ - struct update_param *par = &req->par.update; - int x = par->x; - int y = par->y; - int w = par->width; - int h = par->height; - int bpp; - int conv, transl; - unsigned long offset; - int color_mode = par->color_mode; - int flags = par->flags; - int scr_width = hwa742.fbdev->panel->x_res; - int scr_height = hwa742.fbdev->panel->y_res; - -#ifdef VERBOSE - dev_dbg(hwa742.fbdev->dev, "x %d y %d w %d h %d scr_width %d " - "color_mode %d flags %d\n", - x, y, w, h, scr_width, color_mode, flags); -#endif - - switch (color_mode) { - case OMAPFB_COLOR_YUV422: - bpp = 16; - conv = 0x08; - transl = 0x25; - break; - case OMAPFB_COLOR_YUV420: - bpp = 12; - conv = 0x09; - transl = 0x25; - break; - case OMAPFB_COLOR_RGB565: - bpp = 16; - conv = 0x01; - transl = 0x05; - break; - default: - return -EINVAL; - } - - if (hwa742.prev_flags != flags || - hwa742.prev_color_mode != color_mode) { - set_format_regs(conv, transl, flags); - hwa742.prev_color_mode = color_mode; - hwa742.prev_flags = flags; - } - flags = req->par.update.flags; - if (flags & OMAPFB_FORMAT_FLAG_TEARSYNC) - enable_tearsync(y, scr_width, h, scr_height, - flags & OMAPFB_FORMAT_FLAG_FORCE_VSYNC); - else - disable_tearsync(); - - set_window_regs(x, y, x + w, y + h); - - offset = (scr_width * y + x) * bpp / 8; - - hwa742.int_ctrl->setup_plane(OMAPFB_PLANE_GFX, - OMAPFB_CHANNEL_OUT_LCD, offset, scr_width, 0, 0, w, h, - color_mode); - - hwa742.extif->set_bits_per_cycle(16); - - hwa742.int_ctrl->enable_plane(OMAPFB_PLANE_GFX, 1); - hwa742.extif->transfer_area(w, h, request_complete, req); - - return REQ_PENDING; -} - -static void send_frame_complete(void *data) -{ - hwa742.int_ctrl->enable_plane(OMAPFB_PLANE_GFX, 0); -} - -#define ADD_PREQ(_x, _y, _w, _h) do { \ - req = alloc_req(); \ - req->handler = send_frame_handler; \ - req->complete = send_frame_complete; \ - req->par.update.x = _x; \ - req->par.update.y = _y; \ - req->par.update.width = _w; \ - req->par.update.height = _h; \ - req->par.update.color_mode = color_mode;\ - req->par.update.flags = flags; \ - list_add_tail(&req->entry, req_head); \ -} while(0) - -static void create_req_list(struct omapfb_update_window *win, - struct list_head *req_head) -{ - struct hwa742_request *req; - int x = win->x; - int y = win->y; - int width = win->width; - int height = win->height; - int color_mode; - int flags; - - flags = win->format & ~OMAPFB_FORMAT_MASK; - color_mode = win->format & OMAPFB_FORMAT_MASK; - - if (x & 1) { - ADD_PREQ(x, y, 1, height); - width--; - x++; - flags &= ~OMAPFB_FORMAT_FLAG_TEARSYNC; - } - if (width & ~1) { - unsigned int xspan = width & ~1; - unsigned int ystart = y; - unsigned int yspan = height; - - if (xspan * height * 2 > hwa742.max_transmit_size) { - yspan = hwa742.max_transmit_size / (xspan * 2); - ADD_PREQ(x, ystart, xspan, yspan); - ystart += yspan; - yspan = height - yspan; - flags &= ~OMAPFB_FORMAT_FLAG_TEARSYNC; - } - - ADD_PREQ(x, ystart, xspan, yspan); - x += xspan; - width -= xspan; - flags &= ~OMAPFB_FORMAT_FLAG_TEARSYNC; - } - if (width) - ADD_PREQ(x, y, 1, height); -} - -static void auto_update_complete(void *data) -{ - if (!hwa742.stop_auto_update) - mod_timer(&hwa742.auto_update_timer, - jiffies + HWA742_AUTO_UPDATE_TIME); -} - -static void hwa742_update_window_auto(unsigned long arg) -{ - LIST_HEAD(req_list); - struct hwa742_request *last; - - create_req_list(&hwa742.auto_update_window, &req_list); - last = list_entry(req_list.prev, struct hwa742_request, entry); - - last->complete = auto_update_complete; - last->complete_data = NULL; - - submit_req_list(&req_list); -} - -int hwa742_update_window_async(struct fb_info *fbi, - struct omapfb_update_window *win, - void (*complete_callback)(void *arg), - void *complete_callback_data) -{ - LIST_HEAD(req_list); - struct hwa742_request *last; - int r = 0; - - if (hwa742.update_mode != OMAPFB_MANUAL_UPDATE) { - dev_dbg(hwa742.fbdev->dev, "invalid update mode\n"); - r = -EINVAL; - goto out; - } - if (unlikely(win->format & - ~(0x03 | OMAPFB_FORMAT_FLAG_DOUBLE | - OMAPFB_FORMAT_FLAG_TEARSYNC | OMAPFB_FORMAT_FLAG_FORCE_VSYNC))) { - dev_dbg(hwa742.fbdev->dev, "invalid window flag\n"); - r = -EINVAL; - goto out; - } - - create_req_list(win, &req_list); - last = list_entry(req_list.prev, struct hwa742_request, entry); - - last->complete = complete_callback; - last->complete_data = (void *)complete_callback_data; - - submit_req_list(&req_list); - -out: - return r; -} -EXPORT_SYMBOL(hwa742_update_window_async); - -static int hwa742_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) -{ - if (plane != OMAPFB_PLANE_GFX || - channel_out != OMAPFB_CHANNEL_OUT_LCD) - return -EINVAL; - - return 0; -} - -static int hwa742_enable_plane(int plane, int enable) -{ - if (plane != 0) - return -EINVAL; - - hwa742.int_ctrl->enable_plane(plane, enable); - - return 0; -} - -static int sync_handler(struct hwa742_request *req) -{ - complete(req->par.sync); - return REQ_COMPLETE; -} - -static void hwa742_sync(void) -{ - LIST_HEAD(req_list); - struct hwa742_request *req; - struct completion comp; - - req = alloc_req(); - - req->handler = sync_handler; - req->complete = NULL; - init_completion(&comp); - req->par.sync = ∁ - - list_add(&req->entry, &req_list); - submit_req_list(&req_list); - - wait_for_completion(&comp); -} - -static void hwa742_bind_client(struct omapfb_notifier_block *nb) -{ - dev_dbg(hwa742.fbdev->dev, "update_mode %d\n", hwa742.update_mode); - if (hwa742.update_mode == OMAPFB_MANUAL_UPDATE) { - omapfb_notify_clients(hwa742.fbdev, OMAPFB_EVENT_READY); - } -} - -static int hwa742_set_update_mode(enum omapfb_update_mode mode) -{ - if (mode != OMAPFB_MANUAL_UPDATE && mode != OMAPFB_AUTO_UPDATE && - mode != OMAPFB_UPDATE_DISABLED) - return -EINVAL; - - if (mode == hwa742.update_mode) - return 0; - - dev_info(hwa742.fbdev->dev, "HWA742: setting update mode to %s\n", - mode == OMAPFB_UPDATE_DISABLED ? "disabled" : - (mode == OMAPFB_AUTO_UPDATE ? "auto" : "manual")); - - switch (hwa742.update_mode) { - case OMAPFB_MANUAL_UPDATE: - omapfb_notify_clients(hwa742.fbdev, OMAPFB_EVENT_DISABLED); - break; - case OMAPFB_AUTO_UPDATE: - hwa742.stop_auto_update = 1; - del_timer_sync(&hwa742.auto_update_timer); - break; - case OMAPFB_UPDATE_DISABLED: - break; - } - - hwa742.update_mode = mode; - hwa742_sync(); - hwa742.stop_auto_update = 0; - - switch (mode) { - case OMAPFB_MANUAL_UPDATE: - omapfb_notify_clients(hwa742.fbdev, OMAPFB_EVENT_READY); - break; - case OMAPFB_AUTO_UPDATE: - hwa742_update_window_auto(0); - break; - case OMAPFB_UPDATE_DISABLED: - break; - } - - return 0; -} - -static enum omapfb_update_mode hwa742_get_update_mode(void) -{ - return hwa742.update_mode; -} - -static unsigned long round_to_extif_ticks(unsigned long ps, int div) -{ - int bus_tick = hwa742.extif_clk_period * div; - return (ps + bus_tick - 1) / bus_tick * bus_tick; -} - -static int calc_reg_timing(unsigned long sysclk, int div) -{ - struct extif_timings *t; - unsigned long systim; - - /* CSOnTime 0, WEOnTime 2 ns, REOnTime 2 ns, - * AccessTime 2 ns + 12.2 ns (regs), - * WEOffTime = WEOnTime + 1 ns, - * REOffTime = REOnTime + 16 ns (regs), - * CSOffTime = REOffTime + 1 ns - * ReadCycle = 2ns + 2*SYSCLK (regs), - * WriteCycle = 2*SYSCLK + 2 ns, - * CSPulseWidth = 10 ns */ - systim = 1000000000 / (sysclk / 1000); - dev_dbg(hwa742.fbdev->dev, "HWA742 systim %lu ps extif_clk_period %u ps" - "extif_clk_div %d\n", systim, hwa742.extif_clk_period, div); - - t = &hwa742.reg_timings; - memset(t, 0, sizeof(*t)); - t->clk_div = div; - t->cs_on_time = 0; - t->we_on_time = round_to_extif_ticks(t->cs_on_time + 2000, div); - t->re_on_time = round_to_extif_ticks(t->cs_on_time + 2000, div); - t->access_time = round_to_extif_ticks(t->re_on_time + 12200, div); - t->we_off_time = round_to_extif_ticks(t->we_on_time + 1000, div); - t->re_off_time = round_to_extif_ticks(t->re_on_time + 16000, div); - t->cs_off_time = round_to_extif_ticks(t->re_off_time + 1000, div); - t->we_cycle_time = round_to_extif_ticks(2 * systim + 2000, div); - if (t->we_cycle_time < t->we_off_time) - t->we_cycle_time = t->we_off_time; - t->re_cycle_time = round_to_extif_ticks(2 * systim + 2000, div); - if (t->re_cycle_time < t->re_off_time) - t->re_cycle_time = t->re_off_time; - t->cs_pulse_width = 0; - - dev_dbg(hwa742.fbdev->dev, "[reg]cson %d csoff %d reon %d reoff %d\n", - t->cs_on_time, t->cs_off_time, t->re_on_time, t->re_off_time); - dev_dbg(hwa742.fbdev->dev, "[reg]weon %d weoff %d recyc %d wecyc %d\n", - t->we_on_time, t->we_off_time, t->re_cycle_time, - t->we_cycle_time); - dev_dbg(hwa742.fbdev->dev, "[reg]rdaccess %d cspulse %d\n", - t->access_time, t->cs_pulse_width); - - return hwa742.extif->convert_timings(t); -} - -static int calc_lut_timing(unsigned long sysclk, int div) -{ - struct extif_timings *t; - unsigned long systim; - - /* CSOnTime 0, WEOnTime 2 ns, REOnTime 2 ns, - * AccessTime 2 ns + 4 * SYSCLK + 26 (lut), - * WEOffTime = WEOnTime + 1 ns, - * REOffTime = REOnTime + 4*SYSCLK + 26 ns (lut), - * CSOffTime = REOffTime + 1 ns - * ReadCycle = 2ns + 4*SYSCLK + 26 ns (lut), - * WriteCycle = 2*SYSCLK + 2 ns, - * CSPulseWidth = 10 ns - */ - systim = 1000000000 / (sysclk / 1000); - dev_dbg(hwa742.fbdev->dev, "HWA742 systim %lu ps extif_clk_period %u ps" - "extif_clk_div %d\n", systim, hwa742.extif_clk_period, div); - - t = &hwa742.lut_timings; - memset(t, 0, sizeof(*t)); - - t->clk_div = div; - - t->cs_on_time = 0; - t->we_on_time = round_to_extif_ticks(t->cs_on_time + 2000, div); - t->re_on_time = round_to_extif_ticks(t->cs_on_time + 2000, div); - t->access_time = round_to_extif_ticks(t->re_on_time + 4 * systim + - 26000, div); - t->we_off_time = round_to_extif_ticks(t->we_on_time + 1000, div); - t->re_off_time = round_to_extif_ticks(t->re_on_time + 4 * systim + - 26000, div); - t->cs_off_time = round_to_extif_ticks(t->re_off_time + 1000, div); - t->we_cycle_time = round_to_extif_ticks(2 * systim + 2000, div); - if (t->we_cycle_time < t->we_off_time) - t->we_cycle_time = t->we_off_time; - t->re_cycle_time = round_to_extif_ticks(2000 + 4 * systim + 26000, div); - if (t->re_cycle_time < t->re_off_time) - t->re_cycle_time = t->re_off_time; - t->cs_pulse_width = 0; - - dev_dbg(hwa742.fbdev->dev, "[lut]cson %d csoff %d reon %d reoff %d\n", - t->cs_on_time, t->cs_off_time, t->re_on_time, t->re_off_time); - dev_dbg(hwa742.fbdev->dev, "[lut]weon %d weoff %d recyc %d wecyc %d\n", - t->we_on_time, t->we_off_time, t->re_cycle_time, - t->we_cycle_time); - dev_dbg(hwa742.fbdev->dev, "[lut]rdaccess %d cspulse %d\n", - t->access_time, t->cs_pulse_width); - - return hwa742.extif->convert_timings(t); -} - -static int calc_extif_timings(unsigned long sysclk, int *extif_mem_div) -{ - int max_clk_div; - int div; - - hwa742.extif->get_clk_info(&hwa742.extif_clk_period, &max_clk_div); - for (div = 1; div < max_clk_div; div++) { - if (calc_reg_timing(sysclk, div) == 0) - break; - } - if (div >= max_clk_div) - goto err; - - *extif_mem_div = div; - - for (div = 1; div < max_clk_div; div++) { - if (calc_lut_timing(sysclk, div) == 0) - break; - } - - if (div >= max_clk_div) - goto err; - - return 0; - -err: - dev_err(hwa742.fbdev->dev, "can't setup timings\n"); - return -1; -} - -static void calc_hwa742_clk_rates(unsigned long ext_clk, - unsigned long *sys_clk, unsigned long *pix_clk) -{ - int pix_clk_src; - int sys_div = 0, sys_mul = 0; - int pix_div; - - pix_clk_src = hwa742_read_reg(HWA742_CLK_SRC_REG); - pix_div = ((pix_clk_src >> 3) & 0x1f) + 1; - if ((pix_clk_src & (0x3 << 1)) == 0) { - /* Source is the PLL */ - sys_div = (hwa742_read_reg(HWA742_PLL_DIV_REG) & 0x3f) + 1; - sys_mul = (hwa742_read_reg(HWA742_PLL_4_REG) & 0x7f) + 1; - *sys_clk = ext_clk * sys_mul / sys_div; - } else /* else source is ext clk, or oscillator */ - *sys_clk = ext_clk; - - *pix_clk = *sys_clk / pix_div; /* HZ */ - dev_dbg(hwa742.fbdev->dev, - "ext_clk %ld pix_src %d pix_div %d sys_div %d sys_mul %d\n", - ext_clk, pix_clk_src & (0x3 << 1), pix_div, sys_div, sys_mul); - dev_dbg(hwa742.fbdev->dev, "sys_clk %ld pix_clk %ld\n", - *sys_clk, *pix_clk); -} - - -static int setup_tearsync(unsigned long pix_clk, int extif_div) -{ - int hdisp, vdisp; - int hndp, vndp; - int hsw, vsw; - int hs, vs; - int hs_pol_inv, vs_pol_inv; - int use_hsvs, use_ndp; - u8 b; - - hsw = hwa742_read_reg(HWA742_HS_W_REG); - vsw = hwa742_read_reg(HWA742_VS_W_REG); - hs_pol_inv = !(hsw & 0x80); - vs_pol_inv = !(vsw & 0x80); - hsw = hsw & 0x7f; - vsw = vsw & 0x3f; - - hdisp = (hwa742_read_reg(HWA742_H_DISP_REG) & 0x7f) * 8; - vdisp = hwa742_read_reg(HWA742_V_DISP_1_REG) + - ((hwa742_read_reg(HWA742_V_DISP_2_REG) & 0x3) << 8); - - hndp = hwa742_read_reg(HWA742_H_NDP_REG) & 0x7f; - vndp = hwa742_read_reg(HWA742_V_NDP_REG); - - /* time to transfer one pixel (16bpp) in ps */ - hwa742.pix_tx_time = hwa742.reg_timings.we_cycle_time; - if (hwa742.extif->get_max_tx_rate != NULL) { - /* - * The external interface might have a rate limitation, - * if so, we have to maximize our transfer rate. - */ - unsigned long min_tx_time; - unsigned long max_tx_rate = hwa742.extif->get_max_tx_rate(); - - dev_dbg(hwa742.fbdev->dev, "max_tx_rate %ld HZ\n", - max_tx_rate); - min_tx_time = 1000000000 / (max_tx_rate / 1000); /* ps */ - if (hwa742.pix_tx_time < min_tx_time) - hwa742.pix_tx_time = min_tx_time; - } - - /* time to update one line in ps */ - hwa742.line_upd_time = (hdisp + hndp) * 1000000 / (pix_clk / 1000); - hwa742.line_upd_time *= 1000; - if (hdisp * hwa742.pix_tx_time > hwa742.line_upd_time) - /* - * transfer speed too low, we might have to use both - * HS and VS - */ - use_hsvs = 1; - else - /* decent transfer speed, we'll always use only VS */ - use_hsvs = 0; - - if (use_hsvs && (hs_pol_inv || vs_pol_inv)) { - /* - * HS or'ed with VS doesn't work, use the active high - * TE signal based on HNDP / VNDP - */ - use_ndp = 1; - hs_pol_inv = 0; - vs_pol_inv = 0; - hs = hndp; - vs = vndp; - } else { - /* - * Use HS or'ed with VS as a TE signal if both are needed - * or VNDP if only vsync is needed. - */ - use_ndp = 0; - hs = hsw; - vs = vsw; - if (!use_hsvs) { - hs_pol_inv = 0; - vs_pol_inv = 0; - } - } - - hs = hs * 1000000 / (pix_clk / 1000); /* ps */ - hs *= 1000; - - vs = vs * (hdisp + hndp) * 1000000 / (pix_clk / 1000); /* ps */ - vs *= 1000; - - if (vs <= hs) - return -EDOM; - /* set VS to 120% of HS to minimize VS detection time */ - vs = hs * 12 / 10; - /* minimize HS too */ - hs = 10000; - - b = hwa742_read_reg(HWA742_NDP_CTRL); - b &= ~0x3; - b |= use_hsvs ? 1 : 0; - b |= (use_ndp && use_hsvs) ? 0 : 2; - hwa742_write_reg(HWA742_NDP_CTRL, b); - - hwa742.vsync_only = !use_hsvs; - - dev_dbg(hwa742.fbdev->dev, - "pix_clk %ld HZ pix_tx_time %ld ps line_upd_time %ld ps\n", - pix_clk, hwa742.pix_tx_time, hwa742.line_upd_time); - dev_dbg(hwa742.fbdev->dev, - "hs %d ps vs %d ps mode %d vsync_only %d\n", - hs, vs, (b & 0x3), !use_hsvs); - - return hwa742.extif->setup_tearsync(1, hs, vs, - hs_pol_inv, vs_pol_inv, extif_div); -} - -static void hwa742_get_caps(int plane, struct omapfb_caps *caps) -{ - hwa742.int_ctrl->get_caps(plane, caps); - caps->ctrl |= OMAPFB_CAPS_MANUAL_UPDATE | - OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE; - if (hwa742.te_connected) - caps->ctrl |= OMAPFB_CAPS_TEARSYNC; - caps->wnd_color |= (1 << OMAPFB_COLOR_RGB565) | - (1 << OMAPFB_COLOR_YUV420); -} - -static void hwa742_suspend(void) -{ - hwa742.update_mode_before_suspend = hwa742.update_mode; - hwa742_set_update_mode(OMAPFB_UPDATE_DISABLED); - /* Enable sleep mode */ - hwa742_write_reg(HWA742_POWER_SAVE, 1 << 1); - clk_disable(hwa742.sys_ck); -} - -static void hwa742_resume(void) -{ - clk_enable(hwa742.sys_ck); - - /* Disable sleep mode */ - hwa742_write_reg(HWA742_POWER_SAVE, 0); - while (1) { - /* Loop until PLL output is stabilized */ - if (hwa742_read_reg(HWA742_PLL_DIV_REG) & (1 << 7)) - break; - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(msecs_to_jiffies(5)); - } - hwa742_set_update_mode(hwa742.update_mode_before_suspend); -} - -static int hwa742_init(struct omapfb_device *fbdev, int ext_mode, - struct omapfb_mem_desc *req_vram) -{ - int r = 0, i; - u8 rev, conf; - unsigned long ext_clk; - unsigned long sys_clk, pix_clk; - int extif_mem_div; - struct omapfb_platform_data *omapfb_conf; - - BUG_ON(!fbdev->ext_if || !fbdev->int_ctrl); - - hwa742.fbdev = fbdev; - hwa742.extif = fbdev->ext_if; - hwa742.int_ctrl = fbdev->int_ctrl; - - omapfb_conf = dev_get_platdata(fbdev->dev); - - hwa742.sys_ck = clk_get(NULL, "hwa_sys_ck"); - - spin_lock_init(&hwa742.req_lock); - - if ((r = hwa742.int_ctrl->init(fbdev, 1, req_vram)) < 0) - goto err1; - - if ((r = hwa742.extif->init(fbdev)) < 0) - goto err2; - - ext_clk = clk_get_rate(hwa742.sys_ck); - if ((r = calc_extif_timings(ext_clk, &extif_mem_div)) < 0) - goto err3; - hwa742.extif->set_timings(&hwa742.reg_timings); - clk_enable(hwa742.sys_ck); - - calc_hwa742_clk_rates(ext_clk, &sys_clk, &pix_clk); - if ((r = calc_extif_timings(sys_clk, &extif_mem_div)) < 0) - goto err4; - hwa742.extif->set_timings(&hwa742.reg_timings); - - rev = hwa742_read_reg(HWA742_REV_CODE_REG); - if ((rev & 0xfc) != 0x80) { - dev_err(fbdev->dev, "HWA742: invalid revision %02x\n", rev); - r = -ENODEV; - goto err4; - } - - - if (!(hwa742_read_reg(HWA742_PLL_DIV_REG) & 0x80)) { - dev_err(fbdev->dev, - "HWA742: controller not initialized by the bootloader\n"); - r = -ENODEV; - goto err4; - } - - if ((r = setup_tearsync(pix_clk, extif_mem_div)) < 0) { - dev_err(hwa742.fbdev->dev, - "HWA742: can't setup tearing synchronization\n"); - goto err4; - } - hwa742.te_connected = 1; - - hwa742.max_transmit_size = hwa742.extif->max_transmit_size; - - hwa742.update_mode = OMAPFB_UPDATE_DISABLED; - - hwa742.auto_update_window.x = 0; - hwa742.auto_update_window.y = 0; - hwa742.auto_update_window.width = fbdev->panel->x_res; - hwa742.auto_update_window.height = fbdev->panel->y_res; - hwa742.auto_update_window.format = 0; - - init_timer(&hwa742.auto_update_timer); - hwa742.auto_update_timer.function = hwa742_update_window_auto; - hwa742.auto_update_timer.data = 0; - - hwa742.prev_color_mode = -1; - hwa742.prev_flags = 0; - - hwa742.fbdev = fbdev; - - INIT_LIST_HEAD(&hwa742.free_req_list); - INIT_LIST_HEAD(&hwa742.pending_req_list); - for (i = 0; i < ARRAY_SIZE(hwa742.req_pool); i++) - list_add(&hwa742.req_pool[i].entry, &hwa742.free_req_list); - BUG_ON(i <= IRQ_REQ_POOL_SIZE); - sema_init(&hwa742.req_sema, i - IRQ_REQ_POOL_SIZE); - - conf = hwa742_read_reg(HWA742_CONFIG_REG); - dev_info(fbdev->dev, ": Epson HWA742 LCD controller rev %d " - "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07); - - return 0; -err4: - clk_disable(hwa742.sys_ck); -err3: - hwa742.extif->cleanup(); -err2: - hwa742.int_ctrl->cleanup(); -err1: - return r; -} - -static void hwa742_cleanup(void) -{ - hwa742_set_update_mode(OMAPFB_UPDATE_DISABLED); - hwa742.extif->cleanup(); - hwa742.int_ctrl->cleanup(); - clk_disable(hwa742.sys_ck); -} - -struct lcd_ctrl hwa742_ctrl = { - .name = "hwa742", - .init = hwa742_init, - .cleanup = hwa742_cleanup, - .bind_client = hwa742_bind_client, - .get_caps = hwa742_get_caps, - .set_update_mode = hwa742_set_update_mode, - .get_update_mode = hwa742_get_update_mode, - .setup_plane = hwa742_setup_plane, - .enable_plane = hwa742_enable_plane, - .update_window = hwa742_update_window_async, - .sync = hwa742_sync, - .suspend = hwa742_suspend, - .resume = hwa742_resume, -}; - diff --git a/drivers/video/omap/lcd_ams_delta.c b/drivers/video/omap/lcd_ams_delta.c deleted file mode 100644 index 4a5f2cd3d3bf..000000000000 --- a/drivers/video/omap/lcd_ams_delta.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Based on drivers/video/omap/lcd_inn1510.c - * - * LCD panel support for the Amstrad E3 (Delta) videophone. - * - * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li> - * - * 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/module.h> -#include <linux/platform_device.h> -#include <linux/io.h> -#include <linux/delay.h> -#include <linux/lcd.h> -#include <linux/gpio.h> - -#include <mach/hardware.h> -#include <mach/board-ams-delta.h> - -#include "omapfb.h" - -#define AMS_DELTA_DEFAULT_CONTRAST 112 - -#define AMS_DELTA_MAX_CONTRAST 0x00FF -#define AMS_DELTA_LCD_POWER 0x0100 - - -/* LCD class device section */ - -static int ams_delta_lcd; - -static int ams_delta_lcd_set_power(struct lcd_device *dev, int power) -{ - if (power == FB_BLANK_UNBLANK) { - if (!(ams_delta_lcd & AMS_DELTA_LCD_POWER)) { - omap_writeb(ams_delta_lcd & AMS_DELTA_MAX_CONTRAST, - OMAP_PWL_ENABLE); - omap_writeb(1, OMAP_PWL_CLK_ENABLE); - ams_delta_lcd |= AMS_DELTA_LCD_POWER; - } - } else { - if (ams_delta_lcd & AMS_DELTA_LCD_POWER) { - omap_writeb(0, OMAP_PWL_ENABLE); - omap_writeb(0, OMAP_PWL_CLK_ENABLE); - ams_delta_lcd &= ~AMS_DELTA_LCD_POWER; - } - } - return 0; -} - -static int ams_delta_lcd_set_contrast(struct lcd_device *dev, int value) -{ - if ((value >= 0) && (value <= AMS_DELTA_MAX_CONTRAST)) { - omap_writeb(value, OMAP_PWL_ENABLE); - ams_delta_lcd &= ~AMS_DELTA_MAX_CONTRAST; - ams_delta_lcd |= value; - } - return 0; -} - -#ifdef CONFIG_LCD_CLASS_DEVICE -static int ams_delta_lcd_get_power(struct lcd_device *dev) -{ - if (ams_delta_lcd & AMS_DELTA_LCD_POWER) - return FB_BLANK_UNBLANK; - else - return FB_BLANK_POWERDOWN; -} - -static int ams_delta_lcd_get_contrast(struct lcd_device *dev) -{ - if (!(ams_delta_lcd & AMS_DELTA_LCD_POWER)) - return 0; - - return ams_delta_lcd & AMS_DELTA_MAX_CONTRAST; -} - -static struct lcd_ops ams_delta_lcd_ops = { - .get_power = ams_delta_lcd_get_power, - .set_power = ams_delta_lcd_set_power, - .get_contrast = ams_delta_lcd_get_contrast, - .set_contrast = ams_delta_lcd_set_contrast, -}; -#endif - - -/* omapfb panel section */ - -static const struct gpio _gpios[] = { - { - .gpio = AMS_DELTA_GPIO_PIN_LCD_VBLEN, - .flags = GPIOF_OUT_INIT_LOW, - .label = "lcd_vblen", - }, - { - .gpio = AMS_DELTA_GPIO_PIN_LCD_NDISP, - .flags = GPIOF_OUT_INIT_LOW, - .label = "lcd_ndisp", - }, -}; - -static int ams_delta_panel_init(struct lcd_panel *panel, - struct omapfb_device *fbdev) -{ - return gpio_request_array(_gpios, ARRAY_SIZE(_gpios)); -} - -static void ams_delta_panel_cleanup(struct lcd_panel *panel) -{ - gpio_free_array(_gpios, ARRAY_SIZE(_gpios)); -} - -static int ams_delta_panel_enable(struct lcd_panel *panel) -{ - gpio_set_value(AMS_DELTA_GPIO_PIN_LCD_NDISP, 1); - gpio_set_value(AMS_DELTA_GPIO_PIN_LCD_VBLEN, 1); - return 0; -} - -static void ams_delta_panel_disable(struct lcd_panel *panel) -{ - gpio_set_value(AMS_DELTA_GPIO_PIN_LCD_VBLEN, 0); - gpio_set_value(AMS_DELTA_GPIO_PIN_LCD_NDISP, 0); -} - -static unsigned long ams_delta_panel_get_caps(struct lcd_panel *panel) -{ - return 0; -} - -static struct lcd_panel ams_delta_panel = { - .name = "ams-delta", - .config = 0, - - .bpp = 12, - .data_lines = 16, - .x_res = 480, - .y_res = 320, - .pixel_clock = 4687, - .hsw = 3, - .hfp = 1, - .hbp = 1, - .vsw = 1, - .vfp = 0, - .vbp = 0, - .pcd = 0, - .acb = 37, - - .init = ams_delta_panel_init, - .cleanup = ams_delta_panel_cleanup, - .enable = ams_delta_panel_enable, - .disable = ams_delta_panel_disable, - .get_caps = ams_delta_panel_get_caps, -}; - - -/* platform driver section */ - -static int ams_delta_panel_probe(struct platform_device *pdev) -{ - struct lcd_device *lcd_device = NULL; -#ifdef CONFIG_LCD_CLASS_DEVICE - int ret; - - lcd_device = lcd_device_register("omapfb", &pdev->dev, NULL, - &ams_delta_lcd_ops); - - if (IS_ERR(lcd_device)) { - ret = PTR_ERR(lcd_device); - dev_err(&pdev->dev, "failed to register device\n"); - return ret; - } - - platform_set_drvdata(pdev, lcd_device); - lcd_device->props.max_contrast = AMS_DELTA_MAX_CONTRAST; -#endif - - ams_delta_lcd_set_contrast(lcd_device, AMS_DELTA_DEFAULT_CONTRAST); - ams_delta_lcd_set_power(lcd_device, FB_BLANK_UNBLANK); - - omapfb_register_panel(&ams_delta_panel); - return 0; -} - -static int ams_delta_panel_remove(struct platform_device *pdev) -{ - return 0; -} - -static int ams_delta_panel_suspend(struct platform_device *pdev, - pm_message_t mesg) -{ - return 0; -} - -static int ams_delta_panel_resume(struct platform_device *pdev) -{ - return 0; -} - -static struct platform_driver ams_delta_panel_driver = { - .probe = ams_delta_panel_probe, - .remove = ams_delta_panel_remove, - .suspend = ams_delta_panel_suspend, - .resume = ams_delta_panel_resume, - .driver = { - .name = "lcd_ams_delta", - .owner = THIS_MODULE, - }, -}; - -module_platform_driver(ams_delta_panel_driver); diff --git a/drivers/video/omap/lcd_h3.c b/drivers/video/omap/lcd_h3.c deleted file mode 100644 index 49bdeca81e50..000000000000 --- a/drivers/video/omap/lcd_h3.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * LCD panel support for the TI OMAP H3 board - * - * Copyright (C) 2004 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/module.h> -#include <linux/platform_device.h> -#include <linux/i2c/tps65010.h> - -#include <asm/gpio.h> -#include "omapfb.h" - -#define MODULE_NAME "omapfb-lcd_h3" - -static int h3_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) -{ - return 0; -} - -static void h3_panel_cleanup(struct lcd_panel *panel) -{ -} - -static int h3_panel_enable(struct lcd_panel *panel) -{ - int r = 0; - - /* GPIO1 and GPIO2 of TPS65010 send LCD_ENBKL and LCD_ENVDD signals */ - r = tps65010_set_gpio_out_value(GPIO1, HIGH); - if (!r) - r = tps65010_set_gpio_out_value(GPIO2, HIGH); - if (r) - pr_err(MODULE_NAME ": Unable to turn on LCD panel\n"); - - return r; -} - -static void h3_panel_disable(struct lcd_panel *panel) -{ - int r = 0; - - /* GPIO1 and GPIO2 of TPS65010 send LCD_ENBKL and LCD_ENVDD signals */ - r = tps65010_set_gpio_out_value(GPIO1, LOW); - if (!r) - tps65010_set_gpio_out_value(GPIO2, LOW); - if (r) - pr_err(MODULE_NAME ": Unable to turn off LCD panel\n"); -} - -static unsigned long h3_panel_get_caps(struct lcd_panel *panel) -{ - return 0; -} - -struct lcd_panel h3_panel = { - .name = "h3", - .config = OMAP_LCDC_PANEL_TFT, - - .data_lines = 16, - .bpp = 16, - .x_res = 240, - .y_res = 320, - .pixel_clock = 12000, - .hsw = 12, - .hfp = 14, - .hbp = 72 - 12, - .vsw = 1, - .vfp = 1, - .vbp = 0, - .pcd = 0, - - .init = h3_panel_init, - .cleanup = h3_panel_cleanup, - .enable = h3_panel_enable, - .disable = h3_panel_disable, - .get_caps = h3_panel_get_caps, -}; - -static int h3_panel_probe(struct platform_device *pdev) -{ - omapfb_register_panel(&h3_panel); - return 0; -} - -static int h3_panel_remove(struct platform_device *pdev) -{ - return 0; -} - -static int h3_panel_suspend(struct platform_device *pdev, pm_message_t mesg) -{ - return 0; -} - -static int h3_panel_resume(struct platform_device *pdev) -{ - return 0; -} - -static struct platform_driver h3_panel_driver = { - .probe = h3_panel_probe, - .remove = h3_panel_remove, - .suspend = h3_panel_suspend, - .resume = h3_panel_resume, - .driver = { - .name = "lcd_h3", - .owner = THIS_MODULE, - }, -}; - -module_platform_driver(h3_panel_driver); diff --git a/drivers/video/omap/lcd_htcherald.c b/drivers/video/omap/lcd_htcherald.c deleted file mode 100644 index 20f477851d54..000000000000 --- a/drivers/video/omap/lcd_htcherald.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * File: drivers/video/omap/lcd-htcherald.c - * - * LCD panel support for the HTC Herald - * - * Copyright (C) 2009 Cory Maccarrone <darkstar6262@gmail.com> - * Copyright (C) 2009 Wing Linux - * - * Based on the lcd_htcwizard.c file from the linwizard project: - * Copyright (C) linwizard.sourceforge.net - * Author: Angelo Arrifano <miknix@gmail.com> - * Based on lcd_h4 by 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/module.h> -#include <linux/platform_device.h> - -#include "omapfb.h" - -static int htcherald_panel_init(struct lcd_panel *panel, - struct omapfb_device *fbdev) -{ - return 0; -} - -static void htcherald_panel_cleanup(struct lcd_panel *panel) -{ -} - -static int htcherald_panel_enable(struct lcd_panel *panel) -{ - return 0; -} - -static void htcherald_panel_disable(struct lcd_panel *panel) -{ -} - -static unsigned long htcherald_panel_get_caps(struct lcd_panel *panel) -{ - return 0; -} - -/* Found on WIZ200 (miknix) and some HERA110 models (darkstar62) */ -struct lcd_panel htcherald_panel_1 = { - .name = "lcd_herald", - .config = OMAP_LCDC_PANEL_TFT | - OMAP_LCDC_INV_HSYNC | - OMAP_LCDC_INV_VSYNC | - OMAP_LCDC_INV_PIX_CLOCK, - .bpp = 16, - .data_lines = 16, - .x_res = 240, - .y_res = 320, - .pixel_clock = 6093, - .pcd = 0, /* 15 */ - .hsw = 10, - .hfp = 10, - .hbp = 20, - .vsw = 3, - .vfp = 2, - .vbp = 2, - - .init = htcherald_panel_init, - .cleanup = htcherald_panel_cleanup, - .enable = htcherald_panel_enable, - .disable = htcherald_panel_disable, - .get_caps = htcherald_panel_get_caps, -}; - -static int htcherald_panel_probe(struct platform_device *pdev) -{ - omapfb_register_panel(&htcherald_panel_1); - return 0; -} - -static int htcherald_panel_remove(struct platform_device *pdev) -{ - return 0; -} - -static int htcherald_panel_suspend(struct platform_device *pdev, - pm_message_t mesg) -{ - return 0; -} - -static int htcherald_panel_resume(struct platform_device *pdev) -{ - return 0; -} - -static struct platform_driver htcherald_panel_driver = { - .probe = htcherald_panel_probe, - .remove = htcherald_panel_remove, - .suspend = htcherald_panel_suspend, - .resume = htcherald_panel_resume, - .driver = { - .name = "lcd_htcherald", - .owner = THIS_MODULE, - }, -}; - -module_platform_driver(htcherald_panel_driver); diff --git a/drivers/video/omap/lcd_inn1510.c b/drivers/video/omap/lcd_inn1510.c deleted file mode 100644 index 2ee423279e35..000000000000 --- a/drivers/video/omap/lcd_inn1510.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * LCD panel support for the TI OMAP1510 Innovator board - * - * Copyright (C) 2004 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/module.h> -#include <linux/platform_device.h> -#include <linux/io.h> - -#include <mach/hardware.h> - -#include "omapfb.h" - -static int innovator1510_panel_init(struct lcd_panel *panel, - struct omapfb_device *fbdev) -{ - return 0; -} - -static void innovator1510_panel_cleanup(struct lcd_panel *panel) -{ -} - -static int innovator1510_panel_enable(struct lcd_panel *panel) -{ - __raw_writeb(0x7, OMAP1510_FPGA_LCD_PANEL_CONTROL); - return 0; -} - -static void innovator1510_panel_disable(struct lcd_panel *panel) -{ - __raw_writeb(0x0, OMAP1510_FPGA_LCD_PANEL_CONTROL); -} - -static unsigned long innovator1510_panel_get_caps(struct lcd_panel *panel) -{ - return 0; -} - -struct lcd_panel innovator1510_panel = { - .name = "inn1510", - .config = OMAP_LCDC_PANEL_TFT, - - .bpp = 16, - .data_lines = 16, - .x_res = 240, - .y_res = 320, - .pixel_clock = 12500, - .hsw = 40, - .hfp = 40, - .hbp = 72, - .vsw = 1, - .vfp = 1, - .vbp = 0, - .pcd = 12, - - .init = innovator1510_panel_init, - .cleanup = innovator1510_panel_cleanup, - .enable = innovator1510_panel_enable, - .disable = innovator1510_panel_disable, - .get_caps = innovator1510_panel_get_caps, -}; - -static int innovator1510_panel_probe(struct platform_device *pdev) -{ - omapfb_register_panel(&innovator1510_panel); - return 0; -} - -static int innovator1510_panel_remove(struct platform_device *pdev) -{ - return 0; -} - -static int innovator1510_panel_suspend(struct platform_device *pdev, - pm_message_t mesg) -{ - return 0; -} - -static int innovator1510_panel_resume(struct platform_device *pdev) -{ - return 0; -} - -static struct platform_driver innovator1510_panel_driver = { - .probe = innovator1510_panel_probe, - .remove = innovator1510_panel_remove, - .suspend = innovator1510_panel_suspend, - .resume = innovator1510_panel_resume, - .driver = { - .name = "lcd_inn1510", - .owner = THIS_MODULE, - }, -}; - -module_platform_driver(innovator1510_panel_driver); diff --git a/drivers/video/omap/lcd_inn1610.c b/drivers/video/omap/lcd_inn1610.c deleted file mode 100644 index e3d3d135aa48..000000000000 --- a/drivers/video/omap/lcd_inn1610.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * LCD panel support for the TI OMAP1610 Innovator board - * - * Copyright (C) 2004 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/module.h> -#include <linux/platform_device.h> - -#include <linux/gpio.h> -#include "omapfb.h" - -#define MODULE_NAME "omapfb-lcd_h3" - -static int innovator1610_panel_init(struct lcd_panel *panel, - struct omapfb_device *fbdev) -{ - int r = 0; - - /* configure GPIO(14, 15) as outputs */ - if (gpio_request_one(14, GPIOF_OUT_INIT_LOW, "lcd_en0")) { - pr_err(MODULE_NAME ": can't request GPIO 14\n"); - r = -1; - goto exit; - } - if (gpio_request_one(15, GPIOF_OUT_INIT_LOW, "lcd_en1")) { - pr_err(MODULE_NAME ": can't request GPIO 15\n"); - gpio_free(14); - r = -1; - goto exit; - } -exit: - return r; -} - -static void innovator1610_panel_cleanup(struct lcd_panel *panel) -{ - gpio_free(15); - gpio_free(14); -} - -static int innovator1610_panel_enable(struct lcd_panel *panel) -{ - /* set GPIO14 and GPIO15 high */ - gpio_set_value(14, 1); - gpio_set_value(15, 1); - return 0; -} - -static void innovator1610_panel_disable(struct lcd_panel *panel) -{ - /* set GPIO13, GPIO14 and GPIO15 low */ - gpio_set_value(14, 0); - gpio_set_value(15, 0); -} - -static unsigned long innovator1610_panel_get_caps(struct lcd_panel *panel) -{ - return 0; -} - -struct lcd_panel innovator1610_panel = { - .name = "inn1610", - .config = OMAP_LCDC_PANEL_TFT, - - .bpp = 16, - .data_lines = 16, - .x_res = 320, - .y_res = 240, - .pixel_clock = 12500, - .hsw = 40, - .hfp = 40, - .hbp = 72, - .vsw = 1, - .vfp = 1, - .vbp = 0, - .pcd = 12, - - .init = innovator1610_panel_init, - .cleanup = innovator1610_panel_cleanup, - .enable = innovator1610_panel_enable, - .disable = innovator1610_panel_disable, - .get_caps = innovator1610_panel_get_caps, -}; - -static int innovator1610_panel_probe(struct platform_device *pdev) -{ - omapfb_register_panel(&innovator1610_panel); - return 0; -} - -static int innovator1610_panel_remove(struct platform_device *pdev) -{ - return 0; -} - -static int innovator1610_panel_suspend(struct platform_device *pdev, - pm_message_t mesg) -{ - return 0; -} - -static int innovator1610_panel_resume(struct platform_device *pdev) -{ - return 0; -} - -static struct platform_driver innovator1610_panel_driver = { - .probe = innovator1610_panel_probe, - .remove = innovator1610_panel_remove, - .suspend = innovator1610_panel_suspend, - .resume = innovator1610_panel_resume, - .driver = { - .name = "lcd_inn1610", - .owner = THIS_MODULE, - }, -}; - -module_platform_driver(innovator1610_panel_driver); diff --git a/drivers/video/omap/lcd_mipid.c b/drivers/video/omap/lcd_mipid.c deleted file mode 100644 index 803fee618d57..000000000000 --- a/drivers/video/omap/lcd_mipid.c +++ /dev/null @@ -1,615 +0,0 @@ -/* - * LCD driver for MIPI DBI-C / DCS compatible LCDs - * - * Copyright (C) 2006 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/device.h> -#include <linux/delay.h> -#include <linux/slab.h> -#include <linux/workqueue.h> -#include <linux/spi/spi.h> -#include <linux/module.h> - -#include <linux/platform_data/lcd-mipid.h> - -#include "omapfb.h" - -#define MIPID_MODULE_NAME "lcd_mipid" - -#define MIPID_CMD_READ_DISP_ID 0x04 -#define MIPID_CMD_READ_RED 0x06 -#define MIPID_CMD_READ_GREEN 0x07 -#define MIPID_CMD_READ_BLUE 0x08 -#define MIPID_CMD_READ_DISP_STATUS 0x09 -#define MIPID_CMD_RDDSDR 0x0F -#define MIPID_CMD_SLEEP_IN 0x10 -#define MIPID_CMD_SLEEP_OUT 0x11 -#define MIPID_CMD_DISP_OFF 0x28 -#define MIPID_CMD_DISP_ON 0x29 - -#define MIPID_ESD_CHECK_PERIOD msecs_to_jiffies(5000) - -#define to_mipid_device(p) container_of(p, struct mipid_device, \ - panel) -struct mipid_device { - int enabled; - int revision; - unsigned int saved_bklight_level; - unsigned long hw_guard_end; /* next value of jiffies - when we can issue the - next sleep in/out command */ - unsigned long hw_guard_wait; /* max guard time in jiffies */ - - struct omapfb_device *fbdev; - struct spi_device *spi; - struct mutex mutex; - struct lcd_panel panel; - - struct workqueue_struct *esd_wq; - struct delayed_work esd_work; - void (*esd_check)(struct mipid_device *m); -}; - -static void mipid_transfer(struct mipid_device *md, int cmd, const u8 *wbuf, - int wlen, u8 *rbuf, int rlen) -{ - struct spi_message m; - struct spi_transfer *x, xfer[4]; - u16 w; - int r; - - BUG_ON(md->spi == NULL); - - spi_message_init(&m); - - memset(xfer, 0, sizeof(xfer)); - x = &xfer[0]; - - cmd &= 0xff; - x->tx_buf = &cmd; - x->bits_per_word = 9; - x->len = 2; - spi_message_add_tail(x, &m); - - if (wlen) { - x++; - x->tx_buf = wbuf; - x->len = wlen; - x->bits_per_word = 9; - spi_message_add_tail(x, &m); - } - - if (rlen) { - x++; - x->rx_buf = &w; - x->len = 1; - spi_message_add_tail(x, &m); - - if (rlen > 1) { - /* Arrange for the extra clock before the first - * data bit. - */ - x->bits_per_word = 9; - x->len = 2; - - x++; - x->rx_buf = &rbuf[1]; - x->len = rlen - 1; - spi_message_add_tail(x, &m); - } - } - - r = spi_sync(md->spi, &m); - if (r < 0) - dev_dbg(&md->spi->dev, "spi_sync %d\n", r); - - if (rlen) - rbuf[0] = w & 0xff; -} - -static inline void mipid_cmd(struct mipid_device *md, int cmd) -{ - mipid_transfer(md, cmd, NULL, 0, NULL, 0); -} - -static inline void mipid_write(struct mipid_device *md, - int reg, const u8 *buf, int len) -{ - mipid_transfer(md, reg, buf, len, NULL, 0); -} - -static inline void mipid_read(struct mipid_device *md, - int reg, u8 *buf, int len) -{ - mipid_transfer(md, reg, NULL, 0, buf, len); -} - -static void set_data_lines(struct mipid_device *md, int data_lines) -{ - u16 par; - - switch (data_lines) { - case 16: - par = 0x150; - break; - case 18: - par = 0x160; - break; - case 24: - par = 0x170; - break; - } - mipid_write(md, 0x3a, (u8 *)&par, 2); -} - -static void send_init_string(struct mipid_device *md) -{ - u16 initpar[] = { 0x0102, 0x0100, 0x0100 }; - - mipid_write(md, 0xc2, (u8 *)initpar, sizeof(initpar)); - set_data_lines(md, md->panel.data_lines); -} - -static void hw_guard_start(struct mipid_device *md, int guard_msec) -{ - md->hw_guard_wait = msecs_to_jiffies(guard_msec); - md->hw_guard_end = jiffies + md->hw_guard_wait; -} - -static void hw_guard_wait(struct mipid_device *md) -{ - unsigned long wait = md->hw_guard_end - jiffies; - - if ((long)wait > 0 && wait <= md->hw_guard_wait) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(wait); - } -} - -static void set_sleep_mode(struct mipid_device *md, int on) -{ - int cmd, sleep_time = 50; - - if (on) - cmd = MIPID_CMD_SLEEP_IN; - else - cmd = MIPID_CMD_SLEEP_OUT; - hw_guard_wait(md); - mipid_cmd(md, cmd); - hw_guard_start(md, 120); - /* - * When we enable the panel, it seems we _have_ to sleep - * 120 ms before sending the init string. When disabling the - * panel we'll sleep for the duration of 2 frames, so that the - * controller can still provide the PCLK,HS,VS signals. - */ - if (!on) - sleep_time = 120; - msleep(sleep_time); -} - -static void set_display_state(struct mipid_device *md, int enabled) -{ - int cmd = enabled ? MIPID_CMD_DISP_ON : MIPID_CMD_DISP_OFF; - - mipid_cmd(md, cmd); -} - -static int mipid_set_bklight_level(struct lcd_panel *panel, unsigned int level) -{ - struct mipid_device *md = to_mipid_device(panel); - struct mipid_platform_data *pd = md->spi->dev.platform_data; - - if (pd->get_bklight_max == NULL || pd->set_bklight_level == NULL) - return -ENODEV; - if (level > pd->get_bklight_max(pd)) - return -EINVAL; - if (!md->enabled) { - md->saved_bklight_level = level; - return 0; - } - pd->set_bklight_level(pd, level); - - return 0; -} - -static unsigned int mipid_get_bklight_level(struct lcd_panel *panel) -{ - struct mipid_device *md = to_mipid_device(panel); - struct mipid_platform_data *pd = md->spi->dev.platform_data; - - if (pd->get_bklight_level == NULL) - return -ENODEV; - return pd->get_bklight_level(pd); -} - -static unsigned int mipid_get_bklight_max(struct lcd_panel *panel) -{ - struct mipid_device *md = to_mipid_device(panel); - struct mipid_platform_data *pd = md->spi->dev.platform_data; - - if (pd->get_bklight_max == NULL) - return -ENODEV; - - return pd->get_bklight_max(pd); -} - -static unsigned long mipid_get_caps(struct lcd_panel *panel) -{ - return OMAPFB_CAPS_SET_BACKLIGHT; -} - -static u16 read_first_pixel(struct mipid_device *md) -{ - u16 pixel; - u8 red, green, blue; - - mutex_lock(&md->mutex); - mipid_read(md, MIPID_CMD_READ_RED, &red, 1); - mipid_read(md, MIPID_CMD_READ_GREEN, &green, 1); - mipid_read(md, MIPID_CMD_READ_BLUE, &blue, 1); - mutex_unlock(&md->mutex); - - switch (md->panel.data_lines) { - case 16: - pixel = ((red >> 1) << 11) | (green << 5) | (blue >> 1); - break; - case 24: - /* 24 bit -> 16 bit */ - pixel = ((red >> 3) << 11) | ((green >> 2) << 5) | - (blue >> 3); - break; - default: - pixel = 0; - BUG(); - } - - return pixel; -} - -static int mipid_run_test(struct lcd_panel *panel, int test_num) -{ - struct mipid_device *md = to_mipid_device(panel); - static const u16 test_values[4] = { - 0x0000, 0xffff, 0xaaaa, 0x5555, - }; - int i; - - if (test_num != MIPID_TEST_RGB_LINES) - return MIPID_TEST_INVALID; - - for (i = 0; i < ARRAY_SIZE(test_values); i++) { - int delay; - unsigned long tmo; - - omapfb_write_first_pixel(md->fbdev, test_values[i]); - tmo = jiffies + msecs_to_jiffies(100); - delay = 25; - while (1) { - u16 pixel; - - msleep(delay); - pixel = read_first_pixel(md); - if (pixel == test_values[i]) - break; - if (time_after(jiffies, tmo)) { - dev_err(&md->spi->dev, - "MIPI LCD RGB I/F test failed: " - "expecting %04x, got %04x\n", - test_values[i], pixel); - return MIPID_TEST_FAILED; - } - delay = 10; - } - } - - return 0; -} - -static void ls041y3_esd_recover(struct mipid_device *md) -{ - dev_err(&md->spi->dev, "performing LCD ESD recovery\n"); - set_sleep_mode(md, 1); - set_sleep_mode(md, 0); -} - -static void ls041y3_esd_check_mode1(struct mipid_device *md) -{ - u8 state1, state2; - - mipid_read(md, MIPID_CMD_RDDSDR, &state1, 1); - set_sleep_mode(md, 0); - mipid_read(md, MIPID_CMD_RDDSDR, &state2, 1); - dev_dbg(&md->spi->dev, "ESD mode 1 state1 %02x state2 %02x\n", - state1, state2); - /* Each sleep out command will trigger a self diagnostic and flip - * Bit6 if the test passes. - */ - if (!((state1 ^ state2) & (1 << 6))) - ls041y3_esd_recover(md); -} - -static void ls041y3_esd_check_mode2(struct mipid_device *md) -{ - int i; - u8 rbuf[2]; - static const struct { - int cmd; - int wlen; - u16 wbuf[3]; - } *rd, rd_ctrl[7] = { - { 0xb0, 4, { 0x0101, 0x01fe, } }, - { 0xb1, 4, { 0x01de, 0x0121, } }, - { 0xc2, 4, { 0x0100, 0x0100, } }, - { 0xbd, 2, { 0x0100, } }, - { 0xc2, 4, { 0x01fc, 0x0103, } }, - { 0xb4, 0, }, - { 0x00, 0, }, - }; - - rd = rd_ctrl; - for (i = 0; i < 3; i++, rd++) - mipid_write(md, rd->cmd, (u8 *)rd->wbuf, rd->wlen); - - udelay(10); - mipid_read(md, rd->cmd, rbuf, 2); - rd++; - - for (i = 0; i < 3; i++, rd++) { - udelay(10); - mipid_write(md, rd->cmd, (u8 *)rd->wbuf, rd->wlen); - } - - dev_dbg(&md->spi->dev, "ESD mode 2 state %02x\n", rbuf[1]); - if (rbuf[1] == 0x00) - ls041y3_esd_recover(md); -} - -static void ls041y3_esd_check(struct mipid_device *md) -{ - ls041y3_esd_check_mode1(md); - if (md->revision >= 0x88) - ls041y3_esd_check_mode2(md); -} - -static void mipid_esd_start_check(struct mipid_device *md) -{ - if (md->esd_check != NULL) - queue_delayed_work(md->esd_wq, &md->esd_work, - MIPID_ESD_CHECK_PERIOD); -} - -static void mipid_esd_stop_check(struct mipid_device *md) -{ - if (md->esd_check != NULL) - cancel_delayed_work_sync(&md->esd_work); -} - -static void mipid_esd_work(struct work_struct *work) -{ - struct mipid_device *md = container_of(work, struct mipid_device, - esd_work.work); - - mutex_lock(&md->mutex); - md->esd_check(md); - mutex_unlock(&md->mutex); - mipid_esd_start_check(md); -} - -static int mipid_enable(struct lcd_panel *panel) -{ - struct mipid_device *md = to_mipid_device(panel); - - mutex_lock(&md->mutex); - - if (md->enabled) { - mutex_unlock(&md->mutex); - return 0; - } - set_sleep_mode(md, 0); - md->enabled = 1; - send_init_string(md); - set_display_state(md, 1); - mipid_set_bklight_level(panel, md->saved_bklight_level); - mipid_esd_start_check(md); - - mutex_unlock(&md->mutex); - return 0; -} - -static void mipid_disable(struct lcd_panel *panel) -{ - struct mipid_device *md = to_mipid_device(panel); - - /* - * A final ESD work might be called before returning, - * so do this without holding the lock. - */ - mipid_esd_stop_check(md); - mutex_lock(&md->mutex); - - if (!md->enabled) { - mutex_unlock(&md->mutex); - return; - } - md->saved_bklight_level = mipid_get_bklight_level(panel); - mipid_set_bklight_level(panel, 0); - set_display_state(md, 0); - set_sleep_mode(md, 1); - md->enabled = 0; - - mutex_unlock(&md->mutex); -} - -static int panel_enabled(struct mipid_device *md) -{ - u32 disp_status; - int enabled; - - mipid_read(md, MIPID_CMD_READ_DISP_STATUS, (u8 *)&disp_status, 4); - disp_status = __be32_to_cpu(disp_status); - enabled = (disp_status & (1 << 17)) && (disp_status & (1 << 10)); - dev_dbg(&md->spi->dev, - "LCD panel %senabled by bootloader (status 0x%04x)\n", - enabled ? "" : "not ", disp_status); - return enabled; -} - -static int mipid_init(struct lcd_panel *panel, - struct omapfb_device *fbdev) -{ - struct mipid_device *md = to_mipid_device(panel); - - md->fbdev = fbdev; - md->esd_wq = create_singlethread_workqueue("mipid_esd"); - if (md->esd_wq == NULL) { - dev_err(&md->spi->dev, "can't create ESD workqueue\n"); - return -ENOMEM; - } - INIT_DELAYED_WORK(&md->esd_work, mipid_esd_work); - mutex_init(&md->mutex); - - md->enabled = panel_enabled(md); - - if (md->enabled) - mipid_esd_start_check(md); - else - md->saved_bklight_level = mipid_get_bklight_level(panel); - - return 0; -} - -static void mipid_cleanup(struct lcd_panel *panel) -{ - struct mipid_device *md = to_mipid_device(panel); - - if (md->enabled) - mipid_esd_stop_check(md); - destroy_workqueue(md->esd_wq); -} - -static struct lcd_panel mipid_panel = { - .config = OMAP_LCDC_PANEL_TFT, - - .bpp = 16, - .x_res = 800, - .y_res = 480, - .pixel_clock = 21940, - .hsw = 50, - .hfp = 20, - .hbp = 15, - .vsw = 2, - .vfp = 1, - .vbp = 3, - - .init = mipid_init, - .cleanup = mipid_cleanup, - .enable = mipid_enable, - .disable = mipid_disable, - .get_caps = mipid_get_caps, - .set_bklight_level = mipid_set_bklight_level, - .get_bklight_level = mipid_get_bklight_level, - .get_bklight_max = mipid_get_bklight_max, - .run_test = mipid_run_test, -}; - -static int mipid_detect(struct mipid_device *md) -{ - struct mipid_platform_data *pdata; - u8 display_id[3]; - - pdata = md->spi->dev.platform_data; - if (pdata == NULL) { - dev_err(&md->spi->dev, "missing platform data\n"); - return -ENOENT; - } - - mipid_read(md, MIPID_CMD_READ_DISP_ID, display_id, 3); - dev_dbg(&md->spi->dev, "MIPI display ID: %02x%02x%02x\n", - display_id[0], display_id[1], display_id[2]); - - switch (display_id[0]) { - case 0x45: - md->panel.name = "lph8923"; - break; - case 0x83: - md->panel.name = "ls041y3"; - md->esd_check = ls041y3_esd_check; - break; - default: - md->panel.name = "unknown"; - dev_err(&md->spi->dev, "invalid display ID\n"); - return -ENODEV; - } - - md->revision = display_id[1]; - md->panel.data_lines = pdata->data_lines; - pr_info("omapfb: %s rev %02x LCD detected, %d data lines\n", - md->panel.name, md->revision, md->panel.data_lines); - - return 0; -} - -static int mipid_spi_probe(struct spi_device *spi) -{ - struct mipid_device *md; - int r; - - md = kzalloc(sizeof(*md), GFP_KERNEL); - if (md == NULL) { - dev_err(&spi->dev, "out of memory\n"); - return -ENOMEM; - } - - spi->mode = SPI_MODE_0; - md->spi = spi; - dev_set_drvdata(&spi->dev, md); - md->panel = mipid_panel; - - r = mipid_detect(md); - if (r < 0) - return r; - - omapfb_register_panel(&md->panel); - - return 0; -} - -static int mipid_spi_remove(struct spi_device *spi) -{ - struct mipid_device *md = dev_get_drvdata(&spi->dev); - - mipid_disable(&md->panel); - kfree(md); - - return 0; -} - -static struct spi_driver mipid_spi_driver = { - .driver = { - .name = MIPID_MODULE_NAME, - .owner = THIS_MODULE, - }, - .probe = mipid_spi_probe, - .remove = mipid_spi_remove, -}; - -module_spi_driver(mipid_spi_driver); - -MODULE_DESCRIPTION("MIPI display driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/video/omap/lcd_osk.c b/drivers/video/omap/lcd_osk.c deleted file mode 100644 index 7fbe04bce0ed..000000000000 --- a/drivers/video/omap/lcd_osk.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * LCD panel support for the TI OMAP OSK board - * - * Copyright (C) 2004 Nokia Corporation - * Author: Imre Deak <imre.deak@nokia.com> - * Adapted for OSK by <dirk.behme@de.bosch.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/module.h> -#include <linux/platform_device.h> - -#include <asm/gpio.h> - -#include <mach/hardware.h> -#include <mach/mux.h> - -#include "omapfb.h" - -static int osk_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) -{ - /* gpio2 was allocated in board init */ - return 0; -} - -static void osk_panel_cleanup(struct lcd_panel *panel) -{ -} - -static int osk_panel_enable(struct lcd_panel *panel) -{ - /* configure PWL pin */ - omap_cfg_reg(PWL); - - /* Enable PWL unit */ - omap_writeb(0x01, OMAP_PWL_CLK_ENABLE); - - /* Set PWL level */ - omap_writeb(0xFF, OMAP_PWL_ENABLE); - - /* set GPIO2 high (lcd power enabled) */ - gpio_set_value(2, 1); - - return 0; -} - -static void osk_panel_disable(struct lcd_panel *panel) -{ - /* Set PWL level to zero */ - omap_writeb(0x00, OMAP_PWL_ENABLE); - - /* Disable PWL unit */ - omap_writeb(0x00, OMAP_PWL_CLK_ENABLE); - - /* set GPIO2 low */ - gpio_set_value(2, 0); -} - -static unsigned long osk_panel_get_caps(struct lcd_panel *panel) -{ - return 0; -} - -struct lcd_panel osk_panel = { - .name = "osk", - .config = OMAP_LCDC_PANEL_TFT, - - .bpp = 16, - .data_lines = 16, - .x_res = 240, - .y_res = 320, - .pixel_clock = 12500, - .hsw = 40, - .hfp = 40, - .hbp = 72, - .vsw = 1, - .vfp = 1, - .vbp = 0, - .pcd = 12, - - .init = osk_panel_init, - .cleanup = osk_panel_cleanup, - .enable = osk_panel_enable, - .disable = osk_panel_disable, - .get_caps = osk_panel_get_caps, -}; - -static int osk_panel_probe(struct platform_device *pdev) -{ - omapfb_register_panel(&osk_panel); - return 0; -} - -static int osk_panel_remove(struct platform_device *pdev) -{ - return 0; -} - -static int osk_panel_suspend(struct platform_device *pdev, pm_message_t mesg) -{ - return 0; -} - -static int osk_panel_resume(struct platform_device *pdev) -{ - return 0; -} - -static struct platform_driver osk_panel_driver = { - .probe = osk_panel_probe, - .remove = osk_panel_remove, - .suspend = osk_panel_suspend, - .resume = osk_panel_resume, - .driver = { - .name = "lcd_osk", - .owner = THIS_MODULE, - }, -}; - -module_platform_driver(osk_panel_driver); diff --git a/drivers/video/omap/lcd_palmte.c b/drivers/video/omap/lcd_palmte.c deleted file mode 100644 index ff4fb624b904..000000000000 --- a/drivers/video/omap/lcd_palmte.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * LCD panel support for the Palm Tungsten E - * - * Original version : Romain Goyet <r.goyet@gmail.com> - * Current version : Laurent Gonzalez <palmte.linux@free.fr> - * - * 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/module.h> -#include <linux/platform_device.h> -#include <linux/io.h> - -#include "omapfb.h" - -static int palmte_panel_init(struct lcd_panel *panel, - struct omapfb_device *fbdev) -{ - return 0; -} - -static void palmte_panel_cleanup(struct lcd_panel *panel) -{ -} - -static int palmte_panel_enable(struct lcd_panel *panel) -{ - return 0; -} - -static void palmte_panel_disable(struct lcd_panel *panel) -{ -} - -static unsigned long palmte_panel_get_caps(struct lcd_panel *panel) -{ - return 0; -} - -struct lcd_panel palmte_panel = { - .name = "palmte", - .config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC | - OMAP_LCDC_INV_HSYNC | OMAP_LCDC_HSVS_RISING_EDGE | - OMAP_LCDC_HSVS_OPPOSITE, - - .data_lines = 16, - .bpp = 8, - .pixel_clock = 12000, - .x_res = 320, - .y_res = 320, - .hsw = 4, - .hfp = 8, - .hbp = 28, - .vsw = 1, - .vfp = 8, - .vbp = 7, - .pcd = 0, - - .init = palmte_panel_init, - .cleanup = palmte_panel_cleanup, - .enable = palmte_panel_enable, - .disable = palmte_panel_disable, - .get_caps = palmte_panel_get_caps, -}; - -static int palmte_panel_probe(struct platform_device *pdev) -{ - omapfb_register_panel(&palmte_panel); - return 0; -} - -static int palmte_panel_remove(struct platform_device *pdev) -{ - return 0; -} - -static int palmte_panel_suspend(struct platform_device *pdev, pm_message_t mesg) -{ - return 0; -} - -static int palmte_panel_resume(struct platform_device *pdev) -{ - return 0; -} - -static struct platform_driver palmte_panel_driver = { - .probe = palmte_panel_probe, - .remove = palmte_panel_remove, - .suspend = palmte_panel_suspend, - .resume = palmte_panel_resume, - .driver = { - .name = "lcd_palmte", - .owner = THIS_MODULE, - }, -}; - -module_platform_driver(palmte_panel_driver); diff --git a/drivers/video/omap/lcd_palmtt.c b/drivers/video/omap/lcd_palmtt.c deleted file mode 100644 index aaf3c8ba1243..000000000000 --- a/drivers/video/omap/lcd_palmtt.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * LCD panel support for Palm Tungsten|T - * Current version : Marek Vasut <marek.vasut@gmail.com> - * - * Modified from lcd_inn1510.c - * - * 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. - */ - -/* -GPIO11 - backlight -GPIO12 - screen blanking -GPIO13 - screen blanking -*/ - -#include <linux/platform_device.h> -#include <linux/module.h> -#include <linux/io.h> - -#include <asm/gpio.h> -#include "omapfb.h" - -static int palmtt_panel_init(struct lcd_panel *panel, - struct omapfb_device *fbdev) -{ - return 0; -} - -static void palmtt_panel_cleanup(struct lcd_panel *panel) -{ -} - -static int palmtt_panel_enable(struct lcd_panel *panel) -{ - return 0; -} - -static void palmtt_panel_disable(struct lcd_panel *panel) -{ -} - -static unsigned long palmtt_panel_get_caps(struct lcd_panel *panel) -{ - return OMAPFB_CAPS_SET_BACKLIGHT; -} - -struct lcd_panel palmtt_panel = { - .name = "palmtt", - .config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC | - OMAP_LCDC_INV_HSYNC | OMAP_LCDC_HSVS_RISING_EDGE | - OMAP_LCDC_HSVS_OPPOSITE, - .bpp = 16, - .data_lines = 16, - .x_res = 320, - .y_res = 320, - .pixel_clock = 10000, - .hsw = 4, - .hfp = 8, - .hbp = 28, - .vsw = 1, - .vfp = 8, - .vbp = 7, - .pcd = 0, - - .init = palmtt_panel_init, - .cleanup = palmtt_panel_cleanup, - .enable = palmtt_panel_enable, - .disable = palmtt_panel_disable, - .get_caps = palmtt_panel_get_caps, -}; - -static int palmtt_panel_probe(struct platform_device *pdev) -{ - omapfb_register_panel(&palmtt_panel); - return 0; -} - -static int palmtt_panel_remove(struct platform_device *pdev) -{ - return 0; -} - -static int palmtt_panel_suspend(struct platform_device *pdev, pm_message_t mesg) -{ - return 0; -} - -static int palmtt_panel_resume(struct platform_device *pdev) -{ - return 0; -} - -static struct platform_driver palmtt_panel_driver = { - .probe = palmtt_panel_probe, - .remove = palmtt_panel_remove, - .suspend = palmtt_panel_suspend, - .resume = palmtt_panel_resume, - .driver = { - .name = "lcd_palmtt", - .owner = THIS_MODULE, - }, -}; - -module_platform_driver(palmtt_panel_driver); diff --git a/drivers/video/omap/lcd_palmz71.c b/drivers/video/omap/lcd_palmz71.c deleted file mode 100644 index 3b7d8aa1cf34..000000000000 --- a/drivers/video/omap/lcd_palmz71.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * LCD panel support for the Palm Zire71 - * - * Original version : Romain Goyet - * Current version : Laurent Gonzalez - * Modified for zire71 : Marek Vasut - * - * 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/module.h> -#include <linux/platform_device.h> -#include <linux/io.h> - -#include "omapfb.h" - -static int palmz71_panel_init(struct lcd_panel *panel, - struct omapfb_device *fbdev) -{ - return 0; -} - -static void palmz71_panel_cleanup(struct lcd_panel *panel) -{ - -} - -static int palmz71_panel_enable(struct lcd_panel *panel) -{ - return 0; -} - -static void palmz71_panel_disable(struct lcd_panel *panel) -{ -} - -static unsigned long palmz71_panel_get_caps(struct lcd_panel *panel) -{ - return OMAPFB_CAPS_SET_BACKLIGHT; -} - -struct lcd_panel palmz71_panel = { - .name = "palmz71", - .config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC | - OMAP_LCDC_INV_HSYNC | OMAP_LCDC_HSVS_RISING_EDGE | - OMAP_LCDC_HSVS_OPPOSITE, - .data_lines = 16, - .bpp = 16, - .pixel_clock = 24000, - .x_res = 320, - .y_res = 320, - .hsw = 4, - .hfp = 8, - .hbp = 28, - .vsw = 1, - .vfp = 8, - .vbp = 7, - .pcd = 0, - - .init = palmz71_panel_init, - .cleanup = palmz71_panel_cleanup, - .enable = palmz71_panel_enable, - .disable = palmz71_panel_disable, - .get_caps = palmz71_panel_get_caps, -}; - -static int palmz71_panel_probe(struct platform_device *pdev) -{ - omapfb_register_panel(&palmz71_panel); - return 0; -} - -static int palmz71_panel_remove(struct platform_device *pdev) -{ - return 0; -} - -static int palmz71_panel_suspend(struct platform_device *pdev, - pm_message_t mesg) -{ - return 0; -} - -static int palmz71_panel_resume(struct platform_device *pdev) -{ - return 0; -} - -static struct platform_driver palmz71_panel_driver = { - .probe = palmz71_panel_probe, - .remove = palmz71_panel_remove, - .suspend = palmz71_panel_suspend, - .resume = palmz71_panel_resume, - .driver = { - .name = "lcd_palmz71", - .owner = THIS_MODULE, - }, -}; - -module_platform_driver(palmz71_panel_driver); diff --git a/drivers/video/omap/lcdc.c b/drivers/video/omap/lcdc.c deleted file mode 100644 index b52f62595f65..000000000000 --- a/drivers/video/omap/lcdc.c +++ /dev/null @@ -1,856 +0,0 @@ -/* - * OMAP1 internal LCD controller - * - * Copyright (C) 2004 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/module.h> -#include <linux/device.h> -#include <linux/interrupt.h> -#include <linux/spinlock.h> -#include <linux/err.h> -#include <linux/mm.h> -#include <linux/fb.h> -#include <linux/dma-mapping.h> -#include <linux/vmalloc.h> -#include <linux/clk.h> -#include <linux/gfp.h> - -#include <mach/lcdc.h> -#include <linux/omap-dma.h> - -#include <asm/mach-types.h> - -#include "omapfb.h" - -#include "lcdc.h" - -#define MODULE_NAME "lcdc" - -#define MAX_PALETTE_SIZE PAGE_SIZE - -enum lcdc_load_mode { - OMAP_LCDC_LOAD_PALETTE, - OMAP_LCDC_LOAD_FRAME, - OMAP_LCDC_LOAD_PALETTE_AND_FRAME -}; - -static struct omap_lcd_controller { - enum omapfb_update_mode update_mode; - int ext_mode; - - unsigned long frame_offset; - int screen_width; - int xres; - int yres; - - enum omapfb_color_format color_mode; - int bpp; - void *palette_virt; - dma_addr_t palette_phys; - int palette_code; - int palette_size; - - unsigned int irq_mask; - struct completion last_frame_complete; - struct completion palette_load_complete; - struct clk *lcd_ck; - struct omapfb_device *fbdev; - - void (*dma_callback)(void *data); - void *dma_callback_data; - - int fbmem_allocated; - dma_addr_t vram_phys; - void *vram_virt; - unsigned long vram_size; -} lcdc; - -static void inline enable_irqs(int mask) -{ - lcdc.irq_mask |= mask; -} - -static void inline disable_irqs(int mask) -{ - lcdc.irq_mask &= ~mask; -} - -static void set_load_mode(enum lcdc_load_mode mode) -{ - u32 l; - - l = omap_readl(OMAP_LCDC_CONTROL); - l &= ~(3 << 20); - switch (mode) { - case OMAP_LCDC_LOAD_PALETTE: - l |= 1 << 20; - break; - case OMAP_LCDC_LOAD_FRAME: - l |= 2 << 20; - break; - case OMAP_LCDC_LOAD_PALETTE_AND_FRAME: - break; - default: - BUG(); - } - omap_writel(l, OMAP_LCDC_CONTROL); -} - -static void enable_controller(void) -{ - u32 l; - - l = omap_readl(OMAP_LCDC_CONTROL); - l |= OMAP_LCDC_CTRL_LCD_EN; - l &= ~OMAP_LCDC_IRQ_MASK; - l |= lcdc.irq_mask | OMAP_LCDC_IRQ_DONE; /* enabled IRQs */ - omap_writel(l, OMAP_LCDC_CONTROL); -} - -static void disable_controller_async(void) -{ - u32 l; - u32 mask; - - l = omap_readl(OMAP_LCDC_CONTROL); - mask = OMAP_LCDC_CTRL_LCD_EN | OMAP_LCDC_IRQ_MASK; - /* - * Preserve the DONE mask, since we still want to get the - * final DONE irq. It will be disabled in the IRQ handler. - */ - mask &= ~OMAP_LCDC_IRQ_DONE; - l &= ~mask; - omap_writel(l, OMAP_LCDC_CONTROL); -} - -static void disable_controller(void) -{ - init_completion(&lcdc.last_frame_complete); - disable_controller_async(); - if (!wait_for_completion_timeout(&lcdc.last_frame_complete, - msecs_to_jiffies(500))) - dev_err(lcdc.fbdev->dev, "timeout waiting for FRAME DONE\n"); -} - -static void reset_controller(u32 status) -{ - static unsigned long reset_count; - static unsigned long last_jiffies; - - disable_controller_async(); - reset_count++; - if (reset_count == 1 || time_after(jiffies, last_jiffies + HZ)) { - dev_err(lcdc.fbdev->dev, - "resetting (status %#010x,reset count %lu)\n", - status, reset_count); - last_jiffies = jiffies; - } - if (reset_count < 100) { - enable_controller(); - } else { - reset_count = 0; - dev_err(lcdc.fbdev->dev, - "too many reset attempts, giving up.\n"); - } -} - -/* - * Configure the LCD DMA according to the current mode specified by parameters - * in lcdc.fbdev and fbdev->var. - */ -static void setup_lcd_dma(void) -{ - static const int dma_elem_type[] = { - 0, - OMAP_DMA_DATA_TYPE_S8, - OMAP_DMA_DATA_TYPE_S16, - 0, - OMAP_DMA_DATA_TYPE_S32, - }; - struct omapfb_plane_struct *plane = lcdc.fbdev->fb_info[0]->par; - struct fb_var_screeninfo *var = &lcdc.fbdev->fb_info[0]->var; - unsigned long src; - int esize, xelem, yelem; - - src = lcdc.vram_phys + lcdc.frame_offset; - - switch (var->rotate) { - case 0: - if (plane->info.mirror || (src & 3) || - lcdc.color_mode == OMAPFB_COLOR_YUV420 || - (lcdc.xres & 1)) - esize = 2; - else - esize = 4; - xelem = lcdc.xres * lcdc.bpp / 8 / esize; - yelem = lcdc.yres; - break; - case 90: - case 180: - case 270: - if (cpu_is_omap15xx()) { - BUG(); - } - esize = 2; - xelem = lcdc.yres * lcdc.bpp / 16; - yelem = lcdc.xres; - break; - default: - BUG(); - return; - } -#ifdef VERBOSE - dev_dbg(lcdc.fbdev->dev, - "setup_dma: src %#010lx esize %d xelem %d yelem %d\n", - src, esize, xelem, yelem); -#endif - omap_set_lcd_dma_b1(src, xelem, yelem, dma_elem_type[esize]); - if (!cpu_is_omap15xx()) { - int bpp = lcdc.bpp; - - /* - * YUV support is only for external mode when we have the - * YUV window embedded in a 16bpp frame buffer. - */ - if (lcdc.color_mode == OMAPFB_COLOR_YUV420) - bpp = 16; - /* Set virtual xres elem size */ - omap_set_lcd_dma_b1_vxres( - lcdc.screen_width * bpp / 8 / esize); - /* Setup transformations */ - omap_set_lcd_dma_b1_rotation(var->rotate); - omap_set_lcd_dma_b1_mirror(plane->info.mirror); - } - omap_setup_lcd_dma(); -} - -static irqreturn_t lcdc_irq_handler(int irq, void *dev_id) -{ - u32 status; - - status = omap_readl(OMAP_LCDC_STATUS); - - if (status & (OMAP_LCDC_STAT_FUF | OMAP_LCDC_STAT_SYNC_LOST)) - reset_controller(status); - else { - if (status & OMAP_LCDC_STAT_DONE) { - u32 l; - - /* - * Disable IRQ_DONE. The status bit will be cleared - * only when the controller is reenabled and we don't - * want to get more interrupts. - */ - l = omap_readl(OMAP_LCDC_CONTROL); - l &= ~OMAP_LCDC_IRQ_DONE; - omap_writel(l, OMAP_LCDC_CONTROL); - complete(&lcdc.last_frame_complete); - } - if (status & OMAP_LCDC_STAT_LOADED_PALETTE) { - disable_controller_async(); - complete(&lcdc.palette_load_complete); - } - } - - /* - * Clear these interrupt status bits. - * Sync_lost, FUF bits were cleared by disabling the LCD controller - * LOADED_PALETTE can be cleared this way only in palette only - * load mode. In other load modes it's cleared by disabling the - * controller. - */ - status &= ~(OMAP_LCDC_STAT_VSYNC | - OMAP_LCDC_STAT_LOADED_PALETTE | - OMAP_LCDC_STAT_ABC | - OMAP_LCDC_STAT_LINE_INT); - omap_writel(status, OMAP_LCDC_STATUS); - return IRQ_HANDLED; -} - -/* - * Change to a new video mode. We defer this to a later time to avoid any - * flicker and not to mess up the current LCD DMA context. For this we disable - * the LCD controller, which will generate a DONE irq after the last frame has - * been transferred. Then it'll be safe to reconfigure both the LCD controller - * as well as the LCD DMA. - */ -static int omap_lcdc_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) -{ - struct fb_var_screeninfo *var = &lcdc.fbdev->fb_info[0]->var; - struct lcd_panel *panel = lcdc.fbdev->panel; - int rot_x, rot_y; - - if (var->rotate == 0) { - rot_x = panel->x_res; - rot_y = panel->y_res; - } else { - rot_x = panel->y_res; - rot_y = panel->x_res; - } - if (plane != 0 || channel_out != 0 || pos_x != 0 || pos_y != 0 || - width > rot_x || height > rot_y) { -#ifdef VERBOSE - dev_dbg(lcdc.fbdev->dev, - "invalid plane params plane %d pos_x %d pos_y %d " - "w %d h %d\n", plane, pos_x, pos_y, width, height); -#endif - return -EINVAL; - } - - lcdc.frame_offset = offset; - lcdc.xres = width; - lcdc.yres = height; - lcdc.screen_width = screen_width; - lcdc.color_mode = color_mode; - - switch (color_mode) { - case OMAPFB_COLOR_CLUT_8BPP: - lcdc.bpp = 8; - lcdc.palette_code = 0x3000; - lcdc.palette_size = 512; - break; - case OMAPFB_COLOR_RGB565: - lcdc.bpp = 16; - lcdc.palette_code = 0x4000; - lcdc.palette_size = 32; - break; - case OMAPFB_COLOR_RGB444: - lcdc.bpp = 16; - lcdc.palette_code = 0x4000; - lcdc.palette_size = 32; - break; - case OMAPFB_COLOR_YUV420: - if (lcdc.ext_mode) { - lcdc.bpp = 12; - break; - } - /* fallthrough */ - case OMAPFB_COLOR_YUV422: - if (lcdc.ext_mode) { - lcdc.bpp = 16; - break; - } - /* fallthrough */ - default: - /* FIXME: other BPPs. - * bpp1: code 0, size 256 - * bpp2: code 0x1000 size 256 - * bpp4: code 0x2000 size 256 - * bpp12: code 0x4000 size 32 - */ - dev_dbg(lcdc.fbdev->dev, "invalid color mode %d\n", color_mode); - BUG(); - return -1; - } - - if (lcdc.ext_mode) { - setup_lcd_dma(); - return 0; - } - - if (lcdc.update_mode == OMAPFB_AUTO_UPDATE) { - disable_controller(); - omap_stop_lcd_dma(); - setup_lcd_dma(); - enable_controller(); - } - - return 0; -} - -static int omap_lcdc_enable_plane(int plane, int enable) -{ - dev_dbg(lcdc.fbdev->dev, - "plane %d enable %d update_mode %d ext_mode %d\n", - plane, enable, lcdc.update_mode, lcdc.ext_mode); - if (plane != OMAPFB_PLANE_GFX) - return -EINVAL; - - return 0; -} - -/* - * Configure the LCD DMA for a palette load operation and do the palette - * downloading synchronously. We don't use the frame+palette load mode of - * the controller, since the palette can always be downloaded separately. - */ -static void load_palette(void) -{ - u16 *palette; - - palette = (u16 *)lcdc.palette_virt; - - *(u16 *)palette &= 0x0fff; - *(u16 *)palette |= lcdc.palette_code; - - omap_set_lcd_dma_b1(lcdc.palette_phys, - lcdc.palette_size / 4 + 1, 1, OMAP_DMA_DATA_TYPE_S32); - - omap_set_lcd_dma_single_transfer(1); - omap_setup_lcd_dma(); - - init_completion(&lcdc.palette_load_complete); - enable_irqs(OMAP_LCDC_IRQ_LOADED_PALETTE); - set_load_mode(OMAP_LCDC_LOAD_PALETTE); - enable_controller(); - if (!wait_for_completion_timeout(&lcdc.palette_load_complete, - msecs_to_jiffies(500))) - dev_err(lcdc.fbdev->dev, "timeout waiting for FRAME DONE\n"); - /* The controller gets disabled in the irq handler */ - disable_irqs(OMAP_LCDC_IRQ_LOADED_PALETTE); - omap_stop_lcd_dma(); - - omap_set_lcd_dma_single_transfer(lcdc.ext_mode); -} - -/* Used only in internal controller mode */ -static int omap_lcdc_setcolreg(u_int regno, u16 red, u16 green, u16 blue, - u16 transp, int update_hw_pal) -{ - u16 *palette; - - if (lcdc.color_mode != OMAPFB_COLOR_CLUT_8BPP || regno > 255) - return -EINVAL; - - palette = (u16 *)lcdc.palette_virt; - - palette[regno] &= ~0x0fff; - palette[regno] |= ((red >> 12) << 8) | ((green >> 12) << 4 ) | - (blue >> 12); - - if (update_hw_pal) { - disable_controller(); - omap_stop_lcd_dma(); - load_palette(); - setup_lcd_dma(); - set_load_mode(OMAP_LCDC_LOAD_FRAME); - enable_controller(); - } - - return 0; -} - -static void calc_ck_div(int is_tft, int pck, int *pck_div) -{ - unsigned long lck; - - pck = max(1, pck); - lck = clk_get_rate(lcdc.lcd_ck); - *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) { - /* FIXME: try to adjust logic clock divider as well */ - *pck_div = 255; - dev_warn(lcdc.fbdev->dev, "pixclock %d kHz too low.\n", - pck / 1000); - } -} - -static void inline setup_regs(void) -{ - u32 l; - struct lcd_panel *panel = lcdc.fbdev->panel; - int is_tft = panel->config & OMAP_LCDC_PANEL_TFT; - unsigned long lck; - int pcd; - - l = omap_readl(OMAP_LCDC_CONTROL); - l &= ~OMAP_LCDC_CTRL_LCD_TFT; - l |= is_tft ? OMAP_LCDC_CTRL_LCD_TFT : 0; -#ifdef CONFIG_MACH_OMAP_PALMTE -/* FIXME:if (machine_is_omap_palmte()) { */ - /* PalmTE uses alternate TFT setting in 8BPP mode */ - l |= (is_tft && panel->bpp == 8) ? 0x810000 : 0; -/* } */ -#endif - omap_writel(l, OMAP_LCDC_CONTROL); - - l = omap_readl(OMAP_LCDC_TIMING2); - l &= ~(((1 << 6) - 1) << 20); - l |= (panel->config & OMAP_LCDC_SIGNAL_MASK) << 20; - omap_writel(l, OMAP_LCDC_TIMING2); - - l = panel->x_res - 1; - l |= (panel->hsw - 1) << 10; - l |= (panel->hfp - 1) << 16; - l |= (panel->hbp - 1) << 24; - omap_writel(l, OMAP_LCDC_TIMING0); - - l = panel->y_res - 1; - l |= (panel->vsw - 1) << 10; - l |= panel->vfp << 16; - l |= panel->vbp << 24; - omap_writel(l, OMAP_LCDC_TIMING1); - - l = omap_readl(OMAP_LCDC_TIMING2); - l &= ~0xff; - - lck = clk_get_rate(lcdc.lcd_ck); - - if (!panel->pcd) - calc_ck_div(is_tft, panel->pixel_clock * 1000, &pcd); - else { - dev_warn(lcdc.fbdev->dev, - "Pixel clock divider value is obsolete.\n" - "Try to set pixel_clock to %lu and pcd to 0 " - "in drivers/video/omap/lcd_%s.c and submit a patch.\n", - lck / panel->pcd / 1000, panel->name); - - pcd = panel->pcd; - } - l |= pcd & 0xff; - l |= panel->acb << 8; - omap_writel(l, OMAP_LCDC_TIMING2); - - /* update panel info with the exact clock */ - panel->pixel_clock = lck / pcd / 1000; -} - -/* - * Configure the LCD controller, download the color palette and start a looped - * DMA transfer of the frame image data. Called only in internal - * controller mode. - */ -static int omap_lcdc_set_update_mode(enum omapfb_update_mode mode) -{ - int r = 0; - - if (mode != lcdc.update_mode) { - switch (mode) { - case OMAPFB_AUTO_UPDATE: - setup_regs(); - load_palette(); - - /* Setup and start LCD DMA */ - setup_lcd_dma(); - - set_load_mode(OMAP_LCDC_LOAD_FRAME); - enable_irqs(OMAP_LCDC_IRQ_DONE); - /* This will start the actual DMA transfer */ - enable_controller(); - lcdc.update_mode = mode; - break; - case OMAPFB_UPDATE_DISABLED: - disable_controller(); - omap_stop_lcd_dma(); - lcdc.update_mode = mode; - break; - default: - r = -EINVAL; - } - } - - return r; -} - -static enum omapfb_update_mode omap_lcdc_get_update_mode(void) -{ - return lcdc.update_mode; -} - -/* PM code called only in internal controller mode */ -static void omap_lcdc_suspend(void) -{ - omap_lcdc_set_update_mode(OMAPFB_UPDATE_DISABLED); -} - -static void omap_lcdc_resume(void) -{ - omap_lcdc_set_update_mode(OMAPFB_AUTO_UPDATE); -} - -static void omap_lcdc_get_caps(int plane, struct omapfb_caps *caps) -{ - return; -} - -int omap_lcdc_set_dma_callback(void (*callback)(void *data), void *data) -{ - BUG_ON(callback == NULL); - - if (lcdc.dma_callback) - return -EBUSY; - else { - lcdc.dma_callback = callback; - lcdc.dma_callback_data = data; - } - return 0; -} -EXPORT_SYMBOL(omap_lcdc_set_dma_callback); - -void omap_lcdc_free_dma_callback(void) -{ - lcdc.dma_callback = NULL; -} -EXPORT_SYMBOL(omap_lcdc_free_dma_callback); - -static void lcdc_dma_handler(u16 status, void *data) -{ - if (lcdc.dma_callback) - lcdc.dma_callback(lcdc.dma_callback_data); -} - -static int mmap_kern(void) -{ - struct vm_struct *kvma; - struct vm_area_struct vma; - pgprot_t pgprot; - unsigned long vaddr; - - kvma = get_vm_area(lcdc.vram_size, VM_IOREMAP); - if (kvma == NULL) { - dev_err(lcdc.fbdev->dev, "can't get kernel vm area\n"); - return -ENOMEM; - } - vma.vm_mm = &init_mm; - - vaddr = (unsigned long)kvma->addr; - vma.vm_start = vaddr; - vma.vm_end = vaddr + lcdc.vram_size; - - pgprot = pgprot_writecombine(pgprot_kernel); - if (io_remap_pfn_range(&vma, vaddr, - lcdc.vram_phys >> PAGE_SHIFT, - lcdc.vram_size, pgprot) < 0) { - dev_err(lcdc.fbdev->dev, "kernel mmap for FB memory failed\n"); - return -EAGAIN; - } - - lcdc.vram_virt = (void *)vaddr; - - return 0; -} - -static void unmap_kern(void) -{ - vunmap(lcdc.vram_virt); -} - -static int alloc_palette_ram(void) -{ - lcdc.palette_virt = dma_alloc_writecombine(lcdc.fbdev->dev, - MAX_PALETTE_SIZE, &lcdc.palette_phys, GFP_KERNEL); - if (lcdc.palette_virt == NULL) { - dev_err(lcdc.fbdev->dev, "failed to alloc palette memory\n"); - return -ENOMEM; - } - memset(lcdc.palette_virt, 0, MAX_PALETTE_SIZE); - - return 0; -} - -static void free_palette_ram(void) -{ - dma_free_writecombine(lcdc.fbdev->dev, MAX_PALETTE_SIZE, - lcdc.palette_virt, lcdc.palette_phys); -} - -static int alloc_fbmem(struct omapfb_mem_region *region) -{ - int bpp; - int frame_size; - struct lcd_panel *panel = lcdc.fbdev->panel; - - bpp = panel->bpp; - if (bpp == 12) - bpp = 16; - frame_size = PAGE_ALIGN(panel->x_res * bpp / 8 * panel->y_res); - if (region->size > frame_size) - frame_size = region->size; - lcdc.vram_size = frame_size; - lcdc.vram_virt = dma_alloc_writecombine(lcdc.fbdev->dev, - lcdc.vram_size, &lcdc.vram_phys, GFP_KERNEL); - if (lcdc.vram_virt == NULL) { - dev_err(lcdc.fbdev->dev, "unable to allocate FB DMA memory\n"); - return -ENOMEM; - } - region->size = frame_size; - region->paddr = lcdc.vram_phys; - region->vaddr = lcdc.vram_virt; - region->alloc = 1; - - memset(lcdc.vram_virt, 0, lcdc.vram_size); - - return 0; -} - -static void free_fbmem(void) -{ - dma_free_writecombine(lcdc.fbdev->dev, lcdc.vram_size, - lcdc.vram_virt, lcdc.vram_phys); -} - -static int setup_fbmem(struct omapfb_mem_desc *req_md) -{ - int r; - - if (!req_md->region_cnt) { - dev_err(lcdc.fbdev->dev, "no memory regions defined\n"); - return -EINVAL; - } - - if (req_md->region_cnt > 1) { - dev_err(lcdc.fbdev->dev, "only one plane is supported\n"); - req_md->region_cnt = 1; - } - - if (req_md->region[0].paddr == 0) { - lcdc.fbmem_allocated = 1; - if ((r = alloc_fbmem(&req_md->region[0])) < 0) - return r; - return 0; - } - - lcdc.vram_phys = req_md->region[0].paddr; - lcdc.vram_size = req_md->region[0].size; - - if ((r = mmap_kern()) < 0) - return r; - - dev_dbg(lcdc.fbdev->dev, "vram at %08x size %08lx mapped to 0x%p\n", - lcdc.vram_phys, lcdc.vram_size, lcdc.vram_virt); - - return 0; -} - -static void cleanup_fbmem(void) -{ - if (lcdc.fbmem_allocated) - free_fbmem(); - else - unmap_kern(); -} - -static int omap_lcdc_init(struct omapfb_device *fbdev, int ext_mode, - struct omapfb_mem_desc *req_vram) -{ - int r; - u32 l; - int rate; - struct clk *tc_ck; - - lcdc.irq_mask = 0; - - lcdc.fbdev = fbdev; - lcdc.ext_mode = ext_mode; - - l = 0; - omap_writel(l, OMAP_LCDC_CONTROL); - - /* FIXME: - * According to errata some platforms have a clock rate limitiation - */ - lcdc.lcd_ck = clk_get(fbdev->dev, "lcd_ck"); - if (IS_ERR(lcdc.lcd_ck)) { - dev_err(fbdev->dev, "unable to access LCD clock\n"); - r = PTR_ERR(lcdc.lcd_ck); - goto fail0; - } - - tc_ck = clk_get(fbdev->dev, "tc_ck"); - if (IS_ERR(tc_ck)) { - dev_err(fbdev->dev, "unable to access TC clock\n"); - r = PTR_ERR(tc_ck); - goto fail1; - } - - rate = clk_get_rate(tc_ck); - clk_put(tc_ck); - - if (machine_is_ams_delta()) - rate /= 4; - if (machine_is_omap_h3()) - rate /= 3; - r = clk_set_rate(lcdc.lcd_ck, rate); - if (r) { - dev_err(fbdev->dev, "failed to adjust LCD rate\n"); - goto fail1; - } - clk_enable(lcdc.lcd_ck); - - r = request_irq(OMAP_LCDC_IRQ, lcdc_irq_handler, 0, MODULE_NAME, fbdev); - if (r) { - dev_err(fbdev->dev, "unable to get IRQ\n"); - goto fail2; - } - - r = omap_request_lcd_dma(lcdc_dma_handler, NULL); - if (r) { - dev_err(fbdev->dev, "unable to get LCD DMA\n"); - goto fail3; - } - - omap_set_lcd_dma_single_transfer(ext_mode); - omap_set_lcd_dma_ext_controller(ext_mode); - - if (!ext_mode) - if ((r = alloc_palette_ram()) < 0) - goto fail4; - - if ((r = setup_fbmem(req_vram)) < 0) - goto fail5; - - pr_info("omapfb: LCDC initialized\n"); - - return 0; -fail5: - if (!ext_mode) - free_palette_ram(); -fail4: - omap_free_lcd_dma(); -fail3: - free_irq(OMAP_LCDC_IRQ, lcdc.fbdev); -fail2: - clk_disable(lcdc.lcd_ck); -fail1: - clk_put(lcdc.lcd_ck); -fail0: - return r; -} - -static void omap_lcdc_cleanup(void) -{ - if (!lcdc.ext_mode) - free_palette_ram(); - cleanup_fbmem(); - omap_free_lcd_dma(); - free_irq(OMAP_LCDC_IRQ, lcdc.fbdev); - clk_disable(lcdc.lcd_ck); - clk_put(lcdc.lcd_ck); -} - -const struct lcd_ctrl omap1_int_ctrl = { - .name = "internal", - .init = omap_lcdc_init, - .cleanup = omap_lcdc_cleanup, - .get_caps = omap_lcdc_get_caps, - .set_update_mode = omap_lcdc_set_update_mode, - .get_update_mode = omap_lcdc_get_update_mode, - .update_window = NULL, - .suspend = omap_lcdc_suspend, - .resume = omap_lcdc_resume, - .setup_plane = omap_lcdc_setup_plane, - .enable_plane = omap_lcdc_enable_plane, - .setcolreg = omap_lcdc_setcolreg, -}; diff --git a/drivers/video/omap/lcdc.h b/drivers/video/omap/lcdc.h deleted file mode 100644 index 845222270db3..000000000000 --- a/drivers/video/omap/lcdc.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef LCDC_H -#define LCDC_H - -int omap_lcdc_set_dma_callback(void (*callback)(void *data), void *data); -void omap_lcdc_free_dma_callback(void); - -extern const struct lcd_ctrl omap1_int_ctrl; - -#endif diff --git a/drivers/video/omap/omapfb.h b/drivers/video/omap/omapfb.h deleted file mode 100644 index 2921d20e4fba..000000000000 --- a/drivers/video/omap/omapfb.h +++ /dev/null @@ -1,246 +0,0 @@ -/* - * File: drivers/video/omap/omapfb.h - * - * Framebuffer driver for TI OMAP boards - * - * Copyright (C) 2004 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. - */ - -#ifndef __OMAPFB_H -#define __OMAPFB_H - -#include <linux/fb.h> -#include <linux/mutex.h> -#include <linux/omapfb.h> - -#define OMAPFB_EVENT_READY 1 -#define OMAPFB_EVENT_DISABLED 2 - -#define OMAP_LCDC_INV_VSYNC 0x0001 -#define OMAP_LCDC_INV_HSYNC 0x0002 -#define OMAP_LCDC_INV_PIX_CLOCK 0x0004 -#define OMAP_LCDC_INV_OUTPUT_EN 0x0008 -#define OMAP_LCDC_HSVS_RISING_EDGE 0x0010 -#define OMAP_LCDC_HSVS_OPPOSITE 0x0020 - -#define OMAP_LCDC_SIGNAL_MASK 0x003f - -#define OMAP_LCDC_PANEL_TFT 0x0100 - -#define OMAPFB_PLANE_XRES_MIN 8 -#define OMAPFB_PLANE_YRES_MIN 8 - -struct omapfb_device; - -#define OMAPFB_PLANE_NUM 1 - -struct omapfb_mem_region { - u32 paddr; - void __iomem *vaddr; - unsigned long size; - u8 type; /* OMAPFB_PLANE_MEM_* */ - enum omapfb_color_format format;/* OMAPFB_COLOR_* */ - unsigned format_used:1; /* Must be set when format is set. - * Needed b/c of the badly chosen 0 - * base for OMAPFB_COLOR_* values - */ - unsigned alloc:1; /* allocated by the driver */ - unsigned map:1; /* kernel mapped by the driver */ -}; - -struct omapfb_mem_desc { - int region_cnt; - struct omapfb_mem_region region[OMAPFB_PLANE_NUM]; -}; - -struct lcd_panel { - const char *name; - int config; /* TFT/STN, signal inversion */ - int bpp; /* Pixel format in fb mem */ - int data_lines; /* Lines on LCD HW interface */ - - int x_res, y_res; - int pixel_clock; /* In kHz */ - int hsw; /* Horizontal synchronization - pulse width */ - int hfp; /* Horizontal front porch */ - int hbp; /* Horizontal back porch */ - int vsw; /* Vertical synchronization - pulse width */ - int vfp; /* Vertical front porch */ - int vbp; /* Vertical back porch */ - int acb; /* ac-bias pin frequency */ - int pcd; /* pixel clock divider. - Obsolete use pixel_clock instead */ - - int (*init) (struct lcd_panel *panel, - struct omapfb_device *fbdev); - void (*cleanup) (struct lcd_panel *panel); - int (*enable) (struct lcd_panel *panel); - void (*disable) (struct lcd_panel *panel); - unsigned long (*get_caps) (struct lcd_panel *panel); - int (*set_bklight_level)(struct lcd_panel *panel, - unsigned int level); - unsigned int (*get_bklight_level)(struct lcd_panel *panel); - unsigned int (*get_bklight_max) (struct lcd_panel *panel); - int (*run_test) (struct lcd_panel *panel, int test_num); -}; - -struct extif_timings { - int cs_on_time; - int cs_off_time; - int we_on_time; - int we_off_time; - int re_on_time; - int re_off_time; - int we_cycle_time; - int re_cycle_time; - int cs_pulse_width; - int access_time; - - int clk_div; - - u32 tim[5]; /* set by extif->convert_timings */ - - int converted; -}; - -struct lcd_ctrl_extif { - int (*init) (struct omapfb_device *fbdev); - void (*cleanup) (void); - void (*get_clk_info) (u32 *clk_period, u32 *max_clk_div); - unsigned long (*get_max_tx_rate)(void); - int (*convert_timings) (struct extif_timings *timings); - void (*set_timings) (const struct extif_timings *timings); - void (*set_bits_per_cycle)(int bpc); - void (*write_command) (const void *buf, unsigned int len); - void (*read_data) (void *buf, unsigned int len); - void (*write_data) (const void *buf, unsigned int len); - void (*transfer_area) (int width, int height, - void (callback)(void *data), void *data); - int (*setup_tearsync) (unsigned pin_cnt, - unsigned hs_pulse_time, unsigned vs_pulse_time, - int hs_pol_inv, int vs_pol_inv, int div); - int (*enable_tearsync) (int enable, unsigned line); - - unsigned long max_transmit_size; -}; - -struct omapfb_notifier_block { - struct notifier_block nb; - void *data; - int plane_idx; -}; - -typedef int (*omapfb_notifier_callback_t)(struct notifier_block *, - unsigned long event, - void *fbi); - -struct lcd_ctrl { - const char *name; - void *data; - - int (*init) (struct omapfb_device *fbdev, - int ext_mode, - struct omapfb_mem_desc *req_md); - void (*cleanup) (void); - void (*bind_client) (struct omapfb_notifier_block *nb); - void (*get_caps) (int plane, struct omapfb_caps *caps); - int (*set_update_mode)(enum omapfb_update_mode mode); - enum omapfb_update_mode (*get_update_mode)(void); - int (*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); - int (*set_rotate) (int angle); - int (*setup_mem) (int plane, size_t size, - int mem_type, unsigned long *paddr); - int (*mmap) (struct fb_info *info, - struct vm_area_struct *vma); - int (*set_scale) (int plane, - int orig_width, int orig_height, - int out_width, int out_height); - int (*enable_plane) (int plane, int enable); - int (*update_window) (struct fb_info *fbi, - struct omapfb_update_window *win, - void (*callback)(void *), - void *callback_data); - void (*sync) (void); - void (*suspend) (void); - void (*resume) (void); - int (*run_test) (int test_num); - int (*setcolreg) (u_int regno, u16 red, u16 green, - u16 blue, u16 transp, - int update_hw_mem); - int (*set_color_key) (struct omapfb_color_key *ck); - int (*get_color_key) (struct omapfb_color_key *ck); -}; - -enum omapfb_state { - OMAPFB_DISABLED = 0, - OMAPFB_SUSPENDED = 99, - OMAPFB_ACTIVE = 100 -}; - -struct omapfb_plane_struct { - int idx; - struct omapfb_plane_info info; - enum omapfb_color_format color_mode; - struct omapfb_device *fbdev; -}; - -struct omapfb_device { - int state; - int ext_lcdc; /* Using external - LCD controller */ - struct mutex rqueue_mutex; - - int palette_size; - u32 pseudo_palette[17]; - - struct lcd_panel *panel; /* LCD panel */ - const struct lcd_ctrl *ctrl; /* LCD controller */ - const struct lcd_ctrl *int_ctrl; /* internal LCD ctrl */ - struct lcd_ctrl_extif *ext_if; /* LCD ctrl external - interface */ - struct device *dev; - struct fb_var_screeninfo new_var; /* for mode changes */ - - struct omapfb_mem_desc mem_desc; - struct fb_info *fb_info[OMAPFB_PLANE_NUM]; - - struct platform_device *dssdev; /* dummy dev for clocks */ -}; - -extern struct lcd_ctrl omap1_lcd_ctrl; - -extern void omapfb_register_panel(struct lcd_panel *panel); -extern void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval); -extern void omapfb_notify_clients(struct omapfb_device *fbdev, - unsigned long event); -extern int omapfb_register_client(struct omapfb_notifier_block *nb, - omapfb_notifier_callback_t callback, - void *callback_data); -extern int omapfb_unregister_client(struct omapfb_notifier_block *nb); -extern int omapfb_update_window_async(struct fb_info *fbi, - struct omapfb_update_window *win, - void (*callback)(void *), - void *callback_data); - -#endif /* __OMAPFB_H */ diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c deleted file mode 100644 index e4fc6d9b5371..000000000000 --- a/drivers/video/omap/omapfb_main.c +++ /dev/null @@ -1,1971 +0,0 @@ -/* - * Framebuffer driver for TI OMAP boards - * - * Copyright (C) 2004 Nokia Corporation - * Author: Imre Deak <imre.deak@nokia.com> - * - * Acknowledgements: - * Alex McMains <aam@ridgerun.com> - Original driver - * Juha Yrjola <juha.yrjola@nokia.com> - Original driver and improvements - * Dirk Behme <dirk.behme@de.bosch.com> - changes for 2.6 kernel API - * Texas Instruments - H3 support - * - * 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/platform_device.h> -#include <linux/mm.h> -#include <linux/slab.h> -#include <linux/uaccess.h> -#include <linux/module.h> - -#include <linux/omap-dma.h> - -#include <mach/hardware.h> - -#include "omapfb.h" -#include "lcdc.h" - -#define MODULE_NAME "omapfb" - -static unsigned int def_accel; -static unsigned long def_vram[OMAPFB_PLANE_NUM]; -static unsigned int def_vram_cnt; -static unsigned long def_vxres; -static unsigned long def_vyres; -static unsigned int def_rotate; -static unsigned int def_mirror; - -#ifdef CONFIG_FB_OMAP_MANUAL_UPDATE -static bool manual_update = 1; -#else -static bool manual_update; -#endif - -static struct platform_device *fbdev_pdev; -static struct lcd_panel *fbdev_panel; -static struct omapfb_device *omapfb_dev; - -struct caps_table_struct { - unsigned long flag; - const char *name; -}; - -static struct caps_table_struct ctrl_caps[] = { - { OMAPFB_CAPS_MANUAL_UPDATE, "manual update" }, - { OMAPFB_CAPS_TEARSYNC, "tearing synchronization" }, - { OMAPFB_CAPS_PLANE_RELOCATE_MEM, "relocate plane memory" }, - { OMAPFB_CAPS_PLANE_SCALE, "scale plane" }, - { OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE, "pixel double window" }, - { OMAPFB_CAPS_WINDOW_SCALE, "scale window" }, - { OMAPFB_CAPS_WINDOW_OVERLAY, "overlay window" }, - { OMAPFB_CAPS_WINDOW_ROTATE, "rotate window" }, - { OMAPFB_CAPS_SET_BACKLIGHT, "backlight setting" }, -}; - -static struct caps_table_struct color_caps[] = { - { 1 << OMAPFB_COLOR_RGB565, "RGB565", }, - { 1 << OMAPFB_COLOR_YUV422, "YUV422", }, - { 1 << OMAPFB_COLOR_YUV420, "YUV420", }, - { 1 << OMAPFB_COLOR_CLUT_8BPP, "CLUT8", }, - { 1 << OMAPFB_COLOR_CLUT_4BPP, "CLUT4", }, - { 1 << OMAPFB_COLOR_CLUT_2BPP, "CLUT2", }, - { 1 << OMAPFB_COLOR_CLUT_1BPP, "CLUT1", }, - { 1 << OMAPFB_COLOR_RGB444, "RGB444", }, - { 1 << OMAPFB_COLOR_YUY422, "YUY422", }, -}; - -static void omapdss_release(struct device *dev) -{ -} - -/* dummy device for clocks */ -static struct platform_device omapdss_device = { - .name = "omapdss_dss", - .id = -1, - .dev = { - .release = omapdss_release, - }, -}; - -/* - * --------------------------------------------------------------------------- - * LCD panel - * --------------------------------------------------------------------------- - */ -extern struct lcd_ctrl hwa742_ctrl; - -static const struct lcd_ctrl *ctrls[] = { - &omap1_int_ctrl, - -#ifdef CONFIG_FB_OMAP_LCDC_HWA742 - &hwa742_ctrl, -#endif -}; - -#ifdef CONFIG_FB_OMAP_LCDC_EXTERNAL -extern struct lcd_ctrl_extif omap1_ext_if; -#endif - -static void omapfb_rqueue_lock(struct omapfb_device *fbdev) -{ - mutex_lock(&fbdev->rqueue_mutex); -} - -static void omapfb_rqueue_unlock(struct omapfb_device *fbdev) -{ - mutex_unlock(&fbdev->rqueue_mutex); -} - -/* - * --------------------------------------------------------------------------- - * LCD controller and LCD DMA - * --------------------------------------------------------------------------- - */ -/* - * Allocate resources needed for LCD controller and LCD DMA operations. Video - * memory is allocated from system memory according to the virtual display - * size, except if a bigger memory size is specified explicitly as a kernel - * parameter. - */ -static int ctrl_init(struct omapfb_device *fbdev) -{ - int r; - int i; - - /* kernel/module vram parameters override boot tags/board config */ - if (def_vram_cnt) { - for (i = 0; i < def_vram_cnt; i++) - fbdev->mem_desc.region[i].size = - PAGE_ALIGN(def_vram[i]); - fbdev->mem_desc.region_cnt = i; - } - - if (!fbdev->mem_desc.region_cnt) { - struct lcd_panel *panel = fbdev->panel; - int def_size; - int bpp = panel->bpp; - - /* 12 bpp is packed in 16 bits */ - if (bpp == 12) - bpp = 16; - def_size = def_vxres * def_vyres * bpp / 8; - fbdev->mem_desc.region_cnt = 1; - fbdev->mem_desc.region[0].size = PAGE_ALIGN(def_size); - } - r = fbdev->ctrl->init(fbdev, 0, &fbdev->mem_desc); - if (r < 0) { - dev_err(fbdev->dev, "controller initialization failed (%d)\n", - r); - return r; - } - -#ifdef DEBUG - for (i = 0; i < fbdev->mem_desc.region_cnt; i++) { - dev_dbg(fbdev->dev, "region%d phys %08x virt %p size=%lu\n", - i, - fbdev->mem_desc.region[i].paddr, - fbdev->mem_desc.region[i].vaddr, - fbdev->mem_desc.region[i].size); - } -#endif - return 0; -} - -static void ctrl_cleanup(struct omapfb_device *fbdev) -{ - fbdev->ctrl->cleanup(); -} - -/* Must be called with fbdev->rqueue_mutex held. */ -static int ctrl_change_mode(struct fb_info *fbi) -{ - int r; - unsigned long offset; - struct omapfb_plane_struct *plane = fbi->par; - struct omapfb_device *fbdev = plane->fbdev; - struct fb_var_screeninfo *var = &fbi->var; - - offset = var->yoffset * fbi->fix.line_length + - var->xoffset * var->bits_per_pixel / 8; - - if (fbdev->ctrl->sync) - fbdev->ctrl->sync(); - r = fbdev->ctrl->setup_plane(plane->idx, plane->info.channel_out, - offset, var->xres_virtual, - plane->info.pos_x, plane->info.pos_y, - var->xres, var->yres, plane->color_mode); - if (r < 0) - return r; - - if (fbdev->ctrl->set_rotate != NULL) { - r = fbdev->ctrl->set_rotate(var->rotate); - if (r < 0) - return r; - } - - if (fbdev->ctrl->set_scale != NULL) - r = fbdev->ctrl->set_scale(plane->idx, - var->xres, var->yres, - plane->info.out_width, - plane->info.out_height); - - return r; -} - -/* - * --------------------------------------------------------------------------- - * fbdev framework callbacks and the ioctl interface - * --------------------------------------------------------------------------- - */ -/* Called each time the omapfb device is opened */ -static int omapfb_open(struct fb_info *info, int user) -{ - return 0; -} - -static void omapfb_sync(struct fb_info *info); - -/* Called when the omapfb device is closed. We make sure that any pending - * gfx DMA operations are ended, before we return. */ -static int omapfb_release(struct fb_info *info, int user) -{ - omapfb_sync(info); - return 0; -} - -/* Store a single color palette entry into a pseudo palette or the hardware - * palette if one is available. For now we support only 16bpp and thus store - * the entry only to the pseudo palette. - */ -static int _setcolreg(struct fb_info *info, u_int regno, u_int red, u_int green, - u_int blue, u_int transp, int update_hw_pal) -{ - struct omapfb_plane_struct *plane = info->par; - struct omapfb_device *fbdev = plane->fbdev; - struct fb_var_screeninfo *var = &info->var; - int r = 0; - - switch (plane->color_mode) { - case OMAPFB_COLOR_YUV422: - case OMAPFB_COLOR_YUV420: - case OMAPFB_COLOR_YUY422: - r = -EINVAL; - break; - case OMAPFB_COLOR_CLUT_8BPP: - case OMAPFB_COLOR_CLUT_4BPP: - case OMAPFB_COLOR_CLUT_2BPP: - case OMAPFB_COLOR_CLUT_1BPP: - if (fbdev->ctrl->setcolreg) - r = fbdev->ctrl->setcolreg(regno, red, green, blue, - transp, update_hw_pal); - /* Fallthrough */ - case OMAPFB_COLOR_RGB565: - case OMAPFB_COLOR_RGB444: - if (r != 0) - break; - - if (regno < 0) { - r = -EINVAL; - break; - } - - if (regno < 16) { - u16 pal; - pal = ((red >> (16 - var->red.length)) << - var->red.offset) | - ((green >> (16 - var->green.length)) << - var->green.offset) | - (blue >> (16 - var->blue.length)); - ((u32 *)(info->pseudo_palette))[regno] = pal; - } - break; - default: - BUG(); - } - return r; -} - -static int omapfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, - u_int transp, struct fb_info *info) -{ - return _setcolreg(info, regno, red, green, blue, transp, 1); -} - -static int omapfb_setcmap(struct fb_cmap *cmap, struct fb_info *info) -{ - int count, index, r; - u16 *red, *green, *blue, *transp; - u16 trans = 0xffff; - - red = cmap->red; - green = cmap->green; - blue = cmap->blue; - transp = cmap->transp; - index = cmap->start; - - for (count = 0; count < cmap->len; count++) { - if (transp) - trans = *transp++; - r = _setcolreg(info, index++, *red++, *green++, *blue++, trans, - count == cmap->len - 1); - if (r != 0) - return r; - } - - return 0; -} - -static int omapfb_update_full_screen(struct fb_info *fbi); - -static int omapfb_blank(int blank, struct fb_info *fbi) -{ - struct omapfb_plane_struct *plane = fbi->par; - struct omapfb_device *fbdev = plane->fbdev; - int do_update = 0; - int r = 0; - - omapfb_rqueue_lock(fbdev); - switch (blank) { - case FB_BLANK_UNBLANK: - if (fbdev->state == OMAPFB_SUSPENDED) { - if (fbdev->ctrl->resume) - fbdev->ctrl->resume(); - fbdev->panel->enable(fbdev->panel); - fbdev->state = OMAPFB_ACTIVE; - if (fbdev->ctrl->get_update_mode() == - OMAPFB_MANUAL_UPDATE) - do_update = 1; - } - break; - case FB_BLANK_POWERDOWN: - if (fbdev->state == OMAPFB_ACTIVE) { - fbdev->panel->disable(fbdev->panel); - if (fbdev->ctrl->suspend) - fbdev->ctrl->suspend(); - fbdev->state = OMAPFB_SUSPENDED; - } - break; - default: - r = -EINVAL; - } - omapfb_rqueue_unlock(fbdev); - - if (r == 0 && do_update) - r = omapfb_update_full_screen(fbi); - - return r; -} - -static void omapfb_sync(struct fb_info *fbi) -{ - struct omapfb_plane_struct *plane = fbi->par; - struct omapfb_device *fbdev = plane->fbdev; - - omapfb_rqueue_lock(fbdev); - if (fbdev->ctrl->sync) - fbdev->ctrl->sync(); - omapfb_rqueue_unlock(fbdev); -} - -/* - * Set fb_info.fix fields and also updates fbdev. - * When calling this fb_info.var must be set up already. - */ -static void set_fb_fix(struct fb_info *fbi, int from_init) -{ - struct fb_fix_screeninfo *fix = &fbi->fix; - struct fb_var_screeninfo *var = &fbi->var; - struct omapfb_plane_struct *plane = fbi->par; - struct omapfb_mem_region *rg; - int bpp; - - rg = &plane->fbdev->mem_desc.region[plane->idx]; - fbi->screen_base = rg->vaddr; - - if (!from_init) { - mutex_lock(&fbi->mm_lock); - fix->smem_start = rg->paddr; - fix->smem_len = rg->size; - mutex_unlock(&fbi->mm_lock); - } else { - fix->smem_start = rg->paddr; - fix->smem_len = rg->size; - } - - fix->type = FB_TYPE_PACKED_PIXELS; - bpp = var->bits_per_pixel; - if (var->nonstd) - fix->visual = FB_VISUAL_PSEUDOCOLOR; - else switch (var->bits_per_pixel) { - case 16: - case 12: - fix->visual = FB_VISUAL_TRUECOLOR; - /* 12bpp is stored in 16 bits */ - bpp = 16; - break; - case 1: - case 2: - case 4: - case 8: - fix->visual = FB_VISUAL_PSEUDOCOLOR; - break; - } - fix->accel = FB_ACCEL_OMAP1610; - fix->line_length = var->xres_virtual * bpp / 8; -} - -static int set_color_mode(struct omapfb_plane_struct *plane, - struct fb_var_screeninfo *var) -{ - switch (var->nonstd) { - case 0: - break; - case OMAPFB_COLOR_YUV422: - var->bits_per_pixel = 16; - plane->color_mode = var->nonstd; - return 0; - case OMAPFB_COLOR_YUV420: - var->bits_per_pixel = 12; - plane->color_mode = var->nonstd; - return 0; - case OMAPFB_COLOR_YUY422: - var->bits_per_pixel = 16; - plane->color_mode = var->nonstd; - return 0; - default: - return -EINVAL; - } - - switch (var->bits_per_pixel) { - case 1: - plane->color_mode = OMAPFB_COLOR_CLUT_1BPP; - return 0; - case 2: - plane->color_mode = OMAPFB_COLOR_CLUT_2BPP; - return 0; - case 4: - plane->color_mode = OMAPFB_COLOR_CLUT_4BPP; - return 0; - case 8: - plane->color_mode = OMAPFB_COLOR_CLUT_8BPP; - return 0; - case 12: - var->bits_per_pixel = 16; - case 16: - if (plane->fbdev->panel->bpp == 12) - plane->color_mode = OMAPFB_COLOR_RGB444; - else - plane->color_mode = OMAPFB_COLOR_RGB565; - return 0; - default: - return -EINVAL; - } -} - -/* - * Check the values in var against our capabilities and in case of out of - * bound values try to adjust them. - */ -static int set_fb_var(struct fb_info *fbi, - struct fb_var_screeninfo *var) -{ - int bpp; - unsigned long max_frame_size; - unsigned long line_size; - int xres_min, xres_max; - int yres_min, yres_max; - struct omapfb_plane_struct *plane = fbi->par; - struct omapfb_device *fbdev = plane->fbdev; - struct lcd_panel *panel = fbdev->panel; - - if (set_color_mode(plane, var) < 0) - return -EINVAL; - - bpp = var->bits_per_pixel; - if (plane->color_mode == OMAPFB_COLOR_RGB444) - bpp = 16; - - switch (var->rotate) { - case 0: - case 180: - xres_min = OMAPFB_PLANE_XRES_MIN; - xres_max = panel->x_res; - yres_min = OMAPFB_PLANE_YRES_MIN; - yres_max = panel->y_res; - if (cpu_is_omap15xx()) { - var->xres = panel->x_res; - var->yres = panel->y_res; - } - break; - case 90: - case 270: - xres_min = OMAPFB_PLANE_YRES_MIN; - xres_max = panel->y_res; - yres_min = OMAPFB_PLANE_XRES_MIN; - yres_max = panel->x_res; - if (cpu_is_omap15xx()) { - var->xres = panel->y_res; - var->yres = panel->x_res; - } - break; - default: - return -EINVAL; - } - - if (var->xres < xres_min) - var->xres = xres_min; - if (var->yres < yres_min) - var->yres = yres_min; - if (var->xres > xres_max) - var->xres = xres_max; - if (var->yres > yres_max) - var->yres = yres_max; - - if (var->xres_virtual < var->xres) - var->xres_virtual = var->xres; - if (var->yres_virtual < var->yres) - var->yres_virtual = var->yres; - max_frame_size = fbdev->mem_desc.region[plane->idx].size; - line_size = var->xres_virtual * bpp / 8; - if (line_size * var->yres_virtual > max_frame_size) { - /* Try to keep yres_virtual first */ - line_size = max_frame_size / var->yres_virtual; - var->xres_virtual = line_size * 8 / bpp; - if (var->xres_virtual < var->xres) { - /* Still doesn't fit. Shrink yres_virtual too */ - var->xres_virtual = var->xres; - line_size = var->xres * bpp / 8; - var->yres_virtual = max_frame_size / line_size; - } - /* Recheck this, as the virtual size changed. */ - if (var->xres_virtual < var->xres) - var->xres = var->xres_virtual; - if (var->yres_virtual < var->yres) - var->yres = var->yres_virtual; - if (var->xres < xres_min || var->yres < yres_min) - return -EINVAL; - } - if (var->xres + var->xoffset > var->xres_virtual) - var->xoffset = var->xres_virtual - var->xres; - if (var->yres + var->yoffset > var->yres_virtual) - var->yoffset = var->yres_virtual - var->yres; - - if (plane->color_mode == OMAPFB_COLOR_RGB444) { - var->red.offset = 8; var->red.length = 4; - var->red.msb_right = 0; - var->green.offset = 4; var->green.length = 4; - var->green.msb_right = 0; - var->blue.offset = 0; var->blue.length = 4; - var->blue.msb_right = 0; - } else { - var->red.offset = 11; var->red.length = 5; - var->red.msb_right = 0; - var->green.offset = 5; var->green.length = 6; - var->green.msb_right = 0; - var->blue.offset = 0; var->blue.length = 5; - var->blue.msb_right = 0; - } - - var->height = -1; - var->width = -1; - var->grayscale = 0; - - /* pixclock in ps, the rest in pixclock */ - var->pixclock = 10000000 / (panel->pixel_clock / 100); - var->left_margin = panel->hfp; - var->right_margin = panel->hbp; - var->upper_margin = panel->vfp; - var->lower_margin = panel->vbp; - var->hsync_len = panel->hsw; - var->vsync_len = panel->vsw; - - /* TODO: get these from panel->config */ - var->vmode = FB_VMODE_NONINTERLACED; - var->sync = 0; - - return 0; -} - - -/* Set rotation (0, 90, 180, 270 degree), and switch to the new mode. */ -static void omapfb_rotate(struct fb_info *fbi, int rotate) -{ - struct omapfb_plane_struct *plane = fbi->par; - struct omapfb_device *fbdev = plane->fbdev; - - omapfb_rqueue_lock(fbdev); - if (rotate != fbi->var.rotate) { - struct fb_var_screeninfo *new_var = &fbdev->new_var; - - memcpy(new_var, &fbi->var, sizeof(*new_var)); - new_var->rotate = rotate; - if (set_fb_var(fbi, new_var) == 0 && - memcmp(new_var, &fbi->var, sizeof(*new_var))) { - memcpy(&fbi->var, new_var, sizeof(*new_var)); - ctrl_change_mode(fbi); - } - } - omapfb_rqueue_unlock(fbdev); -} - -/* - * Set new x,y offsets in the virtual display for the visible area and switch - * to the new mode. - */ -static int omapfb_pan_display(struct fb_var_screeninfo *var, - struct fb_info *fbi) -{ - struct omapfb_plane_struct *plane = fbi->par; - struct omapfb_device *fbdev = plane->fbdev; - int r = 0; - - omapfb_rqueue_lock(fbdev); - if (var->xoffset != fbi->var.xoffset || - var->yoffset != fbi->var.yoffset) { - struct fb_var_screeninfo *new_var = &fbdev->new_var; - - memcpy(new_var, &fbi->var, sizeof(*new_var)); - new_var->xoffset = var->xoffset; - new_var->yoffset = var->yoffset; - if (set_fb_var(fbi, new_var)) - r = -EINVAL; - else { - memcpy(&fbi->var, new_var, sizeof(*new_var)); - ctrl_change_mode(fbi); - } - } - omapfb_rqueue_unlock(fbdev); - - return r; -} - -/* Set mirror to vertical axis and switch to the new mode. */ -static int omapfb_mirror(struct fb_info *fbi, int mirror) -{ - struct omapfb_plane_struct *plane = fbi->par; - struct omapfb_device *fbdev = plane->fbdev; - int r = 0; - - omapfb_rqueue_lock(fbdev); - mirror = mirror ? 1 : 0; - if (cpu_is_omap15xx()) - r = -EINVAL; - else if (mirror != plane->info.mirror) { - plane->info.mirror = mirror; - r = ctrl_change_mode(fbi); - } - omapfb_rqueue_unlock(fbdev); - - return r; -} - -/* - * Check values in var, try to adjust them in case of out of bound values if - * possible, or return error. - */ -static int omapfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi) -{ - struct omapfb_plane_struct *plane = fbi->par; - struct omapfb_device *fbdev = plane->fbdev; - int r; - - omapfb_rqueue_lock(fbdev); - if (fbdev->ctrl->sync != NULL) - fbdev->ctrl->sync(); - r = set_fb_var(fbi, var); - omapfb_rqueue_unlock(fbdev); - - return r; -} - -/* - * Switch to a new mode. The parameters for it has been check already by - * omapfb_check_var. - */ -static int omapfb_set_par(struct fb_info *fbi) -{ - struct omapfb_plane_struct *plane = fbi->par; - struct omapfb_device *fbdev = plane->fbdev; - int r = 0; - - omapfb_rqueue_lock(fbdev); - set_fb_fix(fbi, 0); - r = ctrl_change_mode(fbi); - omapfb_rqueue_unlock(fbdev); - - return r; -} - -int omapfb_update_window_async(struct fb_info *fbi, - struct omapfb_update_window *win, - void (*callback)(void *), - void *callback_data) -{ - int xres, yres; - struct omapfb_plane_struct *plane = fbi->par; - struct omapfb_device *fbdev = plane->fbdev; - struct fb_var_screeninfo *var = &fbi->var; - - switch (var->rotate) { - case 0: - case 180: - xres = fbdev->panel->x_res; - yres = fbdev->panel->y_res; - break; - case 90: - case 270: - xres = fbdev->panel->y_res; - yres = fbdev->panel->x_res; - break; - default: - return -EINVAL; - } - - if (win->x >= xres || win->y >= yres || - win->out_x > xres || win->out_y > yres) - return -EINVAL; - - if (!fbdev->ctrl->update_window || - fbdev->ctrl->get_update_mode() != OMAPFB_MANUAL_UPDATE) - return -ENODEV; - - if (win->x + win->width > xres) - win->width = xres - win->x; - if (win->y + win->height > yres) - win->height = yres - win->y; - if (win->out_x + win->out_width > xres) - win->out_width = xres - win->out_x; - if (win->out_y + win->out_height > yres) - win->out_height = yres - win->out_y; - if (!win->width || !win->height || !win->out_width || !win->out_height) - return 0; - - return fbdev->ctrl->update_window(fbi, win, callback, callback_data); -} -EXPORT_SYMBOL(omapfb_update_window_async); - -static int omapfb_update_win(struct fb_info *fbi, - struct omapfb_update_window *win) -{ - struct omapfb_plane_struct *plane = fbi->par; - int ret; - - omapfb_rqueue_lock(plane->fbdev); - ret = omapfb_update_window_async(fbi, win, NULL, NULL); - omapfb_rqueue_unlock(plane->fbdev); - - return ret; -} - -static int omapfb_update_full_screen(struct fb_info *fbi) -{ - struct omapfb_plane_struct *plane = fbi->par; - struct omapfb_device *fbdev = plane->fbdev; - struct omapfb_update_window win; - int r; - - if (!fbdev->ctrl->update_window || - fbdev->ctrl->get_update_mode() != OMAPFB_MANUAL_UPDATE) - return -ENODEV; - - win.x = 0; - win.y = 0; - win.width = fbi->var.xres; - win.height = fbi->var.yres; - win.out_x = 0; - win.out_y = 0; - win.out_width = fbi->var.xres; - win.out_height = fbi->var.yres; - win.format = 0; - - omapfb_rqueue_lock(fbdev); - r = fbdev->ctrl->update_window(fbi, &win, NULL, NULL); - omapfb_rqueue_unlock(fbdev); - - return r; -} - -static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi) -{ - struct omapfb_plane_struct *plane = fbi->par; - struct omapfb_device *fbdev = plane->fbdev; - struct lcd_panel *panel = fbdev->panel; - struct omapfb_plane_info old_info; - int r = 0; - - if (pi->pos_x + pi->out_width > panel->x_res || - pi->pos_y + pi->out_height > panel->y_res) - return -EINVAL; - - omapfb_rqueue_lock(fbdev); - if (pi->enabled && !fbdev->mem_desc.region[plane->idx].size) { - /* - * This plane's memory was freed, can't enable it - * until it's reallocated. - */ - r = -EINVAL; - goto out; - } - old_info = plane->info; - plane->info = *pi; - if (pi->enabled) { - r = ctrl_change_mode(fbi); - if (r < 0) { - plane->info = old_info; - goto out; - } - } - r = fbdev->ctrl->enable_plane(plane->idx, pi->enabled); - if (r < 0) { - plane->info = old_info; - goto out; - } -out: - omapfb_rqueue_unlock(fbdev); - return r; -} - -static int omapfb_query_plane(struct fb_info *fbi, struct omapfb_plane_info *pi) -{ - struct omapfb_plane_struct *plane = fbi->par; - - *pi = plane->info; - return 0; -} - -static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi) -{ - struct omapfb_plane_struct *plane = fbi->par; - struct omapfb_device *fbdev = plane->fbdev; - struct omapfb_mem_region *rg = &fbdev->mem_desc.region[plane->idx]; - size_t size; - int r = 0; - - if (fbdev->ctrl->setup_mem == NULL) - return -ENODEV; - if (mi->type != OMAPFB_MEMTYPE_SDRAM) - return -EINVAL; - - size = PAGE_ALIGN(mi->size); - omapfb_rqueue_lock(fbdev); - if (plane->info.enabled) { - r = -EBUSY; - goto out; - } - if (rg->size != size || rg->type != mi->type) { - struct fb_var_screeninfo *new_var = &fbdev->new_var; - unsigned long old_size = rg->size; - u8 old_type = rg->type; - unsigned long paddr; - - rg->size = size; - rg->type = mi->type; - /* - * size == 0 is a special case, for which we - * don't check / adjust the screen parameters. - * This isn't a problem since the plane can't - * be reenabled unless its size is > 0. - */ - if (old_size != size && size) { - if (size) { - memcpy(new_var, &fbi->var, sizeof(*new_var)); - r = set_fb_var(fbi, new_var); - if (r < 0) - goto out; - } - } - - if (fbdev->ctrl->sync) - fbdev->ctrl->sync(); - r = fbdev->ctrl->setup_mem(plane->idx, size, mi->type, &paddr); - if (r < 0) { - /* Revert changes. */ - rg->size = old_size; - rg->type = old_type; - goto out; - } - rg->paddr = paddr; - - if (old_size != size) { - if (size) { - memcpy(&fbi->var, new_var, sizeof(fbi->var)); - set_fb_fix(fbi, 0); - } else { - /* - * Set these explicitly to indicate that the - * plane memory is dealloce'd, the other - * screen parameters in var / fix are invalid. - */ - mutex_lock(&fbi->mm_lock); - fbi->fix.smem_start = 0; - fbi->fix.smem_len = 0; - mutex_unlock(&fbi->mm_lock); - } - } - } -out: - omapfb_rqueue_unlock(fbdev); - - return r; -} - -static int omapfb_query_mem(struct fb_info *fbi, struct omapfb_mem_info *mi) -{ - struct omapfb_plane_struct *plane = fbi->par; - struct omapfb_device *fbdev = plane->fbdev; - struct omapfb_mem_region *rg; - - rg = &fbdev->mem_desc.region[plane->idx]; - memset(mi, 0, sizeof(*mi)); - mi->size = rg->size; - mi->type = rg->type; - - return 0; -} - -static int omapfb_set_color_key(struct omapfb_device *fbdev, - struct omapfb_color_key *ck) -{ - int r; - - if (!fbdev->ctrl->set_color_key) - return -ENODEV; - - omapfb_rqueue_lock(fbdev); - r = fbdev->ctrl->set_color_key(ck); - omapfb_rqueue_unlock(fbdev); - - return r; -} - -static int omapfb_get_color_key(struct omapfb_device *fbdev, - struct omapfb_color_key *ck) -{ - int r; - - if (!fbdev->ctrl->get_color_key) - return -ENODEV; - - omapfb_rqueue_lock(fbdev); - r = fbdev->ctrl->get_color_key(ck); - omapfb_rqueue_unlock(fbdev); - - return r; -} - -static struct blocking_notifier_head omapfb_client_list[OMAPFB_PLANE_NUM]; -static int notifier_inited; - -static void omapfb_init_notifier(void) -{ - int i; - - for (i = 0; i < OMAPFB_PLANE_NUM; i++) - BLOCKING_INIT_NOTIFIER_HEAD(&omapfb_client_list[i]); -} - -int omapfb_register_client(struct omapfb_notifier_block *omapfb_nb, - omapfb_notifier_callback_t callback, - void *callback_data) -{ - int r; - - if ((unsigned)omapfb_nb->plane_idx > OMAPFB_PLANE_NUM) - return -EINVAL; - - if (!notifier_inited) { - omapfb_init_notifier(); - notifier_inited = 1; - } - - omapfb_nb->nb.notifier_call = (int (*)(struct notifier_block *, - unsigned long, void *))callback; - omapfb_nb->data = callback_data; - r = blocking_notifier_chain_register( - &omapfb_client_list[omapfb_nb->plane_idx], - &omapfb_nb->nb); - if (r) - return r; - if (omapfb_dev != NULL && - omapfb_dev->ctrl && omapfb_dev->ctrl->bind_client) { - omapfb_dev->ctrl->bind_client(omapfb_nb); - } - - return 0; -} -EXPORT_SYMBOL(omapfb_register_client); - -int omapfb_unregister_client(struct omapfb_notifier_block *omapfb_nb) -{ - return blocking_notifier_chain_unregister( - &omapfb_client_list[omapfb_nb->plane_idx], &omapfb_nb->nb); -} -EXPORT_SYMBOL(omapfb_unregister_client); - -void omapfb_notify_clients(struct omapfb_device *fbdev, unsigned long event) -{ - int i; - - if (!notifier_inited) - /* no client registered yet */ - return; - - for (i = 0; i < OMAPFB_PLANE_NUM; i++) - blocking_notifier_call_chain(&omapfb_client_list[i], event, - fbdev->fb_info[i]); -} -EXPORT_SYMBOL(omapfb_notify_clients); - -static int omapfb_set_update_mode(struct omapfb_device *fbdev, - enum omapfb_update_mode mode) -{ - int r; - - omapfb_rqueue_lock(fbdev); - r = fbdev->ctrl->set_update_mode(mode); - omapfb_rqueue_unlock(fbdev); - - return r; -} - -static enum omapfb_update_mode omapfb_get_update_mode(struct omapfb_device *fbdev) -{ - int r; - - omapfb_rqueue_lock(fbdev); - r = fbdev->ctrl->get_update_mode(); - omapfb_rqueue_unlock(fbdev); - - return r; -} - -static void omapfb_get_caps(struct omapfb_device *fbdev, int plane, - struct omapfb_caps *caps) -{ - memset(caps, 0, sizeof(*caps)); - fbdev->ctrl->get_caps(plane, caps); - caps->ctrl |= fbdev->panel->get_caps(fbdev->panel); -} - -/* For lcd testing */ -void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval) -{ - omapfb_rqueue_lock(fbdev); - *(u16 *)fbdev->mem_desc.region[0].vaddr = pixval; - if (fbdev->ctrl->get_update_mode() == OMAPFB_MANUAL_UPDATE) { - struct omapfb_update_window win; - - memset(&win, 0, sizeof(win)); - win.width = 2; - win.height = 2; - win.out_width = 2; - win.out_height = 2; - fbdev->ctrl->update_window(fbdev->fb_info[0], &win, NULL, NULL); - } - omapfb_rqueue_unlock(fbdev); -} -EXPORT_SYMBOL(omapfb_write_first_pixel); - -/* - * Ioctl interface. Part of the kernel mode frame buffer API is duplicated - * here to be accessible by user mode code. - */ -static int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, - unsigned long arg) -{ - struct omapfb_plane_struct *plane = fbi->par; - struct omapfb_device *fbdev = plane->fbdev; - struct fb_ops *ops = fbi->fbops; - union { - struct omapfb_update_window update_window; - struct omapfb_plane_info plane_info; - struct omapfb_mem_info mem_info; - struct omapfb_color_key color_key; - enum omapfb_update_mode update_mode; - struct omapfb_caps caps; - unsigned int mirror; - int plane_out; - int enable_plane; - } p; - int r = 0; - - BUG_ON(!ops); - switch (cmd) { - case OMAPFB_MIRROR: - if (get_user(p.mirror, (int __user *)arg)) - r = -EFAULT; - else - omapfb_mirror(fbi, p.mirror); - break; - case OMAPFB_SYNC_GFX: - omapfb_sync(fbi); - break; - case OMAPFB_VSYNC: - break; - case OMAPFB_SET_UPDATE_MODE: - if (get_user(p.update_mode, (int __user *)arg)) - r = -EFAULT; - else - r = omapfb_set_update_mode(fbdev, p.update_mode); - break; - case OMAPFB_GET_UPDATE_MODE: - p.update_mode = omapfb_get_update_mode(fbdev); - if (put_user(p.update_mode, - (enum omapfb_update_mode __user *)arg)) - r = -EFAULT; - break; - case OMAPFB_UPDATE_WINDOW_OLD: - if (copy_from_user(&p.update_window, (void __user *)arg, - sizeof(struct omapfb_update_window_old))) - r = -EFAULT; - else { - struct omapfb_update_window *u = &p.update_window; - u->out_x = u->x; - u->out_y = u->y; - u->out_width = u->width; - u->out_height = u->height; - memset(u->reserved, 0, sizeof(u->reserved)); - r = omapfb_update_win(fbi, u); - } - break; - case OMAPFB_UPDATE_WINDOW: - if (copy_from_user(&p.update_window, (void __user *)arg, - sizeof(p.update_window))) - r = -EFAULT; - else - r = omapfb_update_win(fbi, &p.update_window); - break; - case OMAPFB_SETUP_PLANE: - if (copy_from_user(&p.plane_info, (void __user *)arg, - sizeof(p.plane_info))) - r = -EFAULT; - else - r = omapfb_setup_plane(fbi, &p.plane_info); - break; - case OMAPFB_QUERY_PLANE: - if ((r = omapfb_query_plane(fbi, &p.plane_info)) < 0) - break; - if (copy_to_user((void __user *)arg, &p.plane_info, - sizeof(p.plane_info))) - r = -EFAULT; - break; - case OMAPFB_SETUP_MEM: - if (copy_from_user(&p.mem_info, (void __user *)arg, - sizeof(p.mem_info))) - r = -EFAULT; - else - r = omapfb_setup_mem(fbi, &p.mem_info); - break; - case OMAPFB_QUERY_MEM: - if ((r = omapfb_query_mem(fbi, &p.mem_info)) < 0) - break; - if (copy_to_user((void __user *)arg, &p.mem_info, - sizeof(p.mem_info))) - r = -EFAULT; - break; - case OMAPFB_SET_COLOR_KEY: - if (copy_from_user(&p.color_key, (void __user *)arg, - sizeof(p.color_key))) - r = -EFAULT; - else - r = omapfb_set_color_key(fbdev, &p.color_key); - break; - case OMAPFB_GET_COLOR_KEY: - if ((r = omapfb_get_color_key(fbdev, &p.color_key)) < 0) - break; - if (copy_to_user((void __user *)arg, &p.color_key, - sizeof(p.color_key))) - r = -EFAULT; - break; - case OMAPFB_GET_CAPS: - omapfb_get_caps(fbdev, plane->idx, &p.caps); - if (copy_to_user((void __user *)arg, &p.caps, sizeof(p.caps))) - r = -EFAULT; - break; - case OMAPFB_LCD_TEST: - { - int test_num; - - if (get_user(test_num, (int __user *)arg)) { - r = -EFAULT; - break; - } - if (!fbdev->panel->run_test) { - r = -EINVAL; - break; - } - r = fbdev->panel->run_test(fbdev->panel, test_num); - break; - } - case OMAPFB_CTRL_TEST: - { - int test_num; - - if (get_user(test_num, (int __user *)arg)) { - r = -EFAULT; - break; - } - if (!fbdev->ctrl->run_test) { - r = -EINVAL; - break; - } - r = fbdev->ctrl->run_test(test_num); - break; - } - default: - r = -EINVAL; - } - - return r; -} - -static int omapfb_mmap(struct fb_info *info, struct vm_area_struct *vma) -{ - struct omapfb_plane_struct *plane = info->par; - struct omapfb_device *fbdev = plane->fbdev; - int r; - - omapfb_rqueue_lock(fbdev); - r = fbdev->ctrl->mmap(info, vma); - omapfb_rqueue_unlock(fbdev); - - return r; -} - -/* - * Callback table for the frame buffer framework. Some of these pointers - * will be changed according to the current setting of fb_info->accel_flags. - */ -static struct fb_ops omapfb_ops = { - .owner = THIS_MODULE, - .fb_open = omapfb_open, - .fb_release = omapfb_release, - .fb_setcolreg = omapfb_setcolreg, - .fb_setcmap = omapfb_setcmap, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, - .fb_blank = omapfb_blank, - .fb_ioctl = omapfb_ioctl, - .fb_check_var = omapfb_check_var, - .fb_set_par = omapfb_set_par, - .fb_rotate = omapfb_rotate, - .fb_pan_display = omapfb_pan_display, -}; - -/* - * --------------------------------------------------------------------------- - * Sysfs interface - * --------------------------------------------------------------------------- - */ -/* omapfbX sysfs entries */ -static ssize_t omapfb_show_caps_num(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct omapfb_device *fbdev = dev_get_drvdata(dev); - int plane; - size_t size; - struct omapfb_caps caps; - - plane = 0; - size = 0; - while (size < PAGE_SIZE && plane < OMAPFB_PLANE_NUM) { - omapfb_get_caps(fbdev, plane, &caps); - size += snprintf(&buf[size], PAGE_SIZE - size, - "plane#%d %#010x %#010x %#010x\n", - plane, caps.ctrl, caps.plane_color, caps.wnd_color); - plane++; - } - return size; -} - -static ssize_t omapfb_show_caps_text(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct omapfb_device *fbdev = dev_get_drvdata(dev); - int i; - struct omapfb_caps caps; - int plane; - size_t size; - - plane = 0; - size = 0; - while (size < PAGE_SIZE && plane < OMAPFB_PLANE_NUM) { - omapfb_get_caps(fbdev, plane, &caps); - size += snprintf(&buf[size], PAGE_SIZE - size, - "plane#%d:\n", plane); - for (i = 0; i < ARRAY_SIZE(ctrl_caps) && - size < PAGE_SIZE; i++) { - if (ctrl_caps[i].flag & caps.ctrl) - size += snprintf(&buf[size], PAGE_SIZE - size, - " %s\n", ctrl_caps[i].name); - } - size += snprintf(&buf[size], PAGE_SIZE - size, - " plane colors:\n"); - for (i = 0; i < ARRAY_SIZE(color_caps) && - size < PAGE_SIZE; i++) { - if (color_caps[i].flag & caps.plane_color) - size += snprintf(&buf[size], PAGE_SIZE - size, - " %s\n", color_caps[i].name); - } - size += snprintf(&buf[size], PAGE_SIZE - size, - " window colors:\n"); - for (i = 0; i < ARRAY_SIZE(color_caps) && - size < PAGE_SIZE; i++) { - if (color_caps[i].flag & caps.wnd_color) - size += snprintf(&buf[size], PAGE_SIZE - size, - " %s\n", color_caps[i].name); - } - - plane++; - } - return size; -} - -static DEVICE_ATTR(caps_num, 0444, omapfb_show_caps_num, NULL); -static DEVICE_ATTR(caps_text, 0444, omapfb_show_caps_text, NULL); - -/* panel sysfs entries */ -static ssize_t omapfb_show_panel_name(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct omapfb_device *fbdev = dev_get_drvdata(dev); - - return snprintf(buf, PAGE_SIZE, "%s\n", fbdev->panel->name); -} - -static ssize_t omapfb_show_bklight_level(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct omapfb_device *fbdev = dev_get_drvdata(dev); - int r; - - if (fbdev->panel->get_bklight_level) { - r = snprintf(buf, PAGE_SIZE, "%d\n", - fbdev->panel->get_bklight_level(fbdev->panel)); - } else - r = -ENODEV; - return r; -} - -static ssize_t omapfb_store_bklight_level(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t size) -{ - struct omapfb_device *fbdev = dev_get_drvdata(dev); - int r; - - if (fbdev->panel->set_bklight_level) { - unsigned int level; - - if (sscanf(buf, "%10d", &level) == 1) { - r = fbdev->panel->set_bklight_level(fbdev->panel, - level); - } else - r = -EINVAL; - } else - r = -ENODEV; - return r ? r : size; -} - -static ssize_t omapfb_show_bklight_max(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct omapfb_device *fbdev = dev_get_drvdata(dev); - int r; - - if (fbdev->panel->get_bklight_level) { - r = snprintf(buf, PAGE_SIZE, "%d\n", - fbdev->panel->get_bklight_max(fbdev->panel)); - } else - r = -ENODEV; - return r; -} - -static struct device_attribute dev_attr_panel_name = - __ATTR(name, 0444, omapfb_show_panel_name, NULL); -static DEVICE_ATTR(backlight_level, 0664, - omapfb_show_bklight_level, omapfb_store_bklight_level); -static DEVICE_ATTR(backlight_max, 0444, omapfb_show_bklight_max, NULL); - -static struct attribute *panel_attrs[] = { - &dev_attr_panel_name.attr, - &dev_attr_backlight_level.attr, - &dev_attr_backlight_max.attr, - NULL, -}; - -static struct attribute_group panel_attr_grp = { - .name = "panel", - .attrs = panel_attrs, -}; - -/* ctrl sysfs entries */ -static ssize_t omapfb_show_ctrl_name(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct omapfb_device *fbdev = dev_get_drvdata(dev); - - return snprintf(buf, PAGE_SIZE, "%s\n", fbdev->ctrl->name); -} - -static struct device_attribute dev_attr_ctrl_name = - __ATTR(name, 0444, omapfb_show_ctrl_name, NULL); - -static struct attribute *ctrl_attrs[] = { - &dev_attr_ctrl_name.attr, - NULL, -}; - -static struct attribute_group ctrl_attr_grp = { - .name = "ctrl", - .attrs = ctrl_attrs, -}; - -static int omapfb_register_sysfs(struct omapfb_device *fbdev) -{ - int r; - - if ((r = device_create_file(fbdev->dev, &dev_attr_caps_num))) - goto fail0; - - if ((r = device_create_file(fbdev->dev, &dev_attr_caps_text))) - goto fail1; - - if ((r = sysfs_create_group(&fbdev->dev->kobj, &panel_attr_grp))) - goto fail2; - - if ((r = sysfs_create_group(&fbdev->dev->kobj, &ctrl_attr_grp))) - goto fail3; - - return 0; -fail3: - sysfs_remove_group(&fbdev->dev->kobj, &panel_attr_grp); -fail2: - device_remove_file(fbdev->dev, &dev_attr_caps_text); -fail1: - device_remove_file(fbdev->dev, &dev_attr_caps_num); -fail0: - dev_err(fbdev->dev, "unable to register sysfs interface\n"); - return r; -} - -static void omapfb_unregister_sysfs(struct omapfb_device *fbdev) -{ - sysfs_remove_group(&fbdev->dev->kobj, &ctrl_attr_grp); - sysfs_remove_group(&fbdev->dev->kobj, &panel_attr_grp); - device_remove_file(fbdev->dev, &dev_attr_caps_num); - device_remove_file(fbdev->dev, &dev_attr_caps_text); -} - -/* - * --------------------------------------------------------------------------- - * LDM callbacks - * --------------------------------------------------------------------------- - */ -/* Initialize system fb_info object and set the default video mode. - * The frame buffer memory already allocated by lcddma_init - */ -static int fbinfo_init(struct omapfb_device *fbdev, struct fb_info *info) -{ - struct fb_var_screeninfo *var = &info->var; - struct fb_fix_screeninfo *fix = &info->fix; - int r = 0; - - info->fbops = &omapfb_ops; - info->flags = FBINFO_FLAG_DEFAULT; - - strncpy(fix->id, MODULE_NAME, sizeof(fix->id)); - - info->pseudo_palette = fbdev->pseudo_palette; - - var->accel_flags = def_accel ? FB_ACCELF_TEXT : 0; - var->xres = def_vxres; - var->yres = def_vyres; - var->xres_virtual = def_vxres; - var->yres_virtual = def_vyres; - var->rotate = def_rotate; - var->bits_per_pixel = fbdev->panel->bpp; - - set_fb_var(info, var); - set_fb_fix(info, 1); - - r = fb_alloc_cmap(&info->cmap, 16, 0); - if (r != 0) - dev_err(fbdev->dev, "unable to allocate color map memory\n"); - - return r; -} - -/* Release the fb_info object */ -static void fbinfo_cleanup(struct omapfb_device *fbdev, struct fb_info *fbi) -{ - fb_dealloc_cmap(&fbi->cmap); -} - -static void planes_cleanup(struct omapfb_device *fbdev) -{ - int i; - - for (i = 0; i < fbdev->mem_desc.region_cnt; i++) { - if (fbdev->fb_info[i] == NULL) - break; - fbinfo_cleanup(fbdev, fbdev->fb_info[i]); - framebuffer_release(fbdev->fb_info[i]); - } -} - -static int planes_init(struct omapfb_device *fbdev) -{ - struct fb_info *fbi; - int i; - int r; - - for (i = 0; i < fbdev->mem_desc.region_cnt; i++) { - struct omapfb_plane_struct *plane; - fbi = framebuffer_alloc(sizeof(struct omapfb_plane_struct), - fbdev->dev); - if (fbi == NULL) { - dev_err(fbdev->dev, - "unable to allocate memory for plane info\n"); - planes_cleanup(fbdev); - return -ENOMEM; - } - plane = fbi->par; - plane->idx = i; - plane->fbdev = fbdev; - plane->info.mirror = def_mirror; - fbdev->fb_info[i] = fbi; - - if ((r = fbinfo_init(fbdev, fbi)) < 0) { - framebuffer_release(fbi); - planes_cleanup(fbdev); - return r; - } - plane->info.out_width = fbi->var.xres; - plane->info.out_height = fbi->var.yres; - } - return 0; -} - -/* - * Free driver resources. Can be called to rollback an aborted initialization - * sequence. - */ -static void omapfb_free_resources(struct omapfb_device *fbdev, int state) -{ - int i; - - switch (state) { - case OMAPFB_ACTIVE: - for (i = 0; i < fbdev->mem_desc.region_cnt; i++) - unregister_framebuffer(fbdev->fb_info[i]); - case 7: - omapfb_unregister_sysfs(fbdev); - case 6: - fbdev->panel->disable(fbdev->panel); - case 5: - omapfb_set_update_mode(fbdev, OMAPFB_UPDATE_DISABLED); - case 4: - planes_cleanup(fbdev); - case 3: - ctrl_cleanup(fbdev); - case 2: - fbdev->panel->cleanup(fbdev->panel); - case 1: - dev_set_drvdata(fbdev->dev, NULL); - kfree(fbdev); - case 0: - /* nothing to free */ - break; - default: - BUG(); - } -} - -static int omapfb_find_ctrl(struct omapfb_device *fbdev) -{ - struct omapfb_platform_data *conf; - char name[17]; - int i; - - conf = dev_get_platdata(fbdev->dev); - - fbdev->ctrl = NULL; - - strncpy(name, conf->lcd.ctrl_name, sizeof(name) - 1); - name[sizeof(name) - 1] = '\0'; - - if (strcmp(name, "internal") == 0) { - fbdev->ctrl = fbdev->int_ctrl; - return 0; - } - - for (i = 0; i < ARRAY_SIZE(ctrls); i++) { - dev_dbg(fbdev->dev, "ctrl %s\n", ctrls[i]->name); - if (strcmp(ctrls[i]->name, name) == 0) { - fbdev->ctrl = ctrls[i]; - break; - } - } - - if (fbdev->ctrl == NULL) { - dev_dbg(fbdev->dev, "ctrl %s not supported\n", name); - return -1; - } - - return 0; -} - -static void check_required_callbacks(struct omapfb_device *fbdev) -{ -#define _C(x) (fbdev->ctrl->x != NULL) -#define _P(x) (fbdev->panel->x != NULL) - BUG_ON(fbdev->ctrl == NULL || fbdev->panel == NULL); - BUG_ON(!(_C(init) && _C(cleanup) && _C(get_caps) && - _C(set_update_mode) && _C(setup_plane) && _C(enable_plane) && - _P(init) && _P(cleanup) && _P(enable) && _P(disable) && - _P(get_caps))); -#undef _P -#undef _C -} - -/* - * Called by LDM binding to probe and attach a new device. - * Initialization sequence: - * 1. allocate system omapfb_device structure - * 2. select controller type according to platform configuration - * init LCD panel - * 3. init LCD controller and LCD DMA - * 4. init system fb_info structure for all planes - * 5. setup video mode for first plane and enable it - * 6. enable LCD panel - * 7. register sysfs attributes - * OMAPFB_ACTIVE: register system fb_info structure for all planes - */ -static int omapfb_do_probe(struct platform_device *pdev, - struct lcd_panel *panel) -{ - struct omapfb_device *fbdev = NULL; - int init_state; - unsigned long phz, hhz, vhz; - unsigned long vram; - int i; - int r = 0; - - init_state = 0; - - if (pdev->num_resources != 0) { - dev_err(&pdev->dev, "probed for an unknown device\n"); - r = -ENODEV; - goto cleanup; - } - - if (dev_get_platdata(&pdev->dev) == NULL) { - dev_err(&pdev->dev, "missing platform data\n"); - r = -ENOENT; - goto cleanup; - } - - fbdev = kzalloc(sizeof(struct omapfb_device), GFP_KERNEL); - if (fbdev == NULL) { - dev_err(&pdev->dev, - "unable to allocate memory for device info\n"); - r = -ENOMEM; - goto cleanup; - } - init_state++; - - fbdev->dev = &pdev->dev; - fbdev->panel = panel; - fbdev->dssdev = &omapdss_device; - platform_set_drvdata(pdev, fbdev); - - mutex_init(&fbdev->rqueue_mutex); - - fbdev->int_ctrl = &omap1_int_ctrl; -#ifdef CONFIG_FB_OMAP_LCDC_EXTERNAL - fbdev->ext_if = &omap1_ext_if; -#endif - if (omapfb_find_ctrl(fbdev) < 0) { - dev_err(fbdev->dev, - "LCD controller not found, board not supported\n"); - r = -ENODEV; - goto cleanup; - } - - r = fbdev->panel->init(fbdev->panel, fbdev); - if (r) - goto cleanup; - - pr_info("omapfb: configured for panel %s\n", fbdev->panel->name); - - def_vxres = def_vxres ? def_vxres : fbdev->panel->x_res; - def_vyres = def_vyres ? def_vyres : fbdev->panel->y_res; - - init_state++; - - r = ctrl_init(fbdev); - if (r) - goto cleanup; - if (fbdev->ctrl->mmap != NULL) - omapfb_ops.fb_mmap = omapfb_mmap; - init_state++; - - check_required_callbacks(fbdev); - - r = planes_init(fbdev); - if (r) - goto cleanup; - init_state++; - -#ifdef CONFIG_FB_OMAP_DMA_TUNE - /* Set DMA priority for EMIFF access to highest */ - omap_set_dma_priority(0, OMAP_DMA_PORT_EMIFF, 15); -#endif - - r = ctrl_change_mode(fbdev->fb_info[0]); - if (r) { - dev_err(fbdev->dev, "mode setting failed\n"); - goto cleanup; - } - - /* GFX plane is enabled by default */ - r = fbdev->ctrl->enable_plane(OMAPFB_PLANE_GFX, 1); - if (r) - goto cleanup; - - omapfb_set_update_mode(fbdev, manual_update ? - OMAPFB_MANUAL_UPDATE : OMAPFB_AUTO_UPDATE); - init_state++; - - r = fbdev->panel->enable(fbdev->panel); - if (r) - goto cleanup; - init_state++; - - r = omapfb_register_sysfs(fbdev); - if (r) - goto cleanup; - init_state++; - - vram = 0; - for (i = 0; i < fbdev->mem_desc.region_cnt; i++) { - r = register_framebuffer(fbdev->fb_info[i]); - if (r != 0) { - dev_err(fbdev->dev, - "registering framebuffer %d failed\n", i); - goto cleanup; - } - vram += fbdev->mem_desc.region[i].size; - } - - fbdev->state = OMAPFB_ACTIVE; - - panel = fbdev->panel; - phz = panel->pixel_clock * 1000; - hhz = phz * 10 / (panel->hfp + panel->x_res + panel->hbp + panel->hsw); - vhz = hhz / (panel->vfp + panel->y_res + panel->vbp + panel->vsw); - - omapfb_dev = fbdev; - - pr_info("omapfb: Framebuffer initialized. Total vram %lu planes %d\n", - vram, fbdev->mem_desc.region_cnt); - pr_info("omapfb: Pixclock %lu kHz hfreq %lu.%lu kHz " - "vfreq %lu.%lu Hz\n", - phz / 1000, hhz / 10000, hhz % 10, vhz / 10, vhz % 10); - - return 0; - -cleanup: - omapfb_free_resources(fbdev, init_state); - - return r; -} - -static int omapfb_probe(struct platform_device *pdev) -{ - int r; - - BUG_ON(fbdev_pdev != NULL); - - r = platform_device_register(&omapdss_device); - if (r) { - dev_err(&pdev->dev, "can't register omapdss device\n"); - return r; - } - - /* Delay actual initialization until the LCD is registered */ - fbdev_pdev = pdev; - if (fbdev_panel != NULL) - omapfb_do_probe(fbdev_pdev, fbdev_panel); - return 0; -} - -void omapfb_register_panel(struct lcd_panel *panel) -{ - BUG_ON(fbdev_panel != NULL); - - fbdev_panel = panel; - if (fbdev_pdev != NULL) - omapfb_do_probe(fbdev_pdev, fbdev_panel); -} - -/* Called when the device is being detached from the driver */ -static int omapfb_remove(struct platform_device *pdev) -{ - struct omapfb_device *fbdev = platform_get_drvdata(pdev); - enum omapfb_state saved_state = fbdev->state; - - /* FIXME: wait till completion of pending events */ - - fbdev->state = OMAPFB_DISABLED; - omapfb_free_resources(fbdev, saved_state); - - platform_device_unregister(&omapdss_device); - fbdev->dssdev = NULL; - - return 0; -} - -/* PM suspend */ -static int omapfb_suspend(struct platform_device *pdev, pm_message_t mesg) -{ - struct omapfb_device *fbdev = platform_get_drvdata(pdev); - - if (fbdev != NULL) - omapfb_blank(FB_BLANK_POWERDOWN, fbdev->fb_info[0]); - return 0; -} - -/* PM resume */ -static int omapfb_resume(struct platform_device *pdev) -{ - struct omapfb_device *fbdev = platform_get_drvdata(pdev); - - if (fbdev != NULL) - omapfb_blank(FB_BLANK_UNBLANK, fbdev->fb_info[0]); - return 0; -} - -static struct platform_driver omapfb_driver = { - .probe = omapfb_probe, - .remove = omapfb_remove, - .suspend = omapfb_suspend, - .resume = omapfb_resume, - .driver = { - .name = MODULE_NAME, - .owner = THIS_MODULE, - }, -}; - -#ifndef MODULE - -/* Process kernel command line parameters */ -static int __init omapfb_setup(char *options) -{ - char *this_opt = NULL; - int r = 0; - - pr_debug("omapfb: options %s\n", options); - - if (!options || !*options) - return 0; - - while (!r && (this_opt = strsep(&options, ",")) != NULL) { - if (!strncmp(this_opt, "accel", 5)) - def_accel = 1; - else if (!strncmp(this_opt, "vram:", 5)) { - char *suffix; - unsigned long vram; - vram = (simple_strtoul(this_opt + 5, &suffix, 0)); - switch (suffix[0]) { - case '\0': - break; - case 'm': - case 'M': - vram *= 1024; - /* Fall through */ - case 'k': - case 'K': - vram *= 1024; - break; - default: - pr_debug("omapfb: invalid vram suffix %c\n", - suffix[0]); - r = -1; - } - def_vram[def_vram_cnt++] = vram; - } - else if (!strncmp(this_opt, "vxres:", 6)) - def_vxres = simple_strtoul(this_opt + 6, NULL, 0); - else if (!strncmp(this_opt, "vyres:", 6)) - def_vyres = simple_strtoul(this_opt + 6, NULL, 0); - else if (!strncmp(this_opt, "rotate:", 7)) - def_rotate = (simple_strtoul(this_opt + 7, NULL, 0)); - else if (!strncmp(this_opt, "mirror:", 7)) - def_mirror = (simple_strtoul(this_opt + 7, NULL, 0)); - else if (!strncmp(this_opt, "manual_update", 13)) - manual_update = 1; - else { - pr_debug("omapfb: invalid option\n"); - r = -1; - } - } - - return r; -} - -#endif - -/* Register both the driver and the device */ -static int __init omapfb_init(void) -{ -#ifndef MODULE - char *option; - - if (fb_get_options("omapfb", &option)) - return -ENODEV; - omapfb_setup(option); -#endif - /* Register the driver with LDM */ - if (platform_driver_register(&omapfb_driver)) { - pr_debug("failed to register omapfb driver\n"); - return -ENODEV; - } - - return 0; -} - -static void __exit omapfb_cleanup(void) -{ - platform_driver_unregister(&omapfb_driver); -} - -module_param_named(accel, def_accel, uint, 0664); -module_param_array_named(vram, def_vram, ulong, &def_vram_cnt, 0664); -module_param_named(vxres, def_vxres, long, 0664); -module_param_named(vyres, def_vyres, long, 0664); -module_param_named(rotate, def_rotate, uint, 0664); -module_param_named(mirror, def_mirror, uint, 0664); -module_param_named(manual_update, manual_update, bool, 0664); - -module_init(omapfb_init); -module_exit(omapfb_cleanup); - -MODULE_DESCRIPTION("TI OMAP framebuffer driver"); -MODULE_AUTHOR("Imre Deak <imre.deak@nokia.com>"); -MODULE_LICENSE("GPL"); diff --git a/drivers/video/omap/sossi.c b/drivers/video/omap/sossi.c deleted file mode 100644 index d4e7684e7045..000000000000 --- a/drivers/video/omap/sossi.c +++ /dev/null @@ -1,693 +0,0 @@ -/* - * OMAP1 Special OptimiSed Screen Interface support - * - * Copyright (C) 2004-2005 Nokia Corporation - * Author: Juha Yrjölä <juha.yrjola@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/module.h> -#include <linux/mm.h> -#include <linux/clk.h> -#include <linux/irq.h> -#include <linux/io.h> -#include <linux/interrupt.h> - -#include <linux/omap-dma.h> - -#include "omapfb.h" -#include "lcdc.h" - -#define MODULE_NAME "omapfb-sossi" - -#define OMAP_SOSSI_BASE 0xfffbac00 -#define SOSSI_ID_REG 0x00 -#define SOSSI_INIT1_REG 0x04 -#define SOSSI_INIT2_REG 0x08 -#define SOSSI_INIT3_REG 0x0c -#define SOSSI_FIFO_REG 0x10 -#define SOSSI_REOTABLE_REG 0x14 -#define SOSSI_TEARING_REG 0x18 -#define SOSSI_INIT1B_REG 0x1c -#define SOSSI_FIFOB_REG 0x20 - -#define DMA_GSCR 0xfffedc04 -#define DMA_LCD_CCR 0xfffee3c2 -#define DMA_LCD_CTRL 0xfffee3c4 -#define DMA_LCD_LCH_CTRL 0xfffee3ea - -#define CONF_SOSSI_RESET_R (1 << 23) - -#define RD_ACCESS 0 -#define WR_ACCESS 1 - -#define SOSSI_MAX_XMIT_BYTES (512 * 1024) - -static struct { - void __iomem *base; - struct clk *fck; - unsigned long fck_hz; - spinlock_t lock; - int bus_pick_count; - int bus_pick_width; - int tearsync_mode; - int tearsync_line; - void (*lcdc_callback)(void *data); - void *lcdc_callback_data; - int vsync_dma_pending; - /* timing for read and write access */ - int clk_div; - u8 clk_tw0[2]; - u8 clk_tw1[2]; - /* - * if last_access is the same as current we don't have to change - * the timings - */ - int last_access; - - struct omapfb_device *fbdev; -} sossi; - -static inline u32 sossi_read_reg(int reg) -{ - return readl(sossi.base + reg); -} - -static inline u16 sossi_read_reg16(int reg) -{ - return readw(sossi.base + reg); -} - -static inline u8 sossi_read_reg8(int reg) -{ - return readb(sossi.base + reg); -} - -static inline void sossi_write_reg(int reg, u32 value) -{ - writel(value, sossi.base + reg); -} - -static inline void sossi_write_reg16(int reg, u16 value) -{ - writew(value, sossi.base + reg); -} - -static inline void sossi_write_reg8(int reg, u8 value) -{ - writeb(value, sossi.base + reg); -} - -static void sossi_set_bits(int reg, u32 bits) -{ - sossi_write_reg(reg, sossi_read_reg(reg) | bits); -} - -static void sossi_clear_bits(int reg, u32 bits) -{ - sossi_write_reg(reg, sossi_read_reg(reg) & ~bits); -} - -#define HZ_TO_PS(x) (1000000000 / (x / 1000)) - -static u32 ps_to_sossi_ticks(u32 ps, int div) -{ - u32 clk_period = HZ_TO_PS(sossi.fck_hz) * div; - return (clk_period + ps - 1) / clk_period; -} - -static int calc_rd_timings(struct extif_timings *t) -{ - u32 tw0, tw1; - int reon, reoff, recyc, actim; - int div = t->clk_div; - - /* - * Make sure that after conversion it still holds that: - * reoff > reon, recyc >= reoff, actim > reon - */ - reon = ps_to_sossi_ticks(t->re_on_time, div); - /* reon will be exactly one sossi tick */ - if (reon > 1) - return -1; - - reoff = ps_to_sossi_ticks(t->re_off_time, div); - - if (reoff <= reon) - reoff = reon + 1; - - tw0 = reoff - reon; - if (tw0 > 0x10) - return -1; - - recyc = ps_to_sossi_ticks(t->re_cycle_time, div); - if (recyc <= reoff) - recyc = reoff + 1; - - tw1 = recyc - tw0; - /* values less then 3 result in the SOSSI block resetting itself */ - if (tw1 < 3) - tw1 = 3; - if (tw1 > 0x40) - return -1; - - actim = ps_to_sossi_ticks(t->access_time, div); - if (actim < reoff) - actim++; - /* - * access time (data hold time) will be exactly one sossi - * tick - */ - if (actim - reoff > 1) - return -1; - - t->tim[0] = tw0 - 1; - t->tim[1] = tw1 - 1; - - return 0; -} - -static int calc_wr_timings(struct extif_timings *t) -{ - u32 tw0, tw1; - int weon, weoff, wecyc; - int div = t->clk_div; - - /* - * Make sure that after conversion it still holds that: - * weoff > weon, wecyc >= weoff - */ - weon = ps_to_sossi_ticks(t->we_on_time, div); - /* weon will be exactly one sossi tick */ - if (weon > 1) - return -1; - - weoff = ps_to_sossi_ticks(t->we_off_time, div); - if (weoff <= weon) - weoff = weon + 1; - tw0 = weoff - weon; - if (tw0 > 0x10) - return -1; - - wecyc = ps_to_sossi_ticks(t->we_cycle_time, div); - if (wecyc <= weoff) - wecyc = weoff + 1; - - tw1 = wecyc - tw0; - /* values less then 3 result in the SOSSI block resetting itself */ - if (tw1 < 3) - tw1 = 3; - if (tw1 > 0x40) - return -1; - - t->tim[2] = tw0 - 1; - t->tim[3] = tw1 - 1; - - return 0; -} - -static void _set_timing(int div, int tw0, int tw1) -{ - u32 l; - -#ifdef VERBOSE - dev_dbg(sossi.fbdev->dev, "Using TW0 = %d, TW1 = %d, div = %d\n", - tw0 + 1, tw1 + 1, div); -#endif - - clk_set_rate(sossi.fck, sossi.fck_hz / div); - clk_enable(sossi.fck); - l = sossi_read_reg(SOSSI_INIT1_REG); - l &= ~((0x0f << 20) | (0x3f << 24)); - l |= (tw0 << 20) | (tw1 << 24); - sossi_write_reg(SOSSI_INIT1_REG, l); - clk_disable(sossi.fck); -} - -static void _set_bits_per_cycle(int bus_pick_count, int bus_pick_width) -{ - u32 l; - - l = sossi_read_reg(SOSSI_INIT3_REG); - l &= ~0x3ff; - l |= ((bus_pick_count - 1) << 5) | ((bus_pick_width - 1) & 0x1f); - sossi_write_reg(SOSSI_INIT3_REG, l); -} - -static void _set_tearsync_mode(int mode, unsigned line) -{ - u32 l; - - l = sossi_read_reg(SOSSI_TEARING_REG); - l &= ~(((1 << 11) - 1) << 15); - l |= line << 15; - l &= ~(0x3 << 26); - l |= mode << 26; - sossi_write_reg(SOSSI_TEARING_REG, l); - if (mode) - sossi_set_bits(SOSSI_INIT2_REG, 1 << 6); /* TE logic */ - else - sossi_clear_bits(SOSSI_INIT2_REG, 1 << 6); -} - -static inline void set_timing(int access) -{ - if (access != sossi.last_access) { - sossi.last_access = access; - _set_timing(sossi.clk_div, - sossi.clk_tw0[access], sossi.clk_tw1[access]); - } -} - -static void sossi_start_transfer(void) -{ - /* WE */ - sossi_clear_bits(SOSSI_INIT2_REG, 1 << 4); - /* CS active low */ - sossi_clear_bits(SOSSI_INIT1_REG, 1 << 30); -} - -static void sossi_stop_transfer(void) -{ - /* WE */ - sossi_set_bits(SOSSI_INIT2_REG, 1 << 4); - /* CS active low */ - sossi_set_bits(SOSSI_INIT1_REG, 1 << 30); -} - -static void wait_end_of_write(void) -{ - /* Before reading we must check if some writings are going on */ - while (!(sossi_read_reg(SOSSI_INIT2_REG) & (1 << 3))); -} - -static void send_data(const void *data, unsigned int len) -{ - while (len >= 4) { - sossi_write_reg(SOSSI_FIFO_REG, *(const u32 *) data); - len -= 4; - data += 4; - } - while (len >= 2) { - sossi_write_reg16(SOSSI_FIFO_REG, *(const u16 *) data); - len -= 2; - data += 2; - } - while (len) { - sossi_write_reg8(SOSSI_FIFO_REG, *(const u8 *) data); - len--; - data++; - } -} - -static void set_cycles(unsigned int len) -{ - unsigned long nr_cycles = len / (sossi.bus_pick_width / 8); - - BUG_ON((nr_cycles - 1) & ~0x3ffff); - - sossi_clear_bits(SOSSI_INIT1_REG, 0x3ffff); - sossi_set_bits(SOSSI_INIT1_REG, (nr_cycles - 1) & 0x3ffff); -} - -static int sossi_convert_timings(struct extif_timings *t) -{ - int r = 0; - int div = t->clk_div; - - t->converted = 0; - - if (div <= 0 || div > 8) - return -1; - - /* no CS on SOSSI, so ignore cson, csoff, cs_pulsewidth */ - if ((r = calc_rd_timings(t)) < 0) - return r; - - if ((r = calc_wr_timings(t)) < 0) - return r; - - t->tim[4] = div; - - t->converted = 1; - - return 0; -} - -static void sossi_set_timings(const struct extif_timings *t) -{ - BUG_ON(!t->converted); - - sossi.clk_tw0[RD_ACCESS] = t->tim[0]; - sossi.clk_tw1[RD_ACCESS] = t->tim[1]; - - sossi.clk_tw0[WR_ACCESS] = t->tim[2]; - sossi.clk_tw1[WR_ACCESS] = t->tim[3]; - - sossi.clk_div = t->tim[4]; -} - -static void sossi_get_clk_info(u32 *clk_period, u32 *max_clk_div) -{ - *clk_period = HZ_TO_PS(sossi.fck_hz); - *max_clk_div = 8; -} - -static void sossi_set_bits_per_cycle(int bpc) -{ - int bus_pick_count, bus_pick_width; - - /* - * We set explicitly the the bus_pick_count as well, although - * with remapping/reordering disabled it will be calculated by HW - * as (32 / bus_pick_width). - */ - switch (bpc) { - case 8: - bus_pick_count = 4; - bus_pick_width = 8; - break; - case 16: - bus_pick_count = 2; - bus_pick_width = 16; - break; - default: - BUG(); - return; - } - sossi.bus_pick_width = bus_pick_width; - sossi.bus_pick_count = bus_pick_count; -} - -static int sossi_setup_tearsync(unsigned pin_cnt, - unsigned hs_pulse_time, unsigned vs_pulse_time, - int hs_pol_inv, int vs_pol_inv, int div) -{ - int hs, vs; - u32 l; - - if (pin_cnt != 1 || div < 1 || div > 8) - return -EINVAL; - - hs = ps_to_sossi_ticks(hs_pulse_time, div); - vs = ps_to_sossi_ticks(vs_pulse_time, div); - if (vs < 8 || vs <= hs || vs >= (1 << 12)) - return -EDOM; - vs /= 8; - vs--; - if (hs > 8) - hs = 8; - if (hs) - hs--; - - dev_dbg(sossi.fbdev->dev, - "setup_tearsync: hs %d vs %d hs_inv %d vs_inv %d\n", - hs, vs, hs_pol_inv, vs_pol_inv); - - clk_enable(sossi.fck); - l = sossi_read_reg(SOSSI_TEARING_REG); - l &= ~((1 << 15) - 1); - l |= vs << 3; - l |= hs; - if (hs_pol_inv) - l |= 1 << 29; - else - l &= ~(1 << 29); - if (vs_pol_inv) - l |= 1 << 28; - else - l &= ~(1 << 28); - sossi_write_reg(SOSSI_TEARING_REG, l); - clk_disable(sossi.fck); - - return 0; -} - -static int sossi_enable_tearsync(int enable, unsigned line) -{ - int mode; - - dev_dbg(sossi.fbdev->dev, "tearsync %d line %d\n", enable, line); - if (line >= 1 << 11) - return -EINVAL; - if (enable) { - if (line) - mode = 2; /* HS or VS */ - else - mode = 3; /* VS only */ - } else - mode = 0; - sossi.tearsync_line = line; - sossi.tearsync_mode = mode; - - return 0; -} - -static void sossi_write_command(const void *data, unsigned int len) -{ - clk_enable(sossi.fck); - set_timing(WR_ACCESS); - _set_bits_per_cycle(sossi.bus_pick_count, sossi.bus_pick_width); - /* CMD#/DATA */ - sossi_clear_bits(SOSSI_INIT1_REG, 1 << 18); - set_cycles(len); - sossi_start_transfer(); - send_data(data, len); - sossi_stop_transfer(); - wait_end_of_write(); - clk_disable(sossi.fck); -} - -static void sossi_write_data(const void *data, unsigned int len) -{ - clk_enable(sossi.fck); - set_timing(WR_ACCESS); - _set_bits_per_cycle(sossi.bus_pick_count, sossi.bus_pick_width); - /* CMD#/DATA */ - sossi_set_bits(SOSSI_INIT1_REG, 1 << 18); - set_cycles(len); - sossi_start_transfer(); - send_data(data, len); - sossi_stop_transfer(); - wait_end_of_write(); - clk_disable(sossi.fck); -} - -static void sossi_transfer_area(int width, int height, - void (callback)(void *data), void *data) -{ - BUG_ON(callback == NULL); - - sossi.lcdc_callback = callback; - sossi.lcdc_callback_data = data; - - clk_enable(sossi.fck); - set_timing(WR_ACCESS); - _set_bits_per_cycle(sossi.bus_pick_count, sossi.bus_pick_width); - _set_tearsync_mode(sossi.tearsync_mode, sossi.tearsync_line); - /* CMD#/DATA */ - sossi_set_bits(SOSSI_INIT1_REG, 1 << 18); - set_cycles(width * height * sossi.bus_pick_width / 8); - - sossi_start_transfer(); - if (sossi.tearsync_mode) { - /* - * Wait for the sync signal and start the transfer only - * then. We can't seem to be able to use HW sync DMA for - * this since LCD DMA shows huge latencies, as if it - * would ignore some of the DMA requests from SoSSI. - */ - unsigned long flags; - - spin_lock_irqsave(&sossi.lock, flags); - sossi.vsync_dma_pending++; - spin_unlock_irqrestore(&sossi.lock, flags); - } else - /* Just start the transfer right away. */ - omap_enable_lcd_dma(); -} - -static void sossi_dma_callback(void *data) -{ - omap_stop_lcd_dma(); - sossi_stop_transfer(); - clk_disable(sossi.fck); - sossi.lcdc_callback(sossi.lcdc_callback_data); -} - -static void sossi_read_data(void *data, unsigned int len) -{ - clk_enable(sossi.fck); - set_timing(RD_ACCESS); - _set_bits_per_cycle(sossi.bus_pick_count, sossi.bus_pick_width); - /* CMD#/DATA */ - sossi_set_bits(SOSSI_INIT1_REG, 1 << 18); - set_cycles(len); - sossi_start_transfer(); - while (len >= 4) { - *(u32 *) data = sossi_read_reg(SOSSI_FIFO_REG); - len -= 4; - data += 4; - } - while (len >= 2) { - *(u16 *) data = sossi_read_reg16(SOSSI_FIFO_REG); - len -= 2; - data += 2; - } - while (len) { - *(u8 *) data = sossi_read_reg8(SOSSI_FIFO_REG); - len--; - data++; - } - sossi_stop_transfer(); - clk_disable(sossi.fck); -} - -static irqreturn_t sossi_match_irq(int irq, void *data) -{ - unsigned long flags; - - spin_lock_irqsave(&sossi.lock, flags); - if (sossi.vsync_dma_pending) { - sossi.vsync_dma_pending--; - omap_enable_lcd_dma(); - } - spin_unlock_irqrestore(&sossi.lock, flags); - return IRQ_HANDLED; -} - -static int sossi_init(struct omapfb_device *fbdev) -{ - u32 l, k; - struct clk *fck; - struct clk *dpll1out_ck; - int r; - - sossi.base = ioremap(OMAP_SOSSI_BASE, SZ_1K); - if (!sossi.base) { - dev_err(fbdev->dev, "can't ioremap SoSSI\n"); - return -ENOMEM; - } - - sossi.fbdev = fbdev; - spin_lock_init(&sossi.lock); - - dpll1out_ck = clk_get(fbdev->dev, "ck_dpll1out"); - if (IS_ERR(dpll1out_ck)) { - dev_err(fbdev->dev, "can't get DPLL1OUT clock\n"); - return PTR_ERR(dpll1out_ck); - } - /* - * We need the parent clock rate, which we might divide further - * depending on the timing requirements of the controller. See - * _set_timings. - */ - sossi.fck_hz = clk_get_rate(dpll1out_ck); - clk_put(dpll1out_ck); - - fck = clk_get(fbdev->dev, "ck_sossi"); - if (IS_ERR(fck)) { - dev_err(fbdev->dev, "can't get SoSSI functional clock\n"); - return PTR_ERR(fck); - } - sossi.fck = fck; - - /* Reset and enable the SoSSI module */ - l = omap_readl(MOD_CONF_CTRL_1); - l |= CONF_SOSSI_RESET_R; - omap_writel(l, MOD_CONF_CTRL_1); - l &= ~CONF_SOSSI_RESET_R; - omap_writel(l, MOD_CONF_CTRL_1); - - clk_enable(sossi.fck); - l = omap_readl(ARM_IDLECT2); - l &= ~(1 << 8); /* DMACK_REQ */ - omap_writel(l, ARM_IDLECT2); - - l = sossi_read_reg(SOSSI_INIT2_REG); - /* Enable and reset the SoSSI block */ - l |= (1 << 0) | (1 << 1); - sossi_write_reg(SOSSI_INIT2_REG, l); - /* Take SoSSI out of reset */ - l &= ~(1 << 1); - sossi_write_reg(SOSSI_INIT2_REG, l); - - sossi_write_reg(SOSSI_ID_REG, 0); - l = sossi_read_reg(SOSSI_ID_REG); - k = sossi_read_reg(SOSSI_ID_REG); - - if (l != 0x55555555 || k != 0xaaaaaaaa) { - dev_err(fbdev->dev, - "invalid SoSSI sync pattern: %08x, %08x\n", l, k); - r = -ENODEV; - goto err; - } - - if ((r = omap_lcdc_set_dma_callback(sossi_dma_callback, NULL)) < 0) { - dev_err(fbdev->dev, "can't get LCDC IRQ\n"); - r = -ENODEV; - goto err; - } - - l = sossi_read_reg(SOSSI_ID_REG); /* Component code */ - l = sossi_read_reg(SOSSI_ID_REG); - dev_info(fbdev->dev, "SoSSI version %d.%d initialized\n", - l >> 16, l & 0xffff); - - l = sossi_read_reg(SOSSI_INIT1_REG); - l |= (1 << 19); /* DMA_MODE */ - l &= ~(1 << 31); /* REORDERING */ - sossi_write_reg(SOSSI_INIT1_REG, l); - - if ((r = request_irq(INT_1610_SoSSI_MATCH, sossi_match_irq, - IRQ_TYPE_EDGE_FALLING, - "sossi_match", sossi.fbdev->dev)) < 0) { - dev_err(sossi.fbdev->dev, "can't get SoSSI match IRQ\n"); - goto err; - } - - clk_disable(sossi.fck); - return 0; - -err: - clk_disable(sossi.fck); - clk_put(sossi.fck); - return r; -} - -static void sossi_cleanup(void) -{ - omap_lcdc_free_dma_callback(); - clk_put(sossi.fck); - iounmap(sossi.base); -} - -struct lcd_ctrl_extif omap1_ext_if = { - .init = sossi_init, - .cleanup = sossi_cleanup, - .get_clk_info = sossi_get_clk_info, - .convert_timings = sossi_convert_timings, - .set_timings = sossi_set_timings, - .set_bits_per_cycle = sossi_set_bits_per_cycle, - .setup_tearsync = sossi_setup_tearsync, - .enable_tearsync = sossi_enable_tearsync, - .write_command = sossi_write_command, - .read_data = sossi_read_data, - .write_data = sossi_write_data, - .transfer_area = sossi_transfer_area, - - .max_transmit_size = SOSSI_MAX_XMIT_BYTES, -}; - |