Commit e563dc81 authored by Imre Deak's avatar Imre Deak Committed by Juha Yrjola

ARM: OMAP: omapfb: main and LCD controller module changes

- Support for
        - overlays through separate /dev/fbX nodes
        - scaling and color space conversion
        - per-plane memory configuration either in SRAM or SDRAM

- Replace custom debug stuff with the default kernel one
Signed-off-by: default avatarImre Deak <ext-imre.deak@nokia.com>
Signed-off-by: default avatarJuha Yrjola <juha.yrjola@solidboot.com>
parent 4741bf3a
......@@ -27,12 +27,13 @@ config FB_OMAP_MANUAL_UPDATE
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_LPH8923
bool "Philips LPH8923 LCD support"
config FB_OMAP_LCD_MIPID
bool "MIPI DBI-C/DCS compatible LCD support"
depends on FB_OMAP
help
Say Y here if you want to have support for the Philips
LPH8923 LCD.
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_BOOTLOADER_INIT
bool "Check bootloader initializaion"
......@@ -42,6 +43,17 @@ config FB_OMAP_BOOTLOADER_INIT
already initialized the display controller. In this case the
driver will skip the initialization.
config FB_OMAP_CONSISTENT_DMA_SIZE
int "Consistent DMA memory size (MB)"
depends on FB_OMAP
range 1 14
default 2
help
Increase the DMA consistent memory size according to your video
memory needs, for example if you want to use multiple planes.
The size must be 2MB aligned.
If unsure say 1.
config FB_OMAP_DMA_TUNE
bool "Set DMA SDRAM access priority high"
depends on FB_OMAP && ARCH_OMAP1
......
......@@ -24,7 +24,7 @@ objs-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o
objs-y$(CONFIG_MACH_OMAP_PERSEUS2) += lcd_p2.o
objs-y$(CONFIG_MACH_OMAP_APOLLON) += lcd_apollon.o
objs-y$(CONFIG_FB_OMAP_LCD_LPH8923) += lcd_lph8923.o
objs-y$(CONFIG_FB_OMAP_LCD_MIPID) += lcd_mipid.o
omapfb-objs := $(objs-yy)
/*
* File: drivers/video/omap_new/debug.c
*
* Debug support for the omapfb driver
*
* 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_DEBUG_H
#define __OMAPFB_DEBUG_H
#ifdef OMAPFB_DBG
#define DBGPRINT(level, fmt, ...) if (level <= OMAPFB_DBG) do { \
printk(KERN_DEBUG "%s: "fmt, \
__FUNCTION__, ## __VA_ARGS__); \
} while (0)
#define DBGENTER(level) DBGPRINT(level, "Enter\n")
#define DBGLEAVE(level) DBGPRINT(level, "Leave\n")
#else /* OMAPFB_DBG */
#define DBGPRINT(level, format, ...)
#define DBGENTER(level)
#define DBGLEAVE(level)
#endif /* OMAPFB_DBG */
#endif /* __OMAPFB_DEBUG_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -21,7 +21,6 @@
* 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/delay.h>
#include <linux/i2c.h>
......@@ -35,14 +34,6 @@
#include "dispc.h"
/* #define OMAPFB_DBG 1 */
#include "debug.h"
#define MODULE_NAME "omapfb-rfbi"
#define pr_err(fmt, args...) printk(KERN_ERR MODULE_NAME ": " fmt, ## args)
#define RFBI_BASE 0x48050800
#define RFBI_REVISION 0x0000
#define RFBI_SYSCONFIG 0x0010
......@@ -73,10 +64,9 @@ static struct {
void *lcdc_callback_data;
unsigned long l4_khz;
int bits_per_cycle;
struct omapfb_device *fbdev;
} rfbi;
struct lcd_ctrl_extif rfbi_extif;
static inline void rfbi_write_reg(int idx, u32 val)
{
__raw_writel(val, rfbi.base + idx);
......@@ -87,7 +77,7 @@ static inline u32 rfbi_read_reg(int idx)
return __raw_readl(rfbi.base + idx);
}
#ifdef OMAPFB_DBG
#ifdef VERBOSE
static void rfbi_print_timings(void)
{
u32 l;
......@@ -98,16 +88,20 @@ static void rfbi_print_timings(void)
if (l & (1 << 4))
time *= 2;
DBGPRINT(1, "Tick time %u ps\n", time);
dev_dbg(rfbi.fbdev->dev, "Tick time %u ps\n", time);
l = rfbi_read_reg(RFBI_ONOFF_TIME0);
DBGPRINT(1, "CSONTIME %d, CSOFFTIME %d, WEONTIME %d, WEOFFTIME %d, "
"REONTIME %d, REOFFTIME %d\n",
l & 0x0f, (l >> 4) & 0x3f, (l >> 10) & 0x0f, (l >> 14) & 0x3f,
(l >> 20) & 0x0f, (l >> 24) & 0x3f);
dev_dbg(rfbi.fbdev->dev,
"CSONTIME %d, CSOFFTIME %d, WEONTIME %d, WEOFFTIME %d, "
"REONTIME %d, REOFFTIME %d\n",
l & 0x0f, (l >> 4) & 0x3f, (l >> 10) & 0x0f, (l >> 14) & 0x3f,
(l >> 20) & 0x0f, (l >> 24) & 0x3f);
l = rfbi_read_reg(RFBI_CYCLE_TIME0);
DBGPRINT(1, "WECYCLETIME %d, RECYCLETIME %d, CSPULSEWIDTH %d, "
"ACCESSTIME %d\n",
(l & 0x3f), (l >> 6) & 0x3f, (l >> 12) & 0x3f, (l >> 22) & 0x3f);
dev_dbg(rfbi.fbdev->dev,
"WECYCLETIME %d, RECYCLETIME %d, CSPULSEWIDTH %d, "
"ACCESSTIME %d\n",
(l & 0x3f), (l >> 6) & 0x3f, (l >> 12) & 0x3f,
(l >> 22) & 0x3f);
}
#else
static void rfbi_print_timings(void) {}
......@@ -341,20 +335,18 @@ static void rfbi_set_bits_per_cycle(int bpc)
rfbi.bits_per_cycle = bpc;
}
static int rfbi_init(void)
static int rfbi_init(struct omapfb_device *fbdev)
{
u32 l;
int r;
struct clk *dss_ick;
rfbi.fbdev = fbdev;
rfbi.base = io_p2v(RFBI_BASE);
l = rfbi_read_reg(RFBI_REVISION);
pr_info(MODULE_NAME ": version %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
dss_ick = clk_get(NULL, "dss_ick");
if (IS_ERR(dss_ick)) {
pr_err("can't get dss_ick\n");
dev_err(fbdev->dev, "can't get dss_ick\n");
return PTR_ERR(dss_ick);
}
......@@ -383,10 +375,14 @@ static int rfbi_init(void)
rfbi_write_reg(RFBI_CONTROL, l);
if ((r = omap_dispc_request_irq(rfbi_dma_callback, NULL)) < 0) {
pr_err("can't get DISPC irq\n");
dev_err(fbdev->dev, "can't get DISPC irq\n");
return r;
}
l = rfbi_read_reg(RFBI_REVISION);
pr_info("omapfb: RFBI version %d.%d initialized\n",
(l >> 4) & 0x0f, l & 0x0f);
return 0;
}
......@@ -395,7 +391,7 @@ static void rfbi_cleanup(void)
omap_dispc_free_irq();
}
struct lcd_ctrl_extif rfbi_extif = {
const struct lcd_ctrl_extif omap2_ext_if = {
.init = rfbi_init,
.cleanup = rfbi_cleanup,
.get_clk_info = rfbi_get_clk_info,
......@@ -406,6 +402,7 @@ struct lcd_ctrl_extif rfbi_extif = {
.read_data = rfbi_read_data,
.write_data = rfbi_write_data,
.transfer_area = rfbi_transfer_area,
.max_transmit_size = (u32)~0,
};
......@@ -20,7 +20,6 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/mm.h>
......@@ -33,10 +32,6 @@
#include "lcdc.h"
/* #define OMAPFB_DBG 1 */
#include "debug.h"
#define MODULE_NAME "omapfb-sossi"
#define OMAP_SOSSI_BASE 0xfffbac00
......@@ -60,10 +55,8 @@
#define SOSSI_MAX_XMIT_BYTES (512 * 1024)
#define pr_err(fmt, args...) printk(KERN_ERR MODULE_NAME ": " fmt, ## args)
static struct sossi {
int base;
static struct {
void __iomem *base;
unsigned long dpll_khz;
int bus_pick_width;
void (*lcdc_callback)(void *data);
......@@ -76,9 +69,10 @@ static struct sossi {
* the timings
*/
int last_access;
} sossi;
struct lcd_ctrl_extif sossi_extif;
struct omapfb_device *fbdev;
struct lcd_ctrl_extif *extif;
} sossi;
static inline u32 sossi_read_reg(int reg)
{
......@@ -126,86 +120,8 @@ static void sossi_clear_bits(int reg, u32 bits)
static void sossi_dma_callback(void *data);
static int sossi_init(void)
{
u32 l, k;
struct clk *dpll_clk;
int r;
sossi.base = IO_ADDRESS(OMAP_SOSSI_BASE);
dpll_clk = clk_get(NULL, "ck_dpll1");
if (IS_ERR(dpll_clk)) {
pr_err("can't get dpll1 clock\n");
return PTR_ERR(dpll_clk);
}
sossi.dpll_khz = clk_get_rate(dpll_clk) / 1000;
clk_put(dpll_clk);
sossi_extif.max_transmit_size = SOSSI_MAX_XMIT_BYTES;
/* 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);
l |= CONF_MOD_SOSSI_CLK_EN_R;
omap_writel(l, MOD_CONF_CTRL_1);
omap_writel(omap_readl(ARM_IDLECT2) | (1 << 11), ARM_IDLECT2);
omap_writel(omap_readl(ARM_IDLECT1) | (1 << 6), ARM_IDLECT1);
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) {
pr_err("Invalid SoSSI sync pattern: %08x, %08x\n", l, k);
return -ENODEV;
}
if ((r = omap_lcdc_set_dma_callback(sossi_dma_callback, NULL)) < 0) {
pr_err("can't get LCDC IRQ\n");
return r;
}
l = sossi_read_reg(SOSSI_ID_REG); /* Component code */
l = sossi_read_reg(SOSSI_ID_REG);
pr_info(KERN_INFO MODULE_NAME ": 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);
return 0;
}
static void sossi_cleanup(void)
{
omap_lcdc_free_dma_callback();
}
#define KHZ_TO_PS(x) (1000000000 / (x))
static void sossi_get_clk_info(u32 *clk_period, u32 *max_clk_div)
{
*clk_period = KHZ_TO_PS(sossi.dpll_khz);
*max_clk_div = 8;
}
static u32 ps_to_sossi_ticks(u32 ps, int div)
{
u32 clk_period = KHZ_TO_PS(sossi.dpll_khz) * div;
......@@ -299,49 +215,14 @@ static int calc_wr_timings(struct extif_timings *t)
return 0;
}
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 - 1;
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 _set_timing(int div, int tw0, int tw1)
{
u32 l;
DBGPRINT(2, "Using TW0 = %d, TW1 = %d, div = %d\n",
#ifdef VERBOSE
dev_dbg(sossi.fbdev->dev, "Using TW0 = %d, TW1 = %d, div = %d\n",
tw0 + 1, tw1 + 1, div + 1);
#endif
l = omap_readl(MOD_CONF_CTRL_1);
l &= ~(7 << 17);
......@@ -363,36 +244,6 @@ static inline void set_timing(int access)
}
}
static void sossi_set_bits_per_cycle(int bpc)
{
u32 l;
int bus_pick_count, bus_pick_width;
DBGPRINT(2, "bits_per_cycle %d\n", bpc);
/* 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;
}
l = sossi_read_reg(SOSSI_INIT3_REG);
sossi.bus_pick_width = bus_pick_width;
l &= ~0x3ff;
l |= ((bus_pick_count - 1) << 5) | ((bus_pick_width - 1) & 0x1f);
sossi_write_reg(SOSSI_INIT3_REG, l);
}
static void sossi_start_transfer(void)
{
/* WE */
......@@ -446,6 +297,78 @@ static void set_cycles(unsigned int len)
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 - 1;
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 = KHZ_TO_PS(sossi.dpll_khz);
*max_clk_div = 8;
}
static void sossi_set_bits_per_cycle(int bpc)
{
u32 l;
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;
}
l = sossi_read_reg(SOSSI_INIT3_REG);
sossi.bus_pick_width = bus_pick_width;
l &= ~0x3ff;
l |= ((bus_pick_count - 1) << 5) | ((bus_pick_width - 1) & 0x1f);
sossi_write_reg(SOSSI_INIT3_REG, l);
}
static void sossi_write_command(const void *data, unsigned int len)
{
set_timing(WR_ACCESS);
......@@ -483,8 +406,6 @@ static void sossi_transfer_area(int width, int height,
sossi_set_bits(SOSSI_INIT1_REG, 1 << 18);
set_cycles(width * height * sossi.bus_pick_width / 8);
DBGPRINT(2, "SOSSI_INIT1_REG %08x\n", sossi_read_reg(SOSSI_INIT1_REG));
sossi_start_transfer();
omap_enable_lcd_dma();
}
......@@ -521,7 +442,79 @@ static void sossi_read_data(void *data, unsigned int len)
sossi_stop_transfer();
}
struct lcd_ctrl_extif sossi_extif = {
static int sossi_init(struct omapfb_device *fbdev)
{
u32 l, k;
struct clk *dpll_clk;
int r;
sossi.fbdev = fbdev;
sossi.base = (void __iomem *)IO_ADDRESS(OMAP_SOSSI_BASE);
dpll_clk = clk_get(fbdev->dev, "ck_dpll1");
if (IS_ERR(dpll_clk)) {
dev_err(fbdev->dev, "can't get dpll1 clock\n");
return PTR_ERR(dpll_clk);
}
sossi.dpll_khz = clk_get_rate(dpll_clk) / 1000;
clk_put(dpll_clk);
/* 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);
l |= CONF_MOD_SOSSI_CLK_EN_R;
omap_writel(l, MOD_CONF_CTRL_1);
omap_writel(omap_readl(ARM_IDLECT2) | (1 << 11), ARM_IDLECT2);
omap_writel(omap_readl(ARM_IDLECT1) | (1 << 6), ARM_IDLECT1);
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);
return -ENODEV;
}
if ((r = omap_lcdc_set_dma_callback(sossi_dma_callback, NULL)) < 0) {
dev_err(fbdev->dev, "can't get LCDC IRQ\n");
return r;
}
l = sossi_read_reg(SOSSI_ID_REG); /* Component code */
l = sossi_read_reg(SOSSI_ID_REG);
pr_info("omapfb: 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);
return 0;
}
static void sossi_cleanup(void)
{
omap_lcdc_free_dma_callback();
}
const struct lcd_ctrl_extif omap1_ext_if = {
.init = sossi_init,
.cleanup = sossi_cleanup,
.get_clk_info = sossi_get_clk_info,
......@@ -532,4 +525,7 @@ struct lcd_ctrl_extif sossi_extif = {
.read_data = sossi_read_data,
.write_data = sossi_write_data,
.transfer_area = sossi_transfer_area,
.max_transmit_size = SOSSI_MAX_XMIT_BYTES,
};
......@@ -24,6 +24,9 @@
#ifndef __OMAPFB_H
#define __OMAPFB_H
#include <asm/ioctl.h>
#include <asm/types.h>
/* IOCTL commands. */
#define OMAP_IOW(num, dtype) _IOW('O', num, dtype)
......@@ -36,14 +39,14 @@
#define OMAPFB_VSYNC OMAP_IO(38)
#define OMAPFB_SET_UPDATE_MODE OMAP_IOW(40, int)
#define OMAPFB_UPDATE_WINDOW_OLD OMAP_IOW(41, struct omapfb_update_window_old)
#define OMAPFB_GET_CAPS OMAP_IOR(42, unsigned long)
#define OMAPFB_GET_UPDATE_MODE OMAP_IOW(43, int)
#define OMAPFB_LCD_TEST OMAP_IOW(45, int)
#define OMAPFB_CTRL_TEST OMAP_IOW(46, int)
#define OMAPFB_UPDATE_WINDOW OMAP_IOW(47, struct omapfb_update_window)
#define OMAPFB_SETUP_PLANE OMAP_IOW(48, struct omapfb_setup_plane)
#define OMAPFB_ENABLE_PLANE OMAP_IOW(49, struct omapfb_enable_plane)
#define OMAPFB_SET_COLOR_KEY OMAP_IOW(50, struct omapfb_color_key)
#define OMAPFB_GET_COLOR_KEY OMAP_IOW(51, struct omapfb_color_key)
#define OMAPFB_SETUP_PLANE OMAP_IOW(52, struct omapfb_plane_info)
#define OMAPFB_QUERY_PLANE OMAP_IOW(53, struct omapfb_plane_info)
#define OMAPFB_CAPS_GENERIC_MASK 0x00000fff
#define OMAPFB_CAPS_LCDC_MASK 0x00fff000
......@@ -56,6 +59,9 @@
#define OMAPFB_FORMAT_MASK 0x00ff
#define OMAPFB_FORMAT_FLAG_DOUBLE 0x0100
#define OMAPFB_EVENT_READY 1
#define OMAPFB_EVENT_DISABLED 2
enum omapfb_color_format {
OMAPFB_COLOR_RGB565 = 0,
OMAPFB_COLOR_YUV422,
......@@ -65,6 +71,7 @@ enum omapfb_color_format {
OMAPFB_COLOR_CLUT_2BPP,
OMAPFB_COLOR_CLUT_1BPP,
OMAPFB_COLOR_RGB444,
OMAPFB_COLOR_YUY422,
};
struct omapfb_update_window {
......@@ -89,18 +96,16 @@ enum omapfb_channel_out {
OMAPFB_CHANNEL_OUT_DIGIT,
};
struct omapfb_setup_plane {
__u8 plane;
struct omapfb_plane_info {
__u32 pos_x;
__u32 pos_y;
__u8 enabled;
__u8 channel_out;
__u32 offset;
__u32 pos_x, pos_y;
__u32 width, height;
__u32 color_mode;
};
struct omapfb_enable_plane {
__u8 plane;
__u8 enable;
__u8 mirror;
__u8 reserved1;
__u32 out_width;
__u32 out_height;
__u32 reserved2[12];
};
enum omapfb_color_key_type {
......@@ -142,6 +147,9 @@ enum omapfb_update_mode {
#define OMAP_LCDC_PANEL_TFT 0x0100
#define OMAPFB_PLANE_XRES_MIN 8
#define OMAPFB_PLANE_YRES_MIN 8
#ifdef CONFIG_ARCH_OMAP1
#define OMAPFB_PLANE_NUM 1
#else
......@@ -170,15 +178,17 @@ struct lcd_panel {
int pcd; /* pixel clock divider.
Obsolete use pixel_clock instead */
int (*init) (struct omapfb_device *fbdev);
void (*cleanup) (void);
int (*enable) (void);
void (*disable) (void);
unsigned long (*get_caps) (void);
int (*set_bklight_level)(unsigned int level);
unsigned int (*get_bklight_level)(void);
unsigned int (*get_bklight_max) (void);
int (*run_test) (int test_num);
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 omapfb_device;
......@@ -203,7 +213,7 @@ struct extif_timings {
};
struct lcd_ctrl_extif {
int (*init) (void);
int (*init) (struct omapfb_device *fbdev);
void (*cleanup) (void);
void (*get_clk_info) (u32 *clk_period, u32 *max_clk_div);
int (*convert_timings) (struct extif_timings *timings);
......@@ -214,30 +224,41 @@ struct lcd_ctrl_extif {
void (*write_data) (const void *buf, unsigned int len);
void (*transfer_area) (int width, int height,
void (callback)(void * data), void *data);
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 omapfb_notifier_block *,
unsigned long event,
struct omapfb_device *fbdev);
typedef int (*omapfb_notifier_callback_t)(struct notifier_block *,
unsigned long event,
void *fbi);
struct omapfb_mem_region {
dma_addr_t paddr;
void *vaddr;
unsigned long size;
int alloc:1;
};
struct omapfb_mem_desc {
int region_cnt;
struct omapfb_mem_region region[OMAPFB_PLANE_NUM];
};
struct lcd_ctrl {
const char *name;
void *data;
int (*init) (struct omapfb_device *fbdev,
int ext_mode, int req_vram_size);
int ext_mode,
struct omapfb_mem_desc *req_md);
void (*cleanup) (void);
void (*bind_client) (struct omapfb_notifier_block *nb);
void (*get_vram_layout)(unsigned long *size,
void **virt_base,
dma_addr_t *phys_base);
int (*mmap) (struct vm_area_struct *vma);
unsigned long (*get_caps) (void);
int (*set_update_mode)(enum omapfb_update_mode mode);
enum omapfb_update_mode (*get_update_mode)(void);
......@@ -246,8 +267,12 @@ struct lcd_ctrl {
int screen_width,
int pos_x, int pos_y, int width,
int height, int color_mode);
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 omapfb_update_window *win,
int (*update_window) (struct fb_info *fbi,
struct omapfb_update_window *win,
void (*callback)(void *),
void *callback_data);
void (*sync) (void);
......@@ -258,6 +283,7 @@ struct lcd_ctrl {
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);
};
......@@ -267,19 +293,20 @@ enum omapfb_state {
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;
void *vram_virt_base;
dma_addr_t vram_phys_base;
unsigned long vram_size;
int color_mode;
int palette_size;
int mirror;
u32 pseudo_palette[17];
struct lcd_panel *panel; /* LCD panel */
......@@ -287,19 +314,17 @@ struct omapfb_device {
struct lcd_ctrl *int_ctrl; /* internal LCD ctrl */
struct lcd_ctrl_extif *ext_if; /* LCD ctrl external
interface */
struct fb_info *fb_info;
struct device *dev;
struct omapfb_mem_desc mem_desc;
struct fb_info *fb_info[OMAPFB_PLANE_NUM];
};
struct omapfb_platform_data {
struct omap_lcd_config lcd;
struct omap_fbmem_config fbmem;
struct omap_lcd_config lcd;
struct omapfb_mem_desc mem_desc;
};
#define OMAPFB_EVENT_READY 1
#define OMAPFB_EVENT_DISABLED 2
#ifdef CONFIG_ARCH_OMAP1
extern struct lcd_ctrl omap1_lcd_ctrl;
#else
......@@ -311,12 +336,13 @@ 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);
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 omapfb_update_window *win,
void (*callback)(void *),
void *callback_data);
extern int omapfb_update_window_async(struct fb_info *fbi,
struct omapfb_update_window *win,
void (*callback)(void *),
void *callback_data);
/* in arch/arm/plat-omap/devices.c */
extern void omapfb_reserve_mem(void);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment