Commit d13970fd authored by Juha Yrjola's avatar Juha Yrjola

ARM: OMAP: Add external LCD controller support for DSP Gateway

If an external LCD controller is in manual update mode, the DSP
must let the FB driver know when a frame should be send over the
remote framebuffer interface.

Original code by Toshihiro, FB parts by Imre.
Signed-off-by: default avatarImre Deak <imre.deak@nokia.com>
Signed-off-by: default avatarJuha Yrjl <juha.yrjola@nokia.com>
parent c5bf6988
...@@ -437,11 +437,15 @@ static DECLARE_WORK(mbx1_work, (void (*)(void *))do_mbx1, NULL); ...@@ -437,11 +437,15 @@ static DECLARE_WORK(mbx1_work, (void (*)(void *))do_mbx1, NULL);
/* /*
* kernel function dispatcher * kernel function dispatcher
*/ */
extern void mbx1_fbctl_upd(void);
extern void mbx1_fbctl_disable(void); extern void mbx1_fbctl_disable(void);
static void mbx1_kfunc_fbctl(unsigned short data) static void mbx1_kfunc_fbctl(unsigned short data)
{ {
switch (data) { switch (data) {
case OMAP_DSP_MBCMD_FBCTL_UPD:
mbx1_fbctl_upd();
break;
case OMAP_DSP_MBCMD_FBCTL_DISABLE: case OMAP_DSP_MBCMD_FBCTL_DISABLE:
mbx1_fbctl_disable(); mbx1_fbctl_disable();
break; break;
......
...@@ -46,9 +46,11 @@ ...@@ -46,9 +46,11 @@
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/arch/tc.h> #include <asm/arch/tc.h>
#include <asm/arch/omapfb.h>
#include <asm/arch/dsp.h> #include <asm/arch/dsp.h>
#include <asm/arch/dsp_common.h> #include <asm/arch/dsp_common.h>
#include "uaccess_dsp.h" #include "uaccess_dsp.h"
#include "ipbuf.h"
#include "dsp.h" #include "dsp.h"
#define SZ_1MB 0x100000 #define SZ_1MB 0x100000
...@@ -116,6 +118,11 @@ struct exmap_tbl { ...@@ -116,6 +118,11 @@ struct exmap_tbl {
static struct exmap_tbl exmap_tbl[DSPMMU_TLB_LINES]; static struct exmap_tbl exmap_tbl[DSPMMU_TLB_LINES];
static DECLARE_RWSEM(exmap_sem); static DECLARE_RWSEM(exmap_sem);
#ifdef CONFIG_FB_OMAP_LCDC_EXTERNAL
static struct omapfb_notifier_block *omapfb_nb;
static int omapfb_ready;
#endif
static int dsp_exunmap(unsigned long dspadr); static int dsp_exunmap(unsigned long dspadr);
static void *dspvect_page; static void *dspvect_page;
...@@ -1002,6 +1009,23 @@ static unsigned long unmap_free_arm(struct exmap_tbl *ent) ...@@ -1002,6 +1009,23 @@ static unsigned long unmap_free_arm(struct exmap_tbl *ent)
"omapdsp: freeing 0x%lx bytes @ adr 0x%8p\n", "omapdsp: freeing 0x%lx bytes @ adr 0x%8p\n",
size, ent->buf); size, ent->buf);
} }
#ifdef CONFIG_FB_OMAP_LCDC_EXTERNAL
else if (ent->type == EXMAP_TYPE_FB) {
int status;
if (omapfb_nb) {
status = omapfb_unregister_client(omapfb_nb);
if (!status)
printk("omapfb_unregister_client(): "
"success\n");
else
printk("omapfb_runegister_client(): "
"failure(%d)\n", status);
kfree(omapfb_nb);
omapfb_nb = NULL;
omapfb_ready = 0;
}
}
#endif
return size; return size;
} }
...@@ -1104,14 +1128,41 @@ static void exmap_flush(void) ...@@ -1104,14 +1128,41 @@ static void exmap_flush(void)
#error You configured OMAP_DSP_FBEXPORT, but FB was not configured! #error You configured OMAP_DSP_FBEXPORT, but FB was not configured!
#endif /* CONFIG_FB */ #endif /* CONFIG_FB */
#ifdef CONFIG_FB_OMAP_LCDC_EXTERNAL
static int omapfb_notifier_cb(struct omapfb_notifier_block *omapfb_nb,
unsigned long event, struct omapfb_device *fbdev)
{
/* XXX */
printk("omapfb_notifier_cb(): event = %s\n",
(event == OMAPFB_EVENT_READY) ? "READY" :
(event == OMAPFB_EVENT_DISABLED) ? "DISABLED" : "Unknown");
if (event == OMAPFB_EVENT_READY)
omapfb_ready = 1;
else if (event == OMAPFB_EVENT_DISABLED)
omapfb_ready = 0;
return 0;
}
#endif
static int dsp_fbexport(unsigned long *dspadr) static int dsp_fbexport(unsigned long *dspadr)
{ {
unsigned long dspadr_actual; unsigned long dspadr_actual;
unsigned long padr_sys, padr, fbsz_sys, fbsz; unsigned long padr_sys, padr, fbsz_sys, fbsz;
int cnt; int cnt;
#ifdef CONFIG_FB_OMAP_LCDC_EXTERNAL
int status;
#endif
printk(KERN_DEBUG "omapdsp: frame buffer export\n"); printk(KERN_DEBUG "omapdsp: frame buffer export\n");
#ifdef CONFIG_FB_OMAP_LCDC_EXTERNAL
if (omapfb_nb) {
printk(KERN_WARNING
"omapdsp: frame buffer has been exported already!\n");
return -EBUSY;
}
#endif
if (num_registered_fb == 0) { if (num_registered_fb == 0) {
printk(KERN_INFO "omapdsp: frame buffer not registered.\n"); printk(KERN_INFO "omapdsp: frame buffer not registered.\n");
return -EINVAL; return -EINVAL;
...@@ -1169,6 +1220,21 @@ static int dsp_fbexport(unsigned long *dspadr) ...@@ -1169,6 +1220,21 @@ static int dsp_fbexport(unsigned long *dspadr)
/* increase the DMA priority */ /* increase the DMA priority */
set_emiff_dma_prio(15); set_emiff_dma_prio(15);
#ifdef CONFIG_FB_OMAP_LCDC_EXTERNAL
omapfb_nb = kmalloc(sizeof(struct omapfb_notifier_block), GFP_KERNEL);
if (omapfb_nb == NULL) {
printk(KERN_ERR
"omapdsp: failed to allocate memory for omapfb_nb!\n");
dsp_exunmap(dspadr_actual);
return -ENOMEM;
}
status = omapfb_register_client(omapfb_nb, omapfb_notifier_cb, NULL);
if (!status)
printk("omapfb_register_client(): success\n");
else
printk("omapfb_register_client(): failure(%d)\n", status);
#endif
return cnt; return cnt;
} }
...@@ -1529,6 +1595,68 @@ static int dsp_mem_release(struct inode *inode, struct file *file) ...@@ -1529,6 +1595,68 @@ static int dsp_mem_release(struct inode *inode, struct file *file)
return 0; return 0;
} }
#ifdef CONFIG_FB_OMAP_LCDC_EXTERNAL
/*
* fb update functions:
* fbupd_response() is executed by the workqueue.
* fbupd_cb() is called when fb update is done, in interrupt context.
* mbx1_fbupd() is called when KFUNC:FBCTL:UPD is received from DSP.
*/
static void fbupd_response(void *arg)
{
int status;
status = dsp_mbsend(MBCMD(KFUNC), OMAP_DSP_MBCMD_KFUNC_FBCTL,
OMAP_DSP_MBCMD_FBCTL_UPD);
if (status < 0) {
/* FIXME: DSP is busy !! */
printk(KERN_ERR
"omapdsp: DSP is busy when trying to send FBCTL:UPD "
"response!\n");
}
}
static DECLARE_WORK(fbupd_response_work, (void (*)(void *))fbupd_response,
NULL);
static void fbupd_cb(void *arg)
{
schedule_work(&fbupd_response_work);
}
void mbx1_fbctl_upd(void)
{
struct omapfb_update_window win;
volatile unsigned short *buf = ipbuf_sys_da->d;
/* FIXME: try count sometimes exceeds 1000. */
if (sync_with_dsp(&ipbuf_sys_da->s, OMAP_DSP_TID_ANON, 5000) < 0) {
printk(KERN_ERR "mbx: FBCTL:UPD - IPBUF sync failed!\n");
return;
}
win.x = buf[0];
win.y = buf[1];
win.width = buf[2];
win.height = buf[3];
win.format = buf[4];
release_ipbuf_pvt(ipbuf_sys_da);
if (!omapfb_ready) {
printk(KERN_WARNING
"omapdsp: fbupd() called while HWA742 is not ready!\n");
return;
}
//printk("calling omapfb_update_window_async()\n");
omapfb_update_window_async(&win, fbupd_cb, NULL);
}
#else /* CONFIG_FB_OMAP_LCDC_EXTERNAL */
void mbx1_fbctl_upd(void)
{
}
#endif /* CONFIG_FB_OMAP_LCDC_EXTERNAL */
/* /*
* sysfs files * sysfs files
*/ */
......
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
/* #define OMAPFB_DBG 1 */ /* #define OMAPFB_DBG 1 */
#include "hwa742.h"
#include "debug.h" #include "debug.h"
#define MODULE_NAME "omapfb-hwa742" #define MODULE_NAME "omapfb-hwa742"
...@@ -159,13 +158,6 @@ static void hwa742_write_reg(u8 reg, u8 data) ...@@ -159,13 +158,6 @@ static void hwa742_write_reg(u8 reg, u8 data)
hwa742.extif->write_data(&data, 1); hwa742.extif->write_data(&data, 1);
} }
void hwa742_read_id(int *rev_code, int *config)
{
*rev_code = hwa742_read_reg(HWA742_REV_CODE_REG);
*config = hwa742_read_reg(HWA742_CONFIG_REG);
}
EXPORT_SYMBOL(hwa742_read_id);
static void set_window_regs(int x_start, int y_start, int x_end, int y_end) static void set_window_regs(int x_start, int y_start, int x_end, int y_end)
{ {
u8 tmp[8]; u8 tmp[8];
...@@ -471,10 +463,12 @@ int hwa742_update_window_async(struct omapfb_update_window *win, ...@@ -471,10 +463,12 @@ int hwa742_update_window_async(struct omapfb_update_window *win,
DBGENTER(2); DBGENTER(2);
if (hwa742.update_mode != OMAPFB_MANUAL_UPDATE) { if (hwa742.update_mode != OMAPFB_MANUAL_UPDATE) {
DBGPRINT(1, "invalid update mode\n");
r = -EINVAL; r = -EINVAL;
goto out; goto out;
} }
if (unlikely(win->format & ~(0x03 | OMAPFB_FORMAT_FLAG_DOUBLE))) { if (unlikely(win->format & ~(0x03 | OMAPFB_FORMAT_FLAG_DOUBLE))) {
DBGPRINT(1, "invalid window flag");
r = -EINVAL; r = -EINVAL;
goto out; goto out;
} }
...@@ -544,37 +538,13 @@ static void hwa742_sync(void) ...@@ -544,37 +538,13 @@ static void hwa742_sync(void)
DBGLEAVE(2); DBGLEAVE(2);
} }
static struct notifier_block *hwa742_client_list; static void hwa742_bind_client(struct omapfb_notifier_block *nb)
int hwa742_register_client(struct hwa742_notifier_block *hwa742_nb,
hwa742_notifier_callback_t callback,
void *callback_data)
{ {
int r;
DBGPRINT(1, "update_mode %d\n", hwa742.update_mode); DBGPRINT(1, "update_mode %d\n", hwa742.update_mode);
hwa742_nb->nb.notifier_call = (int (*)(struct notifier_block *,
unsigned long, void *))callback;
hwa742_nb->data = callback_data;
r = notifier_chain_register(&hwa742_client_list, &hwa742_nb->nb);
if (r)
return r;
if (hwa742.update_mode == OMAPFB_MANUAL_UPDATE) { if (hwa742.update_mode == OMAPFB_MANUAL_UPDATE) {
DBGPRINT(1, "calling client list\n"); omapfb_notify_clients(hwa742.fbdev, OMAPFB_EVENT_READY);
notifier_call_chain(&hwa742_client_list,
HWA742_EVENT_READY,
hwa742.fbdev);
} }
return 0;
}
EXPORT_SYMBOL(hwa742_register_client);
int hwa742_unregister_client(struct hwa742_notifier_block *hwa742_nb)
{
return notifier_chain_unregister(&hwa742_client_list,
&hwa742_nb->nb);
} }
EXPORT_SYMBOL(hwa742_unregister_client);
static int hwa742_set_update_mode(enum omapfb_update_mode mode) static int hwa742_set_update_mode(enum omapfb_update_mode mode)
{ {
...@@ -597,9 +567,7 @@ static int hwa742_set_update_mode(enum omapfb_update_mode mode) ...@@ -597,9 +567,7 @@ static int hwa742_set_update_mode(enum omapfb_update_mode mode)
switch (hwa742.update_mode) { switch (hwa742.update_mode) {
case OMAPFB_MANUAL_UPDATE: case OMAPFB_MANUAL_UPDATE:
notifier_call_chain(&hwa742_client_list, omapfb_notify_clients(hwa742.fbdev, OMAPFB_EVENT_DISABLED);
HWA742_EVENT_DISABLED,
hwa742.fbdev);
break; break;
case OMAPFB_AUTO_UPDATE: case OMAPFB_AUTO_UPDATE:
hwa742.stop_auto_update = 1; hwa742.stop_auto_update = 1;
...@@ -615,9 +583,7 @@ static int hwa742_set_update_mode(enum omapfb_update_mode mode) ...@@ -615,9 +583,7 @@ static int hwa742_set_update_mode(enum omapfb_update_mode mode)
switch (mode) { switch (mode) {
case OMAPFB_MANUAL_UPDATE: case OMAPFB_MANUAL_UPDATE:
notifier_call_chain(&hwa742_client_list, omapfb_notify_clients(hwa742.fbdev, OMAPFB_EVENT_READY);
HWA742_EVENT_READY,
hwa742.fbdev);
break; break;
case OMAPFB_AUTO_UPDATE: case OMAPFB_AUTO_UPDATE:
hwa742_update_window_auto(0); hwa742_update_window_auto(0);
...@@ -915,6 +881,7 @@ struct lcd_ctrl hwa742_ctrl = { ...@@ -915,6 +881,7 @@ struct lcd_ctrl hwa742_ctrl = {
.name = "hwa742", .name = "hwa742",
.init = hwa742_init, .init = hwa742_init,
.cleanup = hwa742_cleanup, .cleanup = hwa742_cleanup,
.bind_client = hwa742_bind_client,
.get_caps = hwa742_get_caps, .get_caps = hwa742_get_caps,
.set_update_mode = hwa742_set_update_mode, .set_update_mode = hwa742_set_update_mode,
.get_update_mode = hwa742_get_update_mode, .get_update_mode = hwa742_get_update_mode,
......
#ifndef __HWA742_H
#define __HWA742_H
#include <linux/fb.h>
#include <asm/arch/omapfb.h>
#define HWA742_EVENT_READY 1
#define HWA742_EVENT_DISABLED 2
struct hwa742_notifier_block {
struct notifier_block nb;
void *data;
};
typedef int (*hwa742_notifier_callback_t)(struct hwa742_notifier_block *,
unsigned long event,
struct omapfb_device *fbdev);
extern void hwa742_read_id(int *rev_code, int *config);
extern int hwa742_register_client(struct hwa742_notifier_block *hwa742_nb,
hwa742_notifier_callback_t callback,
void *callback_data);
extern int hwa742_unregister_client(struct hwa742_notifier_block *hwa742_nb);
extern int hwa742_update_window_async(struct omapfb_update_window *win,
void (*complete_callback)(void *arg),
void *complete_callback_data);
#endif
...@@ -67,6 +67,10 @@ static int manual_update = 1; ...@@ -67,6 +67,10 @@ static int manual_update = 1;
static int manual_update; static int manual_update;
#endif #endif
static struct platform_device *fbdev_pdev;
static struct lcd_panel *fbdev_panel;
static struct omapfb_device *omapfb_dev;
static struct caps_table_struct { static struct caps_table_struct {
unsigned long flag; unsigned long flag;
const char *name; const char *name;
...@@ -576,28 +580,52 @@ static int omapfb_set_par(struct fb_info *fbi) ...@@ -576,28 +580,52 @@ static int omapfb_set_par(struct fb_info *fbi)
return r; return r;
} }
static int omapfb_update_win(struct omapfb_device *fbdev, int omapfb_update_window_async(struct omapfb_update_window *win,
struct omapfb_update_window *win) void (*callback)(void *),
void *callback_data)
{ {
struct fb_var_screeninfo *var = &fbdev->fb_info->var; struct omapfb_device *fbdev = omapfb_dev;
int ret; struct fb_var_screeninfo *var;
DBGENTER(2);
if (fbdev == NULL) {
DBGPRINT(1, "no fbdev\n");
return -ENODEV;
}
var = &fbdev->fb_info->var;
if (win->x >= var->xres || win->y >= var->yres) if (win->x >= var->xres || win->y >= var->yres) {
DBGPRINT(1, "invalid x %d, y %d\n", win->x, win->y);
return -EINVAL; return -EINVAL;
}
if (!fbdev->ctrl->update_window || if (!fbdev->ctrl->update_window ||
fbdev->ctrl->get_update_mode() != OMAPFB_MANUAL_UPDATE) fbdev->ctrl->get_update_mode() != OMAPFB_MANUAL_UPDATE) {
DBGPRINT(1, "invalid update mode\n");
return -ENODEV; return -ENODEV;
}
if (win->x + win->width >= var->xres) if (win->x + win->width >= var->xres)
win->width = var->xres - win->x; win->width = var->xres - win->x;
if (win->y + win->height >= var->yres) if (win->y + win->height >= var->yres)
win->height = var->yres - win->y; win->height = var->yres - win->y;
if (!win->width || !win->height) if (!win->width || !win->height) {
DBGPRINT(1, "zero size window\n");
return 0; return 0;
}
return fbdev->ctrl->update_window(win, callback, callback_data);
}
EXPORT_SYMBOL(omapfb_update_window_async);
static int omapfb_update_win(struct omapfb_device *fbdev,
struct omapfb_update_window *win)
{
int ret;
omapfb_rqueue_lock(fbdev); omapfb_rqueue_lock(fbdev);
ret = fbdev->ctrl->update_window(win, NULL, 0); ret = omapfb_update_window_async(win, NULL, 0);
omapfb_rqueue_unlock(fbdev); omapfb_rqueue_unlock(fbdev);
return ret; return ret;
...@@ -659,6 +687,45 @@ static int omapfb_set_color_key(struct omapfb_device *fbdev, ...@@ -659,6 +687,45 @@ static int omapfb_set_color_key(struct omapfb_device *fbdev,
return r; return r;
} }
static struct notifier_block *omapfb_client_list;
int omapfb_register_client(struct omapfb_notifier_block *omapfb_nb,
omapfb_notifier_callback_t callback,
void *callback_data)
{
int r;
DBGENTER(1);
omapfb_nb->nb.notifier_call = (int (*)(struct notifier_block *,
unsigned long, void *))callback;
omapfb_nb->data = callback_data;
r = notifier_chain_register(&omapfb_client_list, &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 notifier_chain_unregister(&omapfb_client_list,
&omapfb_nb->nb);
}
EXPORT_SYMBOL(omapfb_unregister_client);
void omapfb_notify_clients(struct omapfb_device *fbdev, unsigned long event)
{
DBGENTER(1);
notifier_call_chain(&omapfb_client_list, event, fbdev);
}
EXPORT_SYMBOL(omapfb_notify_clients);
static int omapfb_set_update_mode(struct omapfb_device *fbdev, static int omapfb_set_update_mode(struct omapfb_device *fbdev,
enum omapfb_update_mode mode) enum omapfb_update_mode mode)
{ {
...@@ -1291,6 +1358,8 @@ static int omapfb_do_probe(struct platform_device *pdev, struct lcd_panel *panel ...@@ -1291,6 +1358,8 @@ static int omapfb_do_probe(struct platform_device *pdev, struct lcd_panel *panel
hhz = phz * 10 / (panel->hfp + panel->x_res + panel->hbp + panel->hsw); hhz = phz * 10 / (panel->hfp + panel->x_res + panel->hbp + panel->hsw);
vhz = hhz / (panel->vfp + panel->y_res + panel->vbp + panel->vsw); vhz = hhz / (panel->vfp + panel->y_res + panel->vbp + panel->vsw);
omapfb_dev = fbdev;
pr_info(MODULE_NAME ": initialized vram=%lu " pr_info(MODULE_NAME ": initialized vram=%lu "
"pixclock %lu kHz hfreq %lu.%lu kHz vfreq %lu.%lu Hz\n", "pixclock %lu kHz hfreq %lu.%lu kHz vfreq %lu.%lu Hz\n",
fbdev->vram_size, fbdev->vram_size,
...@@ -1306,9 +1375,6 @@ cleanup: ...@@ -1306,9 +1375,6 @@ cleanup:
return r; return r;
} }
static struct platform_device *fbdev_pdev;
static struct lcd_panel *fbdev_panel;
static int omapfb_probe(struct platform_device *pdev) static int omapfb_probe(struct platform_device *pdev)
{ {
BUG_ON(fbdev_pdev != NULL); BUG_ON(fbdev_pdev != NULL);
......
...@@ -182,6 +182,7 @@ struct omap_dsp_varinfo { ...@@ -182,6 +182,7 @@ struct omap_dsp_varinfo {
#define OMAP_DSP_MBCMD_KFUNC_FBCTL 0x00 #define OMAP_DSP_MBCMD_KFUNC_FBCTL 0x00
#define OMAP_DSP_MBCMD_FBCTL_UPD 0x0000
#define OMAP_DSP_MBCMD_FBCTL_ENABLE 0x0002 #define OMAP_DSP_MBCMD_FBCTL_ENABLE 0x0002
#define OMAP_DSP_MBCMD_FBCTL_DISABLE 0x0003 #define OMAP_DSP_MBCMD_FBCTL_DISABLE 0x0003
......
...@@ -215,6 +215,15 @@ struct lcd_ctrl_extif { ...@@ -215,6 +215,15 @@ struct lcd_ctrl_extif {
unsigned long max_transmit_size; unsigned long max_transmit_size;
}; };
struct omapfb_notifier_block {
struct notifier_block nb;
void *data;
};
typedef int (*omapfb_notifier_callback_t)(struct omapfb_notifier_block *,
unsigned long event,
struct omapfb_device *fbdev);
struct lcd_ctrl { struct lcd_ctrl {
const char *name; const char *name;
void *data; void *data;
...@@ -222,6 +231,7 @@ struct lcd_ctrl { ...@@ -222,6 +231,7 @@ struct lcd_ctrl {
int (*init) (struct omapfb_device *fbdev, int (*init) (struct omapfb_device *fbdev,
int ext_mode, int req_vram_size); int ext_mode, int req_vram_size);
void (*cleanup) (void); void (*cleanup) (void);
void (*bind_client) (struct omapfb_notifier_block *nb);
void (*get_vram_layout)(unsigned long *size, void (*get_vram_layout)(unsigned long *size,
void **virt_base, void **virt_base,
dma_addr_t *phys_base); dma_addr_t *phys_base);
...@@ -285,6 +295,9 @@ struct omapfb_platform_data { ...@@ -285,6 +295,9 @@ struct omapfb_platform_data {
struct omap_fbmem_config fbmem; struct omap_fbmem_config fbmem;
}; };
#define OMAPFB_EVENT_READY 1
#define OMAPFB_EVENT_DISABLED 2
#ifdef CONFIG_ARCH_OMAP1 #ifdef CONFIG_ARCH_OMAP1
extern struct lcd_ctrl omap1_lcd_ctrl; extern struct lcd_ctrl omap1_lcd_ctrl;
#else #else
...@@ -293,6 +306,15 @@ extern struct lcd_ctrl omap2_disp_ctrl; ...@@ -293,6 +306,15 @@ extern struct lcd_ctrl omap2_disp_ctrl;
extern void omapfb_register_panel(struct lcd_panel *panel); extern void omapfb_register_panel(struct lcd_panel *panel);
extern void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval); 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 omapfb_update_window *win,
void (*callback)(void *),
void *callback_data);
/* in arch/arm/plat-omap/devices.c */ /* in arch/arm/plat-omap/devices.c */
extern void omapfb_reserve_mem(void); 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