summaryrefslogtreecommitdiffstats
path: root/drivers/video/omap/blizzard.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap/blizzard.c')
-rw-r--r--drivers/video/omap/blizzard.c1648
1 files changed, 0 insertions, 1648 deletions
diff --git a/drivers/video/omap/blizzard.c b/drivers/video/omap/blizzard.c
deleted file mode 100644
index c0504a8a5079..000000000000
--- a/drivers/video/omap/blizzard.c
+++ /dev/null
@@ -1,1648 +0,0 @@
-/*
- * Epson Blizzard LCD controller driver
- *
- * Copyright (C) 2004-2005 Nokia Corporation
- * Authors: Juha Yrjola <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 <plat/dma.h>
-#include <plat/blizzard.h>
-
-#include "omapfb.h"
-#include "dispc.h"
-
-#define MODULE_NAME "blizzard"
-
-#define BLIZZARD_REV_CODE 0x00
-#define BLIZZARD_CONFIG 0x02
-#define BLIZZARD_PLL_DIV 0x04
-#define BLIZZARD_PLL_LOCK_RANGE 0x06
-#define BLIZZARD_PLL_CLOCK_SYNTH_0 0x08
-#define BLIZZARD_PLL_CLOCK_SYNTH_1 0x0a
-#define BLIZZARD_PLL_MODE 0x0c
-#define BLIZZARD_CLK_SRC 0x0e
-#define BLIZZARD_MEM_BANK0_ACTIVATE 0x10
-#define BLIZZARD_MEM_BANK0_STATUS 0x14
-#define BLIZZARD_PANEL_CONFIGURATION 0x28
-#define BLIZZARD_HDISP 0x2a
-#define BLIZZARD_HNDP 0x2c
-#define BLIZZARD_VDISP0 0x2e
-#define BLIZZARD_VDISP1 0x30
-#define BLIZZARD_VNDP 0x32
-#define BLIZZARD_HSW 0x34
-#define BLIZZARD_VSW 0x38
-#define BLIZZARD_DISPLAY_MODE 0x68
-#define BLIZZARD_INPUT_WIN_X_START_0 0x6c
-#define BLIZZARD_DATA_SOURCE_SELECT 0x8e
-#define BLIZZARD_DISP_MEM_DATA_PORT 0x90
-#define BLIZZARD_DISP_MEM_READ_ADDR0 0x92
-#define BLIZZARD_POWER_SAVE 0xE6
-#define BLIZZARD_NDISP_CTRL_STATUS 0xE8
-
-/* Data source select */
-/* For S1D13745 */
-#define BLIZZARD_SRC_WRITE_LCD_BACKGROUND 0x00
-#define BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE 0x01
-#define BLIZZARD_SRC_WRITE_OVERLAY_ENABLE 0x04
-#define BLIZZARD_SRC_DISABLE_OVERLAY 0x05
-/* For S1D13744 */
-#define BLIZZARD_SRC_WRITE_LCD 0x00
-#define BLIZZARD_SRC_BLT_LCD 0x06
-
-#define BLIZZARD_COLOR_RGB565 0x01
-#define BLIZZARD_COLOR_YUV420 0x09
-
-#define BLIZZARD_VERSION_S1D13745 0x01 /* Hailstorm */
-#define BLIZZARD_VERSION_S1D13744 0x02 /* Blizzard */
-
-#define BLIZZARD_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 blizzard_reg_list {
- int start;
- int end;
-};
-
-/* These need to be saved / restored separately from the rest. */
-static const struct blizzard_reg_list blizzard_pll_regs[] = {
- {
- .start = 0x04, /* Don't save PLL ctrl (0x0C) */
- .end = 0x0a,
- },
- {
- .start = 0x0e, /* Clock configuration */
- .end = 0x0e,
- },
-};
-
-static const struct blizzard_reg_list blizzard_gen_regs[] = {
- {
- .start = 0x18, /* SDRAM control */
- .end = 0x20,
- },
- {
- .start = 0x28, /* LCD Panel configuration */
- .end = 0x5a, /* HSSI interface, TV configuration */
- },
-};
-
-static u8 blizzard_reg_cache[0x5a / 2];
-
-struct update_param {
- int plane;
- int x, y, width, height;
- int out_x, out_y;
- int out_width, out_height;
- int color_mode;
- int bpp;
- int flags;
-};
-
-struct blizzard_request {
- struct list_head entry;
- unsigned int flags;
-
- int (*handler)(struct blizzard_request *req);
- void (*complete)(void *data);
- void *complete_data;
-
- union {
- struct update_param update;
- struct completion *sync;
- } par;
-};
-
-struct plane_info {
- unsigned long offset;
- int pos_x, pos_y;
- int width, height;
- int out_width, out_height;
- int scr_width;
- int color_mode;
- int bpp;
-};
-
-struct blizzard_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;
- int enabled_planes;
- int vid_nonstd_color;
- int vid_scaled;
- int last_color_mode;
- int zoom_on;
- int zoom_area_gx1;
- int zoom_area_gx2;
- int zoom_area_gy1;
- int zoom_area_gy2;
- int screen_width;
- int screen_height;
- unsigned te_connected:1;
- unsigned vsync_only:1;
-
- struct plane_info plane[OMAPFB_PLANE_NUM];
-
- struct blizzard_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;
-
- unsigned long sys_ck_rate;
- struct extif_timings reg_timings, lut_timings;
-
- u32 max_transmit_size;
- u32 extif_clk_period;
- int extif_clk_div;
- 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;
-
- void (*power_up)(struct device *dev);
- void (*power_down)(struct device *dev);
-
- int version;
-} blizzard;
-
-struct lcd_ctrl blizzard_ctrl;
-
-static u8 blizzard_read_reg(u8 reg)
-{
- u8 data;
-
- blizzard.extif->set_bits_per_cycle(8);
- blizzard.extif->write_command(&reg, 1);
- blizzard.extif->read_data(&data, 1);
-
- return data;
-}
-
-static void blizzard_write_reg(u8 reg, u8 val)
-{
- blizzard.extif->set_bits_per_cycle(8);
- blizzard.extif->write_command(&reg, 1);
- blizzard.extif->write_data(&val, 1);
-}
-
-static void blizzard_restart_sdram(void)
-{
- unsigned long tmo;
-
- blizzard_write_reg(BLIZZARD_MEM_BANK0_ACTIVATE, 0);
- udelay(50);
- blizzard_write_reg(BLIZZARD_MEM_BANK0_ACTIVATE, 1);
- tmo = jiffies + msecs_to_jiffies(200);
- while (!(blizzard_read_reg(BLIZZARD_MEM_BANK0_STATUS) & 0x01)) {
- if (time_after(jiffies, tmo)) {
- dev_err(blizzard.fbdev->dev,
- "s1d1374x: SDRAM not ready\n");
- break;
- }
- msleep(1);
- }
-}
-
-static void blizzard_stop_sdram(void)
-{
- blizzard_write_reg(BLIZZARD_MEM_BANK0_ACTIVATE, 0);
-}
-
-/* Wait until the last window was completely written into the controllers
- * SDRAM and we can start transferring the next window.
- */
-static void blizzard_wait_line_buffer(void)
-{
- unsigned long tmo = jiffies + msecs_to_jiffies(30);
-
- while (blizzard_read_reg(BLIZZARD_NDISP_CTRL_STATUS) & (1 << 7)) {
- if (time_after(jiffies, tmo)) {
- if (printk_ratelimit())
- dev_err(blizzard.fbdev->dev,
- "s1d1374x: line buffer not ready\n");
- break;
- }
- }
-}
-
-/* Wait until the YYC color space converter is idle. */
-static void blizzard_wait_yyc(void)
-{
- unsigned long tmo = jiffies + msecs_to_jiffies(30);
-
- while (blizzard_read_reg(BLIZZARD_NDISP_CTRL_STATUS) & (1 << 4)) {
- if (time_after(jiffies, tmo)) {
- if (printk_ratelimit())
- dev_err(blizzard.fbdev->dev,
- "s1d1374x: YYC not ready\n");
- break;
- }
- }
-}
-
-static void disable_overlay(void)
-{
- blizzard_write_reg(BLIZZARD_DATA_SOURCE_SELECT,
- BLIZZARD_SRC_DISABLE_OVERLAY);
-}
-
-static void set_window_regs(int x_start, int y_start, int x_end, int y_end,
- int x_out_start, int y_out_start,
- int x_out_end, int y_out_end, int color_mode,
- int zoom_off, int flags)
-{
- u8 tmp[18];
- 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;
-
- x_out_end--;
- y_out_end--;
- tmp[8] = x_out_start;
- tmp[9] = x_out_start >> 8;
- tmp[10] = y_out_start;
- tmp[11] = y_out_start >> 8;
- tmp[12] = x_out_end;
- tmp[13] = x_out_end >> 8;
- tmp[14] = y_out_end;
- tmp[15] = y_out_end >> 8;
-
- tmp[16] = color_mode;
- if (zoom_off && blizzard.version == BLIZZARD_VERSION_S1D13745)
- tmp[17] = BLIZZARD_SRC_WRITE_LCD_BACKGROUND;
- else if (flags & OMAPFB_FORMAT_FLAG_ENABLE_OVERLAY)
- tmp[17] = BLIZZARD_SRC_WRITE_OVERLAY_ENABLE;
- else
- tmp[17] = blizzard.version == BLIZZARD_VERSION_S1D13744 ?
- BLIZZARD_SRC_WRITE_LCD :
- BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE;
-
- blizzard.extif->set_bits_per_cycle(8);
- cmd = BLIZZARD_INPUT_WIN_X_START_0;
- blizzard.extif->write_command(&cmd, 1);
- blizzard.extif->write_data(tmp, 18);
-}
-
-static void enable_tearsync(int y, int width, int height, int screen_height,
- int out_height, int force_vsync)
-{
- u8 b;
-
- b = blizzard_read_reg(BLIZZARD_NDISP_CTRL_STATUS);
- b |= 1 << 3;
- blizzard_write_reg(BLIZZARD_NDISP_CTRL_STATUS, b);
-
- if (likely(blizzard.vsync_only || force_vsync)) {
- blizzard.extif->enable_tearsync(1, 0);
- return;
- }
-
- if (width * blizzard.pix_tx_time < blizzard.line_upd_time) {
- blizzard.extif->enable_tearsync(1, 0);
- return;
- }
-
- if ((width * blizzard.pix_tx_time / 1000) * height <
- (y + out_height) * (blizzard.line_upd_time / 1000)) {
- blizzard.extif->enable_tearsync(1, 0);
- return;
- }
-
- blizzard.extif->enable_tearsync(1, y + 1);
-}
-
-static void disable_tearsync(void)
-{
- u8 b;
-
- blizzard.extif->enable_tearsync(0, 0);
- b = blizzard_read_reg(BLIZZARD_NDISP_CTRL_STATUS);
- b &= ~(1 << 3);
- blizzard_write_reg(BLIZZARD_NDISP_CTRL_STATUS, b);
- b = blizzard_read_reg(BLIZZARD_NDISP_CTRL_STATUS);
-}
-
-static inline void set_extif_timings(const struct extif_timings *t);
-
-static inline struct blizzard_request *alloc_req(void)
-{
- unsigned long flags;
- struct blizzard_request *req;
- int req_flags = 0;
-
- if (!in_interrupt())
- down(&blizzard.req_sema);
- else
- req_flags = REQ_FROM_IRQ_POOL;
-
- spin_lock_irqsave(&blizzard.req_lock, flags);
- BUG_ON(list_empty(&blizzard.free_req_list));
- req = list_entry(blizzard.free_req_list.next,
- struct blizzard_request, entry);
- list_del(&req->entry);
- spin_unlock_irqrestore(&blizzard.req_lock, flags);
-
- INIT_LIST_HEAD(&req->entry);
- req->flags = req_flags;
-
- return req;
-}
-
-static inline void free_req(struct blizzard_request *req)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&blizzard.req_lock, flags);
-
- list_move(&req->entry, &blizzard.free_req_list);
- if (!(req->flags & REQ_FROM_IRQ_POOL))
- up(&blizzard.req_sema);
-
- spin_unlock_irqrestore(&blizzard.req_lock, flags);
-}
-
-static void process_pending_requests(void)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&blizzard.req_lock, flags);
-
- while (!list_empty(&blizzard.pending_req_list)) {
- struct blizzard_request *req;
- void (*complete)(void *);
- void *complete_data;
-
- req = list_entry(blizzard.pending_req_list.next,
- struct blizzard_request, entry);
- spin_unlock_irqrestore(&blizzard.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(&blizzard.req_lock, flags);
- }
-
- spin_unlock_irqrestore(&blizzard.req_lock, flags);
-}
-
-static void submit_req_list(struct list_head *head)
-{
- unsigned long flags;
- int process = 1;
-
- spin_lock_irqsave(&blizzard.req_lock, flags);
- if (likely(!list_empty(&blizzard.pending_req_list)))
- process = 0;
- list_splice_init(head, blizzard.pending_req_list.prev);
- spin_unlock_irqrestore(&blizzard.req_lock, flags);
-
- if (process)
- process_pending_requests();
-}
-
-static void request_complete(void *data)
-{
- struct blizzard_request *req = (struct blizzard_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 do_full_screen_update(struct blizzard_request *req)
-{
- int i;
- int flags;
-
- for (i = 0; i < 3; i++) {
- struct plane_info *p = &blizzard.plane[i];
- if (!(blizzard.enabled_planes & (1 << i))) {
- blizzard.int_ctrl->enable_plane(i, 0);
- continue;
- }
- dev_dbg(blizzard.fbdev->dev, "pw %d ph %d\n",
- p->width, p->height);
- blizzard.int_ctrl->setup_plane(i,
- OMAPFB_CHANNEL_OUT_LCD, p->offset,
- p->scr_width, p->pos_x, p->pos_y,
- p->width, p->height,
- p->color_mode);
- blizzard.int_ctrl->enable_plane(i, 1);
- }
-
- dev_dbg(blizzard.fbdev->dev, "sw %d sh %d\n",
- blizzard.screen_width, blizzard.screen_height);
- blizzard_wait_line_buffer();
- flags = req->par.update.flags;
- if (flags & OMAPFB_FORMAT_FLAG_TEARSYNC)
- enable_tearsync(0, blizzard.screen_width,
- blizzard.screen_height,
- blizzard.screen_height,
- blizzard.screen_height,
- flags & OMAPFB_FORMAT_FLAG_FORCE_VSYNC);
- else
- disable_tearsync();
-
- set_window_regs(0, 0, blizzard.screen_width, blizzard.screen_height,
- 0, 0, blizzard.screen_width, blizzard.screen_height,
- BLIZZARD_COLOR_RGB565, blizzard.zoom_on, flags);
- blizzard.zoom_on = 0;
-
- blizzard.extif->set_bits_per_cycle(16);
- /* set_window_regs has left the register index at the right
- * place, so no need to set it here.
- */
- blizzard.extif->transfer_area(blizzard.screen_width,
- blizzard.screen_height,
- request_complete, req);
- return REQ_PENDING;
-}
-
-static int check_1d_intersect(int a1, int a2, int b1, int b2)
-{
- if (a2 <= b1 || b2 <= a1)
- return 0;
- return 1;
-}
-
-/* Setup all planes with an overlapping area with the update window. */
-static int do_partial_update(struct blizzard_request *req, int plane,
- int x, int y, int w, int h,
- int x_out, int y_out, int w_out, int h_out,
- int wnd_color_mode, int bpp)
-{
- int i;
- int gx1, gy1, gx2, gy2;
- int gx1_out, gy1_out, gx2_out, gy2_out;
- int color_mode;
- int flags;
- int zoom_off;
- int have_zoom_for_this_update = 0;
-
- /* Global coordinates, relative to pixel 0,0 of the LCD */
- gx1 = x + blizzard.plane[plane].pos_x;
- gy1 = y + blizzard.plane[plane].pos_y;
- gx2 = gx1 + w;
- gy2 = gy1 + h;
-
- flags = req->par.update.flags;
- if (flags & OMAPFB_FORMAT_FLAG_DOUBLE) {
- gx1_out = gx1;
- gy1_out = gy1;
- gx2_out = gx1 + w * 2;
- gy2_out = gy1 + h * 2;
- } else {
- gx1_out = x_out + blizzard.plane[plane].pos_x;
- gy1_out = y_out + blizzard.plane[plane].pos_y;
- gx2_out = gx1_out + w_out;
- gy2_out = gy1_out + h_out;
- }
-
- for (i = 0; i < OMAPFB_PLANE_NUM; i++) {
- struct plane_info *p = &blizzard.plane[i];
- int px1, py1;
- int px2, py2;
- int pw, ph;
- int pposx, pposy;
- unsigned long offset;
-
- if (!(blizzard.enabled_planes & (1 << i)) ||
- (wnd_color_mode && i != plane)) {
- blizzard.int_ctrl->enable_plane(i, 0);
- continue;
- }
- /* Plane coordinates */
- if (i == plane) {
- /* Plane in which we are doing the update.
- * Local coordinates are the one in the update
- * request.
- */
- px1 = x;
- py1 = y;
- px2 = x + w;
- py2 = y + h;
- pposx = 0;
- pposy = 0;
- } else {
- /* Check if this plane has an overlapping part */
- px1 = gx1 - p->pos_x;
- py1 = gy1 - p->pos_y;
- px2 = gx2 - p->pos_x;
- py2 = gy2 - p->pos_y;
- if (px1 >= p->width || py1 >= p->height ||
- px2 <= 0 || py2 <= 0) {
- blizzard.int_ctrl->enable_plane(i, 0);
- continue;
- }
- /* Calculate the coordinates for the overlapping
- * part in the plane's local coordinates.
- */
- pposx = -px1;
- pposy = -py1;
- if (px1 < 0)
- px1 = 0;
- if (py1 < 0)
- py1 = 0;
- if (px2 > p->width)
- px2 = p->width;
- if (py2 > p->height)
- py2 = p->height;
- if (pposx < 0)
- pposx = 0;
- if (pposy < 0)
- pposy = 0;
- }
- pw = px2 - px1;
- ph = py2 - py1;
- offset = p->offset + (p->scr_width * py1 + px1) * p->bpp / 8;
- if (wnd_color_mode)
- /* Window embedded in the plane with a differing
- * color mode / bpp. Calculate the number of DMA
- * transfer elements in terms of the plane's bpp.
- */
- pw = (pw + 1) * bpp / p->bpp;
-#ifdef VERBOSE
- dev_dbg(blizzard.fbdev->dev,
- "plane %d offset %#08lx pposx %d pposy %d "
- "px1 %d py1 %d pw %d ph %d\n",
- i, offset, pposx, pposy, px1, py1, pw, ph);
-#endif
- blizzard.int_ctrl->setup_plane(i,
- OMAPFB_CHANNEL_OUT_LCD, offset,
- p->scr_width,
- pposx, pposy, pw, ph,
- p->color_mode);
-
- blizzard.int_ctrl->enable_plane(i, 1);
- }
-
- switch (wnd_color_mode) {
- case OMAPFB_COLOR_YUV420:
- color_mode = BLIZZARD_COLOR_YUV420;
- /* Currently only the 16 bits/pixel cycle format is
- * supported on the external interface. Adjust the number
- * of transfer elements per line for 12bpp format.
- */
- w = (w + 1) * 3 / 4;
- break;
- default:
- color_mode = BLIZZARD_COLOR_RGB565;
- break;
- }
-
- blizzard_wait_line_buffer();
- if (blizzard.last_color_mode == BLIZZARD_COLOR_YUV420)
- blizzard_wait_yyc();
- blizzard.last_color_mode = color_mode;
- if (flags & OMAPFB_FORMAT_FLAG_TEARSYNC)
- enable_tearsync(gy1, w, h,
- blizzard.screen_height,
- h_out,
- flags & OMAPFB_FORMAT_FLAG_FORCE_VSYNC);
- else
- disable_tearsync();
-
- if ((gx2_out - gx1_out) != (gx2 - gx1) ||
- (gy2_out - gy1_out) != (gy2 - gy1))
- have_zoom_for_this_update = 1;
-
- /* 'background' type of screen update (as opposed to 'destructive')
- can be used to disable scaling if scaling is active */
- zoom_off = blizzard.zoom_on && !have_zoom_for_this_update &&
- (gx1_out == 0) && (gx2_out == blizzard.screen_width) &&
- (gy1_out == 0) && (gy2_out == blizzard.screen_height) &&
- (gx1 == 0) && (gy1 == 0);
-
- if (blizzard.zoom_on && !have_zoom_for_this_update && !zoom_off &&
- check_1d_intersect(blizzard.zoom_area_gx1, blizzard.zoom_area_gx2,
- gx1_out, gx2_out) &&
- check_1d_intersect(blizzard.zoom_area_gy1, blizzard.zoom_area_gy2,
- gy1_out, gy2_out)) {
- /* Previous screen update was using scaling, current update
- * is not using it. Additionally, current screen update is
- * going to overlap with the scaled area. Scaling needs to be
- * disabled in order to avoid 'magnifying glass' effect.
- * Dummy setup of background window can be used for this.
- */
- set_window_regs(0, 0, blizzard.screen_width,
- blizzard.screen_height,
- 0, 0, blizzard.screen_width,
- blizzard.screen_height,
- BLIZZARD_COLOR_RGB565, 1, flags);
- blizzard.zoom_on = 0;
- }
-
- /* remember scaling settings if we have scaled update */
- if (have_zoom_for_this_update) {
- blizzard.zoom_on = 1;
- blizzard.zoom_area_gx1 = gx1_out;
- blizzard.zoom_area_gx2 = gx2_out;
- blizzard.zoom_area_gy1 = gy1_out;
- blizzard.zoom_area_gy2 = gy2_out;
- }
-
- set_window_regs(gx1, gy1, gx2, gy2, gx1_out, gy1_out, gx2_out, gy2_out,
- color_mode, zoom_off, flags);
- if (zoom_off)
- blizzard.zoom_on = 0;
-
- blizzard.extif->set_bits_per_cycle(16);
- /* set_window_regs has left the register index at the right
- * place, so no need to set it here.
- */
- blizzard.extif->transfer_area(w, h, request_complete, req);
-
- return REQ_PENDING;
-}
-
-static int send_frame_handler(struct blizzard_request *req)
-{
- struct update_param *par = &req->par.update;
- int plane = par->plane;
-
-#ifdef VERBOSE
- dev_dbg(blizzard.fbdev->dev,
- "send_frame: x %d y %d w %d h %d "
- "x_out %d y_out %d w_out %d h_out %d "
- "color_mode %04x flags %04x planes %01x\n",
- par->x, par->y, par->width, par->height,
- par->out_x, par->out_y, par->out_width, par->out_height,
- par->color_mode, par->flags, blizzard.enabled_planes);
-#endif
- if (par->flags & OMAPFB_FORMAT_FLAG_DISABLE_OVERLAY)
- disable_overlay();
-
- if ((blizzard.enabled_planes & blizzard.vid_nonstd_color) ||
- (blizzard.enabled_planes & blizzard.vid_scaled))
- return do_full_screen_update(req);
-
- return do_partial_update(req, plane, par->x, par->y,
- par->width, par->height,
- par->out_x, par->out_y,
- par->out_width, par->out_height,
- par->color_mode, par->bpp);
-}
-
-static void send_frame_complete(void *data)
-{
-}
-
-#define ADD_PREQ(_x, _y, _w, _h, _x_out, _y_out, _w_out, _h_out) do { \
- req = alloc_req(); \
- req->handler = send_frame_handler; \
- req->complete = send_frame_complete; \
- req->par.update.plane = plane_idx; \
- req->par.update.x = _x; \
- req->par.update.y = _y; \
- req->par.update.width = _w; \
- req->par.update.height = _h; \
- req->par.update.out_x = _x_out; \
- req->par.update.out_y = _y_out; \
- req->par.update.out_width = _w_out; \
- req->par.update.out_height = _h_out; \
- req->par.update.bpp = bpp; \
- 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(int plane_idx,
- struct omapfb_update_window *win,
- struct list_head *req_head)
-{
- struct blizzard_request *req;
- int x = win->x;
- int y = win->y;
- int width = win->width;
- int height = win->height;
- int x_out = win->out_x;
- int y_out = win->out_y;
- int width_out = win->out_width;
- int height_out = win->out_height;
- int color_mode;
- int bpp;
- int flags;
- unsigned int ystart = y;
- unsigned int yspan = height;
- unsigned int ystart_out = y_out;
- unsigned int yspan_out = height_out;
-
- flags = win->format & ~OMAPFB_FORMAT_MASK;
- color_mode = win->format & OMAPFB_FORMAT_MASK;
- switch (color_mode) {
- case OMAPFB_COLOR_YUV420:
- /* Embedded window with different color mode */
- bpp = 12;
- /* X, Y, height must be aligned at 2, width at 4 pixels */
- x &= ~1;
- y &= ~1;
- height = yspan = height & ~1;
- width = width & ~3;
- break;
- default:
- /* Same as the plane color mode */
- bpp = blizzard.plane[plane_idx].bpp;
- break;
- }
- if (width * height * bpp / 8 > blizzard.max_transmit_size) {
- yspan = blizzard.max_transmit_size / (width * bpp / 8);
- yspan_out = yspan * height_out / height;
- ADD_PREQ(x, ystart, width, yspan, x_out, ystart_out,
- width_out, yspan_out);
- ystart += yspan;
- ystart_out += yspan_out;
- yspan = height - yspan;
- yspan_out = height_out - yspan_out;
- flags &= ~OMAPFB_FORMAT_FLAG_TEARSYNC;
- }
-
- ADD_PREQ(x, ystart, width, yspan, x_out, ystart_out,
- width_out, yspan_out);
-}
-
-static void auto_update_complete(void *data)
-{
- if (!blizzard.stop_auto_update)
- mod_timer(&blizzard.auto_update_timer,
- jiffies + BLIZZARD_AUTO_UPDATE_TIME);
-}
-
-static void blizzard_update_window_auto(unsigned long arg)
-{
- LIST_HEAD(req_list);
- struct blizzard_request *last;
- struct omapfb_plane_struct *plane;
-
- plane = blizzard.fbdev->fb_info[0]->par;
- create_req_list(plane->idx,
- &blizzard.auto_update_window, &req_list);
- last = list_entry(req_list.prev, struct blizzard_request, entry);
-
- last->complete = auto_update_complete;
- last->complete_data = NULL;
-
- submit_req_list(&req_list);
-}
-
-int blizzard_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 blizzard_request *last;
- struct omapfb_plane_struct *plane = fbi->par;
-
- if (unlikely(blizzard.update_mode != OMAPFB_MANUAL_UPDATE))
- return -EINVAL;
- if (unlikely(!blizzard.te_connected &&
- (win->format & OMAPFB_FORMAT_FLAG_TEARSYNC)))
- return -EINVAL;
-
- create_req_list(plane->idx, win, &req_list);
- last = list_entry(req_list.prev, struct blizzard_request, entry);
-
- last->complete = complete_callback;
- last->complete_data = (void *)complete_callback_data;
-
- submit_req_list(&req_list);
-
- return 0;
-}
-EXPORT_SYMBOL(blizzard_update_window_async);
-
-static int update_full_screen(void)
-{
- return blizzard_update_window_async(blizzard.fbdev->fb_info[0],
- &blizzard.auto_update_window, NULL, NULL);
-
-}
-
-static int blizzard_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 plane_info *p;
-
-#ifdef VERBOSE
- dev_dbg(blizzard.fbdev->dev,
- "plane %d ch_out %d offset %#08lx scr_width %d "
- "pos_x %d pos_y %d width %d height %d color_mode %d\n",
- plane, channel_out, offset, screen_width,
- pos_x, pos_y, width, height, color_mode);
-#endif
- if ((unsigned)plane > OMAPFB_PLANE_NUM)
- return -EINVAL;
- p = &blizzard.plane[plane];
-
- switch (color_mode) {
- case OMAPFB_COLOR_YUV422:
- case OMAPFB_COLOR_YUY422:
- p->bpp = 16;
- blizzard.vid_nonstd_color &= ~(1 << plane);
- break;
- case OMAPFB_COLOR_YUV420:
- p->bpp = 12;
- blizzard.vid_nonstd_color |= 1 << plane;
- break;
- case OMAPFB_COLOR_RGB565:
- p->bpp = 16;
- blizzard.vid_nonstd_color &= ~(1 << plane);
- break;
- default:
- return -EINVAL;
- }
-
- p->offset = offset;
- p->pos_x = pos_x;
- p->pos_y = pos_y;
- p->width = width;
- p->height = height;
- p->scr_width = screen_width;
- if (!p->out_width)
- p->out_width = width;
- if (!p->out_height)
- p->out_height = height;
-
- p->color_mode = color_mode;
-
- return 0;
-}
-
-static int blizzard_set_scale(int plane, int orig_w, int orig_h,
- int out_w, int out_h)
-{
- struct plane_info *p = &blizzard.plane[plane];
- int r;
-
- dev_dbg(blizzard.fbdev->dev,
- "plane %d orig_w %d orig_h %d out_w %d out_h %d\n",
- plane, orig_w, orig_h, out_w, out_h);
- if ((unsigned)plane > OMAPFB_PLANE_NUM)
- return -ENODEV;
-
- r = blizzard.int_ctrl->set_scale(plane, orig_w, orig_h, out_w, out_h);
- if (r < 0)
- return r;
-
- p->width = orig_w;
- p->height = orig_h;
- p->out_width = out_w;
- p->out_height = out_h;
- if (orig_w == out_w && orig_h == out_h)
- blizzard.vid_scaled &= ~(1 << plane);
- else
- blizzard.vid_scaled |= 1 << plane;
-
- return 0;
-}
-
-static int blizzard_set_rotate(int angle)
-{
- u32 l;
-
- l = blizzard_read_reg(BLIZZARD_PANEL_CONFIGURATION);
- l &= ~0x03;
-
- switch (angle) {
- case 0:
- l = l | 0x00;
- break;
- case 90:
- l = l | 0x03;
- break;
- case 180:
- l = l | 0x02;
- break;
- case 270:
- l = l | 0x01;
- break;
- default:
- return -EINVAL;
- }
-
- blizzard_write_reg(BLIZZARD_PANEL_CONFIGURATION, l);
-
- return 0;
-}
-
-static int blizzard_enable_plane(int plane, int enable)
-{
- if (enable)
- blizzard.enabled_planes |= 1 << plane;
- else
- blizzard.enabled_planes &= ~(1 << plane);
-
- return 0;
-}
-
-static int sync_handler(struct blizzard_request *req)
-{
- complete(req->par.sync);
- return REQ_COMPLETE;
-}
-
-static void blizzard_sync(void)
-{
- LIST_HEAD(req_list);
- struct blizzard_request *req;
- struct completion comp;
-
- req = alloc_req();
-
- req->handler = sync_handler;
- req->complete = NULL;
- init_completion(&comp);
- req->par.sync = &comp;
-
- list_add(&req->entry, &req_list);
- submit_req_list(&req_list);
-
- wait_for_completion(&comp);
-}
-
-
-static void blizzard_bind_client(struct omapfb_notifier_block *nb)
-{
- if (blizzard.update_mode == OMAPFB_MANUAL_UPDATE) {
- omapfb_notify_clients(blizzard.fbdev, OMAPFB_EVENT_READY);
- }
-}
-
-static int blizzard_set_update_mode(enum omapfb_update_mode mode)
-{
- if (unlikely(mode != OMAPFB_MANUAL_UPDATE &&
- mode != OMAPFB_AUTO_UPDATE &&
- mode != OMAPFB_UPDATE_DISABLED))
- return -EINVAL;
-
- if (mode == blizzard.update_mode)
- return 0;
-
- dev_info(blizzard.fbdev->dev, "s1d1374x: setting update mode to %s\n",
- mode == OMAPFB_UPDATE_DISABLED ? "disabled" :
- (mode == OMAPFB_AUTO_UPDATE ? "auto" : "manual"));
-
- switch (blizzard.update_mode) {
- case OMAPFB_MANUAL_UPDATE:
- omapfb_notify_clients(blizzard.fbdev, OMAPFB_EVENT_DISABLED);
- break;
- case OMAPFB_AUTO_UPDATE:
- blizzard.stop_auto_update = 1;
- del_timer_sync(&blizzard.auto_update_timer);
- break;
- case OMAPFB_UPDATE_DISABLED:
- break;
- }
-
- blizzard.update_mode = mode;
- blizzard_sync();
- blizzard.stop_auto_update = 0;
-
- switch (mode) {
- case OMAPFB_MANUAL_UPDATE:
- omapfb_notify_clients(blizzard.fbdev, OMAPFB_EVENT_READY);
- break;
- case OMAPFB_AUTO_UPDATE:
- blizzard_update_window_auto(0);
- break;
- case OMAPFB_UPDATE_DISABLED:
- break;
- }
-
- return 0;
-}
-
-static enum omapfb_update_mode blizzard_get_update_mode(void)
-{
- return blizzard.update_mode;
-}
-
-static inline void set_extif_timings(const struct extif_timings *t)
-{
- blizzard.extif->set_timings(t);
-}
-
-static inline unsigned long round_to_extif_ticks(unsigned long ps, int div)
-{
- int bus_tick = blizzard.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 + 12 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(blizzard.fbdev->dev,
- "Blizzard systim %lu ps extif_clk_period %u div %d\n",
- systim, blizzard.extif_clk_period, div);
-
- t = &blizzard.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 + 13000, 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(blizzard.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(blizzard.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(blizzard.fbdev->dev, "[reg]rdaccess %d cspulse %d\n",
- t->access_time, t->cs_pulse_width);
-
- return blizzard.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(blizzard.fbdev->dev,
- "Blizzard systim %lu ps extif_clk_period %u div %d\n",
- systim, blizzard.extif_clk_period, div);
-
- t = &blizzard.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(blizzard.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(blizzard.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);