[ARM] 3454/1: ARM: OMAP: 6/8 Update framebuffer low-level init code, take 2

Patch from Tony Lindgren

Update OMAP framebuffer low-level init code from linux-omap tree
by Imre Deak.

Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index a4e5ac7..5dac423 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -1258,6 +1258,11 @@
 	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
 }
 
+int omap_lcd_dma_ext_running(void)
+{
+	return lcd_dma.ext_ctrl && lcd_dma.active;
+}
+
 /*----------------------------------------------------------------------------*/
 
 static int __init omap_init_dma(void)
@@ -1389,6 +1394,7 @@
 EXPORT_SYMBOL(omap_enable_lcd_dma);
 EXPORT_SYMBOL(omap_setup_lcd_dma);
 EXPORT_SYMBOL(omap_stop_lcd_dma);
+EXPORT_SYMBOL(omap_lcd_dma_ext_running);
 EXPORT_SYMBOL(omap_set_lcd_dma_b1);
 EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer);
 EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller);
diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c
new file mode 100644
index 0000000..305e9b9
--- /dev/null
+++ b/arch/arm/plat-omap/fb.c
@@ -0,0 +1,80 @@
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/bootmem.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/board.h>
+#include <asm/arch/sram.h>
+#include <asm/arch/omapfb.h>
+
+#if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE)
+
+static struct omapfb_platform_data omapfb_config;
+
+static u64 omap_fb_dma_mask = ~(u32)0;
+
+static struct platform_device omap_fb_device = {
+	.name		= "omapfb",
+	.id		= -1,
+	.dev = {
+		.dma_mask		= &omap_fb_dma_mask,
+		.coherent_dma_mask	= ~(u32)0,
+		.platform_data		= &omapfb_config,
+	},
+	.num_resources = 0,
+};
+
+/* called from map_io */
+void omapfb_reserve_mem(void)
+{
+	const struct omap_fbmem_config *fbmem_conf;
+
+	omapfb_config.fbmem.fb_sram_start = omap_fb_sram_start;
+	omapfb_config.fbmem.fb_sram_size = omap_fb_sram_size;
+
+	fbmem_conf = omap_get_config(OMAP_TAG_FBMEM, struct omap_fbmem_config);
+
+	if (fbmem_conf != NULL) {
+		/* indicate that the bootloader already initialized the
+		 * fb device, so we'll skip that part in the fb driver
+		 */
+		omapfb_config.fbmem.fb_sdram_start = fbmem_conf->fb_sdram_start;
+		omapfb_config.fbmem.fb_sdram_size = fbmem_conf->fb_sdram_size;
+		if (fbmem_conf->fb_sdram_size) {
+			pr_info("Reserving %u bytes SDRAM for frame buffer\n",
+				fbmem_conf->fb_sdram_size);
+			reserve_bootmem(fbmem_conf->fb_sdram_start,
+					fbmem_conf->fb_sdram_size);
+		}
+	}
+}
+
+static inline int omap_init_fb(void)
+{
+	const struct omap_lcd_config *conf;
+
+	conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);
+	if (conf == NULL)
+		return 0;
+
+	omapfb_config.lcd = *conf;
+
+	return platform_device_register(&omap_fb_device);
+}
+
+arch_initcall(omap_init_fb);
+
+#else
+
+void omapfb_reserve_mem(void) {}
+
+#endif
+
+
diff --git a/include/asm-arm/arch-omap/dma.h b/include/asm-arm/arch-omap/dma.h
index d4e73ef..ca120231 100644
--- a/include/asm-arm/arch-omap/dma.h
+++ b/include/asm-arm/arch-omap/dma.h
@@ -404,6 +404,7 @@
 extern void omap_setup_lcd_dma(void);
 extern void omap_enable_lcd_dma(void);
 extern void omap_stop_lcd_dma(void);
+extern int  omap_lcd_dma_ext_running(void);
 extern void omap_set_lcd_dma_ext_controller(int external);
 extern void omap_set_lcd_dma_single_transfer(int single);
 extern void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
diff --git a/include/asm-arm/arch-omap/lcd_lph8923.h b/include/asm-arm/arch-omap/lcd_lph8923.h
new file mode 100644
index 0000000..004e67e
--- /dev/null
+++ b/include/asm-arm/arch-omap/lcd_lph8923.h
@@ -0,0 +1,14 @@
+#ifndef __LCD_LPH8923_H
+#define __LCD_LPH8923_H
+
+enum lcd_lph8923_test_num {
+	LCD_LPH8923_TEST_RGB_LINES,
+};
+
+enum lcd_lph8923_test_result {
+	LCD_LPH8923_TEST_SUCCESS,
+	LCD_LPH8923_TEST_INVALID,
+	LCD_LPH8923_TEST_FAILED,
+};
+
+#endif
diff --git a/include/asm-arm/arch-omap/omapfb.h b/include/asm-arm/arch-omap/omapfb.h
index 4ba2622..fccdb3d 100644
--- a/include/asm-arm/arch-omap/omapfb.h
+++ b/include/asm-arm/arch-omap/omapfb.h
@@ -34,9 +34,10 @@
 #define OMAPFB_MIRROR		OMAP_IOW(31, int)
 #define OMAPFB_SYNC_GFX		OMAP_IO(37)
 #define OMAPFB_VSYNC		OMAP_IO(38)
