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); \ 5105e52b4bfba0d1fa4195abbc4ac29c24033c8e96Jingoo Han __raw_writel(v, r); \ 5205e52b4bfba0d1fa4195abbc4ac29c24033c8e96Jingoo Han} while (0) 53ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks#endif /* FB_S3C_DEBUG_REGWRITE */ 54ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 55efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak/* irq_flags bits */ 56efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak#define S3C_FB_VSYNC_IRQ_EN 0 57efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 58efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak#define VSYNC_TIMEOUT_MSEC 50 59efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 60ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstruct s3c_fb; 61ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 6250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks#define VALID_BPP(x) (1 << ((x) - 1)) 6350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 64c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks#define OSD_BASE(win, variant) ((variant).osd + ((win) * (variant).osd_stride)) 65c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks#define VIDOSD_A(win, variant) (OSD_BASE(win, variant) + 0x00) 66c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks#define VIDOSD_B(win, variant) (OSD_BASE(win, variant) + 0x04) 67c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks#define VIDOSD_C(win, variant) (OSD_BASE(win, variant) + 0x08) 68c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks#define VIDOSD_D(win, variant) (OSD_BASE(win, variant) + 0x0C) 69c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks 7050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks/** 7150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * struct s3c_fb_variant - fb variant information 72c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks * @is_2443: Set if S3C2443/S3C2416 style hardware. 7350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @nr_windows: The number of windows. 74c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks * @vidtcon: The base for the VIDTCONx registers 75c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks * @wincon: The base for the WINxCON registers. 76c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks * @winmap: The base for the WINxMAP registers. 77c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks * @keycon: The abse for the WxKEYCON registers. 78c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks * @buf_start: Offset of buffer start registers. 79c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks * @buf_size: Offset of buffer size registers. 80c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks * @buf_end: Offset of buffer end registers. 81c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks * @osd: The base for the OSD registers. 8250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @palette: Address of palette memory, or 0 if none. 83067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak * @has_prtcon: Set if has PRTCON register. 84f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak * @has_shadowcon: Set if has SHADOWCON register. 85f7f31e505aa79d91b979a38789b1608744361bdcJingoo Han * @has_blendcon: Set if has BLENDCON register. 86b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han * @has_clksel: Set if VIDCON0 register has CLKSEL bit. 87d8b97db4c8e40e49985fa5802be914292add64f6Jingoo Han * @has_fixvclk: Set if VIDCON1 register has FIXVCLK bits. 8850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks */ 8950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooksstruct s3c_fb_variant { 90c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks unsigned int is_2443:1; 9150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks unsigned short nr_windows; 925c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han unsigned int vidtcon; 93c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks unsigned short wincon; 94c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks unsigned short winmap; 95c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks unsigned short keycon; 96c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks unsigned short buf_start; 97c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks unsigned short buf_end; 98c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks unsigned short buf_size; 99c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks unsigned short osd; 100c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks unsigned short osd_stride; 10150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks unsigned short palette[S3C_FB_MAX_WIN]; 102067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak 103067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak unsigned int has_prtcon:1; 104f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak unsigned int has_shadowcon:1; 105f7f31e505aa79d91b979a38789b1608744361bdcJingoo Han unsigned int has_blendcon:1; 106b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han unsigned int has_clksel:1; 107d8b97db4c8e40e49985fa5802be914292add64f6Jingoo Han unsigned int has_fixvclk:1; 10850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks}; 10950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 11050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks/** 11150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * struct s3c_fb_win_variant 11250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @has_osd_c: Set if has OSD C register. 11350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @has_osd_d: Set if has OSD D register. 114f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak * @has_osd_alpha: Set if can change alpha transparency for a window. 11550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @palette_sz: Size of palette in entries. 11650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @palette_16bpp: Set if palette is 16bits wide. 117f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak * @osd_size_off: If != 0, supports setting up OSD for a window; the appropriate 118f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak * register is located at the given offset from OSD_BASE. 11950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @valid_bpp: 1 bit per BPP setting to show valid bits-per-pixel. 12050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * 12150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * valid_bpp bit x is set if (x+1)BPP is supported. 12250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks */ 12350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooksstruct s3c_fb_win_variant { 12450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks unsigned int has_osd_c:1; 12550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks unsigned int has_osd_d:1; 126f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak unsigned int has_osd_alpha:1; 12750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks unsigned int palette_16bpp:1; 128f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak unsigned short osd_size_off; 12950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks unsigned short palette_sz; 13050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks u32 valid_bpp; 13150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks}; 13250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 13350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks/** 13450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * struct s3c_fb_driverdata - per-device type driver data for init time. 13550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @variant: The variant information for this driver. 13650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @win: The window information for each window. 13750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks */ 13850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooksstruct s3c_fb_driverdata { 13950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks struct s3c_fb_variant variant; 14050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks struct s3c_fb_win_variant *win[S3C_FB_MAX_WIN]; 14150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks}; 14250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 143ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 144bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks * struct s3c_fb_palette - palette information 145bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks * @r: Red bitfield. 146bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks * @g: Green bitfield. 147bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks * @b: Blue bitfield. 148bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks * @a: Alpha bitfield. 149bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks */ 150bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooksstruct s3c_fb_palette { 151bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks struct fb_bitfield r; 152bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks struct fb_bitfield g; 153bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks struct fb_bitfield b; 154bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks struct fb_bitfield a; 155bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks}; 156bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks 157bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks/** 158ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * struct s3c_fb_win - per window private data for each framebuffer. 159ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @windata: The platform data supplied for the window configuration. 160ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @parent: The hardware that this window is part of. 161ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @fbinfo: Pointer pack to the framebuffer info for this window. 16250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @varint: The variant information for this window. 163ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @palette_buffer: Buffer/cache to hold palette entries. 164ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @pseudo_palette: For use in TRUECOLOUR modes for entries 0..15/ 165ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @index: The window number of this window. 166ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @palette: The bitfields for changing r/g/b into a hardware palette entry. 167ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 168ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstruct s3c_fb_win { 169ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_pd_win *windata; 170ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb *parent; 171ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct fb_info *fbinfo; 172ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_palette palette; 17350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks struct s3c_fb_win_variant variant; 174ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 175ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks u32 *palette_buffer; 176ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks u32 pseudo_palette[16]; 177ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks unsigned int index; 178ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks}; 179ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 180ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 181efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * struct s3c_fb_vsync - vsync information 182efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * @wait: a queue for processes waiting for vsync 183efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * @count: vsync interrupt count 184efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak */ 185efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciakstruct s3c_fb_vsync { 186efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak wait_queue_head_t wait; 187efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak unsigned int count; 188efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak}; 189efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 190efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak/** 191ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * struct s3c_fb - overall hardware state of the hardware 192b07f3bbee12163a6b48991138a37b87a1126462aJingoo Han * @slock: The spinlock protection for this data sturcture. 193ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @dev: The device that we bound to, for printing, etc. 194ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk. 195b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han * @lcd_clk: The clk (sclk) feeding pixclk. 196ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @regs: The mapped hardware registers. 19750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @variant: Variant information for this hardware. 198ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @enabled: A bitmask of enabled hardware windows. 199f4f514734e3d398cfb70827615f129826ff84b06Mark Brown * @output_on: Flag if the physical output is enabled. 200ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @pdata: The platform configuration data passed with the device. 201ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @windows: The hardware windows that have been claimed. 202efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * @irq_no: IRQ line number 203efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * @irq_flags: irq flags 204efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * @vsync_info: VSYNC-related information (count, queues...) 205ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 206ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstruct s3c_fb { 207b07f3bbee12163a6b48991138a37b87a1126462aJingoo Han spinlock_t slock; 208ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct device *dev; 209ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct clk *bus_clk; 210b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han struct clk *lcd_clk; 211ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks void __iomem *regs; 21250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks struct s3c_fb_variant variant; 213ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 214ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks unsigned char enabled; 215f4f514734e3d398cfb70827615f129826ff84b06Mark Brown bool output_on; 216ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 217ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_platdata *pdata; 218ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_win *windows[S3C_FB_MAX_WIN]; 219efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 220efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak int irq_no; 221efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak unsigned long irq_flags; 222efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak struct s3c_fb_vsync vsync_info; 223ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks}; 224ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 225ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 22650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * s3c_fb_validate_win_bpp - validate the bits-per-pixel for this mode. 22750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @win: The device window. 22850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @bpp: The bit depth. 229ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 23050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooksstatic bool s3c_fb_validate_win_bpp(struct s3c_fb_win *win, unsigned int bpp) 231ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 23250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks return win->variant.valid_bpp & VALID_BPP(bpp); 233ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 234ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 235ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 236ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_check_var() - framebuffer layer request to verify a given mode. 237ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @var: The screen information to verify. 238ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @info: The framebuffer device. 239ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 240ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Framebuffer layer call to verify the given information and allow us to 241ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * update various information depending on the hardware capabilities. 242ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 243ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic int s3c_fb_check_var(struct fb_var_screeninfo *var, 244ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct fb_info *info) 245ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 246ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_win *win = info->par; 247ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb *sfb = win->parent; 248ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 249ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(sfb->dev, "checking parameters\n"); 250ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 25113e6af8886f3225fb9141dc3b6915d84bd4ad4deJingoo Han var->xres_virtual = max(var->xres_virtual, var->xres); 25213e6af8886f3225fb9141dc3b6915d84bd4ad4deJingoo Han var->yres_virtual = max(var->yres_virtual, var->yres); 253ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 25450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks if (!s3c_fb_validate_win_bpp(win, var->bits_per_pixel)) { 255ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(sfb->dev, "win %d: unsupported bpp %d\n", 256ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks win->index, var->bits_per_pixel); 257ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return -EINVAL; 258ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 259ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 260ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* always ensure these are zero, for drop through cases below */ 261ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->transp.offset = 0; 262ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->transp.length = 0; 263ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 264ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks switch (var->bits_per_pixel) { 265ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 1: 266ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 2: 267ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 4: 268ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 8: 26950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks if (sfb->variant.palette[win->index] != 0) { 270ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* non palletised, A:1,R:2,G:3,B:2 mode */ 271ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->red.offset = 4; 272ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->green.offset = 2; 273ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->blue.offset = 0; 274ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->red.length = 5; 275ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->green.length = 3; 276ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->blue.length = 2; 277ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->transp.offset = 7; 278ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->transp.length = 1; 279ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } else { 280ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->red.offset = 0; 281ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->red.length = var->bits_per_pixel; 282ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->green = var->red; 283ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->blue = var->red; 284ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 285ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 286ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 287ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 19: 288ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* 666 with one bit alpha/transparency */ 289ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->transp.offset = 18; 290ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->transp.length = 1; 291ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 18: 292ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->bits_per_pixel = 32; 293ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 294ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* 666 format */ 295ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->red.offset = 12; 296ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->green.offset = 6; 297ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->blue.offset = 0; 298ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->red.length = 6; 299ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->green.length = 6; 300ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->blue.length = 6; 301ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 302ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 303ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 16: 304ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* 16 bpp, 565 format */ 305ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->red.offset = 11; 306ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->green.offset = 5; 307ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->blue.offset = 0; 308ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->red.length = 5; 309ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->green.length = 6; 310ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->blue.length = 5; 311ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 312ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 313af1ce6b2fad7d572aef040d61a935da28a861853Jingoo Han case 32: 314ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 28: 315ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 25: 316ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->transp.length = var->bits_per_pixel - 24; 317ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->transp.offset = 24; 318ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* drop through */ 319ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 24: 320ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* our 24bpp is unpacked, so 32bpp */ 321ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->bits_per_pixel = 32; 322ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->red.offset = 16; 323ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->red.length = 8; 324ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->green.offset = 8; 325ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->green.length = 8; 326ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->blue.offset = 0; 327ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->blue.length = 8; 328ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 329ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 330ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks default: 331ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_err(sfb->dev, "invalid bpp\n"); 332ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 333ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 334ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(sfb->dev, "%s: verified parameters\n", __func__); 335ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return 0; 336ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 337ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 338ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 339ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_calc_pixclk() - calculate the divider to create the pixel clock. 340ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @sfb: The hardware state. 341ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @pixclock: The pixel clock wanted, in picoseconds. 342ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 343ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Given the specified pixel clock, work out the necessary divider to get 344ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * close to the output frequency. 345ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 346eb29a5cc0b601c458bae9df2f6c3696d75c2d383Mark Brownstatic int s3c_fb_calc_pixclk(struct s3c_fb *sfb, unsigned int pixclk) 347ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 348b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han unsigned long clk; 349eb29a5cc0b601c458bae9df2f6c3696d75c2d383Mark Brown unsigned long long tmp; 350ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks unsigned int result; 351ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 352b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han if (sfb->variant.has_clksel) 353b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han clk = clk_get_rate(sfb->bus_clk); 354b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han else 355b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han clk = clk_get_rate(sfb->lcd_clk); 356b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han 357eb29a5cc0b601c458bae9df2f6c3696d75c2d383Mark Brown tmp = (unsigned long long)clk; 358eb29a5cc0b601c458bae9df2f6c3696d75c2d383Mark Brown tmp *= pixclk; 359eb29a5cc0b601c458bae9df2f6c3696d75c2d383Mark Brown 360eb29a5cc0b601c458bae9df2f6c3696d75c2d383Mark Brown do_div(tmp, 1000000000UL); 361eb29a5cc0b601c458bae9df2f6c3696d75c2d383Mark Brown result = (unsigned int)tmp / 1000; 362ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 363ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(sfb->dev, "pixclk=%u, clk=%lu, div=%d (%lu)\n", 364ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks pixclk, clk, result, clk / result); 365ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 366ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return result; 367ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 368ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 369ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 370ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_align_word() - align pixel count to word boundary 371ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @bpp: The number of bits per pixel 372ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @pix: The value to be aligned. 373ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 374ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Align the given pixel count so that it will start on an 32bit word 375ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * boundary. 376ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 377ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic int s3c_fb_align_word(unsigned int bpp, unsigned int pix) 378ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 379ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks int pix_per_word; 380ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 381ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (bpp > 16) 382ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return pix; 383ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 384ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks pix_per_word = (8 * 32) / bpp; 385ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return ALIGN(pix, pix_per_word); 386ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 387ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 388ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 389f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak * vidosd_set_size() - set OSD size for a window 390f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak * 391f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak * @win: the window to set OSD size for 392f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak * @size: OSD size register value 393f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak */ 394f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciakstatic void vidosd_set_size(struct s3c_fb_win *win, u32 size) 395f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak{ 396f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak struct s3c_fb *sfb = win->parent; 397f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak 398f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak /* OSD can be set up if osd_size_off != 0 for this window */ 399f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak if (win->variant.osd_size_off) 400f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak writel(size, sfb->regs + OSD_BASE(win->index, sfb->variant) 401f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak + win->variant.osd_size_off); 402f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak} 403f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak 404f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak/** 405f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak * vidosd_set_alpha() - set alpha transparency for a window 406f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak * 407f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak * @win: the window to set OSD size for 408f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak * @alpha: alpha register value 409f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak */ 410f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciakstatic void vidosd_set_alpha(struct s3c_fb_win *win, u32 alpha) 411f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak{ 412f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak struct s3c_fb *sfb = win->parent; 413f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak 414f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak if (win->variant.has_osd_alpha) 415f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak writel(alpha, sfb->regs + VIDOSD_C(win->index, sfb->variant)); 416f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak} 417f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak 418f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak/** 419f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak * shadow_protect_win() - disable updating values from shadow registers at vsync 420f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak * 421f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak * @win: window to protect registers for 422f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak * @protect: 1 to protect (disable updates) 423f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak */ 424f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciakstatic void shadow_protect_win(struct s3c_fb_win *win, bool protect) 425f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak{ 426f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak struct s3c_fb *sfb = win->parent; 427f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak u32 reg; 428f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak 429f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak if (protect) { 430f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak if (sfb->variant.has_prtcon) { 431f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak writel(PRTCON_PROTECT, sfb->regs + PRTCON); 432f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak } else if (sfb->variant.has_shadowcon) { 433f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak reg = readl(sfb->regs + SHADOWCON); 434f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak writel(reg | SHADOWCON_WINx_PROTECT(win->index), 435f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak sfb->regs + SHADOWCON); 436f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak } 437f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak } else { 438f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak if (sfb->variant.has_prtcon) { 439f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak writel(0, sfb->regs + PRTCON); 440f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak } else if (sfb->variant.has_shadowcon) { 441f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak reg = readl(sfb->regs + SHADOWCON); 442f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak writel(reg & ~SHADOWCON_WINx_PROTECT(win->index), 443f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak sfb->regs + SHADOWCON); 444f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak } 445f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak } 446f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak} 447f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak 448f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak/** 449a2b77dcebf6e968bada4d415d426b39ac199e8aaMark Brown * s3c_fb_enable() - Set the state of the main LCD output 450a2b77dcebf6e968bada4d415d426b39ac199e8aaMark Brown * @sfb: The main framebuffer state. 451a2b77dcebf6e968bada4d415d426b39ac199e8aaMark Brown * @enable: The state to set. 452a2b77dcebf6e968bada4d415d426b39ac199e8aaMark Brown */ 453a2b77dcebf6e968bada4d415d426b39ac199e8aaMark Brownstatic void s3c_fb_enable(struct s3c_fb *sfb, int enable) 454a2b77dcebf6e968bada4d415d426b39ac199e8aaMark Brown{ 455a2b77dcebf6e968bada4d415d426b39ac199e8aaMark Brown u32 vidcon0 = readl(sfb->regs + VIDCON0); 456a2b77dcebf6e968bada4d415d426b39ac199e8aaMark Brown 457f4f514734e3d398cfb70827615f129826ff84b06Mark Brown if (enable && !sfb->output_on) 458f4f514734e3d398cfb70827615f129826ff84b06Mark Brown pm_runtime_get_sync(sfb->dev); 459f4f514734e3d398cfb70827615f129826ff84b06Mark Brown 460f4f514734e3d398cfb70827615f129826ff84b06Mark Brown if (enable) { 461a2b77dcebf6e968bada4d415d426b39ac199e8aaMark Brown vidcon0 |= VIDCON0_ENVID | VIDCON0_ENVID_F; 462f4f514734e3d398cfb70827615f129826ff84b06Mark Brown } else { 463a2b77dcebf6e968bada4d415d426b39ac199e8aaMark Brown /* see the note in the framebuffer datasheet about 464a2b77dcebf6e968bada4d415d426b39ac199e8aaMark Brown * why you cannot take both of these bits down at the 465a2b77dcebf6e968bada4d415d426b39ac199e8aaMark Brown * same time. */ 466a2b77dcebf6e968bada4d415d426b39ac199e8aaMark Brown 467f4f514734e3d398cfb70827615f129826ff84b06Mark Brown if (vidcon0 & VIDCON0_ENVID) { 468f4f514734e3d398cfb70827615f129826ff84b06Mark Brown vidcon0 |= VIDCON0_ENVID; 469f4f514734e3d398cfb70827615f129826ff84b06Mark Brown vidcon0 &= ~VIDCON0_ENVID_F; 470f4f514734e3d398cfb70827615f129826ff84b06Mark Brown } 471a2b77dcebf6e968bada4d415d426b39ac199e8aaMark Brown } 472a2b77dcebf6e968bada4d415d426b39ac199e8aaMark Brown 473a2b77dcebf6e968bada4d415d426b39ac199e8aaMark Brown writel(vidcon0, sfb->regs + VIDCON0); 474f4f514734e3d398cfb70827615f129826ff84b06Mark Brown 475f4f514734e3d398cfb70827615f129826ff84b06Mark Brown if (!enable && sfb->output_on) 476f4f514734e3d398cfb70827615f129826ff84b06Mark Brown pm_runtime_put_sync(sfb->dev); 477f4f514734e3d398cfb70827615f129826ff84b06Mark Brown 478f4f514734e3d398cfb70827615f129826ff84b06Mark Brown sfb->output_on = enable; 479a2b77dcebf6e968bada4d415d426b39ac199e8aaMark Brown} 480a2b77dcebf6e968bada4d415d426b39ac199e8aaMark Brown 481a2b77dcebf6e968bada4d415d426b39ac199e8aaMark Brown/** 482ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_set_par() - framebuffer request to set new framebuffer state. 483ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @info: The framebuffer to change. 484ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 485ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Framebuffer layer request to set a new mode for the specified framebuffer 486ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 487ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic int s3c_fb_set_par(struct fb_info *info) 488ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 489ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct fb_var_screeninfo *var = &info->var; 490ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_win *win = info->par; 491ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb *sfb = win->parent; 492ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks void __iomem *regs = sfb->regs; 493c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks void __iomem *buf = regs; 494ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks int win_no = win->index; 495f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak u32 alpha = 0; 496ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks u32 data; 497ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks u32 pagewidth; 498ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks int clkdiv; 499ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 500ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(sfb->dev, "setting framebuffer parameters\n"); 501ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 5025751b23efb1d91db729ac52e78dd9c9e57baf19fMark Brown pm_runtime_get_sync(sfb->dev); 5035751b23efb1d91db729ac52e78dd9c9e57baf19fMark Brown 504a8bdabca3ad69de632bd13f1cb65639e9a556e20Pawel Osciak shadow_protect_win(win, 1); 505a8bdabca3ad69de632bd13f1cb65639e9a556e20Pawel Osciak 506ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks switch (var->bits_per_pixel) { 507ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 32: 508ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 24: 509ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 16: 510ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 12: 511ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks info->fix.visual = FB_VISUAL_TRUECOLOR; 512ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 513ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 8: 51450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks if (win->variant.palette_sz >= 256) 515ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks info->fix.visual = FB_VISUAL_PSEUDOCOLOR; 516ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks else 517ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks info->fix.visual = FB_VISUAL_TRUECOLOR; 518ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 519ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 1: 520ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks info->fix.visual = FB_VISUAL_MONO01; 521ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 522ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks default: 523ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks info->fix.visual = FB_VISUAL_PSEUDOCOLOR; 524ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 525ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 526ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 527ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8; 528ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 529067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak info->fix.xpanstep = info->var.xres_virtual > info->var.xres ? 1 : 0; 530067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak info->fix.ypanstep = info->var.yres_virtual > info->var.yres ? 1 : 0; 531067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak 532ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* disable the window whilst we update it */ 533ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks writel(0, regs + WINCON(win_no)); 534ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 535ad04490a171915737c9b99d2fa5cb813830f24c1InKi Dae /* use platform specified window as the basis for the lcd timings */ 536ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 537ad04490a171915737c9b99d2fa5cb813830f24c1InKi Dae if (win_no == sfb->pdata->default_win) { 538eb29a5cc0b601c458bae9df2f6c3696d75c2d383Mark Brown clkdiv = s3c_fb_calc_pixclk(sfb, var->pixclock); 539ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 540ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data = sfb->pdata->vidcon0; 541ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR); 542ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 543ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (clkdiv > 1) 544ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= VIDCON0_CLKVAL_F(clkdiv-1) | VIDCON0_CLKDIR; 545ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks else 546ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data &= ~VIDCON0_CLKDIR; /* 1:1 clock */ 547ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 548ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* write the timing data to the panel */ 549ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 550c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks if (sfb->variant.is_2443) 551c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks data |= (1 << 5); 552c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks 553ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks writel(data, regs + VIDCON0); 554ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 555a2b77dcebf6e968bada4d415d426b39ac199e8aaMark Brown s3c_fb_enable(sfb, 1); 556a2b77dcebf6e968bada4d415d426b39ac199e8aaMark Brown 557ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data = VIDTCON0_VBPD(var->upper_margin - 1) | 558ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks VIDTCON0_VFPD(var->lower_margin - 1) | 559ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks VIDTCON0_VSPW(var->vsync_len - 1); 560ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 561c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(data, regs + sfb->variant.vidtcon); 562ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 563ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data = VIDTCON1_HBPD(var->left_margin - 1) | 564ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks VIDTCON1_HFPD(var->right_margin - 1) | 565ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks VIDTCON1_HSPW(var->hsync_len - 1); 566ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 567c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks /* VIDTCON1 */ 568c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(data, regs + sfb->variant.vidtcon + 4); 569ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 570ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data = VIDTCON2_LINEVAL(var->yres - 1) | 5715c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han VIDTCON2_HOZVAL(var->xres - 1) | 5725c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han VIDTCON2_LINEVAL_E(var->yres - 1) | 5735c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han VIDTCON2_HOZVAL_E(var->xres - 1); 574b73a21fc66fee35b41db755abebfacba48b2fc76Jingoo Han writel(data, regs + sfb->variant.vidtcon + 8); 575ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 576ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 577ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* write the buffer address */ 578ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 579c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks /* start and end registers stride is 8 */ 580c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks buf = regs + win_no * 8; 581c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks 582c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(info->fix.smem_start, buf + sfb->variant.buf_start); 583ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 584ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data = info->fix.smem_start + info->fix.line_length * var->yres; 585c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(data, buf + sfb->variant.buf_end); 586ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 587ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks pagewidth = (var->xres * var->bits_per_pixel) >> 3; 588ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data = VIDW_BUF_SIZE_OFFSET(info->fix.line_length - pagewidth) | 5895c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han VIDW_BUF_SIZE_PAGEWIDTH(pagewidth) | 5905c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han VIDW_BUF_SIZE_OFFSET_E(info->fix.line_length - pagewidth) | 5915c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han VIDW_BUF_SIZE_PAGEWIDTH_E(pagewidth); 592c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(data, regs + sfb->variant.buf_size + (win_no * 4)); 593ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 594ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* write 'OSD' registers to control position of framebuffer */ 595ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 5965c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han data = VIDOSDxA_TOPLEFT_X(0) | VIDOSDxA_TOPLEFT_Y(0) | 5975c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han VIDOSDxA_TOPLEFT_X_E(0) | VIDOSDxA_TOPLEFT_Y_E(0); 598c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(data, regs + VIDOSD_A(win_no, sfb->variant)); 599ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 600ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data = VIDOSDxB_BOTRIGHT_X(s3c_fb_align_word(var->bits_per_pixel, 601ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var->xres - 1)) | 6025c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han VIDOSDxB_BOTRIGHT_Y(var->yres - 1) | 6035c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han VIDOSDxB_BOTRIGHT_X_E(s3c_fb_align_word(var->bits_per_pixel, 6045c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han var->xres - 1)) | 6055c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han VIDOSDxB_BOTRIGHT_Y_E(var->yres - 1); 606ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 607c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(data, regs + VIDOSD_B(win_no, sfb->variant)); 608ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 609ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data = var->xres * var->yres; 61039000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae 611f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak alpha = VIDISD14C_ALPHA1_R(0xf) | 61239000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae VIDISD14C_ALPHA1_G(0xf) | 61339000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae VIDISD14C_ALPHA1_B(0xf); 61439000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae 615f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak vidosd_set_alpha(win, alpha); 616f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak vidosd_set_size(win, data); 617ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 618fab7c5b778b1e0ee89e75679b2d6a1405318bb11Jingoo Han /* Enable DMA channel for this window */ 619fab7c5b778b1e0ee89e75679b2d6a1405318bb11Jingoo Han if (sfb->variant.has_shadowcon) { 620fab7c5b778b1e0ee89e75679b2d6a1405318bb11Jingoo Han data = readl(sfb->regs + SHADOWCON); 621fab7c5b778b1e0ee89e75679b2d6a1405318bb11Jingoo Han data |= SHADOWCON_CHx_ENABLE(win_no); 622fab7c5b778b1e0ee89e75679b2d6a1405318bb11Jingoo Han writel(data, sfb->regs + SHADOWCON); 623fab7c5b778b1e0ee89e75679b2d6a1405318bb11Jingoo Han } 624fab7c5b778b1e0ee89e75679b2d6a1405318bb11Jingoo Han 625ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data = WINCONx_ENWIN; 6262d9ae7ac48c91e15e693038bf0dff004f7872aafJingoo Han sfb->enabled |= (1 << win->index); 627ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 628ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* note, since we have to round up the bits-per-pixel, we end up 629ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * relying on the bitfield information for r/g/b/a to work out 630ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * exactly which mode of operation is intended. */ 631ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 632ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks switch (var->bits_per_pixel) { 633ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 1: 634ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCON0_BPPMODE_1BPP; 635ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCONx_BITSWP; 636ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCONx_BURSTLEN_4WORD; 637ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 638ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 2: 639ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCON0_BPPMODE_2BPP; 640ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCONx_BITSWP; 641ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCONx_BURSTLEN_8WORD; 642ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 643ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 4: 644ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCON0_BPPMODE_4BPP; 645ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCONx_BITSWP; 646ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCONx_BURSTLEN_8WORD; 647ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 648ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 8: 649ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (var->transp.length != 0) 650ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCON1_BPPMODE_8BPP_1232; 651ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks else 652ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCON0_BPPMODE_8BPP_PALETTE; 653ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCONx_BURSTLEN_8WORD; 654ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCONx_BYTSWP; 655ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 656ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 16: 657ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (var->transp.length != 0) 658ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCON1_BPPMODE_16BPP_A1555; 659ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks else 660ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCON0_BPPMODE_16BPP_565; 661ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCONx_HAWSWP; 662ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCONx_BURSTLEN_16WORD; 663ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 664ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 24: 665ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case 32: 666ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (var->red.length == 6) { 667ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (var->transp.length != 0) 668ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCON1_BPPMODE_19BPP_A1666; 669ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks else 670ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCON1_BPPMODE_18BPP_666; 67139000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae } else if (var->transp.length == 1) 67239000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae data |= WINCON1_BPPMODE_25BPP_A1888 67339000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae | WINCON1_BLD_PIX; 6744420dd2b306f1997232a13462bca0d420be5b1b8Jingoo Han else if ((var->transp.length == 4) || 6754420dd2b306f1997232a13462bca0d420be5b1b8Jingoo Han (var->transp.length == 8)) 67639000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae data |= WINCON1_BPPMODE_28BPP_A4888 67739000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae | WINCON1_BLD_PIX | WINCON1_ALPHA_SEL; 678ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks else 679ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCON0_BPPMODE_24BPP_888; 680ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 681dc8498c00f6a41a28f01111a3d2ed9f179356a71InKi Dae data |= WINCONx_WSWP; 682ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks data |= WINCONx_BURSTLEN_16WORD; 683ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 684ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 685ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 686c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks /* Enable the colour keying for the window below this one */ 68739000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae if (win_no > 0) { 68839000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae u32 keycon0_data = 0, keycon1_data = 0; 689c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks void __iomem *keycon = regs + sfb->variant.keycon; 69039000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae 69139000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae keycon0_data = ~(WxKEYCON0_KEYBL_EN | 69239000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae WxKEYCON0_KEYEN_F | 69339000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae WxKEYCON0_DIRCON) | WxKEYCON0_COMPKEY(0); 69439000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae 69539000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae keycon1_data = WxKEYCON1_COLVAL(0xffffff); 69639000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae 697c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks keycon += (win_no - 1) * 8; 698c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks 699c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(keycon0_data, keycon + WKEYCON0); 700c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(keycon1_data, keycon + WKEYCON1); 70139000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae } 70239000d654c2a22ca51fe92a39003d5fade59e9e4InKi Dae 703c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(data, regs + sfb->variant.wincon + (win_no * 4)); 704c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(0x0, regs + sfb->variant.winmap + (win_no * 4)); 705ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 706f7f31e505aa79d91b979a38789b1608744361bdcJingoo Han /* Set alpha value width */ 707f7f31e505aa79d91b979a38789b1608744361bdcJingoo Han if (sfb->variant.has_blendcon) { 708f7f31e505aa79d91b979a38789b1608744361bdcJingoo Han data = readl(sfb->regs + BLENDCON); 709f7f31e505aa79d91b979a38789b1608744361bdcJingoo Han data &= ~BLENDCON_NEW_MASK; 710f7f31e505aa79d91b979a38789b1608744361bdcJingoo Han if (var->transp.length > 4) 711f7f31e505aa79d91b979a38789b1608744361bdcJingoo Han data |= BLENDCON_NEW_8BIT_ALPHA_VALUE; 712f7f31e505aa79d91b979a38789b1608744361bdcJingoo Han else 713f7f31e505aa79d91b979a38789b1608744361bdcJingoo Han data |= BLENDCON_NEW_4BIT_ALPHA_VALUE; 714f7f31e505aa79d91b979a38789b1608744361bdcJingoo Han writel(data, sfb->regs + BLENDCON); 715f7f31e505aa79d91b979a38789b1608744361bdcJingoo Han } 716f7f31e505aa79d91b979a38789b1608744361bdcJingoo Han 717a8bdabca3ad69de632bd13f1cb65639e9a556e20Pawel Osciak shadow_protect_win(win, 0); 718a8bdabca3ad69de632bd13f1cb65639e9a556e20Pawel Osciak 7195751b23efb1d91db729ac52e78dd9c9e57baf19fMark Brown pm_runtime_put_sync(sfb->dev); 7205751b23efb1d91db729ac52e78dd9c9e57baf19fMark Brown 721ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return 0; 722ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 723ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 724ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 725ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_update_palette() - set or schedule a palette update. 726ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @sfb: The hardware information. 727ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @win: The window being updated. 728ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @reg: The palette index being changed. 729ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @value: The computed palette value. 730ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 731ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Change the value of a palette register, either by directly writing to 732ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * the palette (this requires the palette RAM to be disconnected from the 733ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * hardware whilst this is in progress) or schedule the update for later. 734ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 735ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * At the moment, since we have no VSYNC interrupt support, we simply set 736ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * the palette entry directly. 737ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 738ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic void s3c_fb_update_palette(struct s3c_fb *sfb, 739ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_win *win, 740ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks unsigned int reg, 741ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks u32 value) 742ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 743ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks void __iomem *palreg; 744ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks u32 palcon; 745ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 74650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks palreg = sfb->regs + sfb->variant.palette[win->index]; 747ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 748ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(sfb->dev, "%s: win %d, reg %d (%p): %08x\n", 749ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks __func__, win->index, reg, palreg, value); 750ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 751ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks win->palette_buffer[reg] = value; 752ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 753ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks palcon = readl(sfb->regs + WPALCON); 754ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks writel(palcon | WPALCON_PAL_UPDATE, sfb->regs + WPALCON); 755ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 75650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks if (win->variant.palette_16bpp) 75750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks writew(value, palreg + (reg * 2)); 758ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks else 75950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks writel(value, palreg + (reg * 4)); 760ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 761ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks writel(palcon, sfb->regs + WPALCON); 762ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 763ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 764ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic inline unsigned int chan_to_field(unsigned int chan, 765ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct fb_bitfield *bf) 766ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 767ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks chan &= 0xffff; 768ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks chan >>= 16 - bf->length; 769ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return chan << bf->offset; 770ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 771ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 772ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 773ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_setcolreg() - framebuffer layer request to change palette. 774ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @regno: The palette index to change. 775ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @red: The red field for the palette data. 776ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @green: The green field for the palette data. 777ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @blue: The blue field for the palette data. 778ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @trans: The transparency (alpha) field for the palette data. 779ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @info: The framebuffer being changed. 780ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 781ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic int s3c_fb_setcolreg(unsigned regno, 782ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks unsigned red, unsigned green, unsigned blue, 783ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks unsigned transp, struct fb_info *info) 784ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 785ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_win *win = info->par; 786ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb *sfb = win->parent; 787ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks unsigned int val; 788ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 789ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(sfb->dev, "%s: win %d: %d => rgb=%d/%d/%d\n", 790ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks __func__, win->index, regno, red, green, blue); 791ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 7925751b23efb1d91db729ac52e78dd9c9e57baf19fMark Brown pm_runtime_get_sync(sfb->dev); 7935751b23efb1d91db729ac52e78dd9c9e57baf19fMark Brown 794ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks switch (info->fix.visual) { 795ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case FB_VISUAL_TRUECOLOR: 796ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* true-colour, use pseudo-palette */ 797ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 798ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (regno < 16) { 799ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks u32 *pal = info->pseudo_palette; 800ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 801ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks val = chan_to_field(red, &info->var.red); 802ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks val |= chan_to_field(green, &info->var.green); 803ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks val |= chan_to_field(blue, &info->var.blue); 804ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 805ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks pal[regno] = val; 806ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 807ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 808ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 809ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case FB_VISUAL_PSEUDOCOLOR: 81050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks if (regno < win->variant.palette_sz) { 811ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks val = chan_to_field(red, &win->palette.r); 812ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks val |= chan_to_field(green, &win->palette.g); 813ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks val |= chan_to_field(blue, &win->palette.b); 814ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 815ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks s3c_fb_update_palette(sfb, win, regno, val); 816ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 817ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 818ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 819ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 820ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks default: 8215751b23efb1d91db729ac52e78dd9c9e57baf19fMark Brown pm_runtime_put_sync(sfb->dev); 822ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return 1; /* unknown type */ 823ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 824ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 8255751b23efb1d91db729ac52e78dd9c9e57baf19fMark Brown pm_runtime_put_sync(sfb->dev); 826ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return 0; 827ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 828ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 829ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 830ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_blank() - blank or unblank the given window 831ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @blank_mode: The blank state from FB_BLANK_* 832ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @info: The framebuffer to blank. 833ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 834ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Framebuffer layer request to change the power state. 835ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 836ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic int s3c_fb_blank(int blank_mode, struct fb_info *info) 837ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 838ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_win *win = info->par; 839ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb *sfb = win->parent; 840ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks unsigned int index = win->index; 841ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks u32 wincon; 842ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 843ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(sfb->dev, "blank mode %d\n", blank_mode); 844ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 8455751b23efb1d91db729ac52e78dd9c9e57baf19fMark Brown pm_runtime_get_sync(sfb->dev); 8465751b23efb1d91db729ac52e78dd9c9e57baf19fMark Brown 847c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks wincon = readl(sfb->regs + sfb->variant.wincon + (index * 4)); 848ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 849ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks switch (blank_mode) { 850ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case FB_BLANK_POWERDOWN: 851ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks wincon &= ~WINCONx_ENWIN; 852ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks sfb->enabled &= ~(1 << index); 853ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* fall through to FB_BLANK_NORMAL */ 854ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 855ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case FB_BLANK_NORMAL: 856ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* disable the DMA and display 0x0 (black) */ 857ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han shadow_protect_win(win, 1); 858ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks writel(WINxMAP_MAP | WINxMAP_MAP_COLOUR(0x0), 859c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks sfb->regs + sfb->variant.winmap + (index * 4)); 860ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han shadow_protect_win(win, 0); 861ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 862ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 863ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case FB_BLANK_UNBLANK: 864ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han shadow_protect_win(win, 1); 865c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(0x0, sfb->regs + sfb->variant.winmap + (index * 4)); 866ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han shadow_protect_win(win, 0); 867ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks wincon |= WINCONx_ENWIN; 868ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks sfb->enabled |= (1 << index); 869ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks break; 870ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 871ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case FB_BLANK_VSYNC_SUSPEND: 872ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks case FB_BLANK_HSYNC_SUSPEND: 873ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks default: 8745751b23efb1d91db729ac52e78dd9c9e57baf19fMark Brown pm_runtime_put_sync(sfb->dev); 875ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return 1; 876ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 877ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 878ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han shadow_protect_win(win, 1); 879c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(wincon, sfb->regs + sfb->variant.wincon + (index * 4)); 880ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han shadow_protect_win(win, 0); 881ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 882ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* Check the enabled state to see if we need to be running the 883ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * main LCD interface, as if there are no active windows then 884ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * it is highly likely that we also do not need to output 885ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * anything. 886ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 887ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 888ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* We could do something like the following code, but the current 889ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * system of using framebuffer events means that we cannot make 890ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * the distinction between just window 0 being inactive and all 891ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * the windows being down. 892ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 893ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_enable(sfb, sfb->enabled ? 1 : 0); 894ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 895ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 896ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* we're stuck with this until we can do something about overriding 897ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * the power control using the blanking event for a single fb. 898ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 899ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han if (index == sfb->pdata->default_win) { 900ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han shadow_protect_win(win, 1); 901ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks s3c_fb_enable(sfb, blank_mode != FB_BLANK_POWERDOWN ? 1 : 0); 902ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han shadow_protect_win(win, 0); 903ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han } 904ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 9055751b23efb1d91db729ac52e78dd9c9e57baf19fMark Brown pm_runtime_put_sync(sfb->dev); 9065751b23efb1d91db729ac52e78dd9c9e57baf19fMark Brown 907ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return 0; 908ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 909ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 910067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak/** 911067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak * s3c_fb_pan_display() - Pan the display. 912067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak * 913067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak * Note that the offsets can be written to the device at any time, as their 914067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak * values are latched at each vsync automatically. This also means that only 915067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak * the last call to this function will have any effect on next vsync, but 916067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak * there is no need to sleep waiting for it to prevent tearing. 917067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak * 918067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak * @var: The screen information to verify. 919067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak * @info: The framebuffer device. 920067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak */ 921067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciakstatic int s3c_fb_pan_display(struct fb_var_screeninfo *var, 922067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak struct fb_info *info) 923067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak{ 924067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak struct s3c_fb_win *win = info->par; 925067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak struct s3c_fb *sfb = win->parent; 926067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak void __iomem *buf = sfb->regs + win->index * 8; 927067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak unsigned int start_boff, end_boff; 928067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak 9295751b23efb1d91db729ac52e78dd9c9e57baf19fMark Brown pm_runtime_get_sync(sfb->dev); 9305751b23efb1d91db729ac52e78dd9c9e57baf19fMark Brown 931067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak /* Offset in bytes to the start of the displayed area */ 932067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak start_boff = var->yoffset * info->fix.line_length; 933067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak /* X offset depends on the current bpp */ 934067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak if (info->var.bits_per_pixel >= 8) { 935067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak start_boff += var->xoffset * (info->var.bits_per_pixel >> 3); 936067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak } else { 937067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak switch (info->var.bits_per_pixel) { 938067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak case 4: 939067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak start_boff += var->xoffset >> 1; 940067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak break; 941067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak case 2: 942067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak start_boff += var->xoffset >> 2; 943067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak break; 944067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak case 1: 945067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak start_boff += var->xoffset >> 3; 946067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak break; 947067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak default: 948067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak dev_err(sfb->dev, "invalid bpp\n"); 9495751b23efb1d91db729ac52e78dd9c9e57baf19fMark Brown pm_runtime_put_sync(sfb->dev); 950067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak return -EINVAL; 951067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak } 952067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak } 953067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak /* Offset in bytes to the end of the displayed area */ 954d8e7a74bf1f1c3d8235e1d939d3e1e96da94ed82Laurent Pinchart end_boff = start_boff + info->var.yres * info->fix.line_length; 955067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak 956067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak /* Temporarily turn off per-vsync update from shadow registers until 957067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak * both start and end addresses are updated to prevent corruption */ 958f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak shadow_protect_win(win, 1); 959067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak 960067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak writel(info->fix.smem_start + start_boff, buf + sfb->variant.buf_start); 961067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak writel(info->fix.smem_start + end_boff, buf + sfb->variant.buf_end); 962067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak 963f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak shadow_protect_win(win, 0); 964067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak 9655751b23efb1d91db729ac52e78dd9c9e57baf19fMark Brown pm_runtime_put_sync(sfb->dev); 966067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak return 0; 967067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak} 968067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak 969efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak/** 970efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * s3c_fb_enable_irq() - enable framebuffer interrupts 971efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * @sfb: main hardware state 972efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak */ 973efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciakstatic void s3c_fb_enable_irq(struct s3c_fb *sfb) 974efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak{ 975efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak void __iomem *regs = sfb->regs; 976efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak u32 irq_ctrl_reg; 977efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 978efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak if (!test_and_set_bit(S3C_FB_VSYNC_IRQ_EN, &sfb->irq_flags)) { 979efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak /* IRQ disabled, enable it */ 980efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak irq_ctrl_reg = readl(regs + VIDINTCON0); 981efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 982efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak irq_ctrl_reg |= VIDINTCON0_INT_ENABLE; 983efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak irq_ctrl_reg |= VIDINTCON0_INT_FRAME; 984efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 985efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak irq_ctrl_reg &= ~VIDINTCON0_FRAMESEL0_MASK; 986efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak irq_ctrl_reg |= VIDINTCON0_FRAMESEL0_VSYNC; 987efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak irq_ctrl_reg &= ~VIDINTCON0_FRAMESEL1_MASK; 988efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak irq_ctrl_reg |= VIDINTCON0_FRAMESEL1_NONE; 989efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 990efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak writel(irq_ctrl_reg, regs + VIDINTCON0); 991efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak } 992efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak} 993efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 994efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak/** 995efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * s3c_fb_disable_irq() - disable framebuffer interrupts 996efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * @sfb: main hardware state 997efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak */ 998efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciakstatic void s3c_fb_disable_irq(struct s3c_fb *sfb) 999efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak{ 1000efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak void __iomem *regs = sfb->regs; 1001efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak u32 irq_ctrl_reg; 1002efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1003efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak if (test_and_clear_bit(S3C_FB_VSYNC_IRQ_EN, &sfb->irq_flags)) { 1004efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak /* IRQ enabled, disable it */ 1005efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak irq_ctrl_reg = readl(regs + VIDINTCON0); 1006efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1007efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak irq_ctrl_reg &= ~VIDINTCON0_INT_FRAME; 1008efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak irq_ctrl_reg &= ~VIDINTCON0_INT_ENABLE; 1009efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1010efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak writel(irq_ctrl_reg, regs + VIDINTCON0); 1011efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak } 1012efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak} 1013efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1014efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciakstatic irqreturn_t s3c_fb_irq(int irq, void *dev_id) 1015efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak{ 1016efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak struct s3c_fb *sfb = dev_id; 1017efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak void __iomem *regs = sfb->regs; 1018efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak u32 irq_sts_reg; 1019efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1020b07f3bbee12163a6b48991138a37b87a1126462aJingoo Han spin_lock(&sfb->slock); 1021b07f3bbee12163a6b48991138a37b87a1126462aJingoo Han 1022efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak irq_sts_reg = readl(regs + VIDINTCON1); 1023efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1024efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak if (irq_sts_reg & VIDINTCON1_INT_FRAME) { 1025efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1026efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak /* VSYNC interrupt, accept it */ 1027efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak writel(VIDINTCON1_INT_FRAME, regs + VIDINTCON1); 1028efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1029efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak sfb->vsync_info.count++; 1030efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak wake_up_interruptible(&sfb->vsync_info.wait); 1031efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak } 1032efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1033efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak /* We only support waiting for VSYNC for now, so it's safe 1034efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * to always disable irqs here. 1035efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak */ 1036efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak s3c_fb_disable_irq(sfb); 1037efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1038b07f3bbee12163a6b48991138a37b87a1126462aJingoo Han spin_unlock(&sfb->slock); 1039efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak return IRQ_HANDLED; 1040efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak} 1041efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1042efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak/** 1043efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * s3c_fb_wait_for_vsync() - sleep until next VSYNC interrupt or timeout 1044efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * @sfb: main hardware state 1045efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak * @crtc: head index. 1046efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak */ 1047efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciakstatic int s3c_fb_wait_for_vsync(struct s3c_fb *sfb, u32 crtc) 1048efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak{ 1049efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak unsigned long count; 1050efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak int ret; 1051efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1052efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak if (crtc != 0) 1053efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak return -ENODEV; 1054efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 10555751b23efb1d91db729ac52e78dd9c9e57baf19fMark Brown pm_runtime_get_sync(sfb->dev); 10565751b23efb1d91db729ac52e78dd9c9e57baf19fMark Brown 1057efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak count = sfb->vsync_info.count; 1058efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak s3c_fb_enable_irq(sfb); 1059efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak ret = wait_event_interruptible_timeout(sfb->vsync_info.wait, 1060efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak count != sfb->vsync_info.count, 1061efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak msecs_to_jiffies(VSYNC_TIMEOUT_MSEC)); 10625751b23efb1d91db729ac52e78dd9c9e57baf19fMark Brown 10635751b23efb1d91db729ac52e78dd9c9e57baf19fMark Brown pm_runtime_put_sync(sfb->dev); 10645751b23efb1d91db729ac52e78dd9c9e57baf19fMark Brown 1065efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak if (ret == 0) 1066efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak return -ETIMEDOUT; 1067efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1068efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak return 0; 1069efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak} 1070efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1071efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciakstatic int s3c_fb_ioctl(struct fb_info *info, unsigned int cmd, 1072efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak unsigned long arg) 1073efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak{ 1074efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak struct s3c_fb_win *win = info->par; 1075efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak struct s3c_fb *sfb = win->parent; 1076efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak int ret; 1077efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak u32 crtc; 1078efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1079efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak switch (cmd) { 1080efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak case FBIO_WAITFORVSYNC: 1081efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak if (get_user(crtc, (u32 __user *)arg)) { 1082efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak ret = -EFAULT; 1083efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak break; 1084efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak } 1085efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1086efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak ret = s3c_fb_wait_for_vsync(sfb, crtc); 1087efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak break; 1088efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak default: 1089efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak ret = -ENOTTY; 1090efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak } 1091efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1092efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak return ret; 1093efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak} 1094efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1095ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic struct fb_ops s3c_fb_ops = { 1096ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks .owner = THIS_MODULE, 1097ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks .fb_check_var = s3c_fb_check_var, 1098ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks .fb_set_par = s3c_fb_set_par, 1099ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks .fb_blank = s3c_fb_blank, 1100ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks .fb_setcolreg = s3c_fb_setcolreg, 1101ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks .fb_fillrect = cfb_fillrect, 1102ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks .fb_copyarea = cfb_copyarea, 1103ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks .fb_imageblit = cfb_imageblit, 1104067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak .fb_pan_display = s3c_fb_pan_display, 1105efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak .fb_ioctl = s3c_fb_ioctl, 1106ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks}; 1107ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1108ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 11092bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere * s3c_fb_missing_pixclock() - calculates pixel clock 11102bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere * @mode: The video mode to change. 11112bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere * 11122bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere * Calculate the pixel clock when none has been given through platform data. 11132bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere */ 11142bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaerestatic void __devinit s3c_fb_missing_pixclock(struct fb_videomode *mode) 11152bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere{ 11162bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere u64 pixclk = 1000000000000ULL; 11172bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere u32 div; 11182bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere 11192bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere div = mode->left_margin + mode->hsync_len + mode->right_margin + 11202bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere mode->xres; 11212bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere div *= mode->upper_margin + mode->vsync_len + mode->lower_margin + 11222bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere mode->yres; 11232bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere div *= mode->refresh ? : 60; 11242bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere 11252bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere do_div(pixclk, div); 11262bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere 11272bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere mode->pixclock = pixclk; 11282bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere} 11292bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere 11302bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere/** 1131ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_alloc_memory() - allocate display memory for framebuffer window 1132ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @sfb: The base resources for the hardware. 1133ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @win: The window to initialise memory for. 1134ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 1135ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Allocate memory for the given framebuffer. 1136ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 1137ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic int __devinit s3c_fb_alloc_memory(struct s3c_fb *sfb, 1138ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_win *win) 1139ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 1140ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_pd_win *windata = win->windata; 1141ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks unsigned int real_size, virt_size, size; 1142ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct fb_info *fbi = win->fbinfo; 1143ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dma_addr_t map_dma; 1144ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1145ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(sfb->dev, "allocating memory for display\n"); 1146ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1147ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks real_size = windata->win_mode.xres * windata->win_mode.yres; 1148ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks virt_size = windata->virtual_x * windata->virtual_y; 1149ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1150ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(sfb->dev, "real_size=%u (%u.%u), virt_size=%u (%u.%u)\n", 1151ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks real_size, windata->win_mode.xres, windata->win_mode.yres, 1152ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks virt_size, windata->virtual_x, windata->virtual_y); 1153ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1154ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks size = (real_size > virt_size) ? real_size : virt_size; 1155ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks size *= (windata->max_bpp > 16) ? 32 : windata->max_bpp; 1156ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks size /= 8; 1157ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1158ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fbi->fix.smem_len = size; 1159ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks size = PAGE_ALIGN(size); 1160ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1161ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(sfb->dev, "want %u bytes for window\n", size); 1162ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1163ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fbi->screen_base = dma_alloc_writecombine(sfb->dev, size, 1164ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks &map_dma, GFP_KERNEL); 1165ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (!fbi->screen_base) 1166ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return -ENOMEM; 1167ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1168ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(sfb->dev, "mapped %x to %p\n", 1169ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks (unsigned int)map_dma, fbi->screen_base); 1170ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1171ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks memset(fbi->screen_base, 0x0, size); 1172ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fbi->fix.smem_start = map_dma; 1173ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1174ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return 0; 1175ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 1176ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1177ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 1178ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_free_memory() - free the display memory for the given window 1179ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @sfb: The base resources for the hardware. 1180ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @win: The window to free the display memory for. 1181ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 1182ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Free the display memory allocated by s3c_fb_alloc_memory(). 1183ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 1184ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic void s3c_fb_free_memory(struct s3c_fb *sfb, struct s3c_fb_win *win) 1185ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 1186ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct fb_info *fbi = win->fbinfo; 1187ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1188cd7d7e0244955a4694d1e79e8c8a9bef163d6305Pawel Osciak if (fbi->screen_base) 1189cd7d7e0244955a4694d1e79e8c8a9bef163d6305Pawel Osciak dma_free_writecombine(sfb->dev, PAGE_ALIGN(fbi->fix.smem_len), 1190ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fbi->screen_base, fbi->fix.smem_start); 1191ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 1192ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1193ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 1194ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_release_win() - release resources for a framebuffer window. 1195ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @win: The window to cleanup the resources for. 1196ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 1197ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Release the resources that where claimed for the hardware window, 1198ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * such as the framebuffer instance and any memory claimed for it. 1199ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 1200ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic void s3c_fb_release_win(struct s3c_fb *sfb, struct s3c_fb_win *win) 1201ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 120204ab9ef97771ba88789672a1f0d0ddcf8dbc0924Pawel Osciak u32 data; 120304ab9ef97771ba88789672a1f0d0ddcf8dbc0924Pawel Osciak 1204ddc518d9f88d7cf82bd974737ce977193785335dKrzysztof Helt if (win->fbinfo) { 120504ab9ef97771ba88789672a1f0d0ddcf8dbc0924Pawel Osciak if (sfb->variant.has_shadowcon) { 120604ab9ef97771ba88789672a1f0d0ddcf8dbc0924Pawel Osciak data = readl(sfb->regs + SHADOWCON); 120704ab9ef97771ba88789672a1f0d0ddcf8dbc0924Pawel Osciak data &= ~SHADOWCON_CHx_ENABLE(win->index); 120804ab9ef97771ba88789672a1f0d0ddcf8dbc0924Pawel Osciak data &= ~SHADOWCON_CHx_LOCAL_ENABLE(win->index); 120904ab9ef97771ba88789672a1f0d0ddcf8dbc0924Pawel Osciak writel(data, sfb->regs + SHADOWCON); 121004ab9ef97771ba88789672a1f0d0ddcf8dbc0924Pawel Osciak } 1211ddc518d9f88d7cf82bd974737ce977193785335dKrzysztof Helt unregister_framebuffer(win->fbinfo); 1212cd7d7e0244955a4694d1e79e8c8a9bef163d6305Pawel Osciak if (win->fbinfo->cmap.len) 1213cd7d7e0244955a4694d1e79e8c8a9bef163d6305Pawel Osciak fb_dealloc_cmap(&win->fbinfo->cmap); 1214ddc518d9f88d7cf82bd974737ce977193785335dKrzysztof Helt s3c_fb_free_memory(sfb, win); 1215ddc518d9f88d7cf82bd974737ce977193785335dKrzysztof Helt framebuffer_release(win->fbinfo); 1216ddc518d9f88d7cf82bd974737ce977193785335dKrzysztof Helt } 1217ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 1218ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1219ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 1220ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_probe_win() - register an hardware window 1221ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @sfb: The base resources for the hardware 122250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks * @variant: The variant information for this window. 1223ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @res: Pointer to where to place the resultant window. 1224ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 1225ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Allocate and do the basic initialisation for one of the hardware's graphics 1226ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * windows. 1227ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 1228ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no, 122950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks struct s3c_fb_win_variant *variant, 1230ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_win **res) 1231ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 1232ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct fb_var_screeninfo *var; 1233ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct fb_videomode *initmode; 1234ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_pd_win *windata; 1235ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_win *win; 1236ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct fb_info *fbinfo; 1237ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks int palette_size; 1238ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks int ret; 1239ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1240c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks dev_dbg(sfb->dev, "probing window %d, variant %p\n", win_no, variant); 1241ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1242efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak init_waitqueue_head(&sfb->vsync_info.wait); 1243efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 124450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks palette_size = variant->palette_sz * 4; 1245ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1246ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fbinfo = framebuffer_alloc(sizeof(struct s3c_fb_win) + 1247ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks palette_size * sizeof(u32), sfb->dev); 1248ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (!fbinfo) { 1249ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_err(sfb->dev, "failed to allocate framebuffer\n"); 1250ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return -ENOENT; 1251ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 1252ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1253ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks windata = sfb->pdata->win[win_no]; 1254ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks initmode = &windata->win_mode; 1255ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1256ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks WARN_ON(windata->max_bpp == 0); 1257ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks WARN_ON(windata->win_mode.xres == 0); 1258ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks WARN_ON(windata->win_mode.yres == 0); 1259ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1260ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks win = fbinfo->par; 1261cd7d7e0244955a4694d1e79e8c8a9bef163d6305Pawel Osciak *res = win; 1262ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks var = &fbinfo->var; 126350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks win->variant = *variant; 1264ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks win->fbinfo = fbinfo; 1265ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks win->parent = sfb; 1266ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks win->windata = windata; 1267ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks win->index = win_no; 1268ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks win->palette_buffer = (u32 *)(win + 1); 1269ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1270ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks ret = s3c_fb_alloc_memory(sfb, win); 1271ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (ret) { 1272ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_err(sfb->dev, "failed to allocate display memory\n"); 1273ddc518d9f88d7cf82bd974737ce977193785335dKrzysztof Helt return ret; 1274ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 1275ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1276ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* setup the r/b/g positions for the window's palette */ 1277bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks if (win->variant.palette_16bpp) { 1278bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks /* Set RGB 5:6:5 as default */ 1279bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks win->palette.r.offset = 11; 1280bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks win->palette.r.length = 5; 1281bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks win->palette.g.offset = 5; 1282bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks win->palette.g.length = 6; 1283bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks win->palette.b.offset = 0; 1284bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks win->palette.b.length = 5; 1285bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks 1286bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks } else { 1287bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks /* Set 8bpp or 8bpp and 1bit alpha */ 1288bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks win->palette.r.offset = 16; 1289bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks win->palette.r.length = 8; 1290bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks win->palette.g.offset = 8; 1291bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks win->palette.g.length = 8; 1292bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks win->palette.b.offset = 0; 1293bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks win->palette.b.length = 8; 1294bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9Ben Dooks } 1295ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1296ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* setup the initial video mode from the window */ 1297ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fb_videomode_to_var(&fbinfo->var, initmode); 1298ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1299ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fbinfo->fix.type = FB_TYPE_PACKED_PIXELS; 1300ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fbinfo->fix.accel = FB_ACCEL_NONE; 1301ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fbinfo->var.activate = FB_ACTIVATE_NOW; 1302ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fbinfo->var.vmode = FB_VMODE_NONINTERLACED; 1303ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fbinfo->var.bits_per_pixel = windata->default_bpp; 1304ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fbinfo->fbops = &s3c_fb_ops; 1305ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fbinfo->flags = FBINFO_FLAG_DEFAULT; 1306ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fbinfo->pseudo_palette = &win->pseudo_palette; 1307ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1308ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* prepare to actually start the framebuffer */ 1309ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1310ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks ret = s3c_fb_check_var(&fbinfo->var, fbinfo); 1311ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (ret < 0) { 1312ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_err(sfb->dev, "check_var failed on initial video params\n"); 1313ddc518d9f88d7cf82bd974737ce977193785335dKrzysztof Helt return ret; 1314ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 1315ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1316ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* create initial colour map */ 1317ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 131850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks ret = fb_alloc_cmap(&fbinfo->cmap, win->variant.palette_sz, 1); 1319ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (ret == 0) 1320ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks fb_set_cmap(&fbinfo->cmap, fbinfo); 1321ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks else 1322ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_err(sfb->dev, "failed to allocate fb cmap\n"); 1323ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1324ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks s3c_fb_set_par(fbinfo); 1325ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1326ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(sfb->dev, "about to register framebuffer\n"); 1327ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1328ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* run the check_var and set_par on our configuration. */ 1329ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1330ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks ret = register_framebuffer(fbinfo); 1331ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (ret < 0) { 1332ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_err(sfb->dev, "failed to register framebuffer\n"); 1333ddc518d9f88d7cf82bd974737ce977193785335dKrzysztof Helt return ret; 1334ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 1335ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1336ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_info(sfb->dev, "window %d: fb %s\n", win_no, fbinfo->fix.id); 1337ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1338ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return 0; 1339ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 1340ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1341ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 1342ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_clear_win() - clear hardware window registers. 1343ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @sfb: The base resources for the hardware. 1344ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @win: The window to process. 1345ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 1346ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Reset the specific window registers to a known state. 1347ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 1348ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic void s3c_fb_clear_win(struct s3c_fb *sfb, int win) 1349ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 1350ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks void __iomem *regs = sfb->regs; 1351a8bdabca3ad69de632bd13f1cb65639e9a556e20Pawel Osciak u32 reg; 1352ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1353c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(0, regs + sfb->variant.wincon + (win * 4)); 1354c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(0, regs + VIDOSD_A(win, sfb->variant)); 1355c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(0, regs + VIDOSD_B(win, sfb->variant)); 1356c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(0, regs + VIDOSD_C(win, sfb->variant)); 1357a8bdabca3ad69de632bd13f1cb65639e9a556e20Pawel Osciak reg = readl(regs + SHADOWCON); 1358a8bdabca3ad69de632bd13f1cb65639e9a556e20Pawel Osciak writel(reg & ~SHADOWCON_WINx_PROTECT(win), regs + SHADOWCON); 1359ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 1360ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1361ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic int __devinit s3c_fb_probe(struct platform_device *pdev) 1362ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 1363b73a21fc66fee35b41db755abebfacba48b2fc76Jingoo Han const struct platform_device_id *platid; 136450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks struct s3c_fb_driverdata *fbdrv; 1365ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct device *dev = &pdev->dev; 1366ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb_platdata *pd; 1367ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb *sfb; 1368ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct resource *res; 1369ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks int win; 1370ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks int ret = 0; 1371d8b97db4c8e40e49985fa5802be914292add64f6Jingoo Han u32 reg; 1372ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1373b73a21fc66fee35b41db755abebfacba48b2fc76Jingoo Han platid = platform_get_device_id(pdev); 1374b73a21fc66fee35b41db755abebfacba48b2fc76Jingoo Han fbdrv = (struct s3c_fb_driverdata *)platid->driver_data; 137550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 137650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks if (fbdrv->variant.nr_windows > S3C_FB_MAX_WIN) { 137750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks dev_err(dev, "too many windows, cannot attach\n"); 137850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks return -EINVAL; 137950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks } 138050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 1381ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks pd = pdev->dev.platform_data; 1382ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (!pd) { 1383ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_err(dev, "no platform data specified\n"); 1384ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return -EINVAL; 1385ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 1386ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1387857a8df9467a6dfe5d3aa309d9bdef31dc817647Mark Brown sfb = devm_kzalloc(dev, sizeof(struct s3c_fb), GFP_KERNEL); 1388ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (!sfb) { 1389ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_err(dev, "no memory for framebuffers\n"); 1390ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return -ENOMEM; 1391ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 1392ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1393c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks dev_dbg(dev, "allocate new framebuffer %p\n", sfb); 1394c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks 1395ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks sfb->dev = dev; 1396ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks sfb->pdata = pd; 139750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks sfb->variant = fbdrv->variant; 1398ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1399b07f3bbee12163a6b48991138a37b87a1126462aJingoo Han spin_lock_init(&sfb->slock); 1400b07f3bbee12163a6b48991138a37b87a1126462aJingoo Han 1401ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks sfb->bus_clk = clk_get(dev, "lcd"); 1402ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (IS_ERR(sfb->bus_clk)) { 1403ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_err(dev, "failed to get bus clock\n"); 1404942b8d05cdf1da396b4449a38b87c677591947c0Axel Lin ret = PTR_ERR(sfb->bus_clk); 1405ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks goto err_sfb; 1406ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 1407ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1408ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks clk_enable(sfb->bus_clk); 1409ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1410b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han if (!sfb->variant.has_clksel) { 1411b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han sfb->lcd_clk = clk_get(dev, "sclk_fimd"); 1412b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han if (IS_ERR(sfb->lcd_clk)) { 1413b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han dev_err(dev, "failed to get lcd clock\n"); 1414b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han ret = PTR_ERR(sfb->lcd_clk); 1415b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han goto err_bus_clk; 1416b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han } 1417b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han 1418b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han clk_enable(sfb->lcd_clk); 1419b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han } 1420b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han 14214959212c18669f254daa0ae796ad676b67939ba2Jingoo Han pm_runtime_enable(sfb->dev); 14224959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 1423ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1424ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (!res) { 1425ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_err(dev, "failed to find registers\n"); 1426ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks ret = -ENOENT; 1427b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han goto err_lcd_clk; 1428ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 1429ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1430857a8df9467a6dfe5d3aa309d9bdef31dc817647Mark Brown sfb->regs = devm_request_and_ioremap(dev, res); 1431ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (!sfb->regs) { 1432ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_err(dev, "failed to map registers\n"); 1433ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks ret = -ENXIO; 1434857a8df9467a6dfe5d3aa309d9bdef31dc817647Mark Brown goto err_lcd_clk; 1435ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 1436ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1437efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 1438efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak if (!res) { 1439efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak dev_err(dev, "failed to acquire irq resource\n"); 1440efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak ret = -ENOENT; 1441857a8df9467a6dfe5d3aa309d9bdef31dc817647Mark Brown goto err_lcd_clk; 1442efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak } 1443efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak sfb->irq_no = res->start; 1444327e27681c27d3ed5ea470ec483904d1a318cb7fJingoo Han ret = devm_request_irq(dev, sfb->irq_no, s3c_fb_irq, 1445efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 0, "s3c_fb", sfb); 1446efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak if (ret) { 1447efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak dev_err(dev, "irq request failed\n"); 1448857a8df9467a6dfe5d3aa309d9bdef31dc817647Mark Brown goto err_lcd_clk; 1449efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak } 1450efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1451ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_dbg(dev, "got resources (regs %p), probing windows\n", sfb->regs); 1452ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 14534959212c18669f254daa0ae796ad676b67939ba2Jingoo Han platform_set_drvdata(pdev, sfb); 14544959212c18669f254daa0ae796ad676b67939ba2Jingoo Han pm_runtime_get_sync(sfb->dev); 14554959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 1456ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* setup gpio and output polarity controls */ 1457ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1458ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks pd->setup_gpio(); 1459ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1460ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks writel(pd->vidcon1, sfb->regs + VIDCON1); 1461ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1462d8b97db4c8e40e49985fa5802be914292add64f6Jingoo Han /* set video clock running at under-run */ 1463d8b97db4c8e40e49985fa5802be914292add64f6Jingoo Han if (sfb->variant.has_fixvclk) { 1464d8b97db4c8e40e49985fa5802be914292add64f6Jingoo Han reg = readl(sfb->regs + VIDCON1); 1465d8b97db4c8e40e49985fa5802be914292add64f6Jingoo Han reg &= ~VIDCON1_VCLK_MASK; 1466d8b97db4c8e40e49985fa5802be914292add64f6Jingoo Han reg |= VIDCON1_VCLK_RUN; 1467d8b97db4c8e40e49985fa5802be914292add64f6Jingoo Han writel(reg, sfb->regs + VIDCON1); 1468d8b97db4c8e40e49985fa5802be914292add64f6Jingoo Han } 1469d8b97db4c8e40e49985fa5802be914292add64f6Jingoo Han 1470ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* zero all windows before we do anything */ 1471ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 147250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks for (win = 0; win < fbdrv->variant.nr_windows; win++) 1473ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks s3c_fb_clear_win(sfb, win); 1474ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1475949470375393e82dc9158d36d675180c8c250388Ben Dooks /* initialise colour key controls */ 147650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks for (win = 0; win < (fbdrv->variant.nr_windows - 1); win++) { 1477c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks void __iomem *regs = sfb->regs + sfb->variant.keycon; 1478c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks 1479c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks regs += (win * 8); 1480c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(0xffffff, regs + WKEYCON0); 1481c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks writel(0xffffff, regs + WKEYCON1); 1482949470375393e82dc9158d36d675180c8c250388Ben Dooks } 1483949470375393e82dc9158d36d675180c8c250388Ben Dooks 1484ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks /* we have the register setup, start allocating framebuffers */ 1485ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 148650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks for (win = 0; win < fbdrv->variant.nr_windows; win++) { 1487ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (!pd->win[win]) 1488ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks continue; 1489ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 14902bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere if (!pd->win[win]->win_mode.pixclock) 14912bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere s3c_fb_missing_pixclock(&pd->win[win]->win_mode); 14922bb567a38950f0917aecfe1a3e46720d8bbb0020Maurus Cuelenaere 149350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks ret = s3c_fb_probe_win(sfb, win, fbdrv->win[win], 149450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks &sfb->windows[win]); 1495ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks if (ret < 0) { 1496ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks dev_err(dev, "failed to create window %d\n", win); 1497ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks for (; win >= 0; win--) 1498ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks s3c_fb_release_win(sfb, sfb->windows[win]); 14993500b0be62c8cc2f93e8022dc70071ec31b067deMark Brown goto err_pm_runtime; 1500ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 1501ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks } 1502ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1503ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks platform_set_drvdata(pdev, sfb); 1504fe05f8b1c3d28e6204a9ec54dec0d68af6cbf4c8Mark Brown pm_runtime_put_sync(sfb->dev); 1505ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1506ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return 0; 1507ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 15083500b0be62c8cc2f93e8022dc70071ec31b067deMark Brownerr_pm_runtime: 15093500b0be62c8cc2f93e8022dc70071ec31b067deMark Brown pm_runtime_put_sync(sfb->dev); 1510efdc846d2f7190c8f3092c09975c0ebba30a95baPawel Osciak 1511b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Hanerr_lcd_clk: 15123500b0be62c8cc2f93e8022dc70071ec31b067deMark Brown pm_runtime_disable(sfb->dev); 15133500b0be62c8cc2f93e8022dc70071ec31b067deMark Brown 1514b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han if (!sfb->variant.has_clksel) { 1515b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han clk_disable(sfb->lcd_clk); 1516b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han clk_put(sfb->lcd_clk); 1517b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han } 1518b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han 1519b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Hanerr_bus_clk: 1520ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks clk_disable(sfb->bus_clk); 1521ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks clk_put(sfb->bus_clk); 1522ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1523ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dookserr_sfb: 1524ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return ret; 1525ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 1526ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1527ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks/** 1528ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * s3c_fb_remove() - Cleanup on module finalisation 1529ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * @pdev: The platform device we are bound to. 1530ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * 1531ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * Shutdown and then release all the resources that the driver allocated 1532ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks * on initialisation. 1533ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks */ 1534ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic int __devexit s3c_fb_remove(struct platform_device *pdev) 1535ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks{ 1536ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks struct s3c_fb *sfb = platform_get_drvdata(pdev); 1537ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks int win; 1538ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1539fe05f8b1c3d28e6204a9ec54dec0d68af6cbf4c8Mark Brown pm_runtime_get_sync(sfb->dev); 1540fe05f8b1c3d28e6204a9ec54dec0d68af6cbf4c8Mark Brown 1541c42b110caeb128819104d057acdaa1ae564b7c8dPawel Osciak for (win = 0; win < S3C_FB_MAX_WIN; win++) 154217663e59704bea838a9236f299104e30909a43b1Marek Szyprowski if (sfb->windows[win]) 154317663e59704bea838a9236f299104e30909a43b1Marek Szyprowski s3c_fb_release_win(sfb, sfb->windows[win]); 1544ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1545b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han if (!sfb->variant.has_clksel) { 1546b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han clk_disable(sfb->lcd_clk); 1547b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han clk_put(sfb->lcd_clk); 1548b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han } 1549b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han 1550ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks clk_disable(sfb->bus_clk); 1551ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks clk_put(sfb->bus_clk); 1552ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 15534959212c18669f254daa0ae796ad676b67939ba2Jingoo Han pm_runtime_put_sync(sfb->dev); 15544959212c18669f254daa0ae796ad676b67939ba2Jingoo Han pm_runtime_disable(sfb->dev); 15554959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 1556ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks return 0; 1557ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks} 1558ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1559f4f514734e3d398cfb70827615f129826ff84b06Mark Brown#ifdef CONFIG_PM_SLEEP 15604959212c18669f254daa0ae796ad676b67939ba2Jingoo Hanstatic int s3c_fb_suspend(struct device *dev) 15614959212c18669f254daa0ae796ad676b67939ba2Jingoo Han{ 15624959212c18669f254daa0ae796ad676b67939ba2Jingoo Han struct platform_device *pdev = to_platform_device(dev); 15634959212c18669f254daa0ae796ad676b67939ba2Jingoo Han struct s3c_fb *sfb = platform_get_drvdata(pdev); 15644959212c18669f254daa0ae796ad676b67939ba2Jingoo Han struct s3c_fb_win *win; 15654959212c18669f254daa0ae796ad676b67939ba2Jingoo Han int win_no; 15664959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 15674959212c18669f254daa0ae796ad676b67939ba2Jingoo Han for (win_no = S3C_FB_MAX_WIN - 1; win_no >= 0; win_no--) { 15684959212c18669f254daa0ae796ad676b67939ba2Jingoo Han win = sfb->windows[win_no]; 15694959212c18669f254daa0ae796ad676b67939ba2Jingoo Han if (!win) 15704959212c18669f254daa0ae796ad676b67939ba2Jingoo Han continue; 15714959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 15724959212c18669f254daa0ae796ad676b67939ba2Jingoo Han /* use the blank function to push into power-down */ 15734959212c18669f254daa0ae796ad676b67939ba2Jingoo Han s3c_fb_blank(FB_BLANK_POWERDOWN, win->fbinfo); 15744959212c18669f254daa0ae796ad676b67939ba2Jingoo Han } 15754959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 1576b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han if (!sfb->variant.has_clksel) 1577b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han clk_disable(sfb->lcd_clk); 1578b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han 15794959212c18669f254daa0ae796ad676b67939ba2Jingoo Han clk_disable(sfb->bus_clk); 15804959212c18669f254daa0ae796ad676b67939ba2Jingoo Han return 0; 15814959212c18669f254daa0ae796ad676b67939ba2Jingoo Han} 15824959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 15834959212c18669f254daa0ae796ad676b67939ba2Jingoo Hanstatic int s3c_fb_resume(struct device *dev) 15844959212c18669f254daa0ae796ad676b67939ba2Jingoo Han{ 15854959212c18669f254daa0ae796ad676b67939ba2Jingoo Han struct platform_device *pdev = to_platform_device(dev); 15864959212c18669f254daa0ae796ad676b67939ba2Jingoo Han struct s3c_fb *sfb = platform_get_drvdata(pdev); 15874959212c18669f254daa0ae796ad676b67939ba2Jingoo Han struct s3c_fb_platdata *pd = sfb->pdata; 15884959212c18669f254daa0ae796ad676b67939ba2Jingoo Han struct s3c_fb_win *win; 15894959212c18669f254daa0ae796ad676b67939ba2Jingoo Han int win_no; 1590d8b97db4c8e40e49985fa5802be914292add64f6Jingoo Han u32 reg; 15914959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 15924959212c18669f254daa0ae796ad676b67939ba2Jingoo Han clk_enable(sfb->bus_clk); 15934959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 1594b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han if (!sfb->variant.has_clksel) 1595b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han clk_enable(sfb->lcd_clk); 1596b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han 15976aa9681100303bd467cbd0262eb00da8d492fc7fJingoo Han /* setup gpio and output polarity controls */ 15986aa9681100303bd467cbd0262eb00da8d492fc7fJingoo Han pd->setup_gpio(); 15994959212c18669f254daa0ae796ad676b67939ba2Jingoo Han writel(pd->vidcon1, sfb->regs + VIDCON1); 16004959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 1601d8b97db4c8e40e49985fa5802be914292add64f6Jingoo Han /* set video clock running at under-run */ 1602d8b97db4c8e40e49985fa5802be914292add64f6Jingoo Han if (sfb->variant.has_fixvclk) { 1603d8b97db4c8e40e49985fa5802be914292add64f6Jingoo Han reg = readl(sfb->regs + VIDCON1); 1604d8b97db4c8e40e49985fa5802be914292add64f6Jingoo Han reg &= ~VIDCON1_VCLK_MASK; 1605d8b97db4c8e40e49985fa5802be914292add64f6Jingoo Han reg |= VIDCON1_VCLK_RUN; 1606d8b97db4c8e40e49985fa5802be914292add64f6Jingoo Han writel(reg, sfb->regs + VIDCON1); 1607d8b97db4c8e40e49985fa5802be914292add64f6Jingoo Han } 1608d8b97db4c8e40e49985fa5802be914292add64f6Jingoo Han 16094959212c18669f254daa0ae796ad676b67939ba2Jingoo Han /* zero all windows before we do anything */ 16104959212c18669f254daa0ae796ad676b67939ba2Jingoo Han for (win_no = 0; win_no < sfb->variant.nr_windows; win_no++) 16114959212c18669f254daa0ae796ad676b67939ba2Jingoo Han s3c_fb_clear_win(sfb, win_no); 16124959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 16134959212c18669f254daa0ae796ad676b67939ba2Jingoo Han for (win_no = 0; win_no < sfb->variant.nr_windows - 1; win_no++) { 16144959212c18669f254daa0ae796ad676b67939ba2Jingoo Han void __iomem *regs = sfb->regs + sfb->variant.keycon; 1615ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han win = sfb->windows[win_no]; 1616ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han if (!win) 1617ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han continue; 16184959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 1619ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han shadow_protect_win(win, 1); 16204959212c18669f254daa0ae796ad676b67939ba2Jingoo Han regs += (win_no * 8); 16214959212c18669f254daa0ae796ad676b67939ba2Jingoo Han writel(0xffffff, regs + WKEYCON0); 16224959212c18669f254daa0ae796ad676b67939ba2Jingoo Han writel(0xffffff, regs + WKEYCON1); 1623ff8c91072389491375f6d1ea86ce55942c460a04Jingoo Han shadow_protect_win(win, 0); 16244959212c18669f254daa0ae796ad676b67939ba2Jingoo Han } 16254959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 16264959212c18669f254daa0ae796ad676b67939ba2Jingoo Han /* restore framebuffers */ 16274959212c18669f254daa0ae796ad676b67939ba2Jingoo Han for (win_no = 0; win_no < S3C_FB_MAX_WIN; win_no++) { 16284959212c18669f254daa0ae796ad676b67939ba2Jingoo Han win = sfb->windows[win_no]; 16294959212c18669f254daa0ae796ad676b67939ba2Jingoo Han if (!win) 16304959212c18669f254daa0ae796ad676b67939ba2Jingoo Han continue; 16314959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 16324959212c18669f254daa0ae796ad676b67939ba2Jingoo Han dev_dbg(&pdev->dev, "resuming window %d\n", win_no); 16334959212c18669f254daa0ae796ad676b67939ba2Jingoo Han s3c_fb_set_par(win->fbinfo); 16344959212c18669f254daa0ae796ad676b67939ba2Jingoo Han } 16354959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 16364959212c18669f254daa0ae796ad676b67939ba2Jingoo Han return 0; 16374959212c18669f254daa0ae796ad676b67939ba2Jingoo Han} 1638ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks#endif 1639ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 1640f4f514734e3d398cfb70827615f129826ff84b06Mark Brown#ifdef CONFIG_PM_RUNTIME 1641f4f514734e3d398cfb70827615f129826ff84b06Mark Brownstatic int s3c_fb_runtime_suspend(struct device *dev) 1642f4f514734e3d398cfb70827615f129826ff84b06Mark Brown{ 1643f4f514734e3d398cfb70827615f129826ff84b06Mark Brown struct platform_device *pdev = to_platform_device(dev); 1644f4f514734e3d398cfb70827615f129826ff84b06Mark Brown struct s3c_fb *sfb = platform_get_drvdata(pdev); 1645f4f514734e3d398cfb70827615f129826ff84b06Mark Brown 1646f4f514734e3d398cfb70827615f129826ff84b06Mark Brown if (!sfb->variant.has_clksel) 1647f4f514734e3d398cfb70827615f129826ff84b06Mark Brown clk_disable(sfb->lcd_clk); 1648f4f514734e3d398cfb70827615f129826ff84b06Mark Brown 1649f4f514734e3d398cfb70827615f129826ff84b06Mark Brown clk_disable(sfb->bus_clk); 1650f4f514734e3d398cfb70827615f129826ff84b06Mark Brown 1651f4f514734e3d398cfb70827615f129826ff84b06Mark Brown return 0; 1652f4f514734e3d398cfb70827615f129826ff84b06Mark Brown} 1653f4f514734e3d398cfb70827615f129826ff84b06Mark Brown 1654f4f514734e3d398cfb70827615f129826ff84b06Mark Brownstatic int s3c_fb_runtime_resume(struct device *dev) 1655f4f514734e3d398cfb70827615f129826ff84b06Mark Brown{ 1656f4f514734e3d398cfb70827615f129826ff84b06Mark Brown struct platform_device *pdev = to_platform_device(dev); 1657f4f514734e3d398cfb70827615f129826ff84b06Mark Brown struct s3c_fb *sfb = platform_get_drvdata(pdev); 1658f4f514734e3d398cfb70827615f129826ff84b06Mark Brown struct s3c_fb_platdata *pd = sfb->pdata; 1659f4f514734e3d398cfb70827615f129826ff84b06Mark Brown 1660f4f514734e3d398cfb70827615f129826ff84b06Mark Brown clk_enable(sfb->bus_clk); 1661f4f514734e3d398cfb70827615f129826ff84b06Mark Brown 1662f4f514734e3d398cfb70827615f129826ff84b06Mark Brown if (!sfb->variant.has_clksel) 1663f4f514734e3d398cfb70827615f129826ff84b06Mark Brown clk_enable(sfb->lcd_clk); 1664f4f514734e3d398cfb70827615f129826ff84b06Mark Brown 1665f4f514734e3d398cfb70827615f129826ff84b06Mark Brown /* setup gpio and output polarity controls */ 1666f4f514734e3d398cfb70827615f129826ff84b06Mark Brown pd->setup_gpio(); 1667f4f514734e3d398cfb70827615f129826ff84b06Mark Brown writel(pd->vidcon1, sfb->regs + VIDCON1); 1668f4f514734e3d398cfb70827615f129826ff84b06Mark Brown 1669f4f514734e3d398cfb70827615f129826ff84b06Mark Brown return 0; 1670f4f514734e3d398cfb70827615f129826ff84b06Mark Brown} 1671f4f514734e3d398cfb70827615f129826ff84b06Mark Brown#endif 167250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 167350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks#define VALID_BPP124 (VALID_BPP(1) | VALID_BPP(2) | VALID_BPP(4)) 167450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks#define VALID_BPP1248 (VALID_BPP124 | VALID_BPP(8)) 167550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 16768cfdcb2393b05cc80f89ed0110c0f90423d2fee1Marek Szyprowskistatic struct s3c_fb_win_variant s3c_fb_data_64xx_wins[] = { 167750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [0] = { 167850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .has_osd_c = 1, 1679f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak .osd_size_off = 0x8, 168050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .palette_sz = 256, 1681cd74ebaf7ac18eced59a3983b266be39d7b28ee0Jingoo Han .valid_bpp = (VALID_BPP1248 | VALID_BPP(16) | 1682cd74ebaf7ac18eced59a3983b266be39d7b28ee0Jingoo Han VALID_BPP(18) | VALID_BPP(24)), 168350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks }, 168450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [1] = { 168550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .has_osd_c = 1, 168650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .has_osd_d = 1, 1687c9d503e93562e1de093ff16a480fc8801cfa70d9Jingoo Han .osd_size_off = 0xc, 1688f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak .has_osd_alpha = 1, 168950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .palette_sz = 256, 169050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .valid_bpp = (VALID_BPP1248 | VALID_BPP(16) | 169150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks VALID_BPP(18) | VALID_BPP(19) | 1692cd74ebaf7ac18eced59a3983b266be39d7b28ee0Jingoo Han VALID_BPP(24) | VALID_BPP(25) | 1693cd74ebaf7ac18eced59a3983b266be39d7b28ee0Jingoo Han VALID_BPP(28)), 169450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks }, 169550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [2] = { 169650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .has_osd_c = 1, 169750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .has_osd_d = 1, 1698c9d503e93562e1de093ff16a480fc8801cfa70d9Jingoo Han .osd_size_off = 0xc, 1699f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak .has_osd_alpha = 1, 170050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .palette_sz = 16, 170150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .palette_16bpp = 1, 170250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .valid_bpp = (VALID_BPP1248 | VALID_BPP(16) | 170350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks VALID_BPP(18) | VALID_BPP(19) | 1704cd74ebaf7ac18eced59a3983b266be39d7b28ee0Jingoo Han VALID_BPP(24) | VALID_BPP(25) | 1705cd74ebaf7ac18eced59a3983b266be39d7b28ee0Jingoo Han VALID_BPP(28)), 170650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks }, 170750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [3] = { 170850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .has_osd_c = 1, 1709f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak .has_osd_alpha = 1, 171050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .palette_sz = 16, 171150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .palette_16bpp = 1, 171250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .valid_bpp = (VALID_BPP124 | VALID_BPP(16) | 171350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks VALID_BPP(18) | VALID_BPP(19) | 1714cd74ebaf7ac18eced59a3983b266be39d7b28ee0Jingoo Han VALID_BPP(24) | VALID_BPP(25) | 1715cd74ebaf7ac18eced59a3983b266be39d7b28ee0Jingoo Han VALID_BPP(28)), 171650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks }, 171750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [4] = { 171850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .has_osd_c = 1, 1719f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak .has_osd_alpha = 1, 172050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .palette_sz = 4, 172150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .palette_16bpp = 1, 172250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .valid_bpp = (VALID_BPP(1) | VALID_BPP(2) | 172350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks VALID_BPP(16) | VALID_BPP(18) | 1724cd74ebaf7ac18eced59a3983b266be39d7b28ee0Jingoo Han VALID_BPP(19) | VALID_BPP(24) | 1725cd74ebaf7ac18eced59a3983b266be39d7b28ee0Jingoo Han VALID_BPP(25) | VALID_BPP(28)), 172650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks }, 172750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks}; 172850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 1729af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Hanstatic struct s3c_fb_win_variant s3c_fb_data_s5p_wins[] = { 1730af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han [0] = { 1731af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .has_osd_c = 1, 1732af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .osd_size_off = 0x8, 1733af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .palette_sz = 256, 1734af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .valid_bpp = (VALID_BPP1248 | VALID_BPP(13) | 1735af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(15) | VALID_BPP(16) | 1736af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(18) | VALID_BPP(19) | 1737af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(24) | VALID_BPP(25) | 1738af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(32)), 1739af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han }, 1740af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han [1] = { 1741af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .has_osd_c = 1, 1742af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .has_osd_d = 1, 1743af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .osd_size_off = 0xc, 1744af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .has_osd_alpha = 1, 1745af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .palette_sz = 256, 1746af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .valid_bpp = (VALID_BPP1248 | VALID_BPP(13) | 1747af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(15) | VALID_BPP(16) | 1748af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(18) | VALID_BPP(19) | 1749af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(24) | VALID_BPP(25) | 1750af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(32)), 1751af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han }, 1752af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han [2] = { 1753af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .has_osd_c = 1, 1754af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .has_osd_d = 1, 1755af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .osd_size_off = 0xc, 1756af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .has_osd_alpha = 1, 1757af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .palette_sz = 256, 1758af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .valid_bpp = (VALID_BPP1248 | VALID_BPP(13) | 1759af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(15) | VALID_BPP(16) | 1760af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(18) | VALID_BPP(19) | 1761af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(24) | VALID_BPP(25) | 1762af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(32)), 1763af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han }, 1764af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han [3] = { 1765af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .has_osd_c = 1, 1766af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .has_osd_alpha = 1, 1767af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .palette_sz = 256, 1768af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .valid_bpp = (VALID_BPP1248 | VALID_BPP(13) | 1769af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(15) | VALID_BPP(16) | 1770af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(18) | VALID_BPP(19) | 1771af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(24) | VALID_BPP(25) | 1772af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(32)), 1773af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han }, 1774af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han [4] = { 1775af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .has_osd_c = 1, 1776af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .has_osd_alpha = 1, 1777af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .palette_sz = 256, 1778af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .valid_bpp = (VALID_BPP1248 | VALID_BPP(13) | 1779af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(15) | VALID_BPP(16) | 1780af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(18) | VALID_BPP(19) | 1781af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(24) | VALID_BPP(25) | 1782af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han VALID_BPP(32)), 1783af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han }, 1784af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han}; 1785af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han 17868cfdcb2393b05cc80f89ed0110c0f90423d2fee1Marek Szyprowskistatic struct s3c_fb_driverdata s3c_fb_data_64xx = { 178750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .variant = { 178850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .nr_windows = 5, 1789c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .vidtcon = VIDTCON0, 1790c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .wincon = WINCON(0), 1791c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .winmap = WINxMAP(0), 1792c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .keycon = WKEYCON, 1793c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .osd = VIDOSD_BASE, 1794c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .osd_stride = 16, 1795c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .buf_start = VIDW_BUF_START(0), 1796c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .buf_size = VIDW_BUF_SIZE(0), 1797c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .buf_end = VIDW_BUF_END(0), 179850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 179950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .palette = { 180050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [0] = 0x400, 180150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [1] = 0x800, 180250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [2] = 0x300, 180350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [3] = 0x320, 180450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [4] = 0x340, 180550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks }, 1806067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak 1807067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak .has_prtcon = 1, 1808b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .has_clksel = 1, 180950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks }, 181050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .win[0] = &s3c_fb_data_64xx_wins[0], 181150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .win[1] = &s3c_fb_data_64xx_wins[1], 181250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .win[2] = &s3c_fb_data_64xx_wins[2], 181350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .win[3] = &s3c_fb_data_64xx_wins[3], 181450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .win[4] = &s3c_fb_data_64xx_wins[4], 181550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks}; 181650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 18178cfdcb2393b05cc80f89ed0110c0f90423d2fee1Marek Szyprowskistatic struct s3c_fb_driverdata s3c_fb_data_s5pc100 = { 18184e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .variant = { 18194e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .nr_windows = 5, 18204e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .vidtcon = VIDTCON0, 18214e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .wincon = WINCON(0), 18224e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .winmap = WINxMAP(0), 18234e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .keycon = WKEYCON, 18244e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .osd = VIDOSD_BASE, 18254e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .osd_stride = 16, 18264e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .buf_start = VIDW_BUF_START(0), 18274e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .buf_size = VIDW_BUF_SIZE(0), 18284e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .buf_end = VIDW_BUF_END(0), 18294e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak 18304e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .palette = { 18314e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak [0] = 0x2400, 18324e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak [1] = 0x2800, 18334e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak [2] = 0x2c00, 18344e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak [3] = 0x3000, 18354e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak [4] = 0x3400, 18364e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak }, 1837067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak 1838067b226b9e8e20463e0937344c93101ac8d8d2b1Pawel Osciak .has_prtcon = 1, 1839f7f31e505aa79d91b979a38789b1608744361bdcJingoo Han .has_blendcon = 1, 1840b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .has_clksel = 1, 18414e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak }, 1842af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .win[0] = &s3c_fb_data_s5p_wins[0], 1843af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .win[1] = &s3c_fb_data_s5p_wins[1], 1844af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .win[2] = &s3c_fb_data_s5p_wins[2], 1845af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .win[3] = &s3c_fb_data_s5p_wins[3], 1846af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .win[4] = &s3c_fb_data_s5p_wins[4], 18474e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak}; 18484e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak 18498cfdcb2393b05cc80f89ed0110c0f90423d2fee1Marek Szyprowskistatic struct s3c_fb_driverdata s3c_fb_data_s5pv210 = { 185050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .variant = { 185150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .nr_windows = 5, 1852c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .vidtcon = VIDTCON0, 1853c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .wincon = WINCON(0), 1854c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .winmap = WINxMAP(0), 1855c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .keycon = WKEYCON, 1856c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .osd = VIDOSD_BASE, 1857c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .osd_stride = 16, 1858c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .buf_start = VIDW_BUF_START(0), 1859c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .buf_size = VIDW_BUF_SIZE(0), 1860c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .buf_end = VIDW_BUF_END(0), 186150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 186250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .palette = { 186350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [0] = 0x2400, 186450a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [1] = 0x2800, 186550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [2] = 0x2c00, 186650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [3] = 0x3000, 186750a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks [4] = 0x3400, 186850a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks }, 1869f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak 1870f5ec546f1f5e21bfc84ce7a1ac7408702082c65aPawel Osciak .has_shadowcon = 1, 1871f7f31e505aa79d91b979a38789b1608744361bdcJingoo Han .has_blendcon = 1, 1872b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .has_clksel = 1, 1873d8b97db4c8e40e49985fa5802be914292add64f6Jingoo Han .has_fixvclk = 1, 1874b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han }, 1875b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .win[0] = &s3c_fb_data_s5p_wins[0], 1876b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .win[1] = &s3c_fb_data_s5p_wins[1], 1877b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .win[2] = &s3c_fb_data_s5p_wins[2], 1878b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .win[3] = &s3c_fb_data_s5p_wins[3], 1879b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .win[4] = &s3c_fb_data_s5p_wins[4], 1880b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han}; 1881b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han 1882b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Hanstatic struct s3c_fb_driverdata s3c_fb_data_exynos4 = { 1883b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .variant = { 1884b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .nr_windows = 5, 1885b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .vidtcon = VIDTCON0, 1886b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .wincon = WINCON(0), 1887b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .winmap = WINxMAP(0), 1888b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .keycon = WKEYCON, 1889b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .osd = VIDOSD_BASE, 1890b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .osd_stride = 16, 1891b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .buf_start = VIDW_BUF_START(0), 1892b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .buf_size = VIDW_BUF_SIZE(0), 1893b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .buf_end = VIDW_BUF_END(0), 1894b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han 1895b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .palette = { 1896b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han [0] = 0x2400, 1897b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han [1] = 0x2800, 1898b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han [2] = 0x2c00, 1899b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han [3] = 0x3000, 1900b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han [4] = 0x3400, 1901b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han }, 1902b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han 1903b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .has_shadowcon = 1, 1904f7f31e505aa79d91b979a38789b1608744361bdcJingoo Han .has_blendcon = 1, 1905d8b97db4c8e40e49985fa5802be914292add64f6Jingoo Han .has_fixvclk = 1, 190650a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks }, 1907af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .win[0] = &s3c_fb_data_s5p_wins[0], 1908af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .win[1] = &s3c_fb_data_s5p_wins[1], 1909af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .win[2] = &s3c_fb_data_s5p_wins[2], 1910af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .win[3] = &s3c_fb_data_s5p_wins[3], 1911af4a835bba5fe710b870b8ec8c294e2338cbb112Jingoo Han .win[4] = &s3c_fb_data_s5p_wins[4], 191250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks}; 191350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 19145c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Hanstatic struct s3c_fb_driverdata s3c_fb_data_exynos5 = { 19155c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han .variant = { 19165c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han .nr_windows = 5, 19175c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han .vidtcon = VIDTCON0, 19185c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han .wincon = WINCON(0), 19195c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han .winmap = WINxMAP(0), 19205c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han .keycon = WKEYCON, 19215c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han .osd = VIDOSD_BASE, 19225c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han .osd_stride = 16, 19235c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han .buf_start = VIDW_BUF_START(0), 19245c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han .buf_size = VIDW_BUF_SIZE(0), 19255c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han .buf_end = VIDW_BUF_END(0), 19265c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han 19275c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han .palette = { 19285c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han [0] = 0x2400, 19295c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han [1] = 0x2800, 19305c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han [2] = 0x2c00, 19315c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han [3] = 0x3000, 19325c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han [4] = 0x3400, 19335c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han }, 19345c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han .has_shadowcon = 1, 19355c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han .has_blendcon = 1, 19365c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han .has_fixvclk = 1, 19375c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han }, 19385c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han .win[0] = &s3c_fb_data_s5p_wins[0], 19395c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han .win[1] = &s3c_fb_data_s5p_wins[1], 19405c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han .win[2] = &s3c_fb_data_s5p_wins[2], 19415c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han .win[3] = &s3c_fb_data_s5p_wins[3], 19425c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han .win[4] = &s3c_fb_data_s5p_wins[4], 19435c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han}; 19445c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han 1945c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks/* S3C2443/S3C2416 style hardware */ 19468cfdcb2393b05cc80f89ed0110c0f90423d2fee1Marek Szyprowskistatic struct s3c_fb_driverdata s3c_fb_data_s3c2443 = { 1947c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .variant = { 1948c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .nr_windows = 2, 1949c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .is_2443 = 1, 1950c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks 1951c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .vidtcon = 0x08, 1952c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .wincon = 0x14, 1953c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .winmap = 0xd0, 1954c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .keycon = 0xb0, 1955c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .osd = 0x28, 1956c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .osd_stride = 12, 1957c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .buf_start = 0x64, 1958c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .buf_size = 0x94, 1959c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .buf_end = 0x7c, 1960c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks 1961c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .palette = { 1962c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks [0] = 0x400, 1963c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks [1] = 0x800, 1964c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks }, 1965b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .has_clksel = 1, 1966c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks }, 1967c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .win[0] = &(struct s3c_fb_win_variant) { 1968c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .palette_sz = 256, 1969c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .valid_bpp = VALID_BPP1248 | VALID_BPP(16) | VALID_BPP(24), 1970c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks }, 1971c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .win[1] = &(struct s3c_fb_win_variant) { 1972c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .has_osd_c = 1, 1973f676ec2a3526465dfa7b5c513a0c2bb22fb70b80Pawel Osciak .has_osd_alpha = 1, 1974c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .palette_sz = 256, 1975c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .valid_bpp = (VALID_BPP1248 | VALID_BPP(16) | 1976c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks VALID_BPP(18) | VALID_BPP(19) | 1977c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks VALID_BPP(24) | VALID_BPP(25) | 1978c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks VALID_BPP(28)), 1979c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks }, 1980c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks}; 1981c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks 198221b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumarstatic struct s3c_fb_driverdata s3c_fb_data_s5p64x0 = { 198321b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .variant = { 198421b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .nr_windows = 3, 198521b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .vidtcon = VIDTCON0, 198621b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .wincon = WINCON(0), 198721b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .winmap = WINxMAP(0), 198821b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .keycon = WKEYCON, 198921b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .osd = VIDOSD_BASE, 199021b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .osd_stride = 16, 199121b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .buf_start = VIDW_BUF_START(0), 199221b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .buf_size = VIDW_BUF_SIZE(0), 199321b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .buf_end = VIDW_BUF_END(0), 199421b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar 199521b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .palette = { 199621b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar [0] = 0x2400, 199721b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar [1] = 0x2800, 199821b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar [2] = 0x2c00, 199921b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar }, 2000f7f31e505aa79d91b979a38789b1608744361bdcJingoo Han 2001f7f31e505aa79d91b979a38789b1608744361bdcJingoo Han .has_blendcon = 1, 2002d8b97db4c8e40e49985fa5802be914292add64f6Jingoo Han .has_fixvclk = 1, 200321b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar }, 200421b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .win[0] = &s3c_fb_data_s5p_wins[0], 200521b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .win[1] = &s3c_fb_data_s5p_wins[1], 200621b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .win[2] = &s3c_fb_data_s5p_wins[2], 200721b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar}; 200821b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar 200950a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooksstatic struct platform_device_id s3c_fb_driver_ids[] = { 201050a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks { 201150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .name = "s3c-fb", 201250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .driver_data = (unsigned long)&s3c_fb_data_64xx, 201350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks }, { 20144e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .name = "s5pc100-fb", 20154e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .driver_data = (unsigned long)&s3c_fb_data_s5pc100, 20164e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak }, { 20174e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .name = "s5pv210-fb", 20184e591ac620269b3f5fb000d75444bbb397576315Pawel Osciak .driver_data = (unsigned long)&s3c_fb_data_s5pv210, 2019c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks }, { 2020b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .name = "exynos4-fb", 2021b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han .driver_data = (unsigned long)&s3c_fb_data_exynos4, 2022b5480ed72e4f299c53d1857faaf4f492650ccc43Jingoo Han }, { 20235c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han .name = "exynos5-fb", 20245c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han .driver_data = (unsigned long)&s3c_fb_data_exynos5, 20255c44778eb0b8928aabfe039ba6f11ca88be6d650Jingoo Han }, { 2026c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .name = "s3c2443-fb", 2027c4bb6ffa7754e8d0f8b24decd91de259b549fda1Ben Dooks .driver_data = (unsigned long)&s3c_fb_data_s3c2443, 202821b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar }, { 202921b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .name = "s5p64x0-fb", 203021b5a3adf9d16a4eb9874b32cfc84af34f697c1dAjay Kumar .driver_data = (unsigned long)&s3c_fb_data_s5p64x0, 203150a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks }, 203250a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks {}, 203350a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks}; 203450a5503a9208420e6c59d24504a5e9913d603cf7Ben DooksMODULE_DEVICE_TABLE(platform, s3c_fb_driver_ids); 203550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks 2036f4f514734e3d398cfb70827615f129826ff84b06Mark Brownstatic const struct dev_pm_ops s3cfb_pm_ops = { 2037f4f514734e3d398cfb70827615f129826ff84b06Mark Brown SET_SYSTEM_SLEEP_PM_OPS(s3c_fb_suspend, s3c_fb_resume) 2038f4f514734e3d398cfb70827615f129826ff84b06Mark Brown SET_RUNTIME_PM_OPS(s3c_fb_runtime_suspend, s3c_fb_runtime_resume, 2039f4f514734e3d398cfb70827615f129826ff84b06Mark Brown NULL) 2040f4f514734e3d398cfb70827615f129826ff84b06Mark Brown}; 20414959212c18669f254daa0ae796ad676b67939ba2Jingoo Han 2042ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooksstatic struct platform_driver s3c_fb_driver = { 2043ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks .probe = s3c_fb_probe, 20443163eaba34943967aebb1eefa0d4bdc4e5dc197cPeter Korsgaard .remove = __devexit_p(s3c_fb_remove), 204550a5503a9208420e6c59d24504a5e9913d603cf7Ben Dooks .id_table = s3c_fb_driver_ids, 2046ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks .driver = { 2047ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks .name = "s3c-fb", 2048ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks .owner = THIS_MODULE, 2049fe05f8b1c3d28e6204a9ec54dec0d68af6cbf4c8Mark Brown .pm = &s3cfb_pm_ops, 2050ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks }, 2051ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks}; 2052ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 20534277f2c4667187cbbdd3da3be31ee681bc6b8300Axel Linmodule_platform_driver(s3c_fb_driver); 2054ec549a0fdc32171b26677f1ef0b5309faa743362Ben Dooks 2055ec549a0fdc32171b26677f1ef0b5309faa743362Ben DooksMODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); 2056ec549a0fdc32171b26677f1ef0b5309faa743362Ben DooksMODULE_DESCRIPTION("Samsung S3C SoC Framebuffer driver"); 2057ec549a0fdc32171b26677f1ef0b5309faa743362Ben DooksMODULE_LICENSE("GPL"); 2058ec549a0fdc32171b26677f1ef0b5309faa743362Ben DooksMODULE_ALIAS("platform:s3c-fb"); 2059