#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
-#include <linux/vmalloc.h>
-#include <linux/dma-mapping.h>
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
-#include <linux/wait.h>
#include <linux/platform_device.h>
-#include <linux/clk.h>
#include <linux/spinlock.h>
#include <linux/io.h>
-#include <linux/uaccess.h>
+#include <linux/mfd/glamo.h>
#include <asm/div64.h>
#include "glamo-regs.h"
#include "glamo-core.h"
-#ifndef DEBUG
-#define GLAMO_LOG(...)
-#else
-#define GLAMO_LOG(...) \
-do { \
- printk(KERN_DEBUG "in %s:%s:%d", __FILE__, __func__, __LINE__); \
- printk(KERN_DEBUG __VA_ARGS__); \
-} while (0);
-#endif
-
static void glamofb_program_mode(struct glamofb_handle* glamo);
struct glamofb_handle {
+ struct glamo_core *core;
struct fb_info *fb;
struct device *dev;
struct resource *reg;
struct resource *fb_res;
char __iomem *base;
- struct glamofb_platform_data *mach_info;
+ struct glamo_fb_platform_data *mach_info;
char __iomem *cursor_addr;
int cursor_on;
u_int32_t pseudo_pal[16];
int output_enabled; /* 0 if the video output is disabled */
};
-/* 'sibling' spi device for lcm init */
-static struct platform_device glamo_spi_dev = {
- .name = "glamo-lcm-spi",
-};
-
static void glamo_output_enable(struct glamofb_handle *gfb) {
- struct glamo_core *gcore = gfb->mach_info->glamo;
+ struct glamo_core *gcore = gfb->core;
if (gfb->output_enabled)
return;
}
static void glamo_output_disable(struct glamofb_handle *gfb) {
- struct glamo_core *gcore = gfb->mach_info->glamo;
+ struct glamo_core *gcore = gfb->core;
if (!gfb->output_enabled)
return;
{
int i;
- if (glamo->mach_info->glamo->suspending) {
- dev_err(&glamo->mach_info->glamo->pdev->dev,
+ if (glamo->core->suspending) {
+ dev_err(&glamo->core->pdev->dev,
"IGNORING glamofb_run_script while "
"suspended\n");
return -EBUSY;
{
struct glamofb_handle *glamo = info->par;
- if (glamo->mach_info->glamo->suspending) {
- dev_err(&glamo->mach_info->glamo->pdev->dev,
+ if (glamo->core->suspending) {
+ dev_err(&glamo->core->pdev->dev,
"IGNORING glamofb_check_var while "
"suspended\n");
return -EBUSY;
{
int glamo_rot;
- if (glamo->mach_info->glamo->suspending) {
- dev_err(&glamo->mach_info->glamo->pdev->dev,
+ if (glamo->core->suspending) {
+ dev_err(&glamo->core->pdev->dev,
"IGNORING rotate_lcd while "
"suspended\n");
return;
static void glamofb_program_mode(struct glamofb_handle* gfb) {
int sync, bp, disp, fp, total;
unsigned long flags;
- struct glamo_core *gcore = gfb->mach_info->glamo;
+ struct glamo_core *gcore = gfb->core;
struct fb_var_screeninfo *var = &gfb->fb->var;
dev_dbg(&gcore->pdev->dev,
if (var->pixclock)
glamo_engine_reclock(gcore,
GLAMO_ENGINE_LCD,
- gfb->fb->var.pixclock);
+ (1000000000UL / gfb->fb->var.pixclock) * 1000);
reg_set_bit_mask(gfb,
GLAMO_REG_LCD_WIDTH,
static struct fb_videomode *glamofb_find_mode(struct fb_info *info,
struct fb_var_screeninfo *var) {
struct glamofb_handle *glamo = info->par;
- struct glamofb_platform_data *mach_info = glamo->mach_info;
+ struct glamo_fb_platform_data *mach_info = glamo->mach_info;
struct fb_videomode *mode;
int i;
struct fb_var_screeninfo *var = &info->var;
struct fb_videomode *mode;
- if (glamo->mach_info->glamo->suspending) {
- dev_err(&glamo->mach_info->glamo->pdev->dev,
+ if (glamo->core->suspending) {
+ dev_err(&glamo->core->pdev->dev,
"IGNORING glamofb_set_par while "
"suspended\n");
return -EBUSY;
struct glamofb_handle *glamo = info->par;
unsigned int val;
- if (glamo->mach_info->glamo->suspending) {
- dev_err(&glamo->mach_info->glamo->pdev->dev,
+ if (glamo->core->suspending) {
+ dev_err(&glamo->core->pdev->dev,
"IGNORING glamofb_set_par while "
"suspended\n");
return -EBUSY;
return 0;
}
+static int glamofb_ioctl(struct fb_info *info, unsigned int cmd,
+ unsigned long arg) {
+ struct glamofb_handle *gfb = (struct glamofb_handle*)info->par;
+ struct glamo_core *gcore = gfb->core;
+ int retval = -ENOTTY;
+
+ switch (cmd) {
+ case GLAMOFB_ENGINE_ENABLE:
+ retval = glamo_engine_enable(gcore, arg);
+ break;
+ case GLAMOFB_ENGINE_DISABLE:
+ retval = glamo_engine_disable(gcore, arg);
+ break;
+ case GLAMOFB_ENGINE_RESET:
+ glamo_engine_reset(gcore, arg);
+ retval = 0;
+ break;
+ default:
+ break;
+ }
+
+ return retval;
+}
+
+
#ifdef CONFIG_MFD_GLAMO_HWACCEL
static inline void glamofb_vsync_wait(struct glamofb_handle *glamo,
int line, int size, int range)
{
int timeout = 2000000;
- if (gfb->mach_info->glamo->suspending) {
- dev_err(&gfb->mach_info->glamo->pdev->dev,
+ if (gfb->core->suspending) {
+ dev_err(&gfb->core->pdev->dev,
"IGNORING glamofb_cmd_mode while "
"suspended\n");
return -EBUSY;
dev_dbg(gfb->dev, "%s: waiting for cmdq empty: ",
__func__);
while ((!glamofb_cmdq_empty(gfb)) && (timeout--))
- yield();
+ cpu_relax();
if (timeout < 0) {
printk(KERN_ERR"*************"
"glamofb cmd_queue never got empty"
timeout = 2000000;
while ((!reg_read(gfb, GLAMO_REG_LCD_STATUS2) & (1 << 12)) &&
(timeout--))
- /* yield() */;
+ cpu_relax();
if (timeout < 0) {
printk(KERN_ERR"*************"
"glamofb lcd never idle"
{
int timeout = 200000;
- if (gfb->mach_info->glamo->suspending) {
- dev_err(&gfb->mach_info->glamo->pdev->dev,
+ if (gfb->core->suspending) {
+ dev_err(&gfb->core->pdev->dev,
"IGNORING glamofb_cmd_write while "
"suspended\n");
return -EBUSY;
.fb_set_par = glamofb_set_par,
.fb_blank = glamofb_blank,
.fb_setcolreg = glamofb_setcolreg,
+ .fb_ioctl = glamofb_ioctl,
#ifdef CONFIG_MFD_GLAMO_HWACCEL
.fb_cursor = glamofb_cursor,
#endif
int rc = -EIO;
struct fb_info *fbinfo;
struct glamofb_handle *glamofb;
- struct glamofb_platform_data *mach_info = pdev->dev.platform_data;
+ struct glamo_core *core = dev_get_drvdata(pdev->dev.parent);
+ struct glamo_fb_platform_data *mach_info;
printk(KERN_INFO "SMEDIA Glamo frame buffer driver (C) 2007 "
"Openmoko, Inc.\n");
+ if (!core->pdata || !core->pdata->fb_data)
+ return -ENOENT;
+
+
fbinfo = framebuffer_alloc(sizeof(struct glamofb_handle), &pdev->dev);
if (!fbinfo)
return -ENOMEM;
+
glamofb = fbinfo->par;
glamofb->fb = fbinfo;
glamofb->dev = &pdev->dev;
}
glamofb->fb_res = request_mem_region(glamofb->fb_res->start,
- mach_info->fb_mem_size,
+ resource_size(glamofb->fb_res),
pdev->name);
if (!glamofb->fb_res) {
dev_err(&pdev->dev, "failed to request vram region\n");
dev_err(&pdev->dev, "failed to ioremap() mmio memory\n");
goto out_release_fb;
}
+
fbinfo->fix.smem_start = (unsigned long) glamofb->fb_res->start;
fbinfo->fix.smem_len = (__u32) resource_size(glamofb->fb_res);
platform_set_drvdata(pdev, glamofb);
- glamofb->mach_info = pdev->dev.platform_data;
+ mach_info = core->pdata->fb_data;
+ glamofb->core = core;
+ glamofb->mach_info = mach_info;
fbinfo->fix.visual = FB_VISUAL_TRUECOLOR;
fbinfo->fix.type = FB_TYPE_PACKED_PIXELS;
fbinfo->var.accel_flags = 0;
fbinfo->var.vmode = FB_VMODE_NONINTERLACED;
- glamo_engine_enable(mach_info->glamo, GLAMO_ENGINE_LCD);
- glamo_engine_reset(mach_info->glamo, GLAMO_ENGINE_LCD);
+ glamo_engine_enable(core, GLAMO_ENGINE_LCD);
+ glamo_engine_reset(core, GLAMO_ENGINE_LCD);
glamofb->output_enabled = 1;
glamofb->mode_set = 1;
goto out_unmap_fb;
}
- if (mach_info->spi_info) {
- /* register the sibling spi device */
- mach_info->spi_info->glamofb_handle = glamofb;
- glamo_spi_dev.dev.parent = &pdev->dev;
- glamo_spi_dev.dev.platform_data = mach_info->spi_info;
- platform_device_register(&glamo_spi_dev);
- }
-
printk(KERN_INFO "fb%d: %s frame buffer device\n",
fbinfo->node, fbinfo->fix.id);
#ifdef CONFIG_PM
-static int glamofb_suspend(struct platform_device *pdev, pm_message_t state)
+static int glamofb_suspend(struct device *dev)
{
- struct glamofb_handle *gfb = platform_get_drvdata(pdev);
+ struct glamofb_handle *gfb = dev_get_drvdata(dev);
/* we need to stop anything touching our framebuffer */
fb_set_suspend(gfb->fb, 1);
return 0;
}
-static int glamofb_resume(struct platform_device *pdev)
+static int glamofb_resume(struct device *dev)
{
- struct glamofb_handle *gfb = platform_get_drvdata(pdev);
- struct glamofb_platform_data *mach_info = pdev->dev.platform_data;
+ struct glamofb_handle *gfb = dev_get_drvdata(dev);
/* OK let's allow framebuffer ops again */
/* gfb->fb->screen_base = ioremap(gfb->fb_res->start,
resource_size(gfb->fb_res)); */
- glamo_engine_enable(mach_info->glamo, GLAMO_ENGINE_LCD);
- glamo_engine_reset(mach_info->glamo, GLAMO_ENGINE_LCD);
+ glamo_engine_enable(gfb->core, GLAMO_ENGINE_LCD);
+ glamo_engine_reset(gfb->core, GLAMO_ENGINE_LCD);
- printk(KERN_ERR"spin_lock_init\n");
- spin_lock_init(&gfb->lock_cmd);
glamofb_init_regs(gfb);
#ifdef CONFIG_MFD_GLAMO_HWACCEL
glamofb_cursor_onoff(gfb, 1);
return 0;
}
+
+static struct dev_pm_ops glamofb_pm_ops = {
+ .suspend = glamofb_suspend,
+ .resume = glamofb_resume,
+};
+
+#define GLAMOFB_PM_OPS (&glamofb_pm_ops)
+
#else
-#define glamofb_suspend NULL
-#define glamofb_resume NULL
+#define GLAMOFB_PM_OPS NULL
#endif
static struct platform_driver glamofb_driver = {
.probe = glamofb_probe,
.remove = glamofb_remove,
- .suspend = glamofb_suspend,
- .resume = glamofb_resume,
.driver = {
.name = "glamo-fb",
.owner = THIS_MODULE,
+ .pm = GLAMOFB_PM_OPS
},
};