-#define OMAPFB_SET_UPDATE_MODE	OMAP_IOW(40, enum omapfb_update_mode)
+#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, enum omapfb_update_mode)
+#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)
@@ -66,9 +67,14 @@
 };
 
 struct omapfb_update_window {
-	u32 x, y;
-	u32 width, height;
-	u32 format;
+	__u32 x, y;
+	__u32 width, height;
+	__u32 format;
+};
+
+struct omapfb_update_window_old {
+	__u32 x, y;
+	__u32 width, height;
 };
 
 enum omapfb_plane {
@@ -83,17 +89,17 @@
 };
 
 struct omapfb_setup_plane {
-	u8  plane;
-	u8  channel_out;
-	u32 offset;
-	u32 pos_x, pos_y;
-	u32 width, height;
-	u32 color_mode;
+	__u8  plane;
+	__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  plane;
+	__u8  enable;
 };
 
 enum omapfb_color_key_type {
@@ -103,10 +109,10 @@
 };
 
 struct omapfb_color_key {
-	u8  channel_out;
-	u32 background;
-	u32 trans_key;
-	u8  key_type;
+	__u8  channel_out;
+	__u32 background;
+	__u32 trans_key;
+	__u8  key_type;
 };
 
 enum omapfb_update_mode {
@@ -120,6 +126,9 @@
 #include <linux/completion.h>
 #include <linux/interrupt.h>
 #include <linux/fb.h>
+#include <linux/mutex.h>
+
+#include <asm/arch/board.h>
 
 #define OMAP_LCDC_INV_VSYNC             0x0001
 #define OMAP_LCDC_INV_HSYNC             0x0002
@@ -184,19 +193,38 @@
 	int re_cycle_time;
 	int cs_pulse_width;
 	int access_time;
+
+	int clk_div;
+
+	u32 tim[5];		/* set by extif->convert_timings */
+
+	int converted;
 };
 
 struct lcd_ctrl_extif {
 	int  (*init)		(void);
 	void (*cleanup)		(void);
+	void (*get_clk_info)	(u32 *clk_period, u32 *max_clk_div);
+	int  (*convert_timings)	(struct extif_timings *timings);
 	void (*set_timings)	(const struct extif_timings *timings);
-	void (*write_command)	(u32 cmd);
-	u32  (*read_data)	(void);
-	void (*write_data)	(u32 data);
+	void (*set_bits_per_cycle)(int bpc);
+	void (*write_command)	(const void *buf, unsigned int len);
+	void (*read_data)	(void *buf, unsigned int len);
+	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;
+};
+
+typedef int (*omapfb_notifier_callback_t)(struct omapfb_notifier_block *,
+					   unsigned long event,
+					   struct omapfb_device *fbdev);
+
 struct lcd_ctrl {
 	const char	*name;
 	void		*data;
@@ -204,9 +232,11 @@
 	int		(*init)		  (struct omapfb_device *fbdev,
 					   int ext_mode, int req_vram_size);
 	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);
@@ -240,7 +270,7 @@
 	int			state;
 	int                     ext_lcdc;               /* Using external
                                                            LCD controller */
-	struct semaphore	rqueue_sema;
+	struct mutex		rqueue_mutex;
 
 	void			*vram_virt_base;
 	dma_addr_t		vram_phys_base;
@@ -261,12 +291,13 @@
 	struct device		*dev;
 };
 
-extern struct lcd_panel h3_panel;
-extern struct lcd_panel h2_panel;
-extern struct lcd_panel p2_panel;
-extern struct lcd_panel osk_panel;
-extern struct lcd_panel innovator1610_panel;
-extern struct lcd_panel innovator1510_panel;
+struct omapfb_platform_data {
+	struct omap_lcd_config   lcd;
+	struct omap_fbmem_config fbmem;
+};
+
+#define OMAPFB_EVENT_READY	1
+#define OMAPFB_EVENT_DISABLED	2
 
 #ifdef CONFIG_ARCH_OMAP1
 extern struct lcd_ctrl omap1_lcd_ctrl;
@@ -274,7 +305,20 @@
 extern struct lcd_ctrl omap2_disp_ctrl;
 #endif
 
+extern void omapfb_register_panel(struct lcd_panel *panel);
 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 */
+extern void omapfb_reserve_mem(void);
 
 #endif /* __KERNEL__ */