s3c-fb.c revision ff8c91072389491375f6d1ea86ce55942c460a04
1ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/* linux/drivers/video/s3c-fb.c 2ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 3ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Copyright 2008 Openmoko Inc. 450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * Copyright 2008-2010 Simtec Electronics 5ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Ben Dooks <ben@simtec.co.uk> 6ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * http://armlinux.simtec.co.uk/ 7ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 8ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Samsung SoC Framebuffer driver 9ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 10ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * This program is free software; you can redistribute it and/or modify 11ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * it under the terms of the GNU General Public License version 2 as 12c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks * published by the Free Software FoundatIon. 13ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks*/ 14ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 15ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks#include <linux/kernel.h> 16ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks#include <linux/module.h> 17ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks#include <linux/platform_device.h> 18ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks#include <linux/dma-mapping.h> 195a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 20ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks#include <linux/init.h> 21ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks#include <linux/clk.h> 22ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks#include <linux/fb.h> 23ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks#include <linux/io.h> 24efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak#include <linux/uaccess.h> 25efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak#include <linux/interrupt.h> 264959212c18669f254daa0ae796ad676b67939ba2Jingoo Han#include <linux/pm_runtime.h> 27ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 28ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks#include <mach/map.h> 29c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks#include <plat/regs-fb-v4.h> 30ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks#include <plat/fb.h> 31ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 32ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/* This driver will export a number of framebuffer interfaces depending 33ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * on the configuration passed in via the platform data. Each fb instance 34ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * maps to a hardware window. Currently there is no support for runtime 35ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * setting of the alpha-blending functions that each window has, so only 36ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * window 0 is actually useful. 37ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 38ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Window 0 is treated specially, it is used for the basis of the LCD 39ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * output timings and as the control for the output power-down state. 40ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks*/ 41ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 4250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks/* note, the previous use of <mach/regs-fb.h> to get platform specific data 4350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * has been replaced by using the platform device name to pick the correct 4450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * configuration data for the system. 45ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks*/ 46ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 47ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks#ifdef CONFIG_FB_S3C_DEBUG_REGWRITE 48ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks#undef writel 49ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks#define writel(v, r) do { \ 50ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks printk(KERN_DEBUG "%s: %08x => %p\n", __func__, (unsigned int)v, r); \ 51b73a21fc66fee35b41db755abebfacba48b2fc76Jingoo Han __raw_writel(v, r); } while (0) 52ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks#endif /* FB_S3C_DEBUG_REGWRITE */ 53ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 54efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak/* irq_flags bits */ 55efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak#define S3C_FB_VSYNC_IRQ_EN 0 56efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 57efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak#define VSYNC_TIMEOUT_MSEC 50 58efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 59ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstruct s3c_fb; 60ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 6150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks#define VALID_BPP(x) (1 << ((x) - 1)) 6250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 63c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks#define OSD_BASE(win, variant) ((variant).osd + ((win) * (variant).osd_stride)) 64c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks#define VIDOSD_A(win, variant) (OSD_BASE(win, variant) + 0x00) 65c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks#define VIDOSD_B(win, variant) (OSD_BASE(win, variant) + 0x04) 66c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks#define VIDOSD_C(win, variant) (OSD_BASE(win, variant) + 0x08) 67c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks#define VIDOSD_D(win, variant) (OSD_BASE(win, variant) + 0x0C) 68c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks 6950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks/** 7050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * struct s3c_fb_variant - fb variant information 71c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks * @is_2443: Set if S3C2443/S3C2416 style hardware. 7250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @nr_windows: The number of windows. 73c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks * @vidtcon: The base for the VIDTCONx registers 74c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks * @wincon: The base for the WINxCON registers. 75c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks * @winmap: The base for the WINxMAP registers. 76c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks * @keycon: The abse for the WxKEYCON registers. 77c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks * @buf_start: Offset of buffer start registers. 78c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks * @buf_size: Offset of buffer size registers. 79c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks * @buf_end: Offset of buffer end registers. 80c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks * @osd: The base for the OSD registers. 8150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @palette: Address of palette memory, or 0 if none. 82067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak * @has_prtcon: Set if has PRTCON register. 83f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak * @has_shadowcon: Set if has SHADOWCON register. 84b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han * @has_clksel: Set if VIDCON0 register has CLKSEL bit. 8550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks */ 8650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooksstruct s3c_fb_variant { 87c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks unsigned int is_2443:1; 8850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks unsigned short nr_windows; 89c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks unsigned short vidtcon; 90c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks unsigned short wincon; 91c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks unsigned short winmap; 92c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks unsigned short keycon; 93c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks unsigned short buf_start; 94c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks unsigned short buf_end; 95c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks unsigned short buf_size; 96c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks unsigned short osd; 97c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks unsigned short osd_stride; 9850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks unsigned short palette[S3C_FB_MAX_WIN]; 99067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak 100067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak unsigned int has_prtcon:1; 101f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak unsigned int has_shadowcon:1; 102b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han unsigned int has_clksel:1; 10350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks}; 10450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 10550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks/** 10650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * struct s3c_fb_win_variant 10750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @has_osd_c: Set if has OSD C register. 10850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @has_osd_d: Set if has OSD D register. 109f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak * @has_osd_alpha: Set if can change alpha transparency for a window. 11050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @palette_sz: Size of palette in entries. 11150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @palette_16bpp: Set if palette is 16bits wide. 112f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak * @osd_size_off: If != 0, supports setting up OSD for a window; the appropriate 113f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak * register is located at the given offset from OSD_BASE. 11450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @valid_bpp: 1 bit per BPP setting to show valid bits-per-pixel. 11550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * 11650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * valid_bpp bit x is set if (x+1)BPP is supported. 11750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks */ 11850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooksstruct s3c_fb_win_variant { 11950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks unsigned int has_osd_c:1; 12050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks unsigned int has_osd_d:1; 121f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak unsigned int has_osd_alpha:1; 12250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks unsigned int palette_16bpp:1; 123f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak unsigned short osd_size_off; 12450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks unsigned short palette_sz; 12550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks u32 valid_bpp; 12650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks}; 12750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 12850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks/** 12950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * struct s3c_fb_driverdata - per-device type driver data for init time. 13050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @variant: The variant information for this driver. 13150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @win: The window information for each window. 13250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks */ 13350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooksstruct s3c_fb_driverdata { 13450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks struct s3c_fb_variant variant; 13550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks struct s3c_fb_win_variant *win[S3C_FB_MAX_WIN]; 13650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks}; 13750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 138ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 139bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks * struct s3c_fb_palette - palette information 140bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks * @r: Red bitfield. 141bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks * @g: Green bitfield. 142bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks * @b: Blue bitfield. 143bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks * @a: Alpha bitfield. 144bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks */ 145bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooksstruct s3c_fb_palette { 146bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks struct fb_bitfield r; 147bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks struct fb_bitfield g; 148bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks struct fb_bitfield b; 149bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks struct fb_bitfield a; 150bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks}; 151bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks 152bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks/** 153ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * struct s3c_fb_win - per window private data for each framebuffer. 154ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @windata: The platform data supplied for the window configuration. 155ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @parent: The hardware that this window is part of. 156ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @fbinfo: Pointer pack to the framebuffer info for this window. 15750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @varint: The variant information for this window. 158ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @palette_buffer: Buffer/cache to hold palette entries. 159ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @pseudo_palette: For use in TRUECOLOUR modes for entries 0..15/ 160ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @index: The window number of this window. 161ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @palette: The bitfields for changing r/g/b into a hardware palette entry. 162ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 163ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstruct s3c_fb_win { 164ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_pd_win *windata; 165ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb *parent; 166ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct fb_info *fbinfo; 167ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_palette palette; 16850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks struct s3c_fb_win_variant variant; 169ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 170ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks u32 *palette_buffer; 171ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks u32 pseudo_palette[16]; 172ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks unsigned int index; 173ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks}; 174ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 175ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 176efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * struct s3c_fb_vsync - vsync information 177efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * @wait: a queue for processes waiting for vsync 178efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * @count: vsync interrupt count 179efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak */ 180efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciakstruct s3c_fb_vsync { 181efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak wait_queue_head_t wait; 182efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak unsigned int count; 183efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak}; 184efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 185efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak/** 186ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * struct s3c_fb - overall hardware state of the hardware 187b07f3bbee12163a6b48991138a37b87a1126462aJingoo Han * @slock: The spinlock protection for this data sturcture. 188ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @dev: The device that we bound to, for printing, etc. 189ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @regs_res: The resource we claimed for the IO registers. 190ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk. 191b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han * @lcd_clk: The clk (sclk) feeding pixclk. 192ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @regs: The mapped hardware registers. 19350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @variant: Variant information for this hardware. 194ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @enabled: A bitmask of enabled hardware windows. 195ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @pdata: The platform configuration data passed with the device. 196ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @windows: The hardware windows that have been claimed. 197efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * @irq_no: IRQ line number 198efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * @irq_flags: irq flags 199efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * @vsync_info: VSYNC-related information (count, queues...) 200ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 201ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstruct s3c_fb { 202b07f3bbee12163a6b48991138a37b87a1126462aJingoo Han spinlock_t slock; 203ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct device *dev; 204ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct resource *regs_res; 205ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct clk *bus_clk; 206b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han struct clk *lcd_clk; 207ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks void __iomem *regs; 20850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks struct s3c_fb_variant variant; 209ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 210ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks unsigned char enabled; 211ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 212ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_platdata *pdata; 213ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_win *windows[S3C_FB_MAX_WIN]; 214efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 215efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak int irq_no; 216efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak unsigned long irq_flags; 217efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak struct s3c_fb_vsync vsync_info; 218ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks}; 219ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 220ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 22150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * s3c_fb_validate_win_bpp - validate the bits-per-pixel for this mode. 22250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @win: The device window. 22350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @bpp: The bit depth. 224ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 22550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooksstatic bool s3c_fb_validate_win_bpp(struct s3c_fb_win *win, unsigned int bpp) 226ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 22750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks return win->variant.valid_bpp & VALID_BPP(bpp); 228ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 229ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 230ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 231ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_check_var() - framebuffer layer request to verify a given mode. 232ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @var: The screen information to verify. 233ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @info: The framebuffer device. 234ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 235ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Framebuffer layer call to verify the given information and allow us to 236ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * update various information depending on the hardware capabilities. 237ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 238ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic int s3c_fb_check_var(struct fb_var_screeninfo *var, 239ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct fb_info *info) 240ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 241ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_win *win = info->par; 242ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb *sfb = win->parent; 243ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 244ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(sfb->dev, "checking parameters\n"); 245ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 24613e6af8886f3225fb9141dc3b6915d84bd4ad4deJingoo Han var->xres_virtual = max(var->xres_virtual, var->xres); 24713e6af8886f3225fb9141dc3b6915d84bd4ad4deJingoo Han var->yres_virtual = max(var->yres_virtual, var->yres); 248ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 24950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks if (!s3c_fb_validate_win_bpp(win, var->bits_per_pixel)) { 250ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(sfb->dev, "win %d: unsupported bpp %d\n", 251ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks win->index, var->bits_per_pixel); 252ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return -EINVAL; 253ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 254ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 255ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* always ensure these are zero, for drop through cases below */ 256ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->transp.offset = 0; 257ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->transp.length = 0; 258ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 259ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks switch (var->bits_per_pixel) { 260ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 1: 261ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 2: 262ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 4: 263ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 8: 26450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks if (sfb->variant.palette[win->index] != 0) { 265ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* non palletised, A:1,R:2,G:3,B:2 mode */ 266ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->red.offset = 4; 267ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->green.offset = 2; 268ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->blue.offset = 0; 269ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->red.length = 5; 270ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->green.length = 3; 271ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->blue.length = 2; 272ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->transp.offset = 7; 273ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->transp.length = 1; 274ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } else { 275ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->red.offset = 0; 276ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->red.length = var->bits_per_pixel; 277ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->green = var->red; 278ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->blue = var->red; 279ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 280ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 281ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 282ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 19: 283ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* 666 with one bit alpha/transparency */ 284ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->transp.offset = 18; 285ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->transp.length = 1; 286ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 18: 287ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->bits_per_pixel = 32; 288ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 289ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* 666 format */ 290ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->red.offset = 12; 291ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->green.offset = 6; 292ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->blue.offset = 0; 293ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->red.length = 6; 294ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->green.length = 6; 295ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->blue.length = 6; 296ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 297ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 298ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 16: 299ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* 16 bpp, 565 format */ 300ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->red.offset = 11; 301ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->green.offset = 5; 302ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->blue.offset = 0; 303ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->red.length = 5; 304ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->green.length = 6; 305ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->blue.length = 5; 306ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 307ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 308af1ce6b2fad7d572aef040d61a935da28a861853Jingoo Han case 32: 309ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 28: 310ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 25: 311ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->transp.length = var->bits_per_pixel - 24; 312ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->transp.offset = 24; 313ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* drop through */ 314ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 24: 315ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* our 24bpp is unpacked, so 32bpp */ 316ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->bits_per_pixel = 32; 317ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->red.offset = 16; 318ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->red.length = 8; 319ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->green.offset = 8; 320ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->green.length = 8; 321ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->blue.offset = 0; 322ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->blue.length = 8; 323ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 324ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 325ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks default: 326ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_err(sfb->dev, "invalid bpp\n"); 327ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 328ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 329ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(sfb->dev, "%s: verified parameters\n", __func__); 330ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return 0; 331ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 332ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 333ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 334ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_calc_pixclk() - calculate the divider to create the pixel clock. 335ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @sfb: The hardware state. 336ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @pixclock: The pixel clock wanted, in picoseconds. 337ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 338ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Given the specified pixel clock, work out the necessary divider to get 339ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * close to the output frequency. 340ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 341eb29a5cc0b601c458bae9df2f6c3696d75c2d383Mark Brownstatic int s3c_fb_calc_pixclk(struct s3c_fb *sfb, unsigned int pixclk) 342ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 343b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han unsigned long clk; 344eb29a5cc0b601c458bae9df2f6c3696d75c2d383Mark Brown unsigned long long tmp; 345ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks unsigned int result; 346ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 347b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han if (sfb->variant.has_clksel) 348b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han clk = clk_get_rate(sfb->bus_clk); 349b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han else 350b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han clk = clk_get_rate(sfb->lcd_clk); 351b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han 352eb29a5cc0b601c458bae9df2f6c3696d75c2d383Mark Brown tmp = (unsigned long long)clk; 353eb29a5cc0b601c458bae9df2f6c3696d75c2d383Mark Brown tmp *= pixclk; 354eb29a5cc0b601c458bae9df2f6c3696d75c2d383Mark Brown 355eb29a5cc0b601c458bae9df2f6c3696d75c2d383Mark Brown do_div(tmp, 1000000000UL); 356eb29a5cc0b601c458bae9df2f6c3696d75c2d383Mark Brown result = (unsigned int)tmp / 1000; 357ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 358ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(sfb->dev, "pixclk=%u, clk=%lu, div=%d (%lu)\n", 359ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks pixclk, clk, result, clk / result); 360ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 361ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return result; 362ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 363ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 364ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 365ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_align_word() - align pixel count to word boundary 366ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @bpp: The number of bits per pixel 367ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @pix: The value to be aligned. 368ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 369ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Align the given pixel count so that it will start on an 32bit word 370ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * boundary. 371ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 372ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic int s3c_fb_align_word(unsigned int bpp, unsigned int pix) 373ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 374ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks int pix_per_word; 375ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 376ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (bpp > 16) 377ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return pix; 378ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 379ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks pix_per_word = (8 * 32) / bpp; 380ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return ALIGN(pix, pix_per_word); 381ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 382ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 383ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 384f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak * vidosd_set_size() - set OSD size for a window 385f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak * 386f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak * @win: the window to set OSD size for 387f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak * @size: OSD size register value 388f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak */ 389f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciakstatic void vidosd_set_size(struct s3c_fb_win *win, u32 size) 390f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak{ 391f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak struct s3c_fb *sfb = win->parent; 392f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak 393f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak /* OSD can be set up if osd_size_off != 0 for this window */ 394f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak if (win->variant.osd_size_off) 395f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak writel(size, sfb->regs + OSD_BASE(win->index, sfb->variant) 396f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak + win->variant.osd_size_off); 397f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak} 398f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak 399f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak/** 400f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak * vidosd_set_alpha() - set alpha transparency for a window 401f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak * 402f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak * @win: the window to set OSD size for 403f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak * @alpha: alpha register value 404f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak */ 405f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciakstatic void vidosd_set_alpha(struct s3c_fb_win *win, u32 alpha) 406f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak{ 407f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak struct s3c_fb *sfb = win->parent; 408f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak 409f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak if (win->variant.has_osd_alpha) 410f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak writel(alpha, sfb->regs + VIDOSD_C(win->index, sfb->variant)); 411f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak} 412f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak 413f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak/** 414f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak * shadow_protect_win() - disable updating values from shadow registers at vsync 415f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak * 416f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak * @win: window to protect registers for 417f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak * @protect: 1 to protect (disable updates) 418f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak */ 419f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciakstatic void shadow_protect_win(struct s3c_fb_win *win, bool protect) 420f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak{ 421f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak struct s3c_fb *sfb = win->parent; 422f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak u32 reg; 423f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak 424f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak if (protect) { 425f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak if (sfb->variant.has_prtcon) { 426f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak writel(PRTCON_PROTECT, sfb->regs + PRTCON); 427f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak } else if (sfb->variant.has_shadowcon) { 428f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak reg = readl(sfb->regs + SHADOWCON); 429f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak writel(reg | SHADOWCON_WINx_PROTECT(win->index), 430f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak sfb->regs + SHADOWCON); 431f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak } 432f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak } else { 433f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak if (sfb->variant.has_prtcon) { 434f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak writel(0, sfb->regs + PRTCON); 435f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak } else if (sfb->variant.has_shadowcon) { 436f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak reg = readl(sfb->regs + SHADOWCON); 437f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak writel(reg & ~SHADOWCON_WINx_PROTECT(win->index), 438f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak sfb->regs + SHADOWCON); 439f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak } 440f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak } 441f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak} 442f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak 443f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak/** 444ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_set_par() - framebuffer request to set new framebuffer state. 445ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @info: The framebuffer to change. 446ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 447ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Framebuffer layer request to set a new mode for the specified framebuffer 448ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 449ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic int s3c_fb_set_par(struct fb_info *info) 450ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 451ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct fb_var_screeninfo *var = &info->var; 452ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_win *win = info->par; 453ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb *sfb = win->parent; 454ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks void __iomem *regs = sfb->regs; 455c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks void __iomem *buf = regs; 456ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks int win_no = win->index; 457f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak u32 alpha = 0; 458ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks u32 data; 459ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks u32 pagewidth; 460ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks int clkdiv; 461ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 462ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(sfb->dev, "setting framebuffer parameters\n"); 463ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 464a8bdabca3ad69de632bd13f1cb65639e9a556e20Pawel Osciak shadow_protect_win(win, 1); 465a8bdabca3ad69de632bd13f1cb65639e9a556e20Pawel Osciak 466ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks switch (var->bits_per_pixel) { 467ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 32: 468ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 24: 469ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 16: 470ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 12: 471ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks info->fix.visual = FB_VISUAL_TRUECOLOR; 472ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 473ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 8: 47450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks if (win->variant.palette_sz >= 256) 475ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks info->fix.visual = FB_VISUAL_PSEUDOCOLOR; 476ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks else 477ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks info->fix.visual = FB_VISUAL_TRUECOLOR; 478ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 479ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 1: 480ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks info->fix.visual = FB_VISUAL_MONO01; 481ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 482ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks default: 483ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks info->fix.visual = FB_VISUAL_PSEUDOCOLOR; 484ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 485ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 486ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 487ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8; 488ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 489067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak info->fix.xpanstep = info->var.xres_virtual > info->var.xres ? 1 : 0; 490067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak info->fix.ypanstep = info->var.yres_virtual > info->var.yres ? 1 : 0; 491067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak 492ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* disable the window whilst we update it */ 493ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks writel(0, regs + WINCON(win_no)); 494ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 495ad04490a171915737c9b99d2fa5cb813830f24c1InKi Dae /* use platform specified window as the basis for the lcd timings */ 496ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 497ad04490a171915737c9b99d2fa5cb813830f24c1InKi Dae if (win_no == sfb->pdata->default_win) { 498eb29a5cc0b601c458bae9df2f6c3696d75c2d383Mark Brown clkdiv = s3c_fb_calc_pixclk(sfb, var->pixclock); 499ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 500ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data = sfb->pdata->vidcon0; 501ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR); 502ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 503ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (clkdiv > 1) 504ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= VIDCON0_CLKVAL_F(clkdiv-1) | VIDCON0_CLKDIR; 505ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks else 506ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data &= ~VIDCON0_CLKDIR; /* 1:1 clock */ 507ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 508ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* write the timing data to the panel */ 509ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 510c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks if (sfb->variant.is_2443) 511c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks data |= (1 << 5); 512c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks 513ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= VIDCON0_ENVID | VIDCON0_ENVID_F; 514ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks writel(data, regs + VIDCON0); 515ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 516ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data = VIDTCON0_VBPD(var->upper_margin - 1) | 517ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks VIDTCON0_VFPD(var->lower_margin - 1) | 518ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks VIDTCON0_VSPW(var->vsync_len - 1); 519ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 520c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(data, regs + sfb->variant.vidtcon); 521ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 522ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data = VIDTCON1_HBPD(var->left_margin - 1) | 523ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks VIDTCON1_HFPD(var->right_margin - 1) | 524ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks VIDTCON1_HSPW(var->hsync_len - 1); 525ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 526c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks /* VIDTCON1 */ 527c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(data, regs + sfb->variant.vidtcon + 4); 528ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 529ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data = VIDTCON2_LINEVAL(var->yres - 1) | 530ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks VIDTCON2_HOZVAL(var->xres - 1); 531b73a21fc66fee35b41db755abebfacba48b2fc76Jingoo Han writel(data, regs + sfb->variant.vidtcon + 8); 532ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 533ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 534ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* write the buffer address */ 535ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 536c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks /* start and end registers stride is 8 */ 537c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks buf = regs + win_no * 8; 538c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks 539c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(info->fix.smem_start, buf + sfb->variant.buf_start); 540ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 541ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data = info->fix.smem_start + info->fix.line_length * var->yres; 542c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(data, buf + sfb->variant.buf_end); 543ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 544ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks pagewidth = (var->xres * var->bits_per_pixel) >> 3; 545ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data = VIDW_BUF_SIZE_OFFSET(info->fix.line_length - pagewidth) | 546ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks VIDW_BUF_SIZE_PAGEWIDTH(pagewidth); 547c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(data, regs + sfb->variant.buf_size + (win_no * 4)); 548ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 549ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* write 'OSD' registers to control position of framebuffer */ 550ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 551ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data = VIDOSDxA_TOPLEFT_X(0) | VIDOSDxA_TOPLEFT_Y(0); 552c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(data, regs + VIDOSD_A(win_no, sfb->variant)); 553ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 554ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data = VIDOSDxB_BOTRIGHT_X(s3c_fb_align_word(var->bits_per_pixel, 555ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->xres - 1)) | 556ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks VIDOSDxB_BOTRIGHT_Y(var->yres - 1); 557ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 558c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(data, regs + VIDOSD_B(win_no, sfb->variant)); 559ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 560ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data = var->xres * var->yres; 56139000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae 562f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak alpha = VIDISD14C_ALPHA1_R(0xf) | 56339000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae VIDISD14C_ALPHA1_G(0xf) | 56439000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae VIDISD14C_ALPHA1_B(0xf); 56539000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae 566f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak vidosd_set_alpha(win, alpha); 567f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak vidosd_set_size(win, data); 568ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 569fab7c5b778b1e0ee89e75679b2d6a1405318bb11Jingoo Han /* Enable DMA channel for this window */ 570fab7c5b778b1e0ee89e75679b2d6a1405318bb11Jingoo Han if (sfb->variant.has_shadowcon) { 571fab7c5b778b1e0ee89e75679b2d6a1405318bb11Jingoo Han data = readl(sfb->regs + SHADOWCON); 572fab7c5b778b1e0ee89e75679b2d6a1405318bb11Jingoo Han data |= SHADOWCON_CHx_ENABLE(win_no); 573fab7c5b778b1e0ee89e75679b2d6a1405318bb11Jingoo Han writel(data, sfb->regs + SHADOWCON); 574fab7c5b778b1e0ee89e75679b2d6a1405318bb11Jingoo Han } 575fab7c5b778b1e0ee89e75679b2d6a1405318bb11Jingoo Han 576ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data = WINCONx_ENWIN; 5772d9ae7ac48c91e15e693038bf0dff004f7872aafJingoo Han sfb->enabled |= (1 << win->index); 578ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 579ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* note, since we have to round up the bits-per-pixel, we end up 580ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * relying on the bitfield information for r/g/b/a to work out 581ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * exactly which mode of operation is intended. */ 582ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 583ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks switch (var->bits_per_pixel) { 584ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 1: 585ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCON0_BPPMODE_1BPP; 586ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCONx_BITSWP; 587ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCONx_BURSTLEN_4WORD; 588ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 589ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 2: 590ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCON0_BPPMODE_2BPP; 591ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCONx_BITSWP; 592ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCONx_BURSTLEN_8WORD; 593ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 594ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 4: 595ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCON0_BPPMODE_4BPP; 596ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCONx_BITSWP; 597ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCONx_BURSTLEN_8WORD; 598ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 599ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 8: 600ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (var->transp.length != 0) 601ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCON1_BPPMODE_8BPP_1232; 602ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks else 603ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCON0_BPPMODE_8BPP_PALETTE; 604ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCONx_BURSTLEN_8WORD; 605ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCONx_BYTSWP; 606ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 607ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 16: 608ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (var->transp.length != 0) 609ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCON1_BPPMODE_16BPP_A1555; 610ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks else 611ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCON0_BPPMODE_16BPP_565; 612ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCONx_HAWSWP; 613ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCONx_BURSTLEN_16WORD; 614ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 615ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 24: 616ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 32: 617ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (var->red.length == 6) { 618ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (var->transp.length != 0) 619ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCON1_BPPMODE_19BPP_A1666; 620ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks else 621ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCON1_BPPMODE_18BPP_666; 62239000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae } else if (var->transp.length == 1) 62339000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae data |= WINCON1_BPPMODE_25BPP_A1888 62439000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae | WINCON1_BLD_PIX; 6254420dd2b306f1997232a13462bca0d420be5b1b8Jingoo Han else if ((var->transp.length == 4) || 6264420dd2b306f1997232a13462bca0d420be5b1b8Jingoo Han (var->transp.length == 8)) 62739000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae data |= WINCON1_BPPMODE_28BPP_A4888 62839000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae | WINCON1_BLD_PIX | WINCON1_ALPHA_SEL; 629ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks else 630ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCON0_BPPMODE_24BPP_888; 631ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 632dc8498c00f6a41a28f01111a3d2ed9f179356a71InKi Dae data |= WINCONx_WSWP; 633ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCONx_BURSTLEN_16WORD; 634ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 635ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 636ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 637c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks /* Enable the colour keying for the window below this one */ 63839000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae if (win_no > 0) { 63939000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae u32 keycon0_data = 0, keycon1_data = 0; 640c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks void __iomem *keycon = regs + sfb->variant.keycon; 64139000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae 64239000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae keycon0_data = ~(WxKEYCON0_KEYBL_EN | 64339000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae WxKEYCON0_KEYEN_F | 64439000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae WxKEYCON0_DIRCON) | WxKEYCON0_COMPKEY(0); 64539000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae 64639000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae keycon1_data = WxKEYCON1_COLVAL(0xffffff); 64739000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae 648c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks keycon += (win_no - 1) * 8; 649c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks 650c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(keycon0_data, keycon + WKEYCON0); 651c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(keycon1_data, keycon + WKEYCON1); 65239000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae } 65339000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae 654c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(data, regs + sfb->variant.wincon + (win_no * 4)); 655c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(0x0, regs + sfb->variant.winmap + (win_no * 4)); 656ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 657a8bdabca3ad69de632bd13f1cb65639e9a556e20Pawel Osciak shadow_protect_win(win, 0); 658a8bdabca3ad69de632bd13f1cb65639e9a556e20Pawel Osciak 659ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return 0; 660ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 661ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 662ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 663ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_update_palette() - set or schedule a palette update. 664ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @sfb: The hardware information. 665ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @win: The window being updated. 666ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @reg: The palette index being changed. 667ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @value: The computed palette value. 668ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 669ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Change the value of a palette register, either by directly writing to 670ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * the palette (this requires the palette RAM to be disconnected from the 671ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * hardware whilst this is in progress) or schedule the update for later. 672ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 673ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * At the moment, since we have no VSYNC interrupt support, we simply set 674ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * the palette entry directly. 675ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 676ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic void s3c_fb_update_palette(struct s3c_fb *sfb, 677ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_win *win, 678ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks unsigned int reg, 679ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks u32 value) 680ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 681ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks void __iomem *palreg; 682ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks u32 palcon; 683ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 68450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks palreg = sfb->regs + sfb->variant.palette[win->index]; 685ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 686ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(sfb->dev, "%s: win %d, reg %d (%p): %08x\n", 687ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks __func__, win->index, reg, palreg, value); 688ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 689ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks win->palette_buffer[reg] = value; 690ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 691ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks palcon = readl(sfb->regs + WPALCON); 692ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks writel(palcon | WPALCON_PAL_UPDATE, sfb->regs + WPALCON); 693ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 69450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks if (win->variant.palette_16bpp) 69550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks writew(value, palreg + (reg * 2)); 696ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks else 69750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks writel(value, palreg + (reg * 4)); 698ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 699ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks writel(palcon, sfb->regs + WPALCON); 700ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 701ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 702ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic inline unsigned int chan_to_field(unsigned int chan, 703ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct fb_bitfield *bf) 704ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 705ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks chan &= 0xffff; 706ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks chan >>= 16 - bf->length; 707ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return chan << bf->offset; 708ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 709ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 710ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 711ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_setcolreg() - framebuffer layer request to change palette. 712ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @regno: The palette index to change. 713ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @red: The red field for the palette data. 714ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @green: The green field for the palette data. 715ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @blue: The blue field for the palette data. 716ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @trans: The transparency (alpha) field for the palette data. 717ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @info: The framebuffer being changed. 718ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 719ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic int s3c_fb_setcolreg(unsigned regno, 720ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks unsigned red, unsigned green, unsigned blue, 721ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks unsigned transp, struct fb_info *info) 722ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 723ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_win *win = info->par; 724ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb *sfb = win->parent; 725ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks unsigned int val; 726ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 727ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(sfb->dev, "%s: win %d: %d => rgb=%d/%d/%d\n", 728ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks __func__, win->index, regno, red, green, blue); 729ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 730ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks switch (info->fix.visual) { 731ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case FB_VISUAL_TRUECOLOR: 732ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* true-colour, use pseudo-palette */ 733ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 734ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (regno < 16) { 735ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks u32 *pal = info->pseudo_palette; 736ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 737ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks val = chan_to_field(red, &info->var.red); 738ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks val |= chan_to_field(green, &info->var.green); 739ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks val |= chan_to_field(blue, &info->var.blue); 740ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 741ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks pal[regno] = val; 742ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 743ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 744ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 745ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case FB_VISUAL_PSEUDOCOLOR: 74650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks if (regno < win->variant.palette_sz) { 747ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks val = chan_to_field(red, &win->palette.r); 748ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks val |= chan_to_field(green, &win->palette.g); 749ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks val |= chan_to_field(blue, &win->palette.b); 750ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 751ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks s3c_fb_update_palette(sfb, win, regno, val); 752ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 753ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 754ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 755ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 756ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks default: 757ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return 1; /* unknown type */ 758ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 759ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 760ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return 0; 761ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 762ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 763ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 764ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_enable() - Set the state of the main LCD output 765ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @sfb: The main framebuffer state. 766ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @enable: The state to set. 767ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 768ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic void s3c_fb_enable(struct s3c_fb *sfb, int enable) 769ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 770ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks u32 vidcon0 = readl(sfb->regs + VIDCON0); 771ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 772ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (enable) 773ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks vidcon0 |= VIDCON0_ENVID | VIDCON0_ENVID_F; 774ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks else { 775ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* see the note in the framebuffer datasheet about 776ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * why you cannot take both of these bits down at the 777ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * same time. */ 778ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 779ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (!(vidcon0 & VIDCON0_ENVID)) 780ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return; 781ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 782ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks vidcon0 |= VIDCON0_ENVID; 783ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks vidcon0 &= ~VIDCON0_ENVID_F; 784ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 785ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 786ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks writel(vidcon0, sfb->regs + VIDCON0); 787ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 788ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 789ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 790ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_blank() - blank or unblank the given window 791ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @blank_mode: The blank state from FB_BLANK_* 792ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @info: The framebuffer to blank. 793ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 794ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Framebuffer layer request to change the power state. 795ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 796ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic int s3c_fb_blank(int blank_mode, struct fb_info *info) 797ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 798ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_win *win = info->par; 799ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb *sfb = win->parent; 800ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks unsigned int index = win->index; 801ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks u32 wincon; 802ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 803ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(sfb->dev, "blank mode %d\n", blank_mode); 804ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 805c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks wincon = readl(sfb->regs + sfb->variant.wincon + (index * 4)); 806ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 807ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks switch (blank_mode) { 808ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case FB_BLANK_POWERDOWN: 809ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks wincon &= ~WINCONx_ENWIN; 810ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks sfb->enabled &= ~(1 << index); 811ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* fall through to FB_BLANK_NORMAL */ 812ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 813ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case FB_BLANK_NORMAL: 814ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* disable the DMA and display 0x0 (black) */ 815ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han shadow_protect_win(win, 1); 816ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks writel(WINxMAP_MAP | WINxMAP_MAP_COLOUR(0x0), 817c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks sfb->regs + sfb->variant.winmap + (index * 4)); 818ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han shadow_protect_win(win, 0); 819ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 820ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 821ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case FB_BLANK_UNBLANK: 822ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han shadow_protect_win(win, 1); 823c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(0x0, sfb->regs + sfb->variant.winmap + (index * 4)); 824ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han shadow_protect_win(win, 0); 825ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks wincon |= WINCONx_ENWIN; 826ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks sfb->enabled |= (1 << index); 827ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 828ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 829ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case FB_BLANK_VSYNC_SUSPEND: 830ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case FB_BLANK_HSYNC_SUSPEND: 831ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks default: 832ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return 1; 833ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 834ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 835ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han shadow_protect_win(win, 1); 836c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(wincon, sfb->regs + sfb->variant.wincon + (index * 4)); 837ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han shadow_protect_win(win, 0); 838ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 839ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* Check the enabled state to see if we need to be running the 840ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * main LCD interface, as if there are no active windows then 841ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * it is highly likely that we also do not need to output 842ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * anything. 843ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 844ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 845ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* We could do something like the following code, but the current 846ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * system of using framebuffer events means that we cannot make 847ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * the distinction between just window 0 being inactive and all 848ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * the windows being down. 849ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 850ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_enable(sfb, sfb->enabled ? 1 : 0); 851ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 852ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 853ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* we're stuck with this until we can do something about overriding 854ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * the power control using the blanking event for a single fb. 855ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 856ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han if (index == sfb->pdata->default_win) { 857ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han shadow_protect_win(win, 1); 858ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks s3c_fb_enable(sfb, blank_mode != FB_BLANK_POWERDOWN ? 1 : 0); 859ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han shadow_protect_win(win, 0); 860ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han } 861ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 862ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return 0; 863ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 864ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 865067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak/** 866067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak * s3c_fb_pan_display() - Pan the display. 867067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak * 868067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak * Note that the offsets can be written to the device at any time, as their 869067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak * values are latched at each vsync automatically. This also means that only 870067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak * the last call to this function will have any effect on next vsync, but 871067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak * there is no need to sleep waiting for it to prevent tearing. 872067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak * 873067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak * @var: The screen information to verify. 874067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak * @info: The framebuffer device. 875067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak */ 876067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciakstatic int s3c_fb_pan_display(struct fb_var_screeninfo *var, 877067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak struct fb_info *info) 878067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak{ 879067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak struct s3c_fb_win *win = info->par; 880067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak struct s3c_fb *sfb = win->parent; 881067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak void __iomem *buf = sfb->regs + win->index * 8; 882067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak unsigned int start_boff, end_boff; 883067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak 884067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak /* Offset in bytes to the start of the displayed area */ 885067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak start_boff = var->yoffset * info->fix.line_length; 886067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak /* X offset depends on the current bpp */ 887067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak if (info->var.bits_per_pixel >= 8) { 888067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak start_boff += var->xoffset * (info->var.bits_per_pixel >> 3); 889067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak } else { 890067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak switch (info->var.bits_per_pixel) { 891067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak case 4: 892067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak start_boff += var->xoffset >> 1; 893067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak break; 894067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak case 2: 895067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak start_boff += var->xoffset >> 2; 896067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak break; 897067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak case 1: 898067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak start_boff += var->xoffset >> 3; 899067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak break; 900067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak default: 901067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak dev_err(sfb->dev, "invalid bpp\n"); 902067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak return -EINVAL; 903067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak } 904067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak } 905067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak /* Offset in bytes to the end of the displayed area */ 906d8e7a74bf1f1c3d8235e1d939d3e1e96da94ed82Laurent Pinchart end_boff = start_boff + info->var.yres * info->fix.line_length; 907067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak 908067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak /* Temporarily turn off per-vsync update from shadow registers until 909067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak * both start and end addresses are updated to prevent corruption */ 910f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak shadow_protect_win(win, 1); 911067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak 912067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak writel(info->fix.smem_start + start_boff, buf + sfb->variant.buf_start); 913067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak writel(info->fix.smem_start + end_boff, buf + sfb->variant.buf_end); 914067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak 915f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak shadow_protect_win(win, 0); 916067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak 917067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak return 0; 918067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak} 919067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak 920efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak/** 921efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * s3c_fb_enable_irq() - enable framebuffer interrupts 922efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * @sfb: main hardware state 923efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak */ 924efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciakstatic void s3c_fb_enable_irq(struct s3c_fb *sfb) 925efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak{ 926efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak void __iomem *regs = sfb->regs; 927efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak u32 irq_ctrl_reg; 928efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 929efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak if (!test_and_set_bit(S3C_FB_VSYNC_IRQ_EN, &sfb->irq_flags)) { 930efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak /* IRQ disabled, enable it */ 931efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak irq_ctrl_reg = readl(regs + VIDINTCON0); 932efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 933efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak irq_ctrl_reg |= VIDINTCON0_INT_ENABLE; 934efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak irq_ctrl_reg |= VIDINTCON0_INT_FRAME; 935efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 936efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak irq_ctrl_reg &= ~VIDINTCON0_FRAMESEL0_MASK; 937efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak irq_ctrl_reg |= VIDINTCON0_FRAMESEL0_VSYNC; 938efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak irq_ctrl_reg &= ~VIDINTCON0_FRAMESEL1_MASK; 939efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak irq_ctrl_reg |= VIDINTCON0_FRAMESEL1_NONE; 940efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 941efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak writel(irq_ctrl_reg, regs + VIDINTCON0); 942efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak } 943efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak} 944efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 945efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak/** 946efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * s3c_fb_disable_irq() - disable framebuffer interrupts 947efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * @sfb: main hardware state 948efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak */ 949efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciakstatic void s3c_fb_disable_irq(struct s3c_fb *sfb) 950efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak{ 951efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak void __iomem *regs = sfb->regs; 952efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak u32 irq_ctrl_reg; 953efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 954efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak if (test_and_clear_bit(S3C_FB_VSYNC_IRQ_EN, &sfb->irq_flags)) { 955efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak /* IRQ enabled, disable it */ 956efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak irq_ctrl_reg = readl(regs + VIDINTCON0); 957efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 958efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak irq_ctrl_reg &= ~VIDINTCON0_INT_FRAME; 959efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak irq_ctrl_reg &= ~VIDINTCON0_INT_ENABLE; 960efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 961efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak writel(irq_ctrl_reg, regs + VIDINTCON0); 962efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak } 963efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak} 964efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 965efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciakstatic irqreturn_t s3c_fb_irq(int irq, void *dev_id) 966efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak{ 967efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak struct s3c_fb *sfb = dev_id; 968efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak void __iomem *regs = sfb->regs; 969efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak u32 irq_sts_reg; 970efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 971b07f3bbee12163a6b48991138a37b87a1126462aJingoo Han spin_lock(&sfb->slock); 972b07f3bbee12163a6b48991138a37b87a1126462aJingoo Han 973efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak irq_sts_reg = readl(regs + VIDINTCON1); 974efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 975efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak if (irq_sts_reg & VIDINTCON1_INT_FRAME) { 976efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 977efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak /* VSYNC interrupt, accept it */ 978efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak writel(VIDINTCON1_INT_FRAME, regs + VIDINTCON1); 979efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 980efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak sfb->vsync_info.count++; 981efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak wake_up_interruptible(&sfb->vsync_info.wait); 982efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak } 983efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 984efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak /* We only support waiting for VSYNC for now, so it's safe 985efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * to always disable irqs here. 986efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak */ 987efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak s3c_fb_disable_irq(sfb); 988efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 989b07f3bbee12163a6b48991138a37b87a1126462aJingoo Han spin_unlock(&sfb->slock); 990efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak return IRQ_HANDLED; 991efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak} 992efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 993efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak/** 994efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * s3c_fb_wait_for_vsync() - sleep until next VSYNC interrupt or timeout 995efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * @sfb: main hardware state 996efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * @crtc: head index. 997efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak */ 998efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciakstatic int s3c_fb_wait_for_vsync(struct s3c_fb *sfb, u32 crtc) 999efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak{ 1000efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak unsigned long count; 1001efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak int ret; 1002efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1003efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak if (crtc != 0) 1004efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak return -ENODEV; 1005efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1006efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak count = sfb->vsync_info.count; 1007efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak s3c_fb_enable_irq(sfb); 1008efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak ret = wait_event_interruptible_timeout(sfb->vsync_info.wait, 1009efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak count != sfb->vsync_info.count, 1010efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak msecs_to_jiffies(VSYNC_TIMEOUT_MSEC)); 1011efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak if (ret == 0) 1012efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak return -ETIMEDOUT; 1013efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1014efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak return 0; 1015efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak} 1016efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1017efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciakstatic int s3c_fb_ioctl(struct fb_info *info, unsigned int cmd, 1018efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak unsigned long arg) 1019efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak{ 1020efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak struct s3c_fb_win *win = info->par; 1021efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak struct s3c_fb *sfb = win->parent; 1022efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak int ret; 1023efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak u32 crtc; 1024efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1025efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak switch (cmd) { 1026efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak case FBIO_WAITFORVSYNC: 1027efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak if (get_user(crtc, (u32 __user *)arg)) { 1028efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak ret = -EFAULT; 1029efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak break; 1030efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak } 1031efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1032efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak ret = s3c_fb_wait_for_vsync(sfb, crtc); 1033efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak break; 1034efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak default: 1035efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak ret = -ENOTTY; 1036efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak } 1037efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1038efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak return ret; 1039efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak} 1040efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1041ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic struct fb_ops s3c_fb_ops = { 1042ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks .owner = THIS_MODULE, 1043ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks .fb_check_var = s3c_fb_check_var, 1044ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks .fb_set_par = s3c_fb_set_par, 1045ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks .fb_blank = s3c_fb_blank, 1046ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks .fb_setcolreg = s3c_fb_setcolreg, 1047ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks .fb_fillrect = cfb_fillrect, 1048ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks .fb_copyarea = cfb_copyarea, 1049ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks .fb_imageblit = cfb_imageblit, 1050067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak .fb_pan_display = s3c_fb_pan_display, 1051efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak .fb_ioctl = s3c_fb_ioctl, 1052ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks}; 1053ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1054ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 10552bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere * s3c_fb_missing_pixclock() - calculates pixel clock 10562bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere * @mode: The video mode to change. 10572bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere * 10582bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere * Calculate the pixel clock when none has been given through platform data. 10592bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere */ 10602bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaerestatic void __devinit s3c_fb_missing_pixclock(struct fb_videomode *mode) 10612bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere{ 10622bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere u64 pixclk = 1000000000000ULL; 10632bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere u32 div; 10642bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere 10652bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere div = mode->left_margin + mode->hsync_len + mode->right_margin + 10662bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere mode->xres; 10672bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere div *= mode->upper_margin + mode->vsync_len + mode->lower_margin + 10682bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere mode->yres; 10692bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere div *= mode->refresh ? : 60; 10702bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere 10712bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere do_div(pixclk, div); 10722bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere 10732bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere mode->pixclock = pixclk; 10742bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere} 10752bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere 10762bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere/** 1077ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_alloc_memory() - allocate display memory for framebuffer window 1078ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @sfb: The base resources for the hardware. 1079ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @win: The window to initialise memory for. 1080ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 1081ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Allocate memory for the given framebuffer. 1082ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 1083ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic int __devinit s3c_fb_alloc_memory(struct s3c_fb *sfb, 1084ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_win *win) 1085ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 1086ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_pd_win *windata = win->windata; 1087ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks unsigned int real_size, virt_size, size; 1088ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct fb_info *fbi = win->fbinfo; 1089ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dma_addr_t map_dma; 1090ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1091ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(sfb->dev, "allocating memory for display\n"); 1092ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1093ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks real_size = windata->win_mode.xres * windata->win_mode.yres; 1094ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks virt_size = windata->virtual_x * windata->virtual_y; 1095ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1096ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(sfb->dev, "real_size=%u (%u.%u), virt_size=%u (%u.%u)\n", 1097ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks real_size, windata->win_mode.xres, windata->win_mode.yres, 1098ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks virt_size, windata->virtual_x, windata->virtual_y); 1099ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1100ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks size = (real_size > virt_size) ? real_size : virt_size; 1101ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks size *= (windata->max_bpp > 16) ? 32 : windata->max_bpp; 1102ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks size /= 8; 1103ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1104ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fbi->fix.smem_len = size; 1105ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks size = PAGE_ALIGN(size); 1106ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1107ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(sfb->dev, "want %u bytes for window\n", size); 1108ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1109ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fbi->screen_base = dma_alloc_writecombine(sfb->dev, size, 1110ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks &map_dma, GFP_KERNEL); 1111ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (!fbi->screen_base) 1112ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return -ENOMEM; 1113ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1114ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(sfb->dev, "mapped %x to %p\n", 1115ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks (unsigned int)map_dma, fbi->screen_base); 1116ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1117ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks memset(fbi->screen_base, 0x0, size); 1118ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fbi->fix.smem_start = map_dma; 1119ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1120ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return 0; 1121ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 1122ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1123ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 1124ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_free_memory() - free the display memory for the given window 1125ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @sfb: The base resources for the hardware. 1126ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @win: The window to free the display memory for. 1127ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 1128ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Free the display memory allocated by s3c_fb_alloc_memory(). 1129ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 1130ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic void s3c_fb_free_memory(struct s3c_fb *sfb, struct s3c_fb_win *win) 1131ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 1132ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct fb_info *fbi = win->fbinfo; 1133ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1134cd7d7e0244955a4694d1e79e8c8a9bef163d6305Pawel Osciak if (fbi->screen_base) 1135cd7d7e0244955a4694d1e79e8c8a9bef163d6305Pawel Osciak dma_free_writecombine(sfb->dev, PAGE_ALIGN(fbi->fix.smem_len), 1136ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fbi->screen_base, fbi->fix.smem_start); 1137ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 1138ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1139ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 1140ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_release_win() - release resources for a framebuffer window. 1141ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @win: The window to cleanup the resources for. 1142ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 1143ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Release the resources that where claimed for the hardware window, 1144ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * such as the framebuffer instance and any memory claimed for it. 1145ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 1146ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic void s3c_fb_release_win(struct s3c_fb *sfb, struct s3c_fb_win *win) 1147ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 114804ab9ef97771ba88789672a1f0d0ddcf8dbc0924Pawel Osciak u32 data; 114904ab9ef97771ba88789672a1f0d0ddcf8dbc0924Pawel Osciak 1150ddc518d9f88d7cf82bd974737ce977193785335dKrzysztof Helt if (win->fbinfo) { 115104ab9ef97771ba88789672a1f0d0ddcf8dbc0924Pawel Osciak if (sfb->variant.has_shadowcon) { 115204ab9ef97771ba88789672a1f0d0ddcf8dbc0924Pawel Osciak data = readl(sfb->regs + SHADOWCON); 115304ab9ef97771ba88789672a1f0d0ddcf8dbc0924Pawel Osciak data &= ~SHADOWCON_CHx_ENABLE(win->index); 115404ab9ef97771ba88789672a1f0d0ddcf8dbc0924Pawel Osciak data &= ~SHADOWCON_CHx_LOCAL_ENABLE(win->index); 115504ab9ef97771ba88789672a1f0d0ddcf8dbc0924Pawel Osciak writel(data, sfb->regs + SHADOWCON); 115604ab9ef97771ba88789672a1f0d0ddcf8dbc0924Pawel Osciak } 1157ddc518d9f88d7cf82bd974737ce977193785335dKrzysztof Helt unregister_framebuffer(win->fbinfo); 1158cd7d7e0244955a4694d1e79e8c8a9bef163d6305Pawel Osciak if (win->fbinfo->cmap.len) 1159cd7d7e0244955a4694d1e79e8c8a9bef163d6305Pawel Osciak fb_dealloc_cmap(&win->fbinfo->cmap); 1160ddc518d9f88d7cf82bd974737ce977193785335dKrzysztof Helt s3c_fb_free_memory(sfb, win); 1161ddc518d9f88d7cf82bd974737ce977193785335dKrzysztof Helt framebuffer_release(win->fbinfo); 1162ddc518d9f88d7cf82bd974737ce977193785335dKrzysztof Helt } 1163ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 1164ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1165ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 1166ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_probe_win() - register an hardware window 1167ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @sfb: The base resources for the hardware 116850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @variant: The variant information for this window. 1169ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @res: Pointer to where to place the resultant window. 1170ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 1171ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Allocate and do the basic initialisation for one of the hardware's graphics 1172ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * windows. 1173ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 1174ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no, 117550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks struct s3c_fb_win_variant *variant, 1176ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_win **res) 1177ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 1178ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct fb_var_screeninfo *var; 1179ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct fb_videomode *initmode; 1180ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_pd_win *windata; 1181ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_win *win; 1182ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct fb_info *fbinfo; 1183ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks int palette_size; 1184ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks int ret; 1185ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1186c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks dev_dbg(sfb->dev, "probing window %d, variant %p\n", win_no, variant); 1187ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1188efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak init_waitqueue_head(&sfb->vsync_info.wait); 1189efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 119050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks palette_size = variant->palette_sz * 4; 1191ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1192ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fbinfo = framebuffer_alloc(sizeof(struct s3c_fb_win) + 1193ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks palette_size * sizeof(u32), sfb->dev); 1194ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (!fbinfo) { 1195ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_err(sfb->dev, "failed to allocate framebuffer\n"); 1196ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return -ENOENT; 1197ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 1198ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1199ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks windata = sfb->pdata->win[win_no]; 1200ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks initmode = &windata->win_mode; 1201ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1202ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks WARN_ON(windata->max_bpp == 0); 1203ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks WARN_ON(windata->win_mode.xres == 0); 1204ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks WARN_ON(windata->win_mode.yres == 0); 1205ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1206ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks win = fbinfo->par; 1207cd7d7e0244955a4694d1e79e8c8a9bef163d6305Pawel Osciak *res = win; 1208ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var = &fbinfo->var; 120950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks win->variant = *variant; 1210ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks win->fbinfo = fbinfo; 1211ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks win->parent = sfb; 1212ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks win->windata = windata; 1213ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks win->index = win_no; 1214ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks win->palette_buffer = (u32 *)(win + 1); 1215ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1216ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks ret = s3c_fb_alloc_memory(sfb, win); 1217ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (ret) { 1218ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_err(sfb->dev, "failed to allocate display memory\n"); 1219ddc518d9f88d7cf82bd974737ce977193785335dKrzysztof Helt return ret; 1220ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 1221ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1222ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* setup the r/b/g positions for the window's palette */ 1223bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks if (win->variant.palette_16bpp) { 1224bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks /* Set RGB 5:6:5 as default */ 1225bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks win->palette.r.offset = 11; 1226bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks win->palette.r.length = 5; 1227bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks win->palette.g.offset = 5; 1228bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks win->palette.g.length = 6; 1229bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks win->palette.b.offset = 0; 1230bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks win->palette.b.length = 5; 1231bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks 1232bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks } else { 1233bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks /* Set 8bpp or 8bpp and 1bit alpha */ 1234bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks win->palette.r.offset = 16; 1235bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks win->palette.r.length = 8; 1236bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks win->palette.g.offset = 8; 1237bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks win->palette.g.length = 8; 1238bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks win->palette.b.offset = 0; 1239bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks win->palette.b.length = 8; 1240bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks } 1241ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1242ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* setup the initial video mode from the window */ 1243ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fb_videomode_to_var(&fbinfo->var, initmode); 1244ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1245ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fbinfo->fix.type = FB_TYPE_PACKED_PIXELS; 1246ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fbinfo->fix.accel = FB_ACCEL_NONE; 1247ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fbinfo->var.activate = FB_ACTIVATE_NOW; 1248ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fbinfo->var.vmode = FB_VMODE_NONINTERLACED; 1249ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fbinfo->var.bits_per_pixel = windata->default_bpp; 1250ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fbinfo->fbops = &s3c_fb_ops; 1251ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fbinfo->flags = FBINFO_FLAG_DEFAULT; 1252ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fbinfo->pseudo_palette = &win->pseudo_palette; 1253ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1254ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* prepare to actually start the framebuffer */ 1255ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1256ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks ret = s3c_fb_check_var(&fbinfo->var, fbinfo); 1257ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (ret < 0) { 1258ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_err(sfb->dev, "check_var failed on initial video params\n"); 1259ddc518d9f88d7cf82bd974737ce977193785335dKrzysztof Helt return ret; 1260ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 1261ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1262ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* create initial colour map */ 1263ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 126450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks ret = fb_alloc_cmap(&fbinfo->cmap, win->variant.palette_sz, 1); 1265ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (ret == 0) 1266ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fb_set_cmap(&fbinfo->cmap, fbinfo); 1267ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks else 1268ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_err(sfb->dev, "failed to allocate fb cmap\n"); 1269ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1270ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks s3c_fb_set_par(fbinfo); 1271ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1272ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(sfb->dev, "about to register framebuffer\n"); 1273ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1274ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* run the check_var and set_par on our configuration. */ 1275ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1276ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks ret = register_framebuffer(fbinfo); 1277ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (ret < 0) { 1278ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_err(sfb->dev, "failed to register framebuffer\n"); 1279ddc518d9f88d7cf82bd974737ce977193785335dKrzysztof Helt return ret; 1280ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 1281ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1282ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_info(sfb->dev, "window %d: fb %s\n", win_no, fbinfo->fix.id); 1283ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1284ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return 0; 1285ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 1286ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1287ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 1288ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_clear_win() - clear hardware window registers. 1289ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @sfb: The base resources for the hardware. 1290ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @win: The window to process. 1291ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 1292ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Reset the specific window registers to a known state. 1293ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 1294ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic void s3c_fb_clear_win(struct s3c_fb *sfb, int win) 1295ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 1296ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks void __iomem *regs = sfb->regs; 1297a8bdabca3ad69de632bd13f1cb65639e9a556e20Pawel Osciak u32 reg; 1298ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1299c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(0, regs + sfb->variant.wincon + (win * 4)); 1300c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(0, regs + VIDOSD_A(win, sfb->variant)); 1301c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(0, regs + VIDOSD_B(win, sfb->variant)); 1302c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(0, regs + VIDOSD_C(win, sfb->variant)); 1303a8bdabca3ad69de632bd13f1cb65639e9a556e20Pawel Osciak reg = readl(regs + SHADOWCON); 1304a8bdabca3ad69de632bd13f1cb65639e9a556e20Pawel Osciak writel(reg & ~SHADOWCON_WINx_PROTECT(win), regs + SHADOWCON); 1305ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 1306ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1307ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic int __devinit s3c_fb_probe(struct platform_device *pdev) 1308ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 1309b73a21fc66fee35b41db755abebfacba48b2fc76Jingoo Han const struct platform_device_id *platid; 131050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks struct s3c_fb_driverdata *fbdrv; 1311ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct device *dev = &pdev->dev; 1312ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_platdata *pd; 1313ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb *sfb; 1314ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct resource *res; 1315ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks int win; 1316ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks int ret = 0; 1317ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1318b73a21fc66fee35b41db755abebfacba48b2fc76Jingoo Han platid = platform_get_device_id(pdev); 1319b73a21fc66fee35b41db755abebfacba48b2fc76Jingoo Han fbdrv = (struct s3c_fb_driverdata *)platid->driver_data; 132050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 132150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks if (fbdrv->variant.nr_windows > S3C_FB_MAX_WIN) { 132250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks dev_err(dev, "too many windows, cannot attach\n"); 132350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks return -EINVAL; 132450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks } 132550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 1326ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks pd = pdev->dev.platform_data; 1327ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (!pd) { 1328ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_err(dev, "no platform data specified\n"); 1329ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return -EINVAL; 1330ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 1331ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1332ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks sfb = kzalloc(sizeof(struct s3c_fb), GFP_KERNEL); 1333ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (!sfb) { 1334ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_err(dev, "no memory for framebuffers\n"); 1335ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return -ENOMEM; 1336ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 1337ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1338c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks dev_dbg(dev, "allocate new framebuffer %p\n", sfb); 1339c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks 1340ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks sfb->dev = dev; 1341ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks sfb->pdata = pd; 134250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks sfb->variant = fbdrv->variant; 1343ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1344b07f3bbee12163a6b48991138a37b87a1126462aJingoo Han spin_lock_init(&sfb->slock); 1345b07f3bbee12163a6b48991138a37b87a1126462aJingoo Han 1346ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks sfb->bus_clk = clk_get(dev, "lcd"); 1347ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (IS_ERR(sfb->bus_clk)) { 1348ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_err(dev, "failed to get bus clock\n"); 1349942b8d05cdf1da396b4449a38b87c677591947c0Axel Lin ret = PTR_ERR(sfb->bus_clk); 1350ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks goto err_sfb; 1351ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 1352ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1353ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks clk_enable(sfb->bus_clk); 1354ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1355b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han if (!sfb->variant.has_clksel) { 1356b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han sfb->lcd_clk = clk_get(dev, "sclk_fimd"); 1357b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han if (IS_ERR(sfb->lcd_clk)) { 1358b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han dev_err(dev, "failed to get lcd clock\n"); 1359b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han ret = PTR_ERR(sfb->lcd_clk); 1360b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han goto err_bus_clk; 1361b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han } 1362b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han 1363b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han clk_enable(sfb->lcd_clk); 1364b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han } 1365b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han 13664959212c18669f254daa0ae796ad676b67939ba2Jingoo Han pm_runtime_enable(sfb->dev); 13674959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 1368ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1369ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (!res) { 1370ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_err(dev, "failed to find registers\n"); 1371ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks ret = -ENOENT; 1372b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han goto err_lcd_clk; 1373ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 1374ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1375ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks sfb->regs_res = request_mem_region(res->start, resource_size(res), 1376ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_name(dev)); 1377ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (!sfb->regs_res) { 1378ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_err(dev, "failed to claim register region\n"); 1379ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks ret = -ENOENT; 1380b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han goto err_lcd_clk; 1381ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 1382ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1383ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks sfb->regs = ioremap(res->start, resource_size(res)); 1384ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (!sfb->regs) { 1385ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_err(dev, "failed to map registers\n"); 1386ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks ret = -ENXIO; 1387ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks goto err_req_region; 1388ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 1389ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1390efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 1391efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak if (!res) { 1392efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak dev_err(dev, "failed to acquire irq resource\n"); 1393efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak ret = -ENOENT; 1394efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak goto err_ioremap; 1395efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak } 1396efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak sfb->irq_no = res->start; 1397efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak ret = request_irq(sfb->irq_no, s3c_fb_irq, 1398efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 0, "s3c_fb", sfb); 1399efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak if (ret) { 1400efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak dev_err(dev, "irq request failed\n"); 1401efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak goto err_ioremap; 1402efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak } 1403efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1404ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(dev, "got resources (regs %p), probing windows\n", sfb->regs); 1405ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 14064959212c18669f254daa0ae796ad676b67939ba2Jingoo Han platform_set_drvdata(pdev, sfb); 14074959212c18669f254daa0ae796ad676b67939ba2Jingoo Han pm_runtime_get_sync(sfb->dev); 14084959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 1409ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* setup gpio and output polarity controls */ 1410ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1411ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks pd->setup_gpio(); 1412ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1413ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks writel(pd->vidcon1, sfb->regs + VIDCON1); 1414ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1415ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* zero all windows before we do anything */ 1416ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 141750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks for (win = 0; win < fbdrv->variant.nr_windows; win++) 1418ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks s3c_fb_clear_win(sfb, win); 1419ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1420949470375393e82dc9158d36d675180c8c250388Ben Dooks /* initialise colour key controls */ 142150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks for (win = 0; win < (fbdrv->variant.nr_windows - 1); win++) { 1422c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks void __iomem *regs = sfb->regs + sfb->variant.keycon; 1423c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks 1424c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks regs += (win * 8); 1425c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(0xffffff, regs + WKEYCON0); 1426c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(0xffffff, regs + WKEYCON1); 1427949470375393e82dc9158d36d675180c8c250388Ben Dooks } 1428949470375393e82dc9158d36d675180c8c250388Ben Dooks 1429ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* we have the register setup, start allocating framebuffers */ 1430ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 143150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks for (win = 0; win < fbdrv->variant.nr_windows; win++) { 1432ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (!pd->win[win]) 1433ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks continue; 1434ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 14352bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere if (!pd->win[win]->win_mode.pixclock) 14362bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere s3c_fb_missing_pixclock(&pd->win[win]->win_mode); 14372bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere 143850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks ret = s3c_fb_probe_win(sfb, win, fbdrv->win[win], 143950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks &sfb->windows[win]); 1440ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (ret < 0) { 1441ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_err(dev, "failed to create window %d\n", win); 1442ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks for (; win >= 0; win--) 1443ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks s3c_fb_release_win(sfb, sfb->windows[win]); 1444efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak goto err_irq; 1445ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 1446ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 1447ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1448ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks platform_set_drvdata(pdev, sfb); 1449ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1450ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return 0; 1451ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1452efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciakerr_irq: 1453efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak free_irq(sfb->irq_no, sfb); 1454efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1455ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dookserr_ioremap: 1456ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks iounmap(sfb->regs); 1457ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1458ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dookserr_req_region: 1459683e7cdc207f71eef3ff46f5d36ec505c65fbbc6Julia Lawall release_mem_region(sfb->regs_res->start, resource_size(sfb->regs_res)); 1460ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1461b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Hanerr_lcd_clk: 1462b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han if (!sfb->variant.has_clksel) { 1463b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han clk_disable(sfb->lcd_clk); 1464b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han clk_put(sfb->lcd_clk); 1465b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han } 1466b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han 1467b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Hanerr_bus_clk: 1468ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks clk_disable(sfb->bus_clk); 1469ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks clk_put(sfb->bus_clk); 1470ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1471ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dookserr_sfb: 1472ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks kfree(sfb); 1473ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return ret; 1474ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 1475ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1476ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 1477ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_remove() - Cleanup on module finalisation 1478ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @pdev: The platform device we are bound to. 1479ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 1480ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Shutdown and then release all the resources that the driver allocated 1481ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * on initialisation. 1482ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 1483ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic int __devexit s3c_fb_remove(struct platform_device *pdev) 1484ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 1485ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb *sfb = platform_get_drvdata(pdev); 1486ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks int win; 1487ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1488c42b110caeb128819104d057acdaa1ae564b7c8dPawel Osciak for (win = 0; win < S3C_FB_MAX_WIN; win++) 148917663e59704bea838a9236f299104e30909a43b1Marek Szyprowski if (sfb->windows[win]) 149017663e59704bea838a9236f299104e30909a43b1Marek Szyprowski s3c_fb_release_win(sfb, sfb->windows[win]); 1491ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1492efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak free_irq(sfb->irq_no, sfb); 1493efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1494ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks iounmap(sfb->regs); 1495ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1496b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han if (!sfb->variant.has_clksel) { 1497b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han clk_disable(sfb->lcd_clk); 1498b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han clk_put(sfb->lcd_clk); 1499b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han } 1500b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han 1501ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks clk_disable(sfb->bus_clk); 1502ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks clk_put(sfb->bus_clk); 1503ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1504683e7cdc207f71eef3ff46f5d36ec505c65fbbc6Julia Lawall release_mem_region(sfb->regs_res->start, resource_size(sfb->regs_res)); 1505ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 15064959212c18669f254daa0ae796ad676b67939ba2Jingoo Han pm_runtime_put_sync(sfb->dev); 15074959212c18669f254daa0ae796ad676b67939ba2Jingoo Han pm_runtime_disable(sfb->dev); 15084959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 150972ba4cb608e7937792f3d61349ef616bbffda832Jingoo Han kfree(sfb); 1510ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return 0; 1511ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 1512ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 151335784b4315d949e431df9a0ffef721a4801b1588Jingoo Han#ifdef CONFIG_PM_SLEEP 15144959212c18669f254daa0ae796ad676b67939ba2Jingoo Hanstatic int s3c_fb_suspend(struct device *dev) 15154959212c18669f254daa0ae796ad676b67939ba2Jingoo Han{ 15164959212c18669f254daa0ae796ad676b67939ba2Jingoo Han struct platform_device *pdev = to_platform_device(dev); 15174959212c18669f254daa0ae796ad676b67939ba2Jingoo Han struct s3c_fb *sfb = platform_get_drvdata(pdev); 15184959212c18669f254daa0ae796ad676b67939ba2Jingoo Han struct s3c_fb_win *win; 15194959212c18669f254daa0ae796ad676b67939ba2Jingoo Han int win_no; 15204959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 15214959212c18669f254daa0ae796ad676b67939ba2Jingoo Han for (win_no = S3C_FB_MAX_WIN - 1; win_no >= 0; win_no--) { 15224959212c18669f254daa0ae796ad676b67939ba2Jingoo Han win = sfb->windows[win_no]; 15234959212c18669f254daa0ae796ad676b67939ba2Jingoo Han if (!win) 15244959212c18669f254daa0ae796ad676b67939ba2Jingoo Han continue; 15254959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 15264959212c18669f254daa0ae796ad676b67939ba2Jingoo Han /* use the blank function to push into power-down */ 15274959212c18669f254daa0ae796ad676b67939ba2Jingoo Han s3c_fb_blank(FB_BLANK_POWERDOWN, win->fbinfo); 15284959212c18669f254daa0ae796ad676b67939ba2Jingoo Han } 15294959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 1530b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han if (!sfb->variant.has_clksel) 1531b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han clk_disable(sfb->lcd_clk); 1532b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han 15334959212c18669f254daa0ae796ad676b67939ba2Jingoo Han clk_disable(sfb->bus_clk); 153435784b4315d949e431df9a0ffef721a4801b1588Jingoo Han pm_runtime_put_sync(sfb->dev); 153535784b4315d949e431df9a0ffef721a4801b1588Jingoo Han 15364959212c18669f254daa0ae796ad676b67939ba2Jingoo Han return 0; 15374959212c18669f254daa0ae796ad676b67939ba2Jingoo Han} 15384959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 15394959212c18669f254daa0ae796ad676b67939ba2Jingoo Hanstatic int s3c_fb_resume(struct device *dev) 15404959212c18669f254daa0ae796ad676b67939ba2Jingoo Han{ 15414959212c18669f254daa0ae796ad676b67939ba2Jingoo Han struct platform_device *pdev = to_platform_device(dev); 15424959212c18669f254daa0ae796ad676b67939ba2Jingoo Han struct s3c_fb *sfb = platform_get_drvdata(pdev); 15434959212c18669f254daa0ae796ad676b67939ba2Jingoo Han struct s3c_fb_platdata *pd = sfb->pdata; 15444959212c18669f254daa0ae796ad676b67939ba2Jingoo Han struct s3c_fb_win *win; 15454959212c18669f254daa0ae796ad676b67939ba2Jingoo Han int win_no; 15464959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 154735784b4315d949e431df9a0ffef721a4801b1588Jingoo Han pm_runtime_get_sync(sfb->dev); 15484959212c18669f254daa0ae796ad676b67939ba2Jingoo Han clk_enable(sfb->bus_clk); 15494959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 1550b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han if (!sfb->variant.has_clksel) 1551b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han clk_enable(sfb->lcd_clk); 1552b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han 15536aa9681100303bd467cbd0262eb00da8d492fc7fJingoo Han /* setup gpio and output polarity controls */ 15546aa9681100303bd467cbd0262eb00da8d492fc7fJingoo Han pd->setup_gpio(); 15554959212c18669f254daa0ae796ad676b67939ba2Jingoo Han writel(pd->vidcon1, sfb->regs + VIDCON1); 15564959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 15574959212c18669f254daa0ae796ad676b67939ba2Jingoo Han /* zero all windows before we do anything */ 15584959212c18669f254daa0ae796ad676b67939ba2Jingoo Han for (win_no = 0; win_no < sfb->variant.nr_windows; win_no++) 15594959212c18669f254daa0ae796ad676b67939ba2Jingoo Han s3c_fb_clear_win(sfb, win_no); 15604959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 15614959212c18669f254daa0ae796ad676b67939ba2Jingoo Han for (win_no = 0; win_no < sfb->variant.nr_windows - 1; win_no++) { 15624959212c18669f254daa0ae796ad676b67939ba2Jingoo Han void __iomem *regs = sfb->regs + sfb->variant.keycon; 1563ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han win = sfb->windows[win_no]; 1564ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han if (!win) 1565ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han continue; 15664959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 1567ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han shadow_protect_win(win, 1); 15684959212c18669f254daa0ae796ad676b67939ba2Jingoo Han regs += (win_no * 8); 15694959212c18669f254daa0ae796ad676b67939ba2Jingoo Han writel(0xffffff, regs + WKEYCON0); 15704959212c18669f254daa0ae796ad676b67939ba2Jingoo Han writel(0xffffff, regs + WKEYCON1); 1571ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han shadow_protect_win(win, 0); 15724959212c18669f254daa0ae796ad676b67939ba2Jingoo Han } 15734959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 15744959212c18669f254daa0ae796ad676b67939ba2Jingoo Han /* restore framebuffers */ 15754959212c18669f254daa0ae796ad676b67939ba2Jingoo Han for (win_no = 0; win_no < S3C_FB_MAX_WIN; win_no++) { 15764959212c18669f254daa0ae796ad676b67939ba2Jingoo Han win = sfb->windows[win_no]; 15774959212c18669f254daa0ae796ad676b67939ba2Jingoo Han if (!win) 15784959212c18669f254daa0ae796ad676b67939ba2Jingoo Han continue; 15794959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 15804959212c18669f254daa0ae796ad676b67939ba2Jingoo Han dev_dbg(&pdev->dev, "resuming window %d\n", win_no); 15814959212c18669f254daa0ae796ad676b67939ba2Jingoo Han s3c_fb_set_par(win->fbinfo); 15824959212c18669f254daa0ae796ad676b67939ba2Jingoo Han } 15834959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 15844959212c18669f254daa0ae796ad676b67939ba2Jingoo Han return 0; 15854959212c18669f254daa0ae796ad676b67939ba2Jingoo Han} 1586ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks#endif 1587ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 158835784b4315d949e431df9a0ffef721a4801b1588Jingoo Han#ifdef CONFIG_PM_RUNTIME 158935784b4315d949e431df9a0ffef721a4801b1588Jingoo Hanstatic int s3c_fb_runtime_suspend(struct device *dev) 159035784b4315d949e431df9a0ffef721a4801b1588Jingoo Han{ 159135784b4315d949e431df9a0ffef721a4801b1588Jingoo Han return 0; 159235784b4315d949e431df9a0ffef721a4801b1588Jingoo Han} 159335784b4315d949e431df9a0ffef721a4801b1588Jingoo Han 159435784b4315d949e431df9a0ffef721a4801b1588Jingoo Hanstatic int s3c_fb_runtime_resume(struct device *dev) 159535784b4315d949e431df9a0ffef721a4801b1588Jingoo Han{ 159635784b4315d949e431df9a0ffef721a4801b1588Jingoo Han return 0; 159735784b4315d949e431df9a0ffef721a4801b1588Jingoo Han} 159835784b4315d949e431df9a0ffef721a4801b1588Jingoo Han#endif 159950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 160050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks#define VALID_BPP124 (VALID_BPP(1) | VALID_BPP(2) | VALID_BPP(4)) 160150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks#define VALID_BPP1248 (VALID_BPP124 | VALID_BPP(8)) 160250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 16038cfdcb2393b05cc80f89ed0110c0f90423d2fee1Marek Szyprowskistatic struct s3c_fb_win_variant s3c_fb_data_64xx_wins[] = { 160450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [0] = { 160550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .has_osd_c = 1, 1606f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak .osd_size_off = 0x8, 160750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .palette_sz = 256, 1608cd74ebaf7ac18eced59a3983b266be39d7b28ee0Jingoo Han .valid_bpp = (VALID_BPP1248 | VALID_BPP(16) | 1609cd74ebaf7ac18eced59a3983b266be39d7b28ee0Jingoo Han VALID_BPP(18) | VALID_BPP(24)), 161050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks }, 161150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [1] = { 161250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .has_osd_c = 1, 161350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .has_osd_d = 1, 1614c9d503e93562e1de093ff16a480fc8801cfa70d9Jingoo Han .osd_size_off = 0xc, 1615f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak .has_osd_alpha = 1, 161650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .palette_sz = 256, 161750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .valid_bpp = (VALID_BPP1248 | VALID_BPP(16) | 161850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks VALID_BPP(18) | VALID_BPP(19) | 1619cd74ebaf7ac18eced59a3983b266be39d7b28ee0Jingoo Han VALID_BPP(24) | VALID_BPP(25) | 1620cd74ebaf7ac18eced59a3983b266be39d7b28ee0Jingoo Han VALID_BPP(28)), 162150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks }, 162250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [2] = { 162350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .has_osd_c = 1, 162450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .has_osd_d = 1, 1625c9d503e93562e1de093ff16a480fc8801cfa70d9Jingoo Han .osd_size_off = 0xc, 1626f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak .has_osd_alpha = 1, 162750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .palette_sz = 16, 162850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .palette_16bpp = 1, 162950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .valid_bpp = (VALID_BPP1248 | VALID_BPP(16) | 163050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks VALID_BPP(18) | VALID_BPP(19) | 1631cd74ebaf7ac18eced59a3983b266be39d7b28ee0Jingoo Han VALID_BPP(24) | VALID_BPP(25) | 1632cd74ebaf7ac18eced59a3983b266be39d7b28ee0Jingoo Han VALID_BPP(28)), 163350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks }, 163450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [3] = { 163550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .has_osd_c = 1, 1636f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak .has_osd_alpha = 1, 163750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .palette_sz = 16, 163850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .palette_16bpp = 1, 163950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .valid_bpp = (VALID_BPP124 | VALID_BPP(16) | 164050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks VALID_BPP(18) | VALID_BPP(19) | 1641cd74ebaf7ac18eced59a3983b266be39d7b28ee0Jingoo Han VALID_BPP(24) | VALID_BPP(25) | 1642cd74ebaf7ac18eced59a3983b266be39d7b28ee0Jingoo Han VALID_BPP(28)), 164350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks }, 164450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [4] = { 164550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .has_osd_c = 1, 1646f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak .has_osd_alpha = 1, 164750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .palette_sz = 4, 164850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .palette_16bpp = 1, 164950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .valid_bpp = (VALID_BPP(1) | VALID_BPP(2) | 165050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks VALID_BPP(16) | VALID_BPP(18) | 1651cd74ebaf7ac18eced59a3983b266be39d7b28ee0Jingoo Han VALID_BPP(19) | VALID_BPP(24) | 1652cd74ebaf7ac18eced59a3983b266be39d7b28ee0Jingoo Han VALID_BPP(25) | VALID_BPP(28)), 165350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks }, 165450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks}; 165550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 1656af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Hanstatic struct s3c_fb_win_variant s3c_fb_data_s5p_wins[] = { 1657af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han [0] = { 1658af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .has_osd_c = 1, 1659af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .osd_size_off = 0x8, 1660af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .palette_sz = 256, 1661af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .valid_bpp = (VALID_BPP1248 | VALID_BPP(13) | 1662af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(15) | VALID_BPP(16) | 1663af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(18) | VALID_BPP(19) | 1664af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(24) | VALID_BPP(25) | 1665af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(32)), 1666af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han }, 1667af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han [1] = { 1668af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .has_osd_c = 1, 1669af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .has_osd_d = 1, 1670af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .osd_size_off = 0xc, 1671af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .has_osd_alpha = 1, 1672af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .palette_sz = 256, 1673af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .valid_bpp = (VALID_BPP1248 | VALID_BPP(13) | 1674af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(15) | VALID_BPP(16) | 1675af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(18) | VALID_BPP(19) | 1676af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(24) | VALID_BPP(25) | 1677af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(32)), 1678af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han }, 1679af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han [2] = { 1680af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .has_osd_c = 1, 1681af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .has_osd_d = 1, 1682af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .osd_size_off = 0xc, 1683af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .has_osd_alpha = 1, 1684af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .palette_sz = 256, 1685af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .valid_bpp = (VALID_BPP1248 | VALID_BPP(13) | 1686af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(15) | VALID_BPP(16) | 1687af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(18) | VALID_BPP(19) | 1688af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(24) | VALID_BPP(25) | 1689af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(32)), 1690af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han }, 1691af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han [3] = { 1692af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .has_osd_c = 1, 1693af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .has_osd_alpha = 1, 1694af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .palette_sz = 256, 1695af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .valid_bpp = (VALID_BPP1248 | VALID_BPP(13) | 1696af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(15) | VALID_BPP(16) | 1697af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(18) | VALID_BPP(19) | 1698af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(24) | VALID_BPP(25) | 1699af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(32)), 1700af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han }, 1701af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han [4] = { 1702af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .has_osd_c = 1, 1703af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .has_osd_alpha = 1, 1704af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .palette_sz = 256, 1705af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .valid_bpp = (VALID_BPP1248 | VALID_BPP(13) | 1706af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(15) | VALID_BPP(16) | 1707af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(18) | VALID_BPP(19) | 1708af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(24) | VALID_BPP(25) | 1709af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(32)), 1710af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han }, 1711af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han}; 1712af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han 17138cfdcb2393b05cc80f89ed0110c0f90423d2fee1Marek Szyprowskistatic struct s3c_fb_driverdata s3c_fb_data_64xx = { 171450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .variant = { 171550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .nr_windows = 5, 1716c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .vidtcon = VIDTCON0, 1717c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .wincon = WINCON(0), 1718c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .winmap = WINxMAP(0), 1719c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .keycon = WKEYCON, 1720c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .osd = VIDOSD_BASE, 1721c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .osd_stride = 16, 1722c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .buf_start = VIDW_BUF_START(0), 1723c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .buf_size = VIDW_BUF_SIZE(0), 1724c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .buf_end = VIDW_BUF_END(0), 172550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 172650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .palette = { 172750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [0] = 0x400, 172850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [1] = 0x800, 172950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [2] = 0x300, 173050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [3] = 0x320, 173150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [4] = 0x340, 173250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks }, 1733067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak 1734067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak .has_prtcon = 1, 1735b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .has_clksel = 1, 173650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks }, 173750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .win[0] = &s3c_fb_data_64xx_wins[0], 173850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .win[1] = &s3c_fb_data_64xx_wins[1], 173950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .win[2] = &s3c_fb_data_64xx_wins[2], 174050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .win[3] = &s3c_fb_data_64xx_wins[3], 174150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .win[4] = &s3c_fb_data_64xx_wins[4], 174250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks}; 174350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 17448cfdcb2393b05cc80f89ed0110c0f90423d2fee1Marek Szyprowskistatic struct s3c_fb_driverdata s3c_fb_data_s5pc100 = { 17454e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .variant = { 17464e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .nr_windows = 5, 17474e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .vidtcon = VIDTCON0, 17484e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .wincon = WINCON(0), 17494e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .winmap = WINxMAP(0), 17504e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .keycon = WKEYCON, 17514e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .osd = VIDOSD_BASE, 17524e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .osd_stride = 16, 17534e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .buf_start = VIDW_BUF_START(0), 17544e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .buf_size = VIDW_BUF_SIZE(0), 17554e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .buf_end = VIDW_BUF_END(0), 17564e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak 17574e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .palette = { 17584e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak [0] = 0x2400, 17594e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak [1] = 0x2800, 17604e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak [2] = 0x2c00, 17614e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak [3] = 0x3000, 17624e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak [4] = 0x3400, 17634e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak }, 1764067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak 1765067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak .has_prtcon = 1, 1766b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .has_clksel = 1, 17674e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak }, 1768af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .win[0] = &s3c_fb_data_s5p_wins[0], 1769af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .win[1] = &s3c_fb_data_s5p_wins[1], 1770af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .win[2] = &s3c_fb_data_s5p_wins[2], 1771af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .win[3] = &s3c_fb_data_s5p_wins[3], 1772af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .win[4] = &s3c_fb_data_s5p_wins[4], 17734e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak}; 17744e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak 17758cfdcb2393b05cc80f89ed0110c0f90423d2fee1Marek Szyprowskistatic struct s3c_fb_driverdata s3c_fb_data_s5pv210 = { 177650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .variant = { 177750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .nr_windows = 5, 1778c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .vidtcon = VIDTCON0, 1779c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .wincon = WINCON(0), 1780c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .winmap = WINxMAP(0), 1781c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .keycon = WKEYCON, 1782c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .osd = VIDOSD_BASE, 1783c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .osd_stride = 16, 1784c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .buf_start = VIDW_BUF_START(0), 1785c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .buf_size = VIDW_BUF_SIZE(0), 1786c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .buf_end = VIDW_BUF_END(0), 178750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 178850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .palette = { 178950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [0] = 0x2400, 179050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [1] = 0x2800, 179150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [2] = 0x2c00, 179250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [3] = 0x3000, 179350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [4] = 0x3400, 179450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks }, 1795f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak 1796f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak .has_shadowcon = 1, 1797b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .has_clksel = 1, 1798b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han }, 1799b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .win[0] = &s3c_fb_data_s5p_wins[0], 1800b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .win[1] = &s3c_fb_data_s5p_wins[1], 1801b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .win[2] = &s3c_fb_data_s5p_wins[2], 1802b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .win[3] = &s3c_fb_data_s5p_wins[3], 1803b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .win[4] = &s3c_fb_data_s5p_wins[4], 1804b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han}; 1805b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han 1806b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Hanstatic struct s3c_fb_driverdata s3c_fb_data_exynos4 = { 1807b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .variant = { 1808b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .nr_windows = 5, 1809b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .vidtcon = VIDTCON0, 1810b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .wincon = WINCON(0), 1811b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .winmap = WINxMAP(0), 1812b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .keycon = WKEYCON, 1813b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .osd = VIDOSD_BASE, 1814b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .osd_stride = 16, 1815b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .buf_start = VIDW_BUF_START(0), 1816b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .buf_size = VIDW_BUF_SIZE(0), 1817b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .buf_end = VIDW_BUF_END(0), 1818b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han 1819b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .palette = { 1820b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han [0] = 0x2400, 1821b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han [1] = 0x2800, 1822b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han [2] = 0x2c00, 1823b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han [3] = 0x3000, 1824b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han [4] = 0x3400, 1825b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han }, 1826b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han 1827b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .has_shadowcon = 1, 182850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks }, 1829af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .win[0] = &s3c_fb_data_s5p_wins[0], 1830af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .win[1] = &s3c_fb_data_s5p_wins[1], 1831af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .win[2] = &s3c_fb_data_s5p_wins[2], 1832af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .win[3] = &s3c_fb_data_s5p_wins[3], 1833af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .win[4] = &s3c_fb_data_s5p_wins[4], 183450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks}; 183550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 1836c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks/* S3C2443/S3C2416 style hardware */ 18378cfdcb2393b05cc80f89ed0110c0f90423d2fee1Marek Szyprowskistatic struct s3c_fb_driverdata s3c_fb_data_s3c2443 = { 1838c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .variant = { 1839c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .nr_windows = 2, 1840c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .is_2443 = 1, 1841c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks 1842c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .vidtcon = 0x08, 1843c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .wincon = 0x14, 1844c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .winmap = 0xd0, 1845c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .keycon = 0xb0, 1846c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .osd = 0x28, 1847c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .osd_stride = 12, 1848c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .buf_start = 0x64, 1849c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .buf_size = 0x94, 1850c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .buf_end = 0x7c, 1851c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks 1852c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .palette = { 1853c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks [0] = 0x400, 1854c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks [1] = 0x800, 1855c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks }, 1856b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .has_clksel = 1, 1857c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks }, 1858c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .win[0] = &(struct s3c_fb_win_variant) { 1859c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .palette_sz = 256, 1860c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .valid_bpp = VALID_BPP1248 | VALID_BPP(16) | VALID_BPP(24), 1861c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks }, 1862c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .win[1] = &(struct s3c_fb_win_variant) { 1863c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .has_osd_c = 1, 1864f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak .has_osd_alpha = 1, 1865c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .palette_sz = 256, 1866c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .valid_bpp = (VALID_BPP1248 | VALID_BPP(16) | 1867c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks VALID_BPP(18) | VALID_BPP(19) | 1868c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks VALID_BPP(24) | VALID_BPP(25) | 1869c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks VALID_BPP(28)), 1870c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks }, 1871c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks}; 1872c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks 187321b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumarstatic struct s3c_fb_driverdata s3c_fb_data_s5p64x0 = { 187421b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .variant = { 187521b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .nr_windows = 3, 187621b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .vidtcon = VIDTCON0, 187721b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .wincon = WINCON(0), 187821b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .winmap = WINxMAP(0), 187921b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .keycon = WKEYCON, 188021b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .osd = VIDOSD_BASE, 188121b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .osd_stride = 16, 188221b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .buf_start = VIDW_BUF_START(0), 188321b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .buf_size = VIDW_BUF_SIZE(0), 188421b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .buf_end = VIDW_BUF_END(0), 188521b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar 188621b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .palette = { 188721b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar [0] = 0x2400, 188821b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar [1] = 0x2800, 188921b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar [2] = 0x2c00, 189021b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar }, 189121b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar }, 189221b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .win[0] = &s3c_fb_data_s5p_wins[0], 189321b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .win[1] = &s3c_fb_data_s5p_wins[1], 189421b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .win[2] = &s3c_fb_data_s5p_wins[2], 189521b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar}; 189621b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar 189750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooksstatic struct platform_device_id s3c_fb_driver_ids[] = { 189850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks { 189950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .name = "s3c-fb", 190050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .driver_data = (unsigned long)&s3c_fb_data_64xx, 190150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks }, { 19024e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .name = "s5pc100-fb", 19034e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .driver_data = (unsigned long)&s3c_fb_data_s5pc100, 19044e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak }, { 19054e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .name = "s5pv210-fb", 19064e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .driver_data = (unsigned long)&s3c_fb_data_s5pv210, 1907c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks }, { 1908b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .name = "exynos4-fb", 1909b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .driver_data = (unsigned long)&s3c_fb_data_exynos4, 1910b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han }, { 1911c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .name = "s3c2443-fb", 1912c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .driver_data = (unsigned long)&s3c_fb_data_s3c2443, 191321b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar }, { 191421b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .name = "s5p64x0-fb", 191521b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .driver_data = (unsigned long)&s3c_fb_data_s5p64x0, 191650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks }, 191750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks {}, 191850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks}; 191950a5503a9208420e6c59d24504a5e9913d603cf7Ben DooksMODULE_DEVICE_TABLE(platform, s3c_fb_driver_ids); 192050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 192135784b4315d949e431df9a0ffef721a4801b1588Jingoo Hanstatic const struct dev_pm_ops s3c_fb_pm_ops = { 192235784b4315d949e431df9a0ffef721a4801b1588Jingoo Han SET_SYSTEM_SLEEP_PM_OPS(s3c_fb_suspend, s3c_fb_resume) 192335784b4315d949e431df9a0ffef721a4801b1588Jingoo Han SET_RUNTIME_PM_OPS(s3c_fb_runtime_suspend, s3c_fb_runtime_resume, NULL) 192435784b4315d949e431df9a0ffef721a4801b1588Jingoo Han}; 19254959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 1926ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic struct platform_driver s3c_fb_driver = { 1927ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks .probe = s3c_fb_probe, 19283163eaba34943967aebb1eefa0d4bdc4e5dc197cPeter Korsgaard .remove = __devexit_p(s3c_fb_remove), 192950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .id_table = s3c_fb_driver_ids, 1930ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks .driver = { 1931ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks .name = "s3c-fb", 1932ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks .owner = THIS_MODULE, 193335784b4315d949e431df9a0ffef721a4801b1588Jingoo Han .pm = &s3c_fb_pm_ops, 1934ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks }, 1935ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks}; 1936ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 19374277f2c4667187cbbdd3da3be31ee681bc6b8300Axel Linmodule_platform_driver(s3c_fb_driver); 1938ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1939ec549a0fdc32171b26677f1ef0b5309faa743362Ben DooksMODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); 1940ec549a0fdc32171b26677f1ef0b5309faa743362Ben DooksMODULE_DESCRIPTION("Samsung S3C SoC Framebuffer driver"); 1941ec549a0fdc32171b26677f1ef0b5309faa743362Ben DooksMODULE_LICENSE("GPL"); 1942ec549a0fdc32171b26677f1ef0b5309faa743362Ben DooksMODULE_ALIAS("platform:s3c-fb"); 1943