/* linux/drivers/video/s3c-fb.c
*
* Copyright 2008 Openmoko Inc.
* Copyright 2008-2010 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* Samsung SoC Framebuffer driver
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/fb.h>
#include <linux/io.h>
#include <mach/map.h>
#include <mach/regs-fb.h>
#include <plat/fb.h>
/* This driver will export a number of framebuffer interfaces depending
* on the configuration passed in via the platform data. Each fb instance
* maps to a hardware window. Currently there is no support for runtime
* setting of the alpha-blending functions that each window has, so only
* window 0 is actually useful.
*
* Window 0 is treated specially, it is used for the basis of the LCD
* output timings and as the control for the output power-down state.
*/
/* note, the previous use of <mach/regs-fb.h> to get platform specific data
* has been replaced by using the platform device name to pick the correct
* configuration data for the system.
*/
#ifdef CONFIG_FB_S3C_DEBUG_REGWRITE
#undef writel
#define writel(v, r) do { \
printk(KERN_DEBUG "%s: %08x => %p\n", __func__, (unsigned int)v, r); \
__raw_writel(v, r); } while(0)
#endif /* FB_S3C_DEBUG_REGWRITE */
struct s3c_fb;
#define VALID_BPP(x) (1 << ((x) - 1))
/**
* struct s3c_fb_variant - fb variant information
* @nr_windows: The number of windows.
* @palette: Address of palette memory, or 0 if none.
*/
struct s3c_fb_variant {
unsigned short nr_windows;
unsigned short palette[S3C_FB_MAX_WIN];
};
/**
* struct s3c_fb_win_variant
* @has_osd_c: Set if has OSD C register.
* @has_osd_d: Set if has OSD D register.
* @palette_sz: Size of palette in entries.
* @palette_16bpp: Set if palette is 16bits wide.
* @valid_bpp: 1 bit per BPP setting to show valid bits-per-pixel.
*
* valid_bpp bit x is set if (x+1)BPP is supported.
*/
struct s3c_fb_win_variant {
unsigned int has_osd_c:1;
unsigned int has_osd_d:1;
unsigned int palette_16bpp:1;
unsigned short palette_sz;
u32 valid_bpp;
};
/**
* struct s3c_fb_driverdata - per-device type driver data for init time.
* @variant: The variant information for this driver.
* @win: The window information for each window.
*/
struct s3c_fb_driverdata {
struct s3c_fb_variant variant;
struct s3c_fb_win_variant *win[S3C_FB_MAX_WIN];
};
/**
* struct s3c_fb_win - per window private data for each framebuffer.
* @windata: The platform data supplied for the window configuration.
* @parent: The hardware that this window is part of.
* @fbinfo: Pointer pack to the framebuffer info for this window.
* @varint: The variant information for this window.
* @palette_buffer: Buffer/cache to hold palette entries.
* @pseudo_palette: For use in TRUECOLOUR modes for entries 0..15/
* @index: The window number of this window.
* @palette: The bitfields for changing r/g/b into a hardware palette entry.
*/
struct s3c_fb_win {
struct s3c_fb_pd_win *windata;
struct s3c_fb *parent;
struct fb_info *fbinfo;
struct s3c_fb_palette palette;
struct s3c_fb_win_variant variant;
u32 *palette_buffer;
u32 pseudo_palette[16];
unsigned int index;
};
/**
* struct s3c_fb - overall hardware state of the hardware
* @dev: The device that we bound to, for printing, etc.
* @regs_res: The resource we claimed for the IO registers.
* @bus_clk: The clk (hclk) feeding our interface and possibly pixclk.
* @regs: The mapped hardware registers.
* @variant: Variant information for this hardware.
* @enabled: A bitmask of enabled hardware windows.
* @pdata: The platform configuration data passed with the device.
* @windows: The hardware windows that have been claimed.
*/
struct s3c_fb {
struct device *dev;
struct resource *regs_res;
struct clk *bus_clk;
void __iomem *regs;
struct s3c_fb_variant variant;
unsigned char enabled;
struct s3c_fb_platdata *pdata;
struct s3c_fb_win *windows[S3C_FB_MAX_WIN];
};
/**
* s3c_fb_validate_win_bpp - validate the bits-per-pixel for this mode.
* @win: The device window.
* @bpp: The bit depth.
*/
static bool s3c_fb_validate_win_bpp(struct s3c_fb_win *win, unsigned int bpp)
{
return win->variant.valid_bpp & VALID_BPP(bpp);
}
/**
* s3c_fb_check_var() - framebuffer layer request to verify a given mode.
* @var: The screen information to verify.
* @info: The framebuffer device.
*
* Framebuffer layer call to verify the given information and allow us to
* update various information depending on the hardware capabilities.
*/
static int s3c_fb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info)
{
struct s3c_fb_